From e9ee40ac878de7658a1e7f6293249fac6cfda87c Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Mon, 15 Jul 2024 16:33:59 +0200 Subject: [PATCH 0001/2205] DPL Analysis: data model: allow to specify the column/branch name explicitly for an index column (#13291) --- Framework/Core/include/Framework/ASoA.h | 460 ++++++++++++------------ 1 file changed, 233 insertions(+), 227 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index fa9888a698790..4c5a1a8b4c50c 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2033,246 +2033,250 @@ std::tuple getRowData(arrow::Table* table, T rowIterator, /// Array index: return an array of iterators, defined by values in its elements /// SLICE -#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) \ - struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ - static constexpr const char* mLabel = "fIndexSlice" #_Table_ _Suffix_; \ - using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \ - using type = _Type_[2]; \ - using column_t = _Name_##IdSlice; \ - using binding_t = _Table_; \ - _Name_##IdSlice(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##IdSlice() = default; \ - _Name_##IdSlice(_Name_##IdSlice const& other) = default; \ - _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \ - std::array<_Type_, 2> inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - bool has_##_Getter_() const \ - { \ - auto a = *mColumnIterator; \ - return a[0] >= 0 && a[1] >= 0; \ - } \ - \ - std::array<_Type_, 2> _Getter_##Ids() const \ - { \ - auto a = *mColumnIterator; \ - return std::array{a[0], a[1]}; \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ - } \ - if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ - return t->emptySlice(); \ - } \ - auto a = *mColumnIterator; \ - auto r = t->rawSlice(a[0], a[1]); \ - t->copyIndexBindings(r); \ - r.bindInternalIndicesTo(t); \ - return r; \ - } \ - \ - auto _Getter_() const \ - { \ - return _Getter_##_as(); \ - } \ - \ - template \ - bool setCurrent(T const* current) \ - { \ - if constexpr (o2::soa::is_binding_compatible_v()) { \ - assert(current != nullptr); \ - this->mBinding.bind(current); \ - return true; \ - } \ - return false; \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - binding_t const* getCurrent() const { return mBinding.get(); } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ +#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ + struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ + static constexpr const char* mLabel = "fIndexSlice" _Label_ _Suffix_; \ + using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \ + using type = _Type_[2]; \ + using column_t = _Name_##IdSlice; \ + using binding_t = _Table_; \ + _Name_##IdSlice(arrow::ChunkedArray const* column) \ + : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##IdSlice() = default; \ + _Name_##IdSlice(_Name_##IdSlice const& other) = default; \ + _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \ + std::array<_Type_, 2> inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + bool has_##_Getter_() const \ + { \ + auto a = *mColumnIterator; \ + return a[0] >= 0 && a[1] >= 0; \ + } \ + \ + std::array<_Type_, 2> _Getter_##Ids() const \ + { \ + auto a = *mColumnIterator; \ + return std::array{a[0], a[1]}; \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \ + return t->emptySlice(); \ + } \ + auto a = *mColumnIterator; \ + auto r = t->rawSlice(a[0], a[1]); \ + t->copyIndexBindings(r); \ + r.bindInternalIndicesTo(t); \ + return r; \ + } \ + \ + auto _Getter_() const \ + { \ + return _Getter_##_as(); \ + } \ + \ + template \ + bool setCurrent(T const* current) \ + { \ + if constexpr (o2::soa::is_binding_compatible_v()) { \ + assert(current != nullptr); \ + this->mBinding.bind(current); \ + return true; \ + } \ + return false; \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + binding_t const* getCurrent() const { return mBinding.get(); } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ }; +#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") +#define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") /// ARRAY -#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) \ - struct _Name_##Ids : o2::soa::Column, _Name_##Ids> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ - static constexpr const char* mLabel = "fIndexArray" #_Table_ _Suffix_; \ - using base = o2::soa::Column, _Name_##Ids>; \ - using type = std::vector<_Type_>; \ - using column_t = _Name_##Ids; \ - using binding_t = _Table_; \ - _Name_##Ids(arrow::ChunkedArray const* column) \ - : o2::soa::Column, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Ids() = default; \ - _Name_##Ids(_Name_##Ids const& other) = default; \ - _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - \ - gsl::span inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - gsl::span _Getter_##Ids() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return !(*mColumnIterator).empty(); \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ - } \ - return getIterators(); \ - } \ - \ - template \ - auto filtered_##_Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ - } \ - return getFilteredIterators(); \ - } \ - \ - template \ - auto getIterators() const \ - { \ - auto result = std::vector(); \ - for (auto& i : *mColumnIterator) { \ - result.push_back(mBinding.get()->rawIteratorAt(i)); \ - } \ - return result; \ - } \ - \ - template \ - std::vector getFilteredIterators() const \ - { \ - if constexpr (o2::soa::is_soa_filtered_v) { \ - auto result = std::vector(); \ - for (auto const& i : *mColumnIterator) { \ - auto pos = mBinding.get()->isInSelectedRows(i); \ - if (pos > 0) { \ - result.push_back(mBinding.get()->iteratorAt(pos)); \ - } \ - } \ - return result; \ - } else { \ - static_assert(o2::framework::always_static_assert_v, "T is not a Filtered type"); \ - } \ - return {}; \ - } \ - \ - auto _Getter_() const \ - { \ - return _Getter_##_as(); \ - } \ - \ - template \ - auto _Getter_##_first_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ - } \ - return t->rawIteratorAt((*mColumnIterator)[0]); \ - } \ - \ - template \ - auto _Getter_##_last_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ - } \ - return t->rawIteratorAt((*mColumnIterator).back()); \ - } \ - \ - auto _Getter_first() const \ - { \ - return _Getter_##_first_as(); \ - } \ - \ - auto _Getter_last() const \ - { \ - return _Getter_##_last_as(); \ - } \ - \ - template \ - bool setCurrent(T const* current) \ - { \ - if constexpr (o2::soa::is_binding_compatible_v()) { \ - assert(current != nullptr); \ - this->mBinding.bind(current); \ - return true; \ - } \ - return false; \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - binding_t const* getCurrent() const { return mBinding.get(); } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ +#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ + struct _Name_##Ids : o2::soa::Column, _Name_##Ids> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ + static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \ + using base = o2::soa::Column, _Name_##Ids>; \ + using type = std::vector<_Type_>; \ + using column_t = _Name_##Ids; \ + using binding_t = _Table_; \ + _Name_##Ids(arrow::ChunkedArray const* column) \ + : o2::soa::Column, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Ids() = default; \ + _Name_##Ids(_Name_##Ids const& other) = default; \ + _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ + \ + gsl::span inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + gsl::span _Getter_##Ids() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return !(*mColumnIterator).empty(); \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return getIterators(); \ + } \ + \ + template \ + auto filtered_##_Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return getFilteredIterators(); \ + } \ + \ + template \ + auto getIterators() const \ + { \ + auto result = std::vector(); \ + for (auto& i : *mColumnIterator) { \ + result.push_back(mBinding.get()->rawIteratorAt(i)); \ + } \ + return result; \ + } \ + \ + template \ + std::vector getFilteredIterators() const \ + { \ + if constexpr (o2::soa::is_soa_filtered_v) { \ + auto result = std::vector(); \ + for (auto const& i : *mColumnIterator) { \ + auto pos = mBinding.get()->isInSelectedRows(i); \ + if (pos > 0) { \ + result.push_back(mBinding.get()->iteratorAt(pos)); \ + } \ + } \ + return result; \ + } else { \ + static_assert(o2::framework::always_static_assert_v, "T is not a Filtered type"); \ + } \ + return {}; \ + } \ + \ + auto _Getter_() const \ + { \ + return _Getter_##_as(); \ + } \ + \ + template \ + auto _Getter_##_first_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return t->rawIteratorAt((*mColumnIterator)[0]); \ + } \ + \ + template \ + auto _Getter_##_last_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return t->rawIteratorAt((*mColumnIterator).back()); \ + } \ + \ + auto _Getter_first() const \ + { \ + return _Getter_##_first_as(); \ + } \ + \ + auto _Getter_last() const \ + { \ + return _Getter_##_last_as(); \ + } \ + \ + template \ + bool setCurrent(T const* current) \ + { \ + if constexpr (o2::soa::is_binding_compatible_v()) { \ + assert(current != nullptr); \ + this->mBinding.bind(current); \ + return true; \ + } \ + return false; \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + binding_t const* getCurrent() const { return mBinding.get(); } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ }; +#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") +#define DECLARE_SOA_ARRAY_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") /// NORMAL -#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) \ +#define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ - static constexpr const char* mLabel = "fIndex" #_Table_ _Suffix_; \ + static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \ using base = o2::soa::Column<_Type_, _Name_##Id>; \ using type = _Type_; \ using column_t = _Name_##Id; \ @@ -2344,7 +2348,9 @@ std::tuple getRowData(arrow::Table* table, T rowIterator, [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" #_Table_ _Suffix_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \ o2::framework::expressions::selectArrowType<_Type_>() } +#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") +#define DECLARE_SOA_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") /// SELF #define DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) \ From f20ca6dc347ba1943713c12981e6a6792f1ca579 Mon Sep 17 00:00:00 2001 From: Sergio Garcia <47090312+singiamtel@users.noreply.github.com> Date: Wed, 17 Jul 2024 12:15:02 +0200 Subject: [PATCH 0002/2205] Switch actions from hub to gh cli (#13303) GH actions no longer provide `hub` in the path by default so we're switching to `gh`. Follow-up to https://github.com/AliceO2Group/AliceO2/issues/13300 --- .github/workflows/datamodel-doc.yml | 12 +++++++----- .github/workflows/reports.yml | 11 +++-------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/datamodel-doc.yml b/.github/workflows/datamodel-doc.yml index 8b07cbed9d54b..41a181b490029 100644 --- a/.github/workflows/datamodel-doc.yml +++ b/.github/workflows/datamodel-doc.yml @@ -68,9 +68,11 @@ jobs: git push -f origin auto-datamodel-doc # Send pull request - # We need to use "hub" ourselves because alisw/pull-request gets + # We need to use "gh" ourselves because alisw/pull-request gets # confused when multiple repos are checked out. - hub pull-request -b AliceO2Group:master -h alibuild:auto-datamodel-doc \ - --no-edit --no-maintainer-edits -m 'Automatic data model update' \ - -m "This update to the data model documentation was automatically created from tonight's O2 dev branch." || - : # If the PR already exists, hub fails, but we've just force-pushed, so we don't need a new PR. + GH_TOKEN=${{ secrets.GITHUB_TOKEN }} gh pr create -B \ + AliceO2Group:master -H alibuild:auto-datamodel-doc \ + --no-maintainer-edit -t 'Automatic data model update' -b 'This update \ + to the data model documentation was automatically created from \ + tonight's O2 dev branch.' || true + # If the PR already exists, hub fails, but we've just force-pushed, so we don't need a new PR. diff --git a/.github/workflows/reports.yml b/.github/workflows/reports.yml index affd78216b50e..0762debd04d54 100644 --- a/.github/workflows/reports.yml +++ b/.github/workflows/reports.yml @@ -126,11 +126,6 @@ jobs: git config --global user.name "GitHub Action Bot" git commit -m "Updated README" -a || echo "No changes to commit" git push origin HEAD:changelog -f - GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \ - hub pull-request -f -b dev -h changelog \ - --no-edit --no-maintainer-edits \ - 'Auto-generated changelog' \ - -m 'The following changelog has been automatically generated.' || - # If the PR already exists, the force-push will have updated it. - # It's fine if this step fails. - true + # If the PR already exists, the force-push will have updated it. + # It's fine if this step fails. + GH_TOKEN=${{ secrets.GITHUB_TOKEN }} gh pr create -B dev -H changelog -t 'Auto-generated changelog' -b 'The following changelog has been automatically generated.' || true From 99756dc750f6f457fa0ee46a73f2e53bbedd2a9b Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 17 Jul 2024 15:46:28 +0200 Subject: [PATCH 0003/2205] Do not init refitter if no TPC tracks available --- .../GlobalTrackingWorkflow/study/src/TPCTrackStudy.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TPCTrackStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TPCTrackStudy.cxx index ca28aa24c9115..1cb108da5a460 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TPCTrackStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TPCTrackStudy.cxx @@ -184,9 +184,11 @@ void TPCTrackStudySpec::process(o2::globaltracking::RecoContainer& recoData) intRecs = digCont->getEventRecords(); mTPCTrkLabels = recoData.getTPCTracksMCLabels(); } - - mTPCRefitter = std::make_unique(mTPCClusterIdxStruct, &mTPCCorrMapsLoader, prop->getNominalBz(), mTPCTrackClusIdx.data(), 0, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size(), nullptr, o2::base::Propagator::Instance()); - mTPCRefitter->setTrackReferenceX(900); // disable propagation after refit by setting reference to value > 500 + if (mTPCTracksArray.size()) { + LOGP(info, "Found {} TPC tracks", mTPCTracksArray.size()); + mTPCRefitter = std::make_unique(mTPCClusterIdxStruct, &mTPCCorrMapsLoader, prop->getNominalBz(), mTPCTrackClusIdx.data(), 0, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size(), nullptr, o2::base::Propagator::Instance()); + mTPCRefitter->setTrackReferenceX(900); // disable propagation after refit by setting reference to value > 500 + } float vdriftTB = mTPCVDriftHelper.getVDriftObject().getVDrift() * o2::tpc::ParameterElectronics::Instance().ZbinWidth; // VDrift expressed in cm/TimeBin float tpcTBBias = mTPCVDriftHelper.getVDriftObject().getTimeOffset() / (8 * o2::constants::lhc::LHCBunchSpacingMUS); std::vector clSector, clRow; From 5fc78af699388a6d01fd79a637f2982298d2008e Mon Sep 17 00:00:00 2001 From: pillot Date: Tue, 14 May 2024 19:07:56 +0200 Subject: [PATCH 0004/2205] change settings for MUON_SYNC_RECO --- prodtests/full-system-test/dpl-workflow.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prodtests/full-system-test/dpl-workflow.sh b/prodtests/full-system-test/dpl-workflow.sh index ad31aed70e6cb..e94f1e070631c 100755 --- a/prodtests/full-system-test/dpl-workflow.sh +++ b/prodtests/full-system-test/dpl-workflow.sh @@ -335,10 +335,10 @@ if has_processing_step MUON_SYNC_RECO; then [[ -z ${ARGS_EXTRA_PROCESS_o2_mid_reco_workflow:-} ]] && ARGS_EXTRA_PROCESS_o2_mid_reco_workflow="--mid-tracker-keep-best" [[ -z ${ARGS_EXTRA_PROCESS_o2_mch_reco_workflow:-} ]] && ARGS_EXTRA_PROCESS_o2_mch_reco_workflow="--digits" if [[ -z ${CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow:-} ]]; then - if [[ $RUNTYPE == "PHYSICS" || $RUNTYPE == "COSMICS" ]]; then - CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow="MCHTracking.chamberResolutionX=0.4;MCHTracking.chamberResolutionY=0.4;MCHTracking.sigmaCutForTracking=7.;MCHDigitFilter.timeOffset=126;MCHTracking.sigmaCutForImprovement=6.;MCHTracking.maxCandidates=20000;" + if [[ $RUNTYPE == "PHYSICS" && $BEAMTYPE == "pp" ]] || [[ $RUNTYPE == "COSMICS" ]]; then + CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow="MCHTracking.chamberResolutionX=0.4;MCHTracking.chamberResolutionY=0.4;MCHTracking.sigmaCutForTracking=7.;MCHTracking.sigmaCutForImprovement=6.;" elif [[ $RUNTYPE == "SYNTHETIC" ]]; then - CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow="MCHTimeClusterizer.peakSearchSignalOnly=false;MCHDigitFilter.rejectBackground=false;MCHTracking.chamberResolutionX=0.4;MCHTracking.chamberResolutionY=0.4;MCHTracking.sigmaCutForTracking=7.;MCHTracking.sigmaCutForImprovement=6.;" + CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow="MCHTimeClusterizer.peakSearchSignalOnly=false;MCHDigitFilter.rejectBackground=false;" fi has_detector_reco ITS && [[ $RUNTYPE != "COSMICS" ]] && CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow+="MCHTimeClusterizer.irFramesOnly=true;" [[ ! -z ${CUT_RANDOM_FRACTION_MCH:-} ]] && CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow+="MCHTimeClusterizer.rofRejectionFraction=$CUT_RANDOM_FRACTION_MCH;" From 710d1c80fe70f6c689b85d07a2153b47a2eb99aa Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 18 Jul 2024 23:46:57 +0200 Subject: [PATCH 0005/2205] ITS: Add second iteration for the seeding vertexer (#13306) * Add iteration structure * Overrule size of vector param with specific config value, for pp/PbPb * Propagate CKVals only to the first iteration * Add UPC vertices to the output * MC: assign a single flag to each vertex + purity * Improve logging * Tag vertices with iteration * Add DeltaROF skipping to the tracker * Add in-iteration deltaRof filtering * Add 4th iteration for UPCs * Skip second iteration vertices in first three iterations of the tracking --- .../ReconstructionDataFormats/Vertex.h | 2 +- .../GPU/ITStrackingGPU/VertexerTraitsGPU.h | 10 +- .../tracking/GPU/cuda/VertexerTraitsGPU.cu | 44 ++--- .../include/ITStracking/Configuration.h | 3 + .../tracking/include/ITStracking/TimeFrame.h | 30 +++- .../include/ITStracking/TrackingConfigParam.h | 3 + .../tracking/include/ITStracking/Vertexer.h | 30 +++- .../include/ITStracking/VertexerTraits.h | 39 +++-- .../ITSMFT/ITS/tracking/src/TimeFrame.cxx | 164 ++++++++++-------- Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx | 6 +- .../ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 7 +- .../ITS/tracking/src/TrackingInterface.cxx | 64 +++++-- .../ITSMFT/ITS/tracking/src/Vertexer.cxx | 67 +++---- .../ITS/tracking/src/VertexerTraits.cxx | 131 ++++++++------ .../ITS/workflow/src/TrackWriterSpec.cxx | 5 +- .../ITSMFT/ITS/workflow/src/TrackerSpec.cxx | 1 + .../ITS3/workflow/src/TrackWriterSpec.cxx | 2 + .../ITS3/workflow/src/TrackerSpec.cxx | 10 +- 18 files changed, 390 insertions(+), 228 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h index bbc2c01359276..24ae636db560e 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h @@ -141,7 +141,7 @@ class Vertex : public VertexBase GPUd() ushort getFlags() const { return mBits; } GPUd() bool isFlagSet(uint f) const { return mBits & (FlagsMask & f); } GPUd() void setFlags(ushort f) { mBits |= FlagsMask & f; } - GPUd() void resetFrags(ushort f = FlagsMask) { mBits &= ~(FlagsMask & f); } + GPUd() void resetFlags(ushort f = FlagsMask) { mBits &= ~(FlagsMask & f); } GPUd() void setChi2(float v) { mChi2 = v; } GPUd() float getChi2() const { return mChi2; } diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexerTraitsGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexerTraitsGPU.h index fda67bb619d37..6b7e79a187745 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexerTraitsGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexerTraitsGPU.h @@ -42,11 +42,11 @@ class VertexerTraitsGPU : public VertexerTraits public: VertexerTraitsGPU(); ~VertexerTraitsGPU() override; - void initialise(const TrackingParameters&) override; + void initialise(const TrackingParameters&, const int iteration = 0) override; void adoptTimeFrame(TimeFrame*) override; - void computeTracklets() override; - void computeTrackletMatching() override; - void computeVertices() override; + void computeTracklets(const int iteration = 0) override; + void computeTrackletMatching(const int iteration = 0) override; + void computeVertices(const int iteration = 0) override; // Hybrid void initialiseHybrid(const TrackingParameters& pars) override { VertexerTraits::initialise(pars); } @@ -55,7 +55,7 @@ class VertexerTraitsGPU : public VertexerTraits void computeTrackletMatchingHybrid() override { VertexerTraits::computeTrackletMatching(); } void computeVerticesHybrid() override { VertexerTraits::computeVertices(); } - void updateVertexingParameters(const VertexingParameters&, const TimeFrameGPUParameters&) override; + void updateVertexingParameters(const std::vector&, const TimeFrameGPUParameters&) override; void computeVerticesHist(); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu index 9a1ed507ae5a4..d18f9ecc0b7cb 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu @@ -95,7 +95,7 @@ VertexerTraitsGPU::~VertexerTraitsGPU() { } -void VertexerTraitsGPU::initialise(const TrackingParameters& trackingParams) +void VertexerTraitsGPU::initialise(const TrackingParameters& trackingParams, const int iteration) { mTimeFrameGPU->initialise(0, trackingParams, 3, &mIndexTableUtils, &mTfGPUParams); } @@ -595,17 +595,19 @@ GPUg() void computeVertexKernel( } } // namespace gpu -void VertexerTraitsGPU::updateVertexingParameters(const VertexingParameters& vrtPar, const TimeFrameGPUParameters& tfPar) +void VertexerTraitsGPU::updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& tfPar) { mVrtParams = vrtPar; mTfGPUParams = tfPar; - mIndexTableUtils.setTrackingParameters(vrtPar); - mVrtParams.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * mVrtParams.phiCut / - constants::math::TwoPi)); - mVrtParams.zSpan = static_cast(std::ceil(mVrtParams.zCut * mIndexTableUtils.getInverseZCoordinate(0))); + mVrtParams = vrtPar; + mIndexTableUtils.setTrackingParameters(vrtPar[0]); + for (auto& par : mVrtParams) { + par.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * par.phiCut / constants::math::TwoPi)); + par.zSpan = static_cast(std::ceil(par.zCut * mIndexTableUtils.getInverseZCoordinate(0))); + } } -void VertexerTraitsGPU::computeTracklets() +void VertexerTraitsGPU::computeTracklets(const int iteration) { if (!mTimeFrameGPU->getClusters().size()) { return; @@ -635,8 +637,8 @@ void VertexerTraitsGPU::computeTracklets() mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, offset, // const unsigned int startRofId, rofs, // const unsigned int rofSize, - mVrtParams.phiCut, // const float phiCut, - mVrtParams.maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 + mVrtParams[iteration].phiCut, // const float phiCut, + mVrtParams[iteration].maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 gpu::trackleterKernelMultipleRof<<getStream(chunkId).get()>>>( mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(2), // const Cluster* clustersNextLayer, // 0 2 @@ -649,8 +651,8 @@ void VertexerTraitsGPU::computeTracklets() mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, offset, // const unsigned int startRofId, rofs, // const unsigned int rofSize, - mVrtParams.phiCut, // const float phiCut, - mVrtParams.maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 + mVrtParams[iteration].phiCut, // const float phiCut, + mVrtParams[iteration].maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 gpu::trackletSelectionKernelMultipleRof<<getStream(chunkId).get()>>>( mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clusters0, // Clusters on layer 0 @@ -667,9 +669,9 @@ void VertexerTraitsGPU::computeTracklets() mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan offset, // const unsigned int startRofId, // Starting ROF ID rofs, // const unsigned int rofSize, // Number of ROFs to consider - mVrtParams.maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster - mVrtParams.tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda - mVrtParams.phiCut); // const float phiCut = 0.002f) // Cut on phi + mVrtParams[iteration].maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster + mVrtParams[iteration].tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda + mVrtParams[iteration].phiCut); // const float phiCut = 0.002f) // Cut on phi discardResult(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, @@ -681,7 +683,7 @@ void VertexerTraitsGPU::computeTracklets() // Reset used tracklets checkGPUError(cudaMemsetAsync(mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), false, - sizeof(unsigned char) * mVrtParams.maxTrackletsPerCluster * mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), + sizeof(unsigned char) * mVrtParams[iteration].maxTrackletsPerCluster * mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), mTimeFrameGPU->getStream(chunkId).get()), __FILE__, __LINE__); @@ -700,9 +702,9 @@ void VertexerTraitsGPU::computeTracklets() mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan offset, // const unsigned int startRofId, // Starting ROF ID rofs, // const unsigned int rofSize, // Number of ROFs to consider - mVrtParams.maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster - mVrtParams.tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda - mVrtParams.phiCut); // const float phiCut = 0.002f) // Cut on phi + mVrtParams[iteration].maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster + mVrtParams[iteration].tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda + mVrtParams[iteration].phiCut); // const float phiCut = 0.002f) // Cut on phi int nClusters = mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1); int lastFoundLines; @@ -758,7 +760,7 @@ void VertexerTraitsGPU::computeTracklets() gsl::span rofVerts{mTimeFrameGPU->getVerticesInChunks()[chunkId].data() + start, static_cast::size_type>(mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId])}; mTimeFrameGPU->addPrimaryVertices(rofVerts); if (mTimeFrameGPU->hasMCinformation()) { - mTimeFrameGPU->getVerticesLabels().emplace_back(); + // mTimeFrameGPU->getVerticesLabels().emplace_back(); // TODO: add MC labels } start += mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId]; @@ -767,11 +769,11 @@ void VertexerTraitsGPU::computeTracklets() mTimeFrameGPU->wipe(3); } -void VertexerTraitsGPU::computeTrackletMatching() +void VertexerTraitsGPU::computeTrackletMatching(const int iteration) { } -void VertexerTraitsGPU::computeVertices() +void VertexerTraitsGPU::computeVertices(const int iteration) { } diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h index a700dc1e806c0..17844e8338067 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h @@ -98,6 +98,7 @@ struct TrackingParameters { bool FindShortTracks = false; bool PerPrimaryVertexProcessing = false; bool SaveTimeBenchmarks = false; + bool DoUPCIteration = false; }; inline int TrackingParameters::CellMinimumLevel() @@ -106,6 +107,8 @@ inline int TrackingParameters::CellMinimumLevel() } struct VertexingParameters { + int nIterations = 1; // Number of vertexing passes to perform + int vertPerRofThreshold = 0; // Maximum number of vertices per ROF to trigger second a round bool allowSingleContribClusters = false; std::vector LayerZ = {16.333f + 1, 16.333f + 1, 16.333f + 1, 42.140f + 1, 42.140f + 1, 73.745f + 1, 73.745f + 1}; std::vector LayerRadii = {2.33959f, 3.14076f, 3.91924f, 19.6213f, 24.5597f, 34.388f, 39.3329f}; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index 5d222e58f2586..de83d37d6c430 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -80,13 +80,16 @@ class TimeFrame const Vertex& getPrimaryVertex(const int) const; gsl::span getPrimaryVertices(int tf) const; gsl::span getPrimaryVertices(int romin, int romax) const; - gsl::span> getPrimaryVerticesLabels(const int rof) const; + gsl::span> getPrimaryVerticesMCRecInfo(const int rof) const; gsl::span> getPrimaryVerticesXAlpha(int tf) const; void fillPrimaryVerticesXandAlpha(); int getPrimaryVerticesNum(int rofID = -1) const; void addPrimaryVertices(const std::vector& vertices); + void addPrimaryVerticesLabels(std::vector>& labels); void addPrimaryVertices(const gsl::span& vertices); void addPrimaryVertices(const std::vector&); + void addPrimaryVerticesInROF(const std::vector& vertices, const int rofId); + void addPrimaryVerticesLabelsInROF(const std::vector>& labels, const int rofId); void removePrimaryVerticesInROf(const int rofId); int loadROFrameData(const o2::itsmft::ROFRecord& rof, gsl::span clusters, const dataformats::MCTruthContainer* mcLabels = nullptr); @@ -98,6 +101,7 @@ class TimeFrame const dataformats::MCTruthContainer* mcLabels = nullptr); int getTotalClusters() const; + std::vector& getTotVertIteration() { return mTotVertPerIteration; } bool empty() const; bool isGPU() const { return mIsGPU; } int getSortedIndex(int rof, int layer, int i) const; @@ -143,7 +147,7 @@ class TimeFrame std::vector& getCellsLabel(int layer) { return mCellLabels[layer]; } bool hasMCinformation() const; - void initialise(const int iteration, const TrackingParameters& trkParam, const int maxLayers = 7); + void initialise(const int iteration, const TrackingParameters& trkParam, const int maxLayers = 7, bool resetVertices = true); void resetRofPV() { mPrimaryVertices.clear(); @@ -168,7 +172,7 @@ class TimeFrame std::vector& getTracks(int rof) { return mTracks[rof]; } std::vector& getTracksLabel(const int rof) { return mTracksLabel[rof]; } std::vector& getLinesLabel(const int rof) { return mLinesLabels[rof]; } - std::vector>& getVerticesLabels() { return mVerticesLabels; } + std::vector>& getVerticesMCRecInfo() { return mVerticesMCRecInfo; } int getNumberOfClusters() const; int getNumberOfCells() const; @@ -195,6 +199,7 @@ class TimeFrame uint32_t getTotalTrackletsTF(const int iLayer) { return mTotalTracklets[iLayer]; } int getTotalClustersPerROFrange(int rofMin, int range, int layerId) const; std::array& getBeamXY() { return mBeamPos; } + unsigned int& getNoVertexROF() { return mNoVertexROF; } // \Vertexer void initialiseRoadLabels(); @@ -203,6 +208,8 @@ class TimeFrame bool isRoadFake(int i) const; void setMultiplicityCutMask(const std::vector& cutMask) { mMultiplicityCutMask = cutMask; } + void setROFMask(const std::vector& rofMask) { mROFMask = rofMask; } + void swapMasks() { mMultiplicityCutMask.swap(mROFMask); } int hasBogusClusters() const { return std::accumulate(mBogusClusters.begin(), mBogusClusters.end(), 0); } @@ -220,7 +227,10 @@ class TimeFrame } } - virtual void setDevicePropagator(const o2::base::PropagatorImpl*){}; + virtual void setDevicePropagator(const o2::base::PropagatorImpl*) + { + return; + }; const o2::base::PropagatorImpl* getDevicePropagator() const { return mPropagatorDevice; } template @@ -233,6 +243,7 @@ class TimeFrame void setExtAllocator(bool ext) { mExtAllocator = ext; } bool getExtAllocator() const { return mExtAllocator; } + /// Debug and printing void checkTrackletLUTs(); void printROFoffsets(); @@ -282,7 +293,9 @@ class TimeFrame } private: + void prepareClusters(const TrackingParameters& trkParam, const int maxLayers); float mBz = 5.; + unsigned int mNTotalLowPtVertices = 0; int mBeamPosWeight = 0; std::array mBeamPos = {0.f, 0.f}; bool isBeamPositionOverridden = false; @@ -293,6 +306,7 @@ class TimeFrame std::vector mPositionResolution; std::vector mClusterSize; std::vector mMultiplicityCutMask; + std::vector mROFMask; std::vector> mPValphaX; /// PV x and alpha for track propagation std::vector> mTrackletLabels; std::vector> mCellLabels; @@ -311,8 +325,10 @@ class TimeFrame std::vector> mTrackletClusters; std::vector> mTrackletsIndexROf; std::vector> mLinesLabels; - std::vector> mVerticesLabels; + std::vector> mVerticesMCRecInfo; std::array mTotalTracklets = {0, 0}; + unsigned int mNoVertexROF = 0; + std::vector mTotVertPerIteration; // \Vertexer }; @@ -326,12 +342,12 @@ inline gsl::span TimeFrame::getPrimaryVertices(int rof) const return {&mPrimaryVertices[start], static_cast::size_type>(delta)}; } -inline gsl::span> TimeFrame::getPrimaryVerticesLabels(const int rof) const +inline gsl::span> TimeFrame::getPrimaryVerticesMCRecInfo(const int rof) const { const int start = mROframesPV[rof]; const int stop_idx = rof >= mNrof - 1 ? mNrof : rof + 1; int delta = mMultiplicityCutMask[rof] ? mROframesPV[stop_idx] - start : 0; // return empty span if Rof is excluded - return {&mVerticesLabels[start], static_cast::size_type>(delta)}; + return {&(mVerticesMCRecInfo[start]), static_cast>::size_type>(delta)}; } inline gsl::span TimeFrame::getPrimaryVertices(int romin, int romax) const diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h index 36a5fd63b12d1..e76c77008120f 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h @@ -22,6 +22,8 @@ namespace its struct VertexerParamConfig : public o2::conf::ConfigurableParamHelper { + int nIterations = 1; // Number of vertexing passes to perform + int vertPerRofThreshold = 0; // Maximum number of vertices per ROF to trigger second a round bool allowSingleContribClusters = false; // geometrical cuts @@ -80,6 +82,7 @@ struct TrackerParamConfig : public o2::conf::ConfigurableParamHelper& getVertParameters() const; + void setParameters(std::vector& vertParams); void getGlobalConfiguration(); std::vector exportVertices(); @@ -62,8 +63,6 @@ class Vertexer float clustersToVertices(std::function = [](std::string s) { std::cout << s << std::endl; }); float clustersToVerticesHybrid(std::function = [](std::string s) { std::cout << s << std::endl; }); void filterMCTracklets(); - void validateTracklets(); - void validateTrackletsHybrid(); template void findTracklets(T&&... args); @@ -71,7 +70,11 @@ class Vertexer void findTrackletsHybrid(T&&... args); void findTrivialMCTracklets(); - void findVertices(); + template + void validateTracklets(T&&... args); + void validateTrackletsHybrid(); + template + void findVertices(T&&... args); void findVerticesHybrid(); void findHistVertices(); @@ -95,6 +98,8 @@ class Vertexer VertexerTraits* mTraits = nullptr; /// Observer pointer, not owned by this class TimeFrame* mTimeFrame = nullptr; /// Observer pointer, not owned by this class + + std::vector mVertParams; }; template @@ -109,24 +114,31 @@ void Vertexer::findTracklets(T&&... args) mTraits->computeTracklets(std::forward(args)...); } -inline VertexingParameters& Vertexer::getVertParameters() const +inline std::vector& Vertexer::getVertParameters() const { return mTraits->getVertexingParameters(); } +inline void Vertexer::setParameters(std::vector& vertParams) +{ + mVertParams = vertParams; +} + inline void Vertexer::dumpTraits() { mTraits->dumpVertexerTraits(); } -inline void Vertexer::validateTracklets() +template +inline void Vertexer::validateTracklets(T&&... args) { - mTraits->computeTrackletMatching(); + mTraits->computeTrackletMatching(std::forward(args)...); } -inline void Vertexer::findVertices() +template +inline void Vertexer::findVertices(T&&... args) { - mTraits->computeVertices(); + mTraits->computeVertices(std::forward(args)...); } template diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/VertexerTraits.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/VertexerTraits.h index 365a24cfaee62..2961488ab5dbf 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/VertexerTraits.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/VertexerTraits.h @@ -62,12 +62,12 @@ class VertexerTraits GPUhd() static const int2 getPhiBins(float phi, float deltaPhi, const IndexTableUtils&); // virtual vertexer interface - virtual void initialise(const TrackingParameters& trackingParams); - virtual void computeTracklets(); - virtual void computeTrackletMatching(); - virtual void computeVertices(); + virtual void initialise(const TrackingParameters& trackingParams, const int iteration = 0); + virtual void computeTracklets(const int iteration = 0); + virtual void computeTrackletMatching(const int iteration = 0); + virtual void computeVertices(const int iteration = 0); virtual void adoptTimeFrame(TimeFrame* tf); - virtual void updateVertexingParameters(const VertexingParameters& vrtPar, const TimeFrameGPUParameters& gpuTfPar); + virtual void updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& gpuTfPar); // Hybrid virtual void initialiseHybrid(const TrackingParameters& trackingParams) { initialise(trackingParams); }; virtual void computeTrackletsHybrid() { computeTracklets(); }; @@ -83,26 +83,43 @@ class VertexerTraits std::vector&, std::vector&, TimeFrame*, - std::vector*); + std::vector*, + const int iteration = 0); static const std::vector> selectClusters(const int* indexTable, const std::array& selectedBinsRect, const IndexTableUtils& utils); // utils - VertexingParameters& getVertexingParameters() { return mVrtParams; } - VertexingParameters getVertexingParameters() const { return mVrtParams; } + std::vector& getVertexingParameters() { return mVrtParams; } + std::vector getVertexingParameters() const { return mVrtParams; } void setIsGPU(const unsigned char isgpu) { mIsGPU = isgpu; }; + void setVertexingParameters(std::vector& vertParams) { mVrtParams = vertParams; } unsigned char getIsGPU() const { return mIsGPU; }; void dumpVertexerTraits(); void setNThreads(int n); int getNThreads() const { return mNThreads; } + template + static std::pair computeMain(const std::vector& elements) + { + T elem; + size_t maxCount = 0; + for (auto& element : elements) { + size_t count = std::count(elements.begin(), elements.end(), element); + if (count > maxCount) { + maxCount = count; + elem = element; + } + } + return std::make_pair(elem, static_cast(maxCount) / elements.size()); + } + protected: unsigned char mIsGPU; int mNThreads = 1; - VertexingParameters mVrtParams; + std::vector mVrtParams; IndexTableUtils mIndexTableUtils; std::vector mVertices; @@ -110,9 +127,9 @@ class VertexerTraits TimeFrame* mTimeFrame = nullptr; }; -inline void VertexerTraits::initialise(const TrackingParameters& trackingParams) +inline void VertexerTraits::initialise(const TrackingParameters& trackingParams, const int iteration) { - mTimeFrame->initialise(0, trackingParams, 3); + mTimeFrame->initialise(0, trackingParams, 3, (bool)(!iteration)); // iteration for initialisation must be 0 for correctly resetting the frame, we need to pass the non-reset flag for vertices as well, tho. setIsGPU(false); } diff --git a/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx b/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx index 6e7114d9ca54d..ab846197677a2 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx @@ -92,6 +92,24 @@ void TimeFrame::addPrimaryVertices(const std::vector& vertices) mROframesPV.push_back(mPrimaryVertices.size()); } +void TimeFrame::addPrimaryVerticesLabels(std::vector>& labels) +{ + mVerticesMCRecInfo.insert(mVerticesMCRecInfo.end(), labels.begin(), labels.end()); +} + +void TimeFrame::addPrimaryVerticesInROF(const std::vector& vertices, const int rofId) +{ + mPrimaryVertices.insert(mPrimaryVertices.begin() + mROframesPV[rofId], vertices.begin(), vertices.end()); + for (int i = rofId + 1; i < mROframesPV.size(); ++i) { + mROframesPV[i] += vertices.size(); + } +} + +void TimeFrame::addPrimaryVerticesLabelsInROF(const std::vector>& labels, const int rofId) +{ + mVerticesMCRecInfo.insert(mVerticesMCRecInfo.begin() + mROframesPV[rofId], labels.begin(), labels.end()); +} + void TimeFrame::addPrimaryVertices(const gsl::span& vertices) { for (const auto& vertex : vertices) { @@ -248,16 +266,86 @@ int TimeFrame::getTotalClusters() const return int(totalClusters); } -void TimeFrame::initialise(const int iteration, const TrackingParameters& trkParam, const int maxLayers) +void TimeFrame::prepareClusters(const TrackingParameters& trkParam, const int maxLayers) +{ + std::vector cHelper; + std::vector clsPerBin(trkParam.PhiBins * trkParam.ZBins, 0); + for (int rof{0}; rof < mNrof; ++rof) { + if ((int)mMultiplicityCutMask.size() == mNrof && !mMultiplicityCutMask[rof]) { + continue; + } + for (int iLayer{0}; iLayer < std::min(trkParam.NLayers, maxLayers); ++iLayer) { + std::fill(clsPerBin.begin(), clsPerBin.end(), 0); + const auto unsortedClusters{getUnsortedClustersOnLayer(rof, iLayer)}; + const int clustersNum{static_cast(unsortedClusters.size())}; + + deepVectorClear(cHelper); + cHelper.resize(clustersNum); + + for (int iCluster{0}; iCluster < clustersNum; ++iCluster) { + + const Cluster& c = unsortedClusters[iCluster]; + ClusterHelper& h = cHelper[iCluster]; + float x = c.xCoordinate - mBeamPos[0]; + float y = c.yCoordinate - mBeamPos[1]; + const float& z = c.zCoordinate; + float phi = math_utils::computePhi(x, y); + int zBin{mIndexTableUtils.getZBinIndex(iLayer, z)}; + if (zBin < 0) { + zBin = 0; + mBogusClusters[iLayer]++; + } else if (zBin >= trkParam.ZBins) { + zBin = trkParam.ZBins - 1; + mBogusClusters[iLayer]++; + } + int bin = mIndexTableUtils.getBinIndex(zBin, mIndexTableUtils.getPhiBinIndex(phi)); + h.phi = phi; + h.r = math_utils::hypot(x, y); + mMinR[iLayer] = o2::gpu::GPUCommonMath::Min(h.r, mMinR[iLayer]); + mMaxR[iLayer] = o2::gpu::GPUCommonMath::Max(h.r, mMaxR[iLayer]); + h.bin = bin; + h.ind = clsPerBin[bin]++; + } + std::vector lutPerBin(clsPerBin.size()); + lutPerBin[0] = 0; + for (unsigned int iB{1}; iB < lutPerBin.size(); ++iB) { + lutPerBin[iB] = lutPerBin[iB - 1] + clsPerBin[iB - 1]; + } + + auto clusters2beSorted{getClustersOnLayer(rof, iLayer)}; + for (int iCluster{0}; iCluster < clustersNum; ++iCluster) { + const ClusterHelper& h = cHelper[iCluster]; + + Cluster& c = clusters2beSorted[lutPerBin[h.bin] + h.ind]; + c = unsortedClusters[iCluster]; + c.phi = h.phi; + c.radius = h.r; + c.indexTableBinIndex = h.bin; + } + + for (unsigned int iB{0}; iB < clsPerBin.size(); ++iB) { + mIndexTables[iLayer][rof * (trkParam.ZBins * trkParam.PhiBins + 1) + iB] = lutPerBin[iB]; + } + for (auto iB{clsPerBin.size()}; iB < (trkParam.ZBins * trkParam.PhiBins + 1); iB++) { + mIndexTables[iLayer][rof * (trkParam.ZBins * trkParam.PhiBins + 1) + iB] = clustersNum; + } + } + } +} + +void TimeFrame::initialise(const int iteration, const TrackingParameters& trkParam, const int maxLayers, bool resetVertices) { if (iteration == 0) { - if (maxLayers < trkParam.NLayers) { + if (maxLayers < trkParam.NLayers && resetVertices) { resetRofPV(); + deepVectorClear(mTotVertPerIteration); } deepVectorClear(mTracks); deepVectorClear(mTracksLabel); deepVectorClear(mLinesLabels); - deepVectorClear(mVerticesLabels); + if (resetVertices) { + deepVectorClear(mVerticesMCRecInfo); + } mTracks.resize(mNrof); mTracksLabel.resize(mNrof); mLinesLabels.resize(mNrof); @@ -290,9 +378,6 @@ void TimeFrame::initialise(const int iteration, const TrackingParameters& trkPar v = std::vector(mNrof + 1, 0); } - std::vector cHelper; - std::vector clsPerBin(trkParam.PhiBins * trkParam.ZBins, 0); - for (int iLayer{0}; iLayer < trkParam.NLayers; ++iLayer) { if (trkParam.SystErrorY2[iLayer] > 0.f || trkParam.SystErrorZ2[iLayer] > 0.f) { for (auto& tfInfo : mTrackingFrameInfo[iLayer]) { @@ -302,70 +387,13 @@ void TimeFrame::initialise(const int iteration, const TrackingParameters& trkPar } } } - - for (int rof{0}; rof < mNrof; ++rof) { - if ((int)mMultiplicityCutMask.size() == mNrof && !mMultiplicityCutMask[rof]) { - continue; - } - for (int iLayer{0}; iLayer < std::min(trkParam.NLayers, maxLayers); ++iLayer) { - std::fill(clsPerBin.begin(), clsPerBin.end(), 0); - const auto unsortedClusters{getUnsortedClustersOnLayer(rof, iLayer)}; - const int clustersNum{static_cast(unsortedClusters.size())}; - - deepVectorClear(cHelper); - cHelper.resize(clustersNum); - - for (int iCluster{0}; iCluster < clustersNum; ++iCluster) { - - const Cluster& c = unsortedClusters[iCluster]; - ClusterHelper& h = cHelper[iCluster]; - float x = c.xCoordinate - mBeamPos[0]; - float y = c.yCoordinate - mBeamPos[1]; - const float& z = c.zCoordinate; - float phi = math_utils::computePhi(x, y); - int zBin{mIndexTableUtils.getZBinIndex(iLayer, z)}; - if (zBin < 0) { - zBin = 0; - mBogusClusters[iLayer]++; - } else if (zBin >= trkParam.ZBins) { - zBin = trkParam.ZBins - 1; - mBogusClusters[iLayer]++; - } - int bin = mIndexTableUtils.getBinIndex(zBin, mIndexTableUtils.getPhiBinIndex(phi)); - h.phi = phi; - h.r = math_utils::hypot(x, y); - mMinR[iLayer] = o2::gpu::GPUCommonMath::Min(h.r, mMinR[iLayer]); - mMaxR[iLayer] = o2::gpu::GPUCommonMath::Max(h.r, mMaxR[iLayer]); - h.bin = bin; - h.ind = clsPerBin[bin]++; - } - std::vector lutPerBin(clsPerBin.size()); - lutPerBin[0] = 0; - for (unsigned int iB{1}; iB < lutPerBin.size(); ++iB) { - lutPerBin[iB] = lutPerBin[iB - 1] + clsPerBin[iB - 1]; - } - - auto clusters2beSorted{getClustersOnLayer(rof, iLayer)}; - for (int iCluster{0}; iCluster < clustersNum; ++iCluster) { - const ClusterHelper& h = cHelper[iCluster]; - - Cluster& c = clusters2beSorted[lutPerBin[h.bin] + h.ind]; - c = unsortedClusters[iCluster]; - c.phi = h.phi; - c.radius = h.r; - c.indexTableBinIndex = h.bin; - } - - for (unsigned int iB{0}; iB < clsPerBin.size(); ++iB) { - mIndexTables[iLayer][rof * (trkParam.ZBins * trkParam.PhiBins + 1) + iB] = lutPerBin[iB]; - } - for (auto iB{clsPerBin.size()}; iB < (trkParam.ZBins * trkParam.PhiBins + 1); iB++) { - mIndexTables[iLayer][rof * (trkParam.ZBins * trkParam.PhiBins + 1) + iB] = clustersNum; - } - } - } + } + if (iteration == 0 || iteration == 3) { + prepareClusters(trkParam, maxLayers); } + mTotVertPerIteration.resize(1 + iteration); + mNoVertexROF = 0; deepVectorClear(mRoads); deepVectorClear(mRoadLabels); diff --git a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx index 42df15b24f052..b673874a45616 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx @@ -57,7 +57,9 @@ void Tracker::clustersToTracks(std::function logger, std::f } for (int iteration = 0; iteration < (int)mTrkParams.size(); ++iteration) { - + if (iteration == 3 && mTrkParams[0].DoUPCIteration) { + mTimeFrame->swapMasks(); + } logger(fmt::format("ITS Tracking iteration {} summary:", iteration)); double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.}; int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-static_cast(mTimeFrame->getNumberOfTracks())}; @@ -454,6 +456,7 @@ void Tracker::rectifyClusterIndices() void Tracker::getGlobalConfiguration() { + LOGP(info, "tracker::getGlobalConfiguration size of pars is {}", mTrkParams.size()); auto& tc = o2::its::TrackerParamConfig::Instance(); tc.printKeyValues(true, true); if (tc.useMatCorrTGeo) { @@ -476,6 +479,7 @@ void Tracker::getGlobalConfiguration() } } params.DeltaROF = tc.deltaRof; + params.DoUPCIteration = tc.doUPCIteration; params.MaxChi2ClusterAttachment = tc.maxChi2ClusterAttachment > 0 ? tc.maxChi2ClusterAttachment : params.MaxChi2ClusterAttachment; params.MaxChi2NDF = tc.maxChi2NDF > 0 ? tc.maxChi2NDF : params.MaxChi2NDF; params.PhiBins = tc.LUTbinsPhi > 0 ? tc.LUTbinsPhi : params.PhiBins; diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index 672e7370035e0..1722c05ecb4f6 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -70,8 +70,8 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in const Vertex diamondVert({mTrkParams[iteration].Diamond[0], mTrkParams[iteration].Diamond[1], mTrkParams[iteration].Diamond[2]}, {25.e-6f, 0.f, 0.f, 25.e-6f, 0.f, 36.f}, 1, 1.f); gsl::span diamondSpan(&diamondVert, 1); - int startROF{mTrkParams[iteration].nROFsPerIterations > 0 ? std::max(iROFslice * mTrkParams[iteration].nROFsPerIterations - mTrkParams[iteration].DeltaROF, 0) : 0}; - int endROF{mTrkParams[iteration].nROFsPerIterations > 0 ? std::min((iROFslice + 1) * mTrkParams[iteration].nROFsPerIterations + mTrkParams[iteration].DeltaROF, tf->getNrof()) : tf->getNrof()}; + int startROF{mTrkParams[iteration].nROFsPerIterations > 0 ? iROFslice * mTrkParams[iteration].nROFsPerIterations : 0}; + int endROF{mTrkParams[iteration].nROFsPerIterations > 0 ? (iROFslice + 1) * mTrkParams[iteration].nROFsPerIterations + mTrkParams[iteration].DeltaROF : tf->getNrof()}; for (int rof0{startROF}; rof0 < endROF; ++rof0) { gsl::span primaryVertices = mTrkParams[iteration].UseDiamond ? diamondSpan : tf->getPrimaryVertices(rof0); const int startVtx{iVertex >= 0 ? iVertex : 0}; @@ -98,6 +98,9 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in for (int iV{startVtx}; iV < endVtx; ++iV) { auto& primaryVertex{primaryVertices[iV]}; + if (primaryVertex.isFlagSet(1) && iteration != 3) { + continue; + } const float resolution = o2::gpu::CAMath::Sqrt(Sq(mTrkParams[iteration].PVres) / primaryVertex.getNContributors() + Sq(tf->getPositionResolution(iLayer))); const float tanLambda{(currentCluster.zCoordinate - primaryVertex.getZ()) * inverseR0}; diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx index 492976d164227..fd4c5bdc56486 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx @@ -33,31 +33,43 @@ void ITSTrackingInterface::initialise() { mRunVertexer = true; mCosmicsProcessing = false; + std::vector vertParams; std::vector trackParams; if (mMode == TrackingMode::Unset) { mMode = (TrackingMode)(o2::its::TrackerParamConfig::Instance().trackingMode); LOGP(info, "Tracking mode not set, trying to fetch it from configurable params to: {}", asString(mMode)); } if (mMode == TrackingMode::Async) { - trackParams.resize(3); + trackParams.resize(o2::its::TrackerParamConfig::Instance().doUPCIteration ? 4 : 3); + vertParams.resize(2); // The number of actual iterations will be set as a configKeyVal to allow for pp/PbPb choice + trackParams[1].TrackletMinPt = 0.2f; + trackParams[1].CellDeltaTanLambdaSigma *= 2.; + trackParams[2].TrackletMinPt = 0.1f; + trackParams[2].CellDeltaTanLambdaSigma *= 4.; + trackParams[2].MinTrackLength = 4; + if (o2::its::TrackerParamConfig::Instance().doUPCIteration) { + trackParams[3].TrackletMinPt = 0.1f; + trackParams[3].CellDeltaTanLambdaSigma *= 4.; + trackParams[3].MinTrackLength = 4; + trackParams[3].DeltaROF = 0; // UPC specific setting + } for (auto& param : trackParams) { param.ZBins = 64; param.PhiBins = 32; param.CellsPerClusterLimit = 1.e3f; param.TrackletsPerClusterLimit = 1.e3f; } - trackParams[1].TrackletMinPt = 0.2f; - trackParams[1].CellDeltaTanLambdaSigma *= 2.; - trackParams[2].TrackletMinPt = 0.1f; - trackParams[2].CellDeltaTanLambdaSigma *= 4.; - trackParams[2].MinTrackLength = 4; - LOG(info) << "Initializing tracker in async. phase reconstruction with " << trackParams.size() << " passes"; + LOGP(info, "Initializing tracker in async. phase reconstruction with {} passes for tracking and {}/{} for vertexing", trackParams.size(), o2::its::VertexerParamConfig::Instance().nIterations, vertParams.size()); + vertParams[1].phiCut = 0.015f; + vertParams[1].tanLambdaCut = 0.015f; + vertParams[1].vertPerRofThreshold = 0; } else if (mMode == TrackingMode::Sync) { trackParams.resize(1); trackParams[0].ZBins = 64; trackParams[0].PhiBins = 32; trackParams[0].MinTrackLength = 4; - LOG(info) << "Initializing tracker in sync. phase reconstruction with " << trackParams.size() << " passes"; + LOGP(info, "Initializing tracker in sync. phase reconstruction with {} passes", trackParams.size()); + vertParams.resize(1); } else if (mMode == TrackingMode::Cosmics) { mCosmicsProcessing = true; mRunVertexer = false; @@ -71,7 +83,7 @@ void ITSTrackingInterface::initialise() trackParams[0].MaxChi2NDF = 40.; trackParams[0].TrackletsPerClusterLimit = 100.; trackParams[0].CellsPerClusterLimit = 100.; - LOG(info) << "Initializing tracker in reconstruction for cosmics with " << trackParams.size() << " passes"; + LOGP(info, "Initializing tracker in reconstruction for cosmics with {} passes", trackParams.size()); } else { throw std::runtime_error(fmt::format("Unsupported ITS tracking mode {:s} ", asString(mMode))); @@ -81,6 +93,7 @@ void ITSTrackingInterface::initialise() params.CorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT; } mTracker->setParameters(trackParams); + mVertexer->setParameters(vertParams); } template @@ -130,8 +143,10 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) // MC static pmr::vector dummyMCLabTracks, dummyMCLabVerts; + static pmr::vector dummyMCPurVerts; auto& allTrackLabels = mIsMC ? pc.outputs().make>(Output{"ITS", "TRACKSMCTR", 0}) : dummyMCLabTracks; auto& allVerticesLabels = mIsMC ? pc.outputs().make>(Output{"ITS", "VERTICESMCTR", 0}) : dummyMCLabVerts; + auto& allVerticesPurities = mIsMC ? pc.outputs().make>(Output{"ITS", "VERTICESMCPUR", 0}) : dummyMCPurVerts; std::uint32_t roFrame = 0; @@ -159,8 +174,9 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) auto errorLogger = [&](std::string s) { LOG(error) << s; }; FastMultEst multEst; // mult estimator - std::vector processingMask; - int cutVertexMult{0}, cutRandomMult = int(rofs.size()) - multEst.selectROFs(rofs, compClusters, physTriggers, processingMask); + std::vector processingMask, processUPCMask; + int cutVertexMult{0}, cutUPCVertex{0}, cutRandomMult = int(rofs.size()) - multEst.selectROFs(rofs, compClusters, physTriggers, processingMask); + processUPCMask.resize(processingMask.size(), false); mTimeFrame->setMultiplicityCutMask(processingMask); float vertexerElapsedTime{0.f}; if (mRunVertexer) { @@ -175,12 +191,21 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) mTimeFrame->resetRofPV(); } const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts + gsl::span> vMCRecInfo; for (auto iRof{0}; iRof < rofspan.size(); ++iRof) { std::vector vtxVecLoc; auto& vtxROF = vertROFvec.emplace_back(rofspan[iRof]); vtxROF.setFirstEntry(vertices.size()); if (mRunVertexer) { auto vtxSpan = mTimeFrame->getPrimaryVertices(iRof); + if (mIsMC) { + vMCRecInfo = mTimeFrame->getPrimaryVerticesMCRecInfo(iRof); + } + if (o2::its::TrackerParamConfig::Instance().doUPCIteration && (vtxSpan.size() && vtxSpan[0].getFlags() == 1)) { // at least one vertex in this ROF and it is from second vertex iteration + LOGP(debug, "ROF {} rejected as vertices are from the UPC iteration", iRof); + processUPCMask[iRof] = true; + cutUPCVertex++; + } vtxROF.setNEntries(vtxSpan.size()); bool selROF = vtxSpan.size() == 0; for (auto iV{0}; iV < vtxSpan.size(); ++iV) { @@ -191,9 +216,8 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) selROF = true; vertices.push_back(v); if (mIsMC) { - auto vLabels = mTimeFrame->getPrimaryVerticesLabels(iRof)[iV]; - allVerticesLabels.reserve(allVerticesLabels.size() + vLabels.size()); - std::copy(vLabels.begin(), vLabels.end(), std::back_inserter(allVerticesLabels)); + allVerticesLabels.push_back(vMCRecInfo[iV].first); + allVerticesPurities.push_back(vMCRecInfo[iV].second); } } if (processingMask[iRof] && !selROF) { // passed selection in clusters and not in vertex multiplicity @@ -211,8 +235,14 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) mTimeFrame->addPrimaryVertices(vtxVecLoc); } } - LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}", cutRandomMult + cutVertexMult, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult); - LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} vertices found in {} ROFs", vertexerElapsedTime, mTimeFrame->getPrimaryVerticesNum(), rofspan.size()); + LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}, upc.sel:{}", cutRandomMult + cutVertexMult + cutUPCVertex, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult, cutUPCVertex); + LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} ({} + {}) vertices found in {}/{} ROFs", + vertexerElapsedTime, + mTimeFrame->getPrimaryVerticesNum(), + mTimeFrame->getTotVertIteration()[0], + o2::its::VertexerParamConfig::Instance().nIterations > 1 ? mTimeFrame->getTotVertIteration()[1] : 0, + rofspan.size() - mTimeFrame->getNoVertexROF(), + rofspan.size()); if (mOverrideBeamEstimation) { LOG(info) << fmt::format(" - Beam position set to: {}, {} from meanvertex object", mTimeFrame->getBeamX(), mTimeFrame->getBeamY()); @@ -224,6 +254,7 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) } else { mTimeFrame->setMultiplicityCutMask(processingMask); + mTimeFrame->setROFMask(processUPCMask); // Run CA tracker if constexpr (isGPU) { if (mMode == o2::its::TrackingMode::Async) { @@ -281,6 +312,7 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) if (mIsMC) { LOGP(info, "ITSTracker pushed {} track labels", allTrackLabels.size()); LOGP(info, "ITSTracker pushed {} vertex labels", allVerticesLabels.size()); + LOGP(info, "ITSTracker pushed {} vertex purities", allVerticesPurities.size()); } } } diff --git a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx index acc59a66a7c2c..8bfe04e87edaf 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx @@ -33,6 +33,7 @@ Vertexer::Vertexer(VertexerTraits* traits) if (!traits) { LOG(fatal) << "nullptr passed to ITS vertexer construction."; } + mVertParams.resize(1); mTraits = traits; } @@ -40,12 +41,17 @@ float Vertexer::clustersToVertices(std::function logger) { float total{0.f}; TrackingParameters trkPars; - trkPars.PhiBins = mTraits->getVertexingParameters().PhiBins; - trkPars.ZBins = mTraits->getVertexingParameters().ZBins; - total += evaluateTask(&Vertexer::initialiseVertexer, "Vertexer initialisation", logger, trkPars); - total += evaluateTask(&Vertexer::findTracklets, "Vertexer tracklet finding", logger); - total += evaluateTask(&Vertexer::validateTracklets, "Vertexer adjacent tracklets validation", logger); - total += evaluateTask(&Vertexer::findVertices, "Vertexer vertex finding", logger); + TimeFrameGPUParameters tfGPUpar; + mTraits->updateVertexingParameters(mVertParams, tfGPUpar); + for (int iteration = 0; iteration < std::min(mVertParams[0].nIterations, (int)mVertParams.size()); ++iteration) { + logger(fmt::format("ITS Seeding vertexer iteration {} summary:", iteration)); + trkPars.PhiBins = mTraits->getVertexingParameters()[0].PhiBins; + trkPars.ZBins = mTraits->getVertexingParameters()[0].ZBins; + total += evaluateTask(&Vertexer::initialiseVertexer, "Vertexer initialisation", logger, trkPars, iteration); + total += evaluateTask(&Vertexer::findTracklets, "Vertexer tracklet finding", logger, iteration); + total += evaluateTask(&Vertexer::validateTracklets, "Vertexer adjacent tracklets validation", logger, iteration); + total += evaluateTask(&Vertexer::findVertices, "Vertexer vertex finding", logger, iteration); + } printEpilog(logger, total); return total; } @@ -54,8 +60,8 @@ float Vertexer::clustersToVerticesHybrid(std::function logg { float total{0.f}; TrackingParameters trkPars; - trkPars.PhiBins = mTraits->getVertexingParameters().PhiBins; - trkPars.ZBins = mTraits->getVertexingParameters().ZBins; + trkPars.PhiBins = mTraits->getVertexingParameters()[0].PhiBins; + trkPars.ZBins = mTraits->getVertexingParameters()[0].ZBins; total += evaluateTask(&Vertexer::initialiseVertexerHybrid, "Hybrid Vertexer initialisation", logger, trkPars); total += evaluateTask(&Vertexer::findTrackletsHybrid, "Hybrid Vertexer tracklet finding", logger); total += evaluateTask(&Vertexer::validateTrackletsHybrid, "Hybrid Vertexer adjacent tracklets validation", logger); @@ -70,30 +76,27 @@ void Vertexer::getGlobalConfiguration() vc.printKeyValues(true, true); auto& grc = o2::its::GpuRecoParamConfig::Instance(); - VertexingParameters verPar; - verPar.allowSingleContribClusters = vc.allowSingleContribClusters; - verPar.zCut = vc.zCut; - verPar.phiCut = vc.phiCut; - verPar.pairCut = vc.pairCut; - verPar.clusterCut = vc.clusterCut; - verPar.histPairCut = vc.histPairCut; - verPar.tanLambdaCut = vc.tanLambdaCut; - verPar.lowMultBeamDistCut = vc.lowMultBeamDistCut; - verPar.vertNsigmaCut = vc.vertNsigmaCut; - verPar.vertRadiusSigma = vc.vertRadiusSigma; - verPar.trackletSigma = vc.trackletSigma; - verPar.maxZPositionAllowed = vc.maxZPositionAllowed; - verPar.clusterContributorsCut = vc.clusterContributorsCut; - verPar.maxTrackletsPerCluster = vc.maxTrackletsPerCluster; - verPar.phiSpan = vc.phiSpan; - verPar.nThreads = vc.nThreads; - verPar.ZBins = vc.ZBins; - verPar.PhiBins = vc.PhiBins; - - TimeFrameGPUParameters tfGPUpar; - // tfGPUpar.nROFsPerChunk = grc.nROFsPerChunk; - - mTraits->updateVertexingParameters(verPar, tfGPUpar); + // This is odd: we override only the parameters for the first iteration. + // Variations for the next iterations are set in the trackingInterfrace. + mVertParams[0].nIterations = vc.nIterations; + mVertParams[0].allowSingleContribClusters = vc.allowSingleContribClusters; + mVertParams[0].zCut = vc.zCut; + mVertParams[0].phiCut = vc.phiCut; + mVertParams[0].pairCut = vc.pairCut; + mVertParams[0].clusterCut = vc.clusterCut; + mVertParams[0].histPairCut = vc.histPairCut; + mVertParams[0].tanLambdaCut = vc.tanLambdaCut; + mVertParams[0].lowMultBeamDistCut = vc.lowMultBeamDistCut; + mVertParams[0].vertNsigmaCut = vc.vertNsigmaCut; + mVertParams[0].vertRadiusSigma = vc.vertRadiusSigma; + mVertParams[0].trackletSigma = vc.trackletSigma; + mVertParams[0].maxZPositionAllowed = vc.maxZPositionAllowed; + mVertParams[0].clusterContributorsCut = vc.clusterContributorsCut; + mVertParams[0].maxTrackletsPerCluster = vc.maxTrackletsPerCluster; + mVertParams[0].phiSpan = vc.phiSpan; + mVertParams[0].nThreads = vc.nThreads; + mVertParams[0].ZBins = vc.ZBins; + mVertParams[0].PhiBins = vc.PhiBins; } void Vertexer::adoptTimeFrame(TimeFrame& tf) diff --git a/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx index ceb5e4d0d44b7..2196e04752484 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx @@ -158,44 +158,47 @@ const std::vector> VertexerTraits::selectClusters(const int* return filteredBins; } -void VertexerTraits::updateVertexingParameters(const VertexingParameters& vrtPar, const TimeFrameGPUParameters& tfPar) +void VertexerTraits::updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& tfPar) { mVrtParams = vrtPar; - mIndexTableUtils.setTrackingParameters(vrtPar); - mVrtParams.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * mVrtParams.phiCut / - constants::math::TwoPi)); - mVrtParams.zSpan = static_cast(std::ceil(mVrtParams.zCut * mIndexTableUtils.getInverseZCoordinate(0))); - setNThreads(mVrtParams.nThreads); + mIndexTableUtils.setTrackingParameters(vrtPar[0]); + for (auto& par : mVrtParams) { + par.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * par.phiCut / constants::math::TwoPi)); + par.zSpan = static_cast(std::ceil(par.zCut * mIndexTableUtils.getInverseZCoordinate(0))); + } + setNThreads(vrtPar[0].nThreads); } -void VertexerTraits::computeTracklets() +// Main functions +void VertexerTraits::computeTracklets(const int iteration) { #pragma omp parallel num_threads(mNThreads) { #pragma omp for schedule(dynamic) for (int rofId = 0; rofId < mTimeFrame->getNrof(); ++rofId) { + bool skipROF = iteration && (int)mTimeFrame->getPrimaryVertices(rofId).size() > mVrtParams[iteration].vertPerRofThreshold; trackleterKernelHost( - mTimeFrame->getClustersOnLayer(rofId, 0), - mTimeFrame->getClustersOnLayer(rofId, 1), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 0) : gsl::span(), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 1) : gsl::span(), mTimeFrame->getIndexTable(rofId, 0).data(), - mVrtParams.phiCut, + mVrtParams[iteration].phiCut, mTimeFrame->getTracklets()[0], mTimeFrame->getNTrackletsCluster(rofId, 0), mIndexTableUtils, rofId, 0, - mVrtParams.maxTrackletsPerCluster); + mVrtParams[iteration].maxTrackletsPerCluster); trackleterKernelHost( - mTimeFrame->getClustersOnLayer(rofId, 2), - mTimeFrame->getClustersOnLayer(rofId, 1), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 2) : gsl::span(), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 1) : gsl::span(), mTimeFrame->getIndexTable(rofId, 2).data(), - mVrtParams.phiCut, + mVrtParams[iteration].phiCut, mTimeFrame->getTracklets()[1], mTimeFrame->getNTrackletsCluster(rofId, 1), mIndexTableUtils, rofId, 0, - mVrtParams.maxTrackletsPerCluster); + mVrtParams[iteration].maxTrackletsPerCluster); mTimeFrame->getNTrackletsROf(rofId, 0) = std::accumulate(mTimeFrame->getNTrackletsCluster(rofId, 0).begin(), mTimeFrame->getNTrackletsCluster(rofId, 0).end(), 0); mTimeFrame->getNTrackletsROf(rofId, 1) = std::accumulate(mTimeFrame->getNTrackletsCluster(rofId, 1).begin(), mTimeFrame->getNTrackletsCluster(rofId, 1).end(), 0); } @@ -208,28 +211,29 @@ void VertexerTraits::computeTracklets() #pragma omp for schedule(dynamic) for (int rofId = 0; rofId < mTimeFrame->getNrof(); ++rofId) { + bool skipROF = iteration && (int)mTimeFrame->getPrimaryVertices(rofId).size() > mVrtParams[iteration].vertPerRofThreshold; trackleterKernelHost( - mTimeFrame->getClustersOnLayer(rofId, 0), - mTimeFrame->getClustersOnLayer(rofId, 1), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 0) : gsl::span(), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 1) : gsl::span(), mTimeFrame->getIndexTable(rofId, 0).data(), - mVrtParams.phiCut, + mVrtParams[iteration].phiCut, mTimeFrame->getTracklets()[0], mTimeFrame->getNTrackletsCluster(rofId, 0), mIndexTableUtils, rofId, mTimeFrame->getNTrackletsROf(rofId, 0), - mVrtParams.maxTrackletsPerCluster); + mVrtParams[iteration].maxTrackletsPerCluster); trackleterKernelHost( - mTimeFrame->getClustersOnLayer(rofId, 2), - mTimeFrame->getClustersOnLayer(rofId, 1), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 2) : gsl::span(), + !skipROF ? mTimeFrame->getClustersOnLayer(rofId, 1) : gsl::span(), mTimeFrame->getIndexTable(rofId, 2).data(), - mVrtParams.phiCut, + mVrtParams[iteration].phiCut, mTimeFrame->getTracklets()[1], mTimeFrame->getNTrackletsCluster(rofId, 1), mIndexTableUtils, rofId, mTimeFrame->getNTrackletsROf(rofId, 1), - mVrtParams.maxTrackletsPerCluster); + mVrtParams[iteration].maxTrackletsPerCluster); } } @@ -292,10 +296,13 @@ void VertexerTraits::computeTracklets() #endif } // namespace its -void VertexerTraits::computeTrackletMatching() +void VertexerTraits::computeTrackletMatching(const int iteration) { #pragma omp parallel for num_threads(mNThreads) schedule(dynamic) for (int rofId = 0; rofId < mTimeFrame->getNrof(); ++rofId) { + if (iteration && (int)mTimeFrame->getPrimaryVertices(rofId).size() > mVrtParams[iteration].vertPerRofThreshold) { + continue; + } mTimeFrame->getLines(rofId).reserve(mTimeFrame->getNTrackletsCluster(rofId, 0).size()); trackletSelectionKernelHost( mTimeFrame->getClustersOnLayer(rofId, 0), @@ -307,8 +314,8 @@ void VertexerTraits::computeTrackletMatching() mTimeFrame->getLines(rofId), mTimeFrame->getLabelsFoundTracklets(rofId, 0), mTimeFrame->getLinesLabel(rofId), - mVrtParams.tanLambdaCut, - mVrtParams.phiCut); + mVrtParams[iteration].tanLambdaCut, + mVrtParams[iteration].phiCut); } #ifdef VTX_DEBUG @@ -342,16 +349,19 @@ void VertexerTraits::computeTrackletMatching() #endif } -void VertexerTraits::computeVertices() +void VertexerTraits::computeVertices(const int iteration) { - - auto nsigmaCut{std::min(mVrtParams.vertNsigmaCut * mVrtParams.vertNsigmaCut * (mVrtParams.vertRadiusSigma * mVrtParams.vertRadiusSigma + mVrtParams.trackletSigma * mVrtParams.trackletSigma), 1.98f)}; + auto nsigmaCut{std::min(mVrtParams[iteration].vertNsigmaCut * mVrtParams[iteration].vertNsigmaCut * (mVrtParams[iteration].vertRadiusSigma * mVrtParams[iteration].vertRadiusSigma + mVrtParams[iteration].trackletSigma * mVrtParams[iteration].trackletSigma), 1.98f)}; std::vector vertices; + std::vector> polls; #ifdef VTX_DEBUG std::vector> dbg_clusLines(mTimeFrame->getNrof()); #endif std::vector noClustersVec(mTimeFrame->getNrof(), 0); for (int rofId{0}; rofId < mTimeFrame->getNrof(); ++rofId) { + if (iteration && (int)mTimeFrame->getPrimaryVertices(rofId).size() > mVrtParams[iteration].vertPerRofThreshold) { + continue; + } const int numTracklets{static_cast(mTimeFrame->getLines(rofId).size())}; std::vector usedTracklets(numTracklets, false); @@ -364,7 +374,7 @@ void VertexerTraits::computeVertices() continue; } auto dca{Line::getDCA(mTimeFrame->getLines(rofId)[line1], mTimeFrame->getLines(rofId)[line2])}; - if (dca < mVrtParams.pairCut) { + if (dca < mVrtParams[iteration].pairCut) { mTimeFrame->getTrackletClusters(rofId).emplace_back(line1, mTimeFrame->getLines(rofId)[line1], line2, mTimeFrame->getLines(rofId)[line2]); std::array tmpVertex{mTimeFrame->getTrackletClusters(rofId).back().getVertex()}; if (tmpVertex[0] * tmpVertex[0] + tmpVertex[1] * tmpVertex[1] > 4.f) { @@ -377,7 +387,7 @@ void VertexerTraits::computeVertices() if (usedTracklets[tracklet3]) { continue; } - if (Line::getDistanceFromPoint(mTimeFrame->getLines(rofId)[tracklet3], tmpVertex) < mVrtParams.pairCut) { + if (Line::getDistanceFromPoint(mTimeFrame->getLines(rofId)[tracklet3], tmpVertex) < mVrtParams[iteration].pairCut) { mTimeFrame->getTrackletClusters(rofId).back().add(tracklet3, mTimeFrame->getLines(rofId)[tracklet3]); usedTracklets[tracklet3] = true; tmpVertex = mTimeFrame->getTrackletClusters(rofId).back().getVertex(); @@ -387,12 +397,12 @@ void VertexerTraits::computeVertices() } } } - if (mVrtParams.allowSingleContribClusters) { + if (mVrtParams[iteration].allowSingleContribClusters) { auto beamLine = Line{{mTimeFrame->getBeamX(), mTimeFrame->getBeamY(), -50.f}, {mTimeFrame->getBeamX(), mTimeFrame->getBeamY(), 50.f}}; // use beam position as contributor for (size_t iLine{0}; iLine < numTracklets; ++iLine) { if (!usedTracklets[iLine]) { auto dca = Line::getDCA(mTimeFrame->getLines(rofId)[iLine], beamLine); - if (dca < mVrtParams.pairCut) { + if (dca < mVrtParams[iteration].pairCut) { mTimeFrame->getTrackletClusters(rofId).emplace_back(iLine, mTimeFrame->getLines(rofId)[iLine], -1, beamLine); // beamline must be passed as second line argument } } @@ -408,11 +418,11 @@ void VertexerTraits::computeVertices() std::array vertex2{}; for (int iCluster2{iCluster1 + 1}; iCluster2 < noClustersVec[rofId]; ++iCluster2) { vertex2 = mTimeFrame->getTrackletClusters(rofId)[iCluster2].getVertex(); - if (std::abs(vertex1[2] - vertex2[2]) < mVrtParams.clusterCut) { + if (std::abs(vertex1[2] - vertex2[2]) < mVrtParams[iteration].clusterCut) { float distance{(vertex1[0] - vertex2[0]) * (vertex1[0] - vertex2[0]) + (vertex1[1] - vertex2[1]) * (vertex1[1] - vertex2[1]) + (vertex1[2] - vertex2[2]) * (vertex1[2] - vertex2[2])}; - if (distance < mVrtParams.pairCut * mVrtParams.pairCut) { + if (distance < mVrtParams[iteration].pairCut * mVrtParams[iteration].pairCut) { for (auto label : mTimeFrame->getTrackletClusters(rofId)[iCluster2].getLabels()) { mTimeFrame->getTrackletClusters(rofId)[iCluster1].add(label, mTimeFrame->getLines(rofId)[label]); vertex1 = mTimeFrame->getTrackletClusters(rofId)[iCluster1].getVertex(); @@ -439,8 +449,8 @@ void VertexerTraits::computeVertices() bool lowMultCandidate{false}; double beamDistance2{(mTimeFrame->getBeamX() - mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[0]) * (mTimeFrame->getBeamX() - mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[0]) + (mTimeFrame->getBeamY() - mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[1]) * (mTimeFrame->getBeamY() - mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[1])}; - if (atLeastOneFound && (lowMultCandidate = mTimeFrame->getTrackletClusters(rofId)[iCluster].getSize() < mVrtParams.clusterContributorsCut)) { // We might have pile up with nContr > cut. - lowMultCandidate &= (beamDistance2 < mVrtParams.lowMultBeamDistCut * mVrtParams.lowMultBeamDistCut); + if (atLeastOneFound && (lowMultCandidate = mTimeFrame->getTrackletClusters(rofId)[iCluster].getSize() < mVrtParams[iteration].clusterContributorsCut)) { // We might have pile up with nContr > cut. + lowMultCandidate &= (beamDistance2 < mVrtParams[iteration].lowMultBeamDistCut * mVrtParams[iteration].lowMultBeamDistCut); if (!lowMultCandidate) { // Not the first cluster and not a low multiplicity candidate, we can remove it mTimeFrame->getTrackletClusters(rofId).erase(mTimeFrame->getTrackletClusters(rofId).begin() + iCluster); noClustersVec[rofId]--; @@ -448,7 +458,7 @@ void VertexerTraits::computeVertices() } } - if (beamDistance2 < nsigmaCut && std::abs(mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[2]) < mVrtParams.maxZPositionAllowed) { + if (beamDistance2 < nsigmaCut && std::abs(mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[2]) < mVrtParams[iteration].maxZPositionAllowed) { atLeastOneFound = true; vertices.emplace_back(o2::math_utils::Point3D(mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[0], mTimeFrame->getTrackletClusters(rofId)[iCluster].getVertex()[1], @@ -459,15 +469,31 @@ void VertexerTraits::computeVertices() mTimeFrame->getTrackletClusters(rofId)[iCluster].getAvgDistance2()); // In place of chi2 vertices.back().setTimeStamp(rofId); + vertices.back().setFlags(iteration); if (mTimeFrame->hasMCinformation()) { - mTimeFrame->getVerticesLabels().emplace_back(); + std::vector labels; for (auto& index : mTimeFrame->getTrackletClusters(rofId)[iCluster].getLabels()) { - mTimeFrame->getVerticesLabels().back().push_back(mTimeFrame->getLinesLabel(rofId)[index]); // then we can use nContributors from vertices to get the labels + labels.push_back(mTimeFrame->getLinesLabel(rofId)[index]); // then we can use nContributors from vertices to get the labels } + polls.push_back(computeMain(labels)); } } } - mTimeFrame->addPrimaryVertices(vertices); + if (!iteration) { + mTimeFrame->addPrimaryVertices(vertices); + if (mTimeFrame->hasMCinformation()) { + mTimeFrame->addPrimaryVerticesLabels(polls); + } + } else { + mTimeFrame->addPrimaryVerticesInROF(vertices, rofId); + if (mTimeFrame->hasMCinformation()) { + mTimeFrame->addPrimaryVerticesLabelsInROF(polls, rofId); + } + } + mTimeFrame->getTotVertIteration()[iteration] += vertices.size(); + if (!vertices.size() && !(iteration && (int)mTimeFrame->getPrimaryVertices(rofId).size() > mVrtParams[iteration].vertPerRofThreshold)) { + mTimeFrame->getNoVertexROF()++; + } } #ifdef VTX_DEBUG TFile* dbg_file = TFile::Open("artefacts_tf.root", "update"); @@ -511,10 +537,11 @@ void VertexerTraits::computeVerticesInRof(int rofId, std::vector& vertices, std::vector& verticesInRof, TimeFrame* tf, - std::vector* labels) + std::vector* labels, + const int iteration) { int foundVertices{0}; - auto nsigmaCut{std::min(mVrtParams.vertNsigmaCut * mVrtParams.vertNsigmaCut * (mVrtParams.vertRadiusSigma * mVrtParams.vertRadiusSigma + mVrtParams.trackletSigma * mVrtParams.trackletSigma), 1.98f)}; + auto nsigmaCut{std::min(mVrtParams[iteration].vertNsigmaCut * mVrtParams[iteration].vertNsigmaCut * (mVrtParams[iteration].vertRadiusSigma * mVrtParams[iteration].vertRadiusSigma + mVrtParams[iteration].trackletSigma * mVrtParams[iteration].trackletSigma), 1.98f)}; const int numTracklets{static_cast(lines.size())}; for (int line1{0}; line1 < numTracklets; ++line1) { if (usedLines[line1]) { @@ -525,7 +552,7 @@ void VertexerTraits::computeVerticesInRof(int rofId, continue; } auto dca{Line::getDCA(lines[line1], lines[line2])}; - if (dca < mVrtParams.pairCut) { + if (dca < mVrtParams[iteration].pairCut) { clusterLines.emplace_back(line1, lines[line1], line2, lines[line2]); std::array tmpVertex{clusterLines.back().getVertex()}; if (tmpVertex[0] * tmpVertex[0] + tmpVertex[1] * tmpVertex[1] > 4.f) { @@ -538,7 +565,7 @@ void VertexerTraits::computeVerticesInRof(int rofId, if (usedLines[tracklet3]) { continue; } - if (Line::getDistanceFromPoint(lines[tracklet3], tmpVertex) < mVrtParams.pairCut) { + if (Line::getDistanceFromPoint(lines[tracklet3], tmpVertex) < mVrtParams[iteration].pairCut) { clusterLines.back().add(tracklet3, lines[tracklet3]); usedLines[tracklet3] = true; tmpVertex = clusterLines.back().getVertex(); @@ -549,12 +576,12 @@ void VertexerTraits::computeVerticesInRof(int rofId, } } - if (mVrtParams.allowSingleContribClusters) { + if (mVrtParams[iteration].allowSingleContribClusters) { auto beamLine = Line{{tf->getBeamX(), tf->getBeamY(), -50.f}, {tf->getBeamX(), tf->getBeamY(), 50.f}}; // use beam position as contributor for (size_t iLine{0}; iLine < numTracklets; ++iLine) { if (!usedLines[iLine]) { auto dca = Line::getDCA(lines[iLine], beamLine); - if (dca < mVrtParams.pairCut) { + if (dca < mVrtParams[iteration].pairCut) { clusterLines.emplace_back(iLine, lines[iLine], -1, beamLine); // beamline must be passed as second line argument } } @@ -569,11 +596,11 @@ void VertexerTraits::computeVerticesInRof(int rofId, std::array vertex2{}; for (int iCluster2{iCluster1 + 1}; iCluster2 < nClusters; ++iCluster2) { vertex2 = clusterLines[iCluster2].getVertex(); - if (std::abs(vertex1[2] - vertex2[2]) < mVrtParams.clusterCut) { + if (std::abs(vertex1[2] - vertex2[2]) < mVrtParams[iteration].clusterCut) { float distance{(vertex1[0] - vertex2[0]) * (vertex1[0] - vertex2[0]) + (vertex1[1] - vertex2[1]) * (vertex1[1] - vertex2[1]) + (vertex1[2] - vertex2[2]) * (vertex1[2] - vertex2[2])}; - if (distance < mVrtParams.pairCut * mVrtParams.pairCut) { + if (distance < mVrtParams[iteration].pairCut * mVrtParams[iteration].pairCut) { for (auto label : clusterLines[iCluster2].getLabels()) { clusterLines[iCluster1].add(label, lines[label]); vertex1 = clusterLines[iCluster1].getVertex(); @@ -594,15 +621,15 @@ void VertexerTraits::computeVerticesInRof(int rofId, double beamDistance2{(tf->getBeamX() - clusterLines[iCluster].getVertex()[0]) * (tf->getBeamX() - clusterLines[iCluster].getVertex()[0]) + (tf->getBeamY() - clusterLines[iCluster].getVertex()[1]) * (tf->getBeamY() - clusterLines[iCluster].getVertex()[1])}; - if (atLeastOneFound && (lowMultCandidate = clusterLines[iCluster].getSize() < mVrtParams.clusterContributorsCut)) { // We might have pile up with nContr > cut. - lowMultCandidate &= (beamDistance2 < mVrtParams.lowMultBeamDistCut * mVrtParams.lowMultBeamDistCut); + if (atLeastOneFound && (lowMultCandidate = clusterLines[iCluster].getSize() < mVrtParams[iteration].clusterContributorsCut)) { // We might have pile up with nContr > cut. + lowMultCandidate &= (beamDistance2 < mVrtParams[iteration].lowMultBeamDistCut * mVrtParams[iteration].lowMultBeamDistCut); if (!lowMultCandidate) { // Not the first cluster and not a low multiplicity candidate, we can remove it clusterLines.erase(clusterLines.begin() + iCluster); nClusters--; continue; } } - if (beamDistance2 < nsigmaCut && std::abs(clusterLines[iCluster].getVertex()[2]) < mVrtParams.maxZPositionAllowed) { + if (beamDistance2 < nsigmaCut && std::abs(clusterLines[iCluster].getVertex()[2]) < mVrtParams[iteration].maxZPositionAllowed) { atLeastOneFound = true; ++foundVertices; vertices.emplace_back(o2::math_utils::Point3D(clusterLines[iCluster].getVertex()[0], diff --git a/Detectors/ITSMFT/ITS/workflow/src/TrackWriterSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/TrackWriterSpec.cxx index 02632cd4e3d3d..5cb6aa199ab64 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/TrackWriterSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/TrackWriterSpec.cxx @@ -72,7 +72,10 @@ DataProcessorSpec getTrackWriterSpec(bool useMC) BranchDefinition{InputSpec{"MC2ROframes", "ITS", "ITSTrackMC2ROF", 0}, "ITSTracksMC2ROF", (useMC ? 1 : 0), // one branch if mc labels enabled - ""})(); + ""}, + BranchDefinition>{InputSpec{"purityVertices", "ITS", "VERTICESMCPUR", 0}, + "ITSVertexMCPurity", (useMC ? 1 : 0), // one branch if mc labels enabled + ""})(); } } // namespace its diff --git a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx index 367fa8673cc70..ec0b0d26f873c 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx @@ -114,6 +114,7 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, int trgType, const st inputs.emplace_back("itsmclabels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); inputs.emplace_back("ITSMC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "VERTICESMCTR", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "VERTICESMCPUR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe); } diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx index a0b879e7e4d99..24400e26eb2e2 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx @@ -69,6 +69,8 @@ DataProcessorSpec getTrackWriterSpec(bool useMC) "ITSVertexMCTruth", (useMC ? 1 : 0), // one branch if mc labels enabled ""}, + BranchDefinition>{InputSpec{"purityVertices", "ITS", "VERTICESMCPUR", 0}, + "ITSVertexMCPurity", (useMC ? 1 : 0), ""}, BranchDefinition{InputSpec{"MC2ROframes", "ITS", "ITSTrackMC2ROF", 0}, "ITSTracksMC2ROF", (useMC ? 1 : 0), // one branch if mc labels enabled diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx index 62212031691b2..a6d01b2ba8710 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx @@ -182,6 +182,7 @@ void TrackerDPL::run(ProcessingContext& pc) auto& allTracks = pc.outputs().make>(Output{orig, "TRACKS", 0}); std::vector allTrackLabels; std::vector allVerticesLabels; + std::vector allVerticesPurities; auto& vertROFvec = pc.outputs().make>(Output{orig, "VERTICESROF", 0}); auto& vertices = pc.outputs().make>(Output{orig, "VERTICES", 0}); @@ -212,12 +213,16 @@ void TrackerDPL::run(ProcessingContext& pc) vertexerElapsedTime = mVertexer->clustersToVertices(logger); } const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts + gsl::span> vMCRecInfo; for (size_t iRof{0}; iRof < rofspan.size(); ++iRof) { std::vector vtxVecLoc; auto& vtxROF = vertROFvec.emplace_back(rofspan[iRof]); vtxROF.setFirstEntry(vertices.size()); if (mRunVertexer) { auto vtxSpan = timeFrame->getPrimaryVertices(iRof); + if (mIsMC) { + vMCRecInfo = timeFrame->getPrimaryVerticesMCRecInfo(iRof); + } vtxROF.setNEntries(vtxSpan.size()); bool selROF = vtxSpan.size() == 0; for (size_t iV{0}; iV < vtxSpan.size(); ++iV) { @@ -228,8 +233,8 @@ void TrackerDPL::run(ProcessingContext& pc) selROF = true; vertices.push_back(v); if (mIsMC) { - auto vLabels = timeFrame->getPrimaryVerticesLabels(iRof)[iV]; - std::copy(vLabels.begin(), vLabels.end(), std::back_inserter(allVerticesLabels)); + allVerticesLabels.push_back(vMCRecInfo[iV].first); + allVerticesPurities.push_back(vMCRecInfo[iV].second); } } if (processingMask[iRof] && !selROF) { // passed selection in clusters and not in vertex multiplicity @@ -303,6 +308,7 @@ void TrackerDPL::run(ProcessingContext& pc) pc.outputs().snapshot(Output{orig, "TRACKSMCTR", 0}, allTrackLabels); pc.outputs().snapshot(Output{orig, "VERTICESMCTR", 0}, allVerticesLabels); + pc.outputs().snapshot(Output{orig, "VERTICESMCPUR", 0}, allVerticesPurities); pc.outputs().snapshot(Output{orig, "ITSTrackMC2ROF", 0}, mc2rofs); } } From 648119ebaedb7783cf62722c8e9fbc8f840fef10 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Fri, 19 Jul 2024 09:37:46 +0200 Subject: [PATCH 0006/2205] DPL Analysis: modernize expressions (#13285) --- .../Core/include/Framework/Expressions.h | 278 +++++++++--------- 1 file changed, 132 insertions(+), 146 deletions(-) diff --git a/Framework/Core/include/Framework/Expressions.h b/Framework/Core/include/Framework/Expressions.h index 1d0f3d96ebe9e..877474fb9ede6 100644 --- a/Framework/Core/include/Framework/Expressions.h +++ b/Framework/Core/include/Framework/Expressions.h @@ -167,37 +167,37 @@ struct ConditionalNode { /// A generic tree node struct Node { - Node(LiteralNode v) : self{v}, left{nullptr}, right{nullptr}, condition{nullptr} + Node(LiteralNode&& v) : self{std::forward(v)}, left{nullptr}, right{nullptr}, condition{nullptr} { } - Node(PlaceholderNode v) : self{v}, left{nullptr}, right{nullptr}, condition{nullptr} + Node(PlaceholderNode&& v) : self{std::forward(v)}, left{nullptr}, right{nullptr}, condition{nullptr} { } - Node(Node&& n) : self{n.self}, left{std::move(n.left)}, right{std::move(n.right)}, condition{std::move(n.condition)} + Node(Node&& n) : self{std::forward(n.self)}, left{std::forward>(n.left)}, right{std::forward>(n.right)}, condition{std::forward>(n.condition)} { } - Node(BindingNode n) : self{n}, left{nullptr}, right{nullptr}, condition{nullptr} + Node(BindingNode const& n) : self{n}, left{nullptr}, right{nullptr}, condition{nullptr} { } Node(ConditionalNode op, Node&& then_, Node&& else_, Node&& condition_) : self{op}, - left{std::make_unique(std::move(then_))}, - right{std::make_unique(std::move(else_))}, - condition{std::make_unique(std::move(condition_))} {} + left{std::make_unique(std::forward(then_))}, + right{std::make_unique(std::forward(else_))}, + condition{std::make_unique(std::forward(condition_))} {} Node(OpNode op, Node&& l, Node&& r) : self{op}, - left{std::make_unique(std::move(l))}, - right{std::make_unique(std::move(r))}, + left{std::make_unique(std::forward(l))}, + right{std::make_unique(std::forward(r))}, condition{nullptr} {} Node(OpNode op, Node&& l) : self{op}, - left{std::make_unique(std::move(l))}, + left{std::make_unique(std::forward(l))}, right{nullptr}, condition{nullptr} {} @@ -213,55 +213,52 @@ struct Node { /// overloaded operators to build the tree from an expression -#define BINARY_OP_NODES(_operator_, _operation_) \ - template \ - inline Node operator _operator_(Node&& left, T right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, std::move(left), LiteralNode{right}}; \ - } \ - template \ - inline Node operator _operator_(T left, Node&& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::move(right)}; \ - } \ - template \ - inline Node operator _operator_(Node&& left, Configurable const& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, std::move(left), PlaceholderNode{right}}; \ - } \ - template \ - inline Node operator _operator_(Configurable const& left, Node&& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::move(right)}; \ - } \ - inline Node operator _operator_(Node&& left, Node&& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, std::move(left), std::move(right)}; \ - } \ - inline Node operator _operator_(BindingNode left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, left, right}; \ - } \ - template <> \ - inline Node operator _operator_(BindingNode left, Node&& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, left, std::move(right)}; \ - } \ - template <> \ - inline Node operator _operator_(Node&& left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, std::move(left), right}; \ - } \ - \ - template \ - inline Node operator _operator_(Configurable const& left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \ - } \ - template \ - inline Node operator _operator_(BindingNode left, Configurable const& right) \ - { \ - return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \ +#define BINARY_OP_NODES(_operator_, _operation_) \ + inline Node operator _operator_(Node&& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, std::forward(left), std::forward(right)}; \ + } \ + template \ + inline Node operator _operator_(Node&& left, T right) requires(std::is_arithmetic_v>) \ + { \ + return Node{OpNode{BasicOp::_operation_}, std::forward(left), LiteralNode{right}}; \ + } \ + template \ + inline Node operator _operator_(T left, Node&& right) requires(std::is_arithmetic_v>) \ + { \ + return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::forward(right)}; \ + } \ + template \ + inline Node operator _operator_(Node&& left, Configurable const& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, std::forward(left), PlaceholderNode{right}}; \ + } \ + template \ + inline Node operator _operator_(Configurable const& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::forward(right)}; \ + } \ + inline Node operator _operator_(BindingNode const& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, left, right}; \ + } \ + inline Node operator _operator_(BindingNode const& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, left, std::forward(right)}; \ + } \ + inline Node operator _operator_(Node&& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, std::forward(left), right}; \ + } \ + template \ + inline Node operator _operator_(Configurable const& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \ + } \ + template \ + inline Node operator _operator_(BindingNode const& left, Configurable const& right) \ + { \ + return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \ } BINARY_OP_NODES(&, BitwiseAnd); @@ -282,74 +279,70 @@ BINARY_OP_NODES(||, LogicalOr); /// functions template -inline Node npow(Node left, T right) +inline Node npow(Node&& left, T right) requires(std::is_arithmetic_v) { - return Node{OpNode{BasicOp::Power}, std::move(left), LiteralNode{right}}; + return Node{OpNode{BasicOp::Power}, std::forward(left), LiteralNode{right}}; } -#define BINARY_FUNC_NODES(_func_, _node_) \ - template \ - inline Node _node_(L left, R right) \ - { \ - return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \ - } \ - \ - template <> \ - inline Node _node_(Node left, Node right) \ - { \ - return Node{OpNode{BasicOp::_func_}, std::move(left), std::move(right)}; \ - } \ - \ - template <> \ - inline Node _node_(Node left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_func_}, std::move(left), right}; \ - } \ - \ - template <> \ - inline Node _node_(BindingNode left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_func_}, left, right}; \ - } \ - \ - template <> \ - inline Node _node_(BindingNode left, Node right) \ - { \ - return Node{OpNode{BasicOp::_func_}, left, std::move(right)}; \ - } \ - \ - template \ - inline Node _node_(Node left, Configurable right) \ - { \ - return Node{OpNode{BasicOp::_func_}, std::move(left), PlaceholderNode{right}}; \ - } \ - \ - template \ - inline Node _node_(Configurable left, Node right) \ - { \ - return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::move(right)}; \ - } \ - \ - template \ - inline Node _node_(BindingNode left, Configurable right) \ - { \ - return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \ - } \ - \ - template \ - inline Node _node_(Configurable left, BindingNode right) \ - { \ - return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \ +#define BINARY_FUNC_NODES(_func_, _node_) \ + template \ + inline Node _node_(L left, R right) requires(std::is_arithmetic_v && std::is_arithmetic_v) \ + { \ + return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \ + } \ + \ + inline Node _node_(Node&& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, std::forward(left), std::forward(right)}; \ + } \ + \ + inline Node _node_(Node&& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, std::forward(left), right}; \ + } \ + \ + inline Node _node_(BindingNode const& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, left, right}; \ + } \ + \ + inline Node _node_(BindingNode const& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, left, std::forward(right)}; \ + } \ + \ + template \ + inline Node _node_(Node&& left, Configurable const& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, std::forward(left), PlaceholderNode{right}}; \ + } \ + \ + template \ + inline Node _node_(Configurable const& left, Node&& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::forward(right)}; \ + } \ + \ + template \ + inline Node _node_(BindingNode const& left, Configurable const& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \ + } \ + \ + template \ + inline Node _node_(Configurable const& left, BindingNode const& right) \ + { \ + return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \ } BINARY_FUNC_NODES(Atan2, natan2); #define ncheckbit(_node_, _bit_) ((_node_ & _bit_) == _bit_) /// unary functions on nodes -#define UNARY_FUNC_NODES(_func_, _node_) \ - inline Node _node_(Node arg) \ - { \ - return Node{OpNode{BasicOp::_func_}, std::move(arg)}; \ +#define UNARY_FUNC_NODES(_func_, _node_) \ + inline Node _node_(Node&& arg) \ + { \ + return Node{OpNode{BasicOp::_func_}, std::forward(arg)}; \ } UNARY_FUNC_NODES(Round, nround); @@ -367,68 +360,61 @@ UNARY_FUNC_NODES(Atan, natan); UNARY_FUNC_NODES(BitwiseNot, nbitwise_not); /// conditionals -template -inline Node ifnode(C condition_, T then_, E else_) +inline Node ifnode(Node&& condition_, Node&& then_, Node&& else_) { - return Node{ConditionalNode{}, std::move(then_), std::move(else_), std::move(condition_)}; + return Node{ConditionalNode{}, std::forward(then_), std::forward(else_), std::forward(condition_)}; } -template <> -inline Node ifnode(Node condition_, Node then_, Node else_) -{ - return Node{ConditionalNode{}, std::move(then_), std::move(else_), std::move(condition_)}; -} - -template ::value || std::is_floating_point::value, bool> = true> -inline Node ifnode(Node condition_, Node then_, L else_) +template +inline Node ifnode(Node&& condition_, Node&& then_, L else_) requires(std::is_arithmetic_v) { - return Node{ConditionalNode{}, std::move(then_), LiteralNode{else_}, std::move(condition_)}; + return Node{ConditionalNode{}, std::forward(then_), LiteralNode{else_}, std::forward(condition_)}; } -template ::value || std::is_floating_point::value, bool> = true> -inline Node ifnode(Node condition_, L then_, Node else_) +template +inline Node ifnode(Node&& condition_, L then_, Node&& else_) requires(std::is_arithmetic_v) { - return Node{ConditionalNode{}, LiteralNode{then_}, std::move(else_), std::move(condition_)}; + return Node{ConditionalNode{}, LiteralNode{then_}, std::forward(else_), std::forward(condition_)}; } -template ::value || std::is_floating_point::value) && (std::is_integral::value || std::is_floating_point::value), bool> = true> -inline Node ifnode(Node condition_, L1 then_, L2 else_) +template +inline Node ifnode(Node&& condition_, L1 then_, L2 else_) requires(std::is_arithmetic_v&& std::is_arithmetic_v) { - return Node{ConditionalNode{}, LiteralNode{then_}, LiteralNode{else_}, std::move(condition_)}; + return Node{ConditionalNode{}, LiteralNode{then_}, LiteralNode{else_}, std::forward(condition_)}; } template -inline Node ifnode(Configurable condition_, Node then_, Node else_) +inline Node ifnode(Configurable const& condition_, Node&& then_, Node&& else_) { - return Node{ConditionalNode{}, std::move(then_), std::move(else_), PlaceholderNode{condition_}}; + return Node{ConditionalNode{}, std::forward(then_), std::forward(else_), PlaceholderNode{condition_}}; } template -inline Node ifnode(Node condition_, Node then_, Configurable else_) +inline Node ifnode(Node&& condition_, Node&& then_, Configurable const& else_) { - return Node{ConditionalNode{}, std::move(then_), PlaceholderNode{else_}, std::move(condition_)}; + return Node{ConditionalNode{}, std::forward(then_), PlaceholderNode{else_}, std::forward(condition_)}; } template -inline Node ifnode(Node condition_, Configurable then_, Node else_) +inline Node ifnode(Node&& condition_, Configurable const& then_, Node&& else_) { - return Node{ConditionalNode{}, PlaceholderNode{then_}, std::move(else_), std::move(condition_)}; + return Node{ConditionalNode{}, PlaceholderNode{then_}, std::forward(else_), std::forward(condition_)}; } template -inline Node ifnode(Node condition_, Configurable then_, Configurable else_) +inline Node ifnode(Node&& condition_, Configurable const& then_, Configurable const& else_) { - return Node{ConditionalNode{}, PlaceholderNode{then_}, PlaceholderNode{else_}, std::move(condition_)}; + return Node{ConditionalNode{}, PlaceholderNode{then_}, PlaceholderNode{else_}, std::forward(condition_)}; } /// A struct, containing the root of the expression tree struct Filter { - Filter(Node&& node_) : node{std::make_unique(std::move(node_))} + Filter(Node&& node_) : node{std::make_unique(std::forward(node_))} { (void)designateSubtrees(node.get()); } - Filter(Filter&& other) : node{std::move(other.node)} + Filter(Filter&& other) : node{std::forward>(other.node)} { (void)designateSubtrees(node.get()); } From 31e7cfec734590986b1c3596e21c99853fe8bece Mon Sep 17 00:00:00 2001 From: Peter Hristov Date: Fri, 19 Jul 2024 14:48:24 +0200 Subject: [PATCH 0007/2205] Add EP angle only if available from the generator (#13311) Trivial change, merging. --- Generators/src/GeneratorPythia8.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Generators/src/GeneratorPythia8.cxx b/Generators/src/GeneratorPythia8.cxx index 7e0c71823d848..a2740a37af19f 100644 --- a/Generators/src/GeneratorPythia8.cxx +++ b/Generators/src/GeneratorPythia8.cxx @@ -706,7 +706,9 @@ void GeneratorPythia8::updateHeader(o2::dataformats::MCEventHeader* eventHeader) eventHeader->SetB(hiinfo->b()); eventHeader->putInfo(Key::impactParameter, hiinfo->b()); /** set event plane angle **/ +#if PYTHIA_VERSION_INTEGER >= 8310 eventHeader->putInfo(Key::planeAngle, hiinfo->phi()); +#endif auto bImp = hiinfo->b(); /** set Ncoll, Npart and Nremn **/ int nColl, nPart; From 66ae06b8f940350e4aa12fb3c94551e8267a465d Mon Sep 17 00:00:00 2001 From: Hadi Hassan Date: Fri, 19 Jul 2024 16:41:49 +0300 Subject: [PATCH 0008/2205] [FOCAL-98] Optimizing the hit processing in FOCAL (#13297) Use std::unordered_map with hit key based on hit coordinates in order to have fast hash-based hit search. --- Detectors/FOCAL/base/include/FOCALBase/Hit.h | 34 +++++++++++++++++++ .../include/FOCALSimulation/Detector.h | 5 +-- Detectors/FOCAL/simulation/src/Detector.cxx | 28 ++++++++------- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/Detectors/FOCAL/base/include/FOCALBase/Hit.h b/Detectors/FOCAL/base/include/FOCALBase/Hit.h index 31d6054386b36..e24c48ac60284 100644 --- a/Detectors/FOCAL/base/include/FOCALBase/Hit.h +++ b/Detectors/FOCAL/base/include/FOCALBase/Hit.h @@ -14,6 +14,7 @@ #include #include "SimulationDataFormat/BaseHits.h" #include "CommonUtils/ShmAllocator.h" +#include namespace o2::focal { @@ -35,6 +36,39 @@ class Hit : public o2::BasicXYZEHit UNKNOWN ///< Undefined }; + /// \struct HitID + /// \brief Mapped information of a channel + struct HitID { + int mParentID; ///< parentID of the track creating this hit + uint8_t mRow; ///< Row of the hit in the calorimeter + uint8_t mColumn; ///< Column of the hit in the calorimeter + uint8_t mLayer; ///< Layer the was hit + + bool operator==(const HitID& other) const + { + return mParentID == other.mParentID && mRow == other.mRow && mColumn == other.mColumn && mLayer == other.mLayer; + } + friend std::ostream& operator<<(std::ostream& stream, const Hit::HitID& channel); + }; + + /// \struct HitIDHasher + /// \brief Hash functor for hit ID + struct HitIDHasher { + + /// \brief Functor implementation + /// \param s Hit for which to determine a hash value + /// \return hash value for channel ID + size_t operator()(const HitID& s) const + { + std::size_t seed = 0; + boost::hash_combine(seed, s.mParentID); + boost::hash_combine(seed, s.mRow); + boost::hash_combine(seed, s.mColumn); + boost::hash_combine(seed, s.mLayer); + return seed; + } + }; + /// \brief Dummy constructor Hit() = default; diff --git a/Detectors/FOCAL/simulation/include/FOCALSimulation/Detector.h b/Detectors/FOCAL/simulation/include/FOCALSimulation/Detector.h index 1a66435fea9a2..0c32112d59288 100644 --- a/Detectors/FOCAL/simulation/include/FOCALSimulation/Detector.h +++ b/Detectors/FOCAL/simulation/include/FOCALSimulation/Detector.h @@ -184,13 +184,14 @@ class Detector : public o2::base::DetImpl Geometry* mGeometry; //! mGeoCompositions; //!* mHits; ///< Container with hits + std::vector* mHits; ///< Container with hits + std::unordered_map mHitIndexMapping; ///< Mapping the hits to a cell in the detector std::unordered_map mSuperParentsIndices; //! mSuperParents; //!("FOC", active), mHits(o2::utils::createSimVector()), + mHitIndexMapping(), mGeometry(nullptr), mMedSensHCal(-1), mMedSensECalPad(-1), @@ -166,23 +167,23 @@ Hit* Detector::AddHit(int trackID, int primary, double initialEnergy, int detID, LOG(debug3) << "Adding hit for track " << trackID << " with position (" << pos.X() << ", " << pos.Y() << ", " << pos.Z() << ") with energy " << initialEnergy << " loosing " << eLoss; mHits->emplace_back(primary, trackID, detID, subsystem, initialEnergy, pos, time, eLoss); + + auto [isin, col, row, layer, segment] = mGeometry->getVirtualInfo(pos.X(), pos.Y(), pos.Z()); + mHitIndexMapping.insert(std::pair({trackID, uint8_t(row), uint8_t(col), uint8_t(layer)}, static_cast(mHits->size() - 1))); + return &(mHits->back()); } Hit* Detector::FindHit(int parentID, int col, int row, int layer) { + Hit::HitID hitToFind{parentID, uint8_t(row), uint8_t(col), uint8_t(layer)}; + auto found = mHitIndexMapping.find(hitToFind); - auto HitComparison = [&](const Hit& hit) { - auto information = mGeometry->getVirtualInfo(hit.GetX(), hit.GetY(), hit.GetZ()); - // FIXME Should we compare segments instead of layers ??? - return hit.GetTrackID() == parentID && col == std::get<1>(information) && row == std::get<2>(information) && layer == std::get<3>(information); - }; - - auto result = std::find_if(mHits->begin(), mHits->end(), HitComparison); - if (result == mHits->end()) { + if (found == mHitIndexMapping.end()) { return nullptr; } - return &(*result); + + return &((*mHits)[found->second]); } Parent* Detector::AddSuperparent(int trackID, int pdg, double energy) @@ -205,6 +206,7 @@ void Detector::Reset() if (!o2::utils::ShmManager::Instance().isOperational()) { mHits->clear(); } + mHitIndexMapping.clear(); mSuperParentsIndices.clear(); mSuperParents.clear(); @@ -928,12 +930,12 @@ void Detector::CreateECALGeometry() if (geom->getTowerGapMaterial() == "Cu") { // Copper // if (contains(geom->getTowerGapMaterial(), "Cu")) { // Copper - volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium("FOCAL_Cu$")); + volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium(getMediumID(ID_COPPER))); } else if (geom->getTowerGapMaterial() == "Al") { // Aluminium // else if (contains(geom->getTowerGapMaterial(), "Al")) { // Aluminium - volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium("FOCAL_AlPlate")); + volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium(getMediumID(ID_ALUMINIUM))); } else { - volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium("FOCAL_AirGaps$")); + volumeColdPlate = new TGeoVolume("volColdPlate", coldPlateBox, gGeoManager->GetMedium(getMediumID(ID_AIR))); } // mSensitiveECALPad.push_back(volumeColdPlate->GetName()); mSensitive.push_back(volumeColdPlate->GetName()); @@ -957,7 +959,7 @@ void Detector::CreateECALGeometry() // Create SiPad box for the two sensitive layers to be placed in front of ECAL TGeoBBox* siPadBox = new TGeoBBox("SiPadBox", geom->getTowerSizeX() / 2. + geom->getTowerGapSizeX() / 2., geom->getTowerSizeY() / 2. + geom->getTowerGapSizeY() / 2., 0.03 / 2.0); - TGeoVolume* volumeSiPad = new TGeoVolume("volSiPad", siPadBox, gGeoManager->GetMedium("FOCAL_SiSens$")); + TGeoVolume* volumeSiPad = new TGeoVolume("volSiPad", siPadBox, gGeoManager->GetMedium(getMediumID(ID_SILICON))); volumeSiPad->SetLineColor(kOrange + 7); // mSensitiveECALPad.push_back(volumeSiPad->GetName()); mSensitive.push_back(volumeSiPad->GetName()); From 7458f6792c6fee5c72db8cfc27057ef4d76945bb Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sat, 20 Jul 2024 07:53:44 +0200 Subject: [PATCH 0009/2205] Trying to get ROOT 6.32.0 to digest the type (#13310) --- .../include/CommonDataFormat/AbstractRef.h | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/DataFormats/common/include/CommonDataFormat/AbstractRef.h b/DataFormats/common/include/CommonDataFormat/AbstractRef.h index 8dce94d502ffb..403bab3cbd62f 100644 --- a/DataFormats/common/include/CommonDataFormat/AbstractRef.h +++ b/DataFormats/common/include/CommonDataFormat/AbstractRef.h @@ -20,9 +20,7 @@ #include "GPUCommonRtypes.h" #include "GPUCommonTypeTraits.h" -namespace o2 -{ -namespace dataformats +namespace o2::dataformats { template @@ -32,8 +30,19 @@ class AbstractRef static constexpr auto MVAR() { static_assert(NBIT <= 64, "> 64 bits not supported"); - typename std::conditional<(NBIT > 32), uint64_t, typename std::conditional<(NBIT > 16), uint32_t, typename std::conditional<(NBIT > 8), uint16_t, uint8_t>::type>::type>::type tp = 0; - return tp; + if constexpr (NBIT > 32) { + uint64_t tp = 0; + return tp; + } else if constexpr (NBIT > 16) { + uint32_t tp = 0; + return tp; + } else if constexpr (NBIT > 8) { + uint16_t tp = 0; + return tp; + } else { + uint8_t tp = 0; + return tp; + } } public: @@ -87,7 +96,6 @@ class AbstractRef ClassDefNV(AbstractRef, 1); }; -} // namespace dataformats -} // namespace o2 +} // namespace o2::dataformats #endif From cce25a432d0febb2358daaeddfa66945c38e2fde Mon Sep 17 00:00:00 2001 From: Sergio Garcia <47090312+singiamtel@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:49:39 +0200 Subject: [PATCH 0010/2205] GitHub Action: Fix typo (#13312) --- .github/workflows/datamodel-doc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/datamodel-doc.yml b/.github/workflows/datamodel-doc.yml index 41a181b490029..0146fbd35fe46 100644 --- a/.github/workflows/datamodel-doc.yml +++ b/.github/workflows/datamodel-doc.yml @@ -72,7 +72,7 @@ jobs: # confused when multiple repos are checked out. GH_TOKEN=${{ secrets.GITHUB_TOKEN }} gh pr create -B \ AliceO2Group:master -H alibuild:auto-datamodel-doc \ - --no-maintainer-edit -t 'Automatic data model update' -b 'This update \ + --no-maintainer-edit -t 'Automatic data model update' -b "This update \ to the data model documentation was automatically created from \ - tonight's O2 dev branch.' || true + tonight's O2 dev branch." || true # If the PR already exists, hub fails, but we've just force-pushed, so we don't need a new PR. From 94dab004d5703eabc5ee6cfb26167624ee4aeaf9 Mon Sep 17 00:00:00 2001 From: pillot Date: Mon, 22 Jul 2024 14:32:04 +0200 Subject: [PATCH 0011/2205] add creation of default MCH/Calib/HV object (#13313) --- Detectors/MUON/Common/README.md | 12 +++++++++++- Detectors/MUON/Common/src/dcs-ccdb.cxx | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Detectors/MUON/Common/README.md b/Detectors/MUON/Common/README.md index b8f8adafca1d6..eb214dae7c5ed 100644 --- a/Detectors/MUON/Common/README.md +++ b/Detectors/MUON/Common/README.md @@ -78,7 +78,17 @@ o2-mid-dcs-ccdb --put-datapoint-config --ccdb http://localhost:8080 ### Default CCDB object -The default object in the CCDB can be produced with: +The default objects in the CCDB can be produced as follow: + +#### MCH/Calib/HV + +```shell +o2-mch-dcs-ccdb --ccdb http://localhost:8080 --upload-default-values -t 1546300800000 +``` + +One DCS data point is created for each channel with the timestamp provided with the `-t` option. The validity range of the object is set from 1 to 9999999999999 and its creation time is set to 1. + +#### MID/Calib/HV ```shell o2-mid-dcs-ccdb --ccdb http://localhost:8080 --upload-default-values -t 1662532507890 diff --git a/Detectors/MUON/Common/src/dcs-ccdb.cxx b/Detectors/MUON/Common/src/dcs-ccdb.cxx index e11628b2a17f0..e85e95cb606a5 100644 --- a/Detectors/MUON/Common/src/dcs-ccdb.cxx +++ b/Detectors/MUON/Common/src/dcs-ccdb.cxx @@ -93,8 +93,9 @@ void dump(const std::string what, DPMAP m, int verbose) std::cout << fmt::format("{:64s} {:4d} ({:4d} unique) values of mean {:7.2f} : ", i.first.get_alias(), v.size(), vv.size(), mean); if (verbose > 1) { + std::cout << "\n"; for (auto dp : vv) { - std::cout << " " << dp << "\n"; + std::cout << fmt::format(" {:7.2f} ", sum(0., dp)) << dp << "\n"; } } std::cout << "timeRange=" << timeRange.first << " " << timeRange.second << "\n"; @@ -187,7 +188,15 @@ void makeDefaultCCDBEntry(const std::string ccdbUrl, uint64_t timestamp) DPMAP dpMap; std::string ccdb = fmt::format("{}/Calib/HV", o2::muon::subsysname()); #if defined(MUON_SUBSYSTEM_MCH) - // TODO: do the same for MCH + std::array types{o2::mch::dcs::MeasurementType::HV_V, o2::mch::dcs::MeasurementType::HV_I}; + std::array defaultValues{1650., 0.1}; + for (size_t itype = 0; itype < 2; ++itype) { + auto aliases = o2::mch::dcs::aliases({types[itype]}); + for (const auto& alias : aliases) { + auto obj = o2::dcs::createDataPointCompositeObject(alias, defaultValues[itype], timestamp_seconds, timestamp_ms); + dpMap[obj.id].emplace_back(obj.data); + } + } #elif defined(MUON_SUBSYSTEM_MID) std::array types{o2::mid::dcs::MeasurementType::HV_V, o2::mid::dcs::MeasurementType::HV_I}; std::array defaultValues{9600., 5}; @@ -209,7 +218,12 @@ void makeDefaultCCDBEntry(const std::string ccdbUrl, uint64_t timestamp) md["default"] = "true"; std::cout << "storing default values of " << o2::muon::subsysname() << " data points to " << ccdb << "\n"; +#if defined(MUON_SUBSYSTEM_MCH) + md["Created"] = "1"; + api.storeAsTFileAny(&dpMap, ccdb, md, 1, 9999999999999); +#elif defined(MUON_SUBSYSTEM_MID) api.storeAsTFileAny(&dpMap, ccdb, md, 1, timestamp); +#endif } bool match(const std::vector& queries, const char* pattern) From 99f308ca2b93cec738487356738a8daa0e8733a2 Mon Sep 17 00:00:00 2001 From: pillot Date: Wed, 17 Jul 2024 12:05:43 +0200 Subject: [PATCH 0012/2205] fix digit time in MC --- Detectors/MUON/MCH/Simulation/CMakeLists.txt | 1 - .../MCH/Simulation/include/MCHSimulation/DEDigitizer.h | 8 ++++++++ .../MUON/MCH/Simulation/include/MCHSimulation/Digitizer.h | 3 +++ Detectors/MUON/MCH/Simulation/src/DEDigitizer.cxx | 4 ++-- Detectors/MUON/MCH/Simulation/src/Digitizer.cxx | 7 +++++++ Steer/DigitizerWorkflow/src/MCHDigitizerSpec.cxx | 2 ++ 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Detectors/MUON/MCH/Simulation/CMakeLists.txt b/Detectors/MUON/MCH/Simulation/CMakeLists.txt index b7e92fbb28087..57cf85ef0c502 100644 --- a/Detectors/MUON/MCH/Simulation/CMakeLists.txt +++ b/Detectors/MUON/MCH/Simulation/CMakeLists.txt @@ -21,7 +21,6 @@ o2_add_library(MCHSimulation PUBLIC_LINK_LIBRARIES O2::DataFormatsMCH O2::DetectorsBase O2::DetectorsPassive - O2::DetectorsRaw O2::MCHBase O2::MCHGeometryCreator O2::MCHMappingInterface diff --git a/Detectors/MUON/MCH/Simulation/include/MCHSimulation/DEDigitizer.h b/Detectors/MUON/MCH/Simulation/include/MCHSimulation/DEDigitizer.h index b8125f0e4cd32..f3eccdb6155bf 100644 --- a/Detectors/MUON/MCH/Simulation/include/MCHSimulation/DEDigitizer.h +++ b/Detectors/MUON/MCH/Simulation/include/MCHSimulation/DEDigitizer.h @@ -43,6 +43,12 @@ class DEDigitizer */ DEDigitizer(int deId, math_utils::Transform3D transformation, std::mt19937& random); + /** Set the first orbit of the processed TF. + * + * @param firstTFOrbit TF first orbit + */ + void setFirstTFOrbit(uint32_t firstTFOrbit) { mFirstTFOrbit = firstTFOrbit; } + /** Process one MCH Hit. * * This will convert the hit eloss into a charge and spread (according @@ -123,6 +129,8 @@ class DEDigitizer std::uniform_int_distribution mPadIdDist; ///< random pad ID generator (uniform distribution) std::uniform_int_distribution mBCDist; ///< random BC number inside ROF generator (uniform distribution) + uint32_t mFirstTFOrbit; ///< first orbit of the TF being processed + std::vector> mSignals; ///< list of signals per pad }; diff --git a/Detectors/MUON/MCH/Simulation/include/MCHSimulation/Digitizer.h b/Detectors/MUON/MCH/Simulation/include/MCHSimulation/Digitizer.h index a3e083f08dea5..e10488aff7e63 100644 --- a/Detectors/MUON/MCH/Simulation/include/MCHSimulation/Digitizer.h +++ b/Detectors/MUON/MCH/Simulation/include/MCHSimulation/Digitizer.h @@ -40,6 +40,9 @@ class Digitizer */ Digitizer(geo::TransformationCreator transformationCreator); + /// @see DEDigitizer::setFirstTFOrbit + void setFirstTFOrbit(uint32_t firstTFOrbit); + /// @see DEDigitizer::processHit void processHits(gsl::span hits, const InteractionRecord& collisionTime, int evID, int srcID); diff --git a/Detectors/MUON/MCH/Simulation/src/DEDigitizer.cxx b/Detectors/MUON/MCH/Simulation/src/DEDigitizer.cxx index 5078f464aabe5..adbd57cc17b1e 100644 --- a/Detectors/MUON/MCH/Simulation/src/DEDigitizer.cxx +++ b/Detectors/MUON/MCH/Simulation/src/DEDigitizer.cxx @@ -15,7 +15,6 @@ #include #include -#include "DetectorsRaw/HBFUtils.h" #include "MCHSimulation/DigitizerParam.h" #include #include "Field/MagneticField.h" @@ -45,6 +44,7 @@ DEDigitizer::DEDigitizer(int deId, math_utils::Transform3D transformation, std:: mNofNoisyPadsDist{DigitizerParam::Instance().noiseOnlyProba * mSegmentation.nofPads()}, mPadIdDist{0, mSegmentation.nofPads() - 1}, mBCDist{0, 3}, + mFirstTFOrbit{0}, mSignals(mSegmentation.nofPads()) { } @@ -281,7 +281,7 @@ DEDigitizer::DigitsAndLabels* DEDigitizer::addNewDigit(std::mapsetFirstTFOrbit(firstTFOrbit); + } +} + void Digitizer::processHits(gsl::span hits, const InteractionRecord& collisionTime, int evID, int srcID) { for (const auto& hit : hits) { diff --git a/Steer/DigitizerWorkflow/src/MCHDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/MCHDigitizerSpec.cxx index 2cd17ba16f5d5..e2a6397f1a2cf 100644 --- a/Steer/DigitizerWorkflow/src/MCHDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/MCHDigitizerSpec.cxx @@ -76,6 +76,8 @@ class MCHDPLDigitizerTask : public o2::base::BaseDPLDigitizer return; } + mDigitizer->setFirstTFOrbit(pc.services().get().firstTForbit); + auto tStart = std::chrono::high_resolution_clock::now(); auto context = pc.inputs().get("collisioncontext"); context->initSimChains(o2::detectors::DetID::MCH, mSimChains); From 3e8ac600872808181056482d0174f615fc1ba94e Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:29:09 +0200 Subject: [PATCH 0013/2205] Add dependency to Bookkeeping in the correct place (#13314) --- dependencies/O2Dependencies.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencies/O2Dependencies.cmake b/dependencies/O2Dependencies.cmake index 9f35a89449601..48a5d57d17c96 100644 --- a/dependencies/O2Dependencies.cmake +++ b/dependencies/O2Dependencies.cmake @@ -99,6 +99,9 @@ set_package_properties(Configuration PROPERTIES TYPE REQUIRED) find_package(Monitoring CONFIG) set_package_properties(Monitoring PROPERTIES TYPE REQUIRED) +find_package(BookkeepingApi CONFIG) +set_package_properties(BookeepingApi PROPERTIES TYPE REQUIRED) + find_package(Common CONFIG) set_package_properties(Common PROPERTIES TYPE REQUIRED) From aa2411a5a691c26fa3b4d879061a5796b87ef667 Mon Sep 17 00:00:00 2001 From: Kirill Naumov Date: Tue, 16 Jul 2024 05:08:43 +0200 Subject: [PATCH 0014/2205] ITS: Fix for verification of TrailerAfterHeader error --- .../include/ITSMFTReconstruction/AlpideCoder.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h index 215e4e33712b2..1fe86263cccfc 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h @@ -680,8 +680,9 @@ class AlpideCoder if (isChipHeader(dataRaw) && isChipEmpty(dataRec)) { // This error can be verified by skipping a bunch counter byte and // checking that the following byte corresponds to the chip trailer - buffer.next(dataRaw); - buffer.next(dataRaw); + buffer.next(dataRaw); // Skipping chip header + buffer.next(dataRaw); // Skipping bunch counter + buffer.current(dataRaw); if (isChipTrailer(dataRaw)) { res = VerifierMismatchResult::EXPECTED_MISMATCH; } From b7abf5460cca6ec32a535dfd24104cf9a9226d6a Mon Sep 17 00:00:00 2001 From: Kirill Naumov Date: Wed, 17 Jul 2024 03:46:44 +0200 Subject: [PATCH 0015/2205] ITS: Adding partial error handling in the verifier This patch adds the support for the following errors: - APE_STRIP_START - APE_ILLEGAL_CHIPID - APE_DET_TIMEOUT - APE_OOT - APE_PROTOCOL_ERROR - APE_LANE_FIFO_OVERFLOW_ERROR - APE_FSM_ERROR - APE_PENDING_DETECTOR_EVENT_LIMIT - APE_PENDING_LANE_EVENT_LIMIT - APE_O2N_ERROR - APE_RATE_MISSING_TRG_ERROR --- .../ITSMFTReconstruction/AlpideCoder.h | 20 ++++++++++++++++++- .../ITSMFTReconstruction/DecodingStat.h | 9 +++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h index 1fe86263cccfc..321ed52258ff2 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h @@ -659,6 +659,7 @@ class AlpideCoder case ChipStat::UnknownWord: case ChipStat::RepeatingPixel: case ChipStat::WrongRow: + break; case ChipStat::APE_STRIP_START: case ChipStat::APE_ILLEGAL_CHIPID: case ChipStat::APE_DET_TIMEOUT: @@ -669,7 +670,24 @@ class AlpideCoder case ChipStat::APE_PENDING_DETECTOR_EVENT_LIMIT: case ChipStat::APE_PENDING_LANE_EVENT_LIMIT: case ChipStat::APE_O2N_ERROR: - case ChipStat::APE_RATE_MISSING_TRG_ERROR: + case ChipStat::APE_RATE_MISSING_TRG_ERROR: { + uint8_t errorByte = ChipStat::getAPEByte((ChipStat::DecErrors)errIdx); + if (dataRaw == errorByte) { + buffer.next(dataRaw); // Skipping error byte + // If we encountered the byte corresponding to the APE error, + // check that the rest of the raw stream consists of only + // padding. + while (buffer.next(dataRaw)) { + if (dataRaw != 0x00) { + break; + } + } + if (buffer.isEmpty()) { + res = VerifierMismatchResult::EXPECTED_MISMATCH; + } + } + break; + } case ChipStat::APE_PE_DATA_MISSING: case ChipStat::APE_OOT_DATA_MISSING: case ChipStat::WrongDColOrder: diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h index d41742c4a6722..705e814fb4904 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h @@ -174,6 +174,15 @@ struct ChipStat { ft = c >= 0xf2 && c <= 0xfe; return APE_STRIP_START + c - 0xf2; } + + // return APE byte that corresponds to the given APE DecErrors + static uint8_t getAPEByte(DecErrors c) + { + if (c < APE_STRIP_START || c > APE_OOT_DATA_MISSING) { + return 0xFF; + } + return 0xF2 + c - APE_STRIP_START; + } uint32_t getNErrors() const; uint32_t addErrors(const ChipPixelData& d, int verbosity); void print(bool skipNoErr = true, const std::string& pref = "FEEID") const; From 53d086a65176a95d1c4c5c96962317a8dff543b6 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Tue, 23 Jul 2024 12:50:29 +0200 Subject: [PATCH 0016/2205] DPL Analysis: signed comparison fix (#13316) --- Framework/Core/include/Framework/ASoA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 4c5a1a8b4c50c..2e80dca06fa36 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -1291,7 +1291,7 @@ auto doSliceBy(T const* table, o2::framework::PresliceBase const template auto prepareFilteredSlice(T const* table, std::shared_ptr slice, uint64_t offset) { - if (offset >= table->tableSize()) { + if (offset >= static_cast(table->tableSize())) { if constexpr (soa::is_soa_filtered_v) { Filtered fresult{{{slice}}, SelectionVector{}, 0}; table->copyIndexBindings(fresult); From 279c652bbf0cbe1c09cf7d96d33c1cc3acbd7c5a Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 24 Jul 2024 07:30:41 +0200 Subject: [PATCH 0017/2205] DPL Data Model: introduce bit to keep track of data created after EoS (#13315) --- DataFormats/Headers/include/Headers/DataHeader.h | 3 ++- Framework/Core/include/Framework/DataProcessingHeader.h | 3 +++ Framework/Core/include/Framework/TimingInfo.h | 6 ++++-- Framework/Core/src/DataAllocator.cxx | 1 + Framework/Core/src/DataProcessingDevice.cxx | 6 ++++++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index c37eff9b34f20..2dbfbd67d8d6c 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -373,7 +373,8 @@ struct BaseHeader { uint32_t flags; struct { uint32_t flagsNextHeader : 1, // do we have a next header after this one? - flagsUnused : 31; // currently unused + flagsReserved : 15, // reserved for future use + flagsDerivedHeader : 16; // reserved for usage by the derived header }; }; diff --git a/Framework/Core/include/Framework/DataProcessingHeader.h b/Framework/Core/include/Framework/DataProcessingHeader.h index 5c068b4e4179a..484dbb9d51a8e 100644 --- a/Framework/Core/include/Framework/DataProcessingHeader.h +++ b/Framework/Core/include/Framework/DataProcessingHeader.h @@ -42,6 +42,9 @@ namespace o2::framework /// @ingroup aliceo2_dataformats_dataheader struct DataProcessingHeader : public header::BaseHeader { static constexpr uint64_t DUMMY_CREATION_TIME_OFFSET = 0x8000000000000000; + // The following flags are used to indicate the behavior of the data processing + static constexpr int32_t KEEP_AT_EOS_FLAG = 1; + /// We return some number of milliseconds, offsetting int by 0x8000000000000000 /// to make sure we can understand when the dummy constructor of DataProcessingHeader was /// used without overriding it with an actual real time from epoch. diff --git a/Framework/Core/include/Framework/TimingInfo.h b/Framework/Core/include/Framework/TimingInfo.h index 84f3971ad3a4a..6b61b8e4ef5b5 100644 --- a/Framework/Core/include/Framework/TimingInfo.h +++ b/Framework/Core/include/Framework/TimingInfo.h @@ -23,7 +23,7 @@ namespace o2::framework struct TimingInfo { constexpr static ServiceKind service_kind = ServiceKind::Stream; - size_t timeslice; /// the timeslice associated to current processing + size_t timeslice; /// the timeslice associated to current processing uint32_t firstTForbit = -1; /// the orbit the TF begins uint32_t tfCounter = -1; // the counter associated to a TF uint32_t runNumber = -1; @@ -36,9 +36,11 @@ struct TimingInfo { /// from a new run, as being processed by the current stream. /// FIXME: for now this is the same as the above. bool streamRunNumberChanged = false; + /// Wether this kind of data should be flushed during end of stream. + bool keepAtEndOfStream = false; static bool timesliceIsTimer(size_t timeslice) { return timeslice > 1652945069870351; } - bool isTimer() const { return timesliceIsTimer(timeslice); }; + [[nodiscard]] bool isTimer() const { return timesliceIsTimer(timeslice); }; }; } // namespace o2::framework diff --git a/Framework/Core/src/DataAllocator.cxx b/Framework/Core/src/DataAllocator.cxx index 0bf0f86f812ec..bae40f2b47947 100644 --- a/Framework/Core/src/DataAllocator.cxx +++ b/Framework/Core/src/DataAllocator.cxx @@ -121,6 +121,7 @@ fair::mq::MessagePtr DataAllocator::headerMessageFromOutput(Output const& spec, dh.runNumber = timingInfo.runNumber; DataProcessingHeader dph{timingInfo.timeslice, 1, timingInfo.creation}; + static_cast(dph).flagsDerivedHeader |= timingInfo.keepAtEndOfStream ? DataProcessingHeader::KEEP_AT_EOS_FLAG : 0; auto& proxy = mRegistry.get(); auto* transport = proxy.getOutputTransport(routeIndex); diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 93940ef5ec21a..dd0528c1b2b42 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1710,6 +1710,12 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) while (DataProcessingDevice::tryDispatchComputation(ref, context.completed) && shouldProcess) { relayer.processDanglingInputs(context.expirationHandlers, *context.registry, false); } + + auto& timingInfo = ref.get(); + // We should keep the data generated at end of stream only for those + // which are not sources. + timingInfo.keepAtEndOfStream = shouldProcess; + EndOfStreamContext eosContext{*context.registry, ref.get()}; context.preEOSCallbacks(eosContext); From f0f5933fb2d830526865c861cd14b7d8bbe39481 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:37:57 +0200 Subject: [PATCH 0018/2205] DPL GUI: add dispatch policy to the inspector --- Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx b/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx index 3ef8b99ed26bb..0e7d21f5eaf27 100644 --- a/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx @@ -365,6 +365,7 @@ void displayDeviceInspector(DeviceSpec const& spec, if (ImGui::CollapsingHeader("Policies")) { ImGui::Text("Completion: %s", spec.completionPolicy.name.c_str()); ImGui::Text("Sending: %s", spec.sendingPolicy.name.c_str()); + ImGui::Text("Dispatching: %s", spec.dispatchPolicy.name.c_str()); } if (ImGui::CollapsingHeader("Signals", ImGuiTreeNodeFlags_DefaultOpen)) { From f73fab661434667638f1f3ec9fafdbbb0bedd936 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:53:37 +0200 Subject: [PATCH 0019/2205] DPL: improve debug message --- Framework/Core/src/DataProcessingDevice.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index dd0528c1b2b42..49ea1bbaf2609 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1847,7 +1847,8 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& // This is because in principle we should track the size of each of // the parts and sum it up. Not for now. O2_SIGNPOST_ID_FROM_POINTER(pid, parts, headerData); - O2_SIGNPOST_START(parts, pid, "parts", "Processing DataHeader with splitPayloadParts %d and splitPayloadIndex %d", dh->splitPayloadParts, dh->splitPayloadIndex); + O2_SIGNPOST_START(parts, pid, "parts", "Processing DataHeader %{public}-4s/%{public}-16s/%d with splitPayloadParts %d and splitPayloadIndex %d", + dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->splitPayloadParts, dh->splitPayloadIndex); if (!dph) { insertInputInfo(pi, 2, InputType::Invalid, info.id); O2_SIGNPOST_EVENT_EMIT_ERROR(device, cid, "handle_data", "Header stack does not contain DataProcessingHeader"); From c57a63a114ee4a0feef7d64207d6fabb95c65a52 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:53:37 +0200 Subject: [PATCH 0020/2205] DPL: simplify code Remove lambdas which were meant to simplify code, and made it more obscure in the end. --- Framework/Core/src/DataProcessingDevice.cxx | 34 ++++++--------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 49ea1bbaf2609..e6bf8f3330597 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -2108,28 +2108,6 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v // should work just fine. std::vector currentSetOfInputs; - // For the moment we have a simple "immediately dispatch" policy for stuff - // in the cache. This could be controlled from the outside e.g. by waiting - // for a few sets of inputs to arrive before we actually dispatch the - // computation, however this can be defined at a later stage. - auto canDispatchSomeComputation = [&completed, ref]() -> bool { - ref.get().getReadyToProcess(completed); - return completed.empty() == false; - }; - - // We use this to get a list with the actual indexes in the cache which - // indicate a complete set of inputs. Notice how I fill the completed - // vector and return it, so that I can have a nice for loop iteration later - // on. - auto getReadyActions = [&completed, ref]() -> std::vector { - auto& stats = ref.get(); - auto& relayer = ref.get(); - using namespace o2::framework; - stats.updateStats({(int)ProcessingStatsId::PENDING_INPUTS, DataProcessingStats::Op::Set, static_cast(relayer.getParallelTimeslices() - completed.size())}); - stats.updateStats({(int)ProcessingStatsId::INCOMPLETE_INPUTS, DataProcessingStats::Op::Set, completed.empty() ? 1 : 0}); - return completed; - }; - // auto getInputSpan = [ref, ¤tSetOfInputs](TimesliceSlot slot, bool consume = true) { auto& relayer = ref.get(); @@ -2264,7 +2242,8 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v control.notifyStreamingState(state.streaming); }; - if (canDispatchSomeComputation() == false) { + ref.get().getReadyToProcess(completed); + if (completed.empty() == true) { LOGP(debug, "No computations available for dispatching."); return false; } @@ -2322,7 +2301,14 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v auto& streamContext = ref.get(); O2_SIGNPOST_ID_GENERATE(sid, device); O2_SIGNPOST_START(device, sid, "device", "Start processing ready actions"); - for (auto action : getReadyActions()) { + + auto& stats = ref.get(); + auto& relayer = ref.get(); + using namespace o2::framework; + stats.updateStats({(int)ProcessingStatsId::PENDING_INPUTS, DataProcessingStats::Op::Set, static_cast(relayer.getParallelTimeslices() - completed.size())}); + stats.updateStats({(int)ProcessingStatsId::INCOMPLETE_INPUTS, DataProcessingStats::Op::Set, completed.empty() ? 1 : 0}); + + for (auto action : completed) { O2_SIGNPOST_ID_GENERATE(aid, device); O2_SIGNPOST_START(device, aid, "device", "Processing action on slot %lu for action %{public}s", action.slot.index, fmt::format("{}", action.op).c_str()); if (action.op == CompletionPolicy::CompletionOp::Wait) { From 642289bcae65ca3067232991dcf7e795d5fa3ffd Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 23 Jul 2024 21:56:00 +0200 Subject: [PATCH 0021/2205] DPL: provide ability to customise consumption order --- Framework/Core/include/Framework/CompletionPolicy.h | 9 +++++++++ Framework/Core/src/DataProcessingDevice.cxx | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/Framework/Core/include/Framework/CompletionPolicy.h b/Framework/Core/include/Framework/CompletionPolicy.h index 55d3014166956..987adfac90e7a 100644 --- a/Framework/Core/include/Framework/CompletionPolicy.h +++ b/Framework/Core/include/Framework/CompletionPolicy.h @@ -62,6 +62,13 @@ struct CompletionPolicy { Retry, }; + /// Order in which the completed slots must be consumed + enum struct CompletionOrder { + Any, + Timeslice, + Slot + }; + using Matcher = std::function; using InputSetElement = DataRef; using CallbackFull = std::function const&, ServiceRegistryRef&)>; @@ -91,6 +98,8 @@ struct CompletionPolicy { /// data. bool balanceChannels = true; + CompletionOrder order = CompletionOrder::Any; + /// Helper to create the default configuration. static std::vector createDefaultPolicies(); }; diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index e6bf8f3330597..36f12156bab85 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -2307,6 +2307,17 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v using namespace o2::framework; stats.updateStats({(int)ProcessingStatsId::PENDING_INPUTS, DataProcessingStats::Op::Set, static_cast(relayer.getParallelTimeslices() - completed.size())}); stats.updateStats({(int)ProcessingStatsId::INCOMPLETE_INPUTS, DataProcessingStats::Op::Set, completed.empty() ? 1 : 0}); + switch (spec.completionPolicy.order) { + case CompletionPolicy::CompletionOrder::Timeslice: + std::sort(completed.begin(), completed.end(), [](auto const& a, auto const& b) { return a.timeslice.value < b.timeslice.value; }); + break; + case CompletionPolicy::CompletionOrder::Slot: + std::sort(completed.begin(), completed.end(), [](auto const& a, auto const& b) { return a.slot.index < b.slot.index; }); + break; + case CompletionPolicy::CompletionOrder::Any: + default: + break; + } for (auto action : completed) { O2_SIGNPOST_ID_GENERATE(aid, device); From 3fbb21c9f33bba1c2cf67548d8e80dd435d83f06 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 24 Jul 2024 09:12:17 +0200 Subject: [PATCH 0022/2205] DPL: add dummy workflow mimicking CCDB populator behaviour --- Framework/TestWorkflows/CMakeLists.txt | 4 + .../src/o2DummyPopulatorWorkflow.cxx | 85 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 Framework/TestWorkflows/src/o2DummyPopulatorWorkflow.cxx diff --git a/Framework/TestWorkflows/CMakeLists.txt b/Framework/TestWorkflows/CMakeLists.txt index 21af45422e0b1..8548d6570e4a4 100644 --- a/Framework/TestWorkflows/CMakeLists.txt +++ b/Framework/TestWorkflows/CMakeLists.txt @@ -33,6 +33,10 @@ o2_add_dpl_workflow(diamond-workflow SOURCES src/o2DiamondWorkflow.cxx COMPONENT_NAME TestWorkflows) +o2_add_dpl_workflow(dummy-populator-workflow + SOURCES src/o2DummyPopulatorWorkflow.cxx + COMPONENT_NAME TestWorkflows) + o2_add_dpl_workflow(analysis-histograms SOURCES src/o2TestHistograms.cxx COMPONENT_NAME TestWorkflows) diff --git a/Framework/TestWorkflows/src/o2DummyPopulatorWorkflow.cxx b/Framework/TestWorkflows/src/o2DummyPopulatorWorkflow.cxx new file mode 100644 index 0000000000000..c7a88dd3c5d32 --- /dev/null +++ b/Framework/TestWorkflows/src/o2DummyPopulatorWorkflow.cxx @@ -0,0 +1,85 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/ConfigParamSpec.h" +#include "Framework/DataTakingContext.h" +#include "Framework/CompletionPolicyHelpers.h" +#include "Framework/DeviceSpec.h" +#include "Framework/RawDeviceService.h" +#include "Framework/ControlService.h" +#include "Framework/Configurable.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/CallbackService.h" +#include "Framework/RateLimiter.h" +#include + +#include +#include +#include +#include + +using namespace o2::framework; + +struct WorkflowOptions { + Configurable anInt{"anInt", 1, ""}; + Configurable aFloat{"aFloat", 2.0f, {"a float option"}}; + Configurable aDouble{"aDouble", 3., {"a double option"}}; + Configurable aString{"aString", "foobar", {"a string option"}}; + Configurable aBool{"aBool", true, {"a boolean option"}}; +}; + +void customize(std::vector& policies) +{ + auto a = CompletionPolicyHelpers::consumeWhenAll(); + a.order = CompletionPolicy::CompletionOrder::Timeslice; + policies.clear(); + policies.push_back(a); +} + +#include "Framework/runDataProcessing.h" + +// This is how you can define your processing in a declarative way +WorkflowSpec defineDataProcessing(ConfigContext const& specs) +{ + DataProcessorSpec a{ + .name = "A", + .algorithm = AlgorithmSpec{adaptStateless( + [](DataAllocator& outputs, RawDeviceService& device, DataTakingContext& context, ProcessingContext& pcx) { + for (unsigned int i = 0; i < 10; i++) { + outputs.snapshot(Output{"TS1", "A1", i}, i); + outputs.snapshot(Output{"TS2", "A2", i}, i); + } + })}, + .options = { + ConfigParamSpec{"some-device-param", VariantType::Int, 1, {"Some device parameter"}}, + }}; + + a.outputs.emplace_back(ConcreteDataTypeMatcher{"TS1", "A1"}, Lifetime::Sporadic); + a.outputs.emplace_back(ConcreteDataTypeMatcher{"TS2", "A2"}, Lifetime::Sporadic); + + DataProcessorSpec d{ + .name = "D", + .inputs = {InputSpec{"a", "TS1", Lifetime::Sporadic}, InputSpec{"b", "TS2", Lifetime::Sporadic}}, + .algorithm = AlgorithmSpec{adaptStateless( + [](InputRecord& inputs) { + auto ref = inputs.get("b"); + if (!ref.header) { + LOG(info) << "Header is not there"; + return; + } + auto dph = o2::header::get(ref.header); + auto dh = o2::header::get(ref.header); + LOG(info) << "Start time: " << dph->startTime; + LOG(info) << "Subspec: " << dh->subSpecification; + })}, + }; + + return workflow::concat(WorkflowSpec{a}, WorkflowSpec{d}); +} From ab2ef089c2f28543da9c393f36656cdc202e071a Mon Sep 17 00:00:00 2001 From: pillot Date: Wed, 24 Jul 2024 14:07:49 +0200 Subject: [PATCH 0023/2205] [MCH] filter digits based on HV status (#13308) * preparation for recording HV status in status map * Addition of HV issues algorithm * improve TF timestamp calculation and add time margin * activate the digit filtering on bad HV * update documentation * add protection against invalid DCS alias --------- Co-authored-by: Stephan Potgieter <77969712+comrademarvin@users.noreply.github.com> --- Detectors/MUON/MCH/DigitFiltering/README.md | 4 + .../MCHDigitFiltering/DigitFilterParam.h | 4 +- Detectors/MUON/MCH/Status/CMakeLists.txt | 2 + Detectors/MUON/MCH/Status/README.md | 2 +- .../include/MCHStatus/HVStatusCreator.h | 116 +++++++++++++ .../include/MCHStatus/StatusMapCreatorParam.h | 11 +- .../MUON/MCH/Status/src/HVStatusCreator.cxx | 155 +++++++++++++++++ .../MCH/Status/src/StatusMapCreatorSpec.cxx | 160 +++++++++++++----- 8 files changed, 403 insertions(+), 51 deletions(-) create mode 100644 Detectors/MUON/MCH/Status/include/MCHStatus/HVStatusCreator.h create mode 100644 Detectors/MUON/MCH/Status/src/HVStatusCreator.cxx diff --git a/Detectors/MUON/MCH/DigitFiltering/README.md b/Detectors/MUON/MCH/DigitFiltering/README.md index fa005b8b5c766..42273fb372adc 100644 --- a/Detectors/MUON/MCH/DigitFiltering/README.md +++ b/Detectors/MUON/MCH/DigitFiltering/README.md @@ -11,6 +11,10 @@ o2-mch-digits-filtering-workflow Filter out some digits. +**StatusMap based filtering :** + +The [status map](/Detectors/MUON/MCH/Status/README.md) lists all the pads that are not perfect and assigns them a status word summarizing the origin of the issue(s). The filtering based on the status map is governed by the [MCHDigitFilterParam](/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h)`.statusMask` parameter, from which we can select the issue(s) to be filtered. + **Noise filtering :** The exact behavior of the noise filtering is governed by the [MCHDigitFilterParam](/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h) configurable param, where you can select the minimum ADC value to consider, and whether to select signal (i.e. killing as much background as possible, possibly killing some signal as well) and/or to reject background (while not killing signal). diff --git a/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h index 811ab236b02e6..d2f3fb6925cf9 100644 --- a/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h +++ b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h @@ -14,6 +14,7 @@ #include "CommonUtils/ConfigurableParam.h" #include "CommonUtils/ConfigurableParamHelper.h" +#include "MCHStatus/StatusMap.h" namespace o2::mch { @@ -29,7 +30,8 @@ struct DigitFilterParam : public o2::conf::ConfigurableParamHelper +#include +#include +#include + +#include "DetectorsDCS/DataPointIdentifier.h" +#include "DetectorsDCS/DataPointValue.h" + +namespace o2::mch +{ + +class StatusMap; + +/** + * @class HVStatusCreator + * @brief Find HV issues from DCS data points and add them to the status map + * + * This is a 3 step procedure: + * + * 1) Find all potential issues from the DCS data points stored in one HV file. + * This must be done each time a new HV file is read from the CCDB. It stores in + * an internal map the time range(s) of the issue(s) for each affected HV channel. + * + * 2) Find all real issues at a given time stamp. + * This must be done for every TF. It updates the internal list of bad HV + * channels if it is different from the current one and tells if that happens. + * + * 3) Update the status maps if needed. + * This must be done each time the current list of bad HV channel has changed. + * It adds every electronics channels associated to the bad HV channels into the + * status map given as a parameter. + */ +class HVStatusCreator +{ + public: + using DPID = o2::dcs::DataPointIdentifier; + using DPVAL = o2::dcs::DataPointValue; + using DPMAP = std::unordered_map>; + + /// Internal structure to define a time range + struct TimeRange { + uint64_t begin = 0; ///< beginning of time range + uint64_t end = 0; ///< end of time range + + /** + * Constructor of time range + * @param begin beginning of time range (ms) + * @param end end of time range (ms) + */ + TimeRange(uint64_t begin, uint64_t end) : begin(begin), end(end){}; + + /** + * Check if the time range contains the given time stamp + * @param timestamp time stamp of interest (ms) + * @return true if the time stamp is in the time range + */ + bool contains(uint64_t timestamp) const { return timestamp >= begin && timestamp < end; } + }; + + using BADHVMAP = std::unordered_map>; + + /** + * Getter for the internal map of HV issues + * @return map of bad HV channels with the time ranges concerned + */ + const BADHVMAP& getBadHVs() const { return mBadHVTimeRanges; } + + /** + * Find all HV issues and their time ranges + * @param dpMap DCS HV data points from CCDB + */ + void findBadHVs(const DPMAP& dpMap); + + /** + * Find HV issues at a given time stamp + * @param timestamp time stamp of interest + * @return true if the list of issues has changed + */ + bool findCurrentBadHVs(uint64_t timestamp); + + /** + * Add channels affected by current HV issues to the status map + * @param statusMap statusMap to update + */ + void updateStatusMap(StatusMap& statusMap) const; + + /// Clear the internal lists of HV issues + void clear() + { + mBadHVTimeRanges.clear(); + mCurrentBadHVs.clear(); + } + + private: + /// map of bad HV channels with the time ranges concerned + BADHVMAP mBadHVTimeRanges{}; + std::set mCurrentBadHVs{}; ///< current list of bad HV channels +}; + +} // namespace o2::mch + +#endif // O2_MCH_HV_STATUS_CREATOR_H_ diff --git a/Detectors/MUON/MCH/Status/include/MCHStatus/StatusMapCreatorParam.h b/Detectors/MUON/MCH/Status/include/MCHStatus/StatusMapCreatorParam.h index 0054acdc9fba7..34b334928f455 100644 --- a/Detectors/MUON/MCH/Status/include/MCHStatus/StatusMapCreatorParam.h +++ b/Detectors/MUON/MCH/Status/include/MCHStatus/StatusMapCreatorParam.h @@ -25,9 +25,16 @@ namespace o2::mch struct StatusMapCreatorParam : public o2::conf::ConfigurableParamHelper { bool useBadChannels = true; ///< reject bad channels (obtained during pedestal calibration runs) - bool useRejectList = true; ///< use extra (relative to bad channels above) rejection list + bool useRejectList = true; ///< use extra rejection list (relative to other bad channels sources) + bool useHV = true; ///< reject channels connected to bad HV sectors - bool isActive() const { return useBadChannels || useRejectList; } + /// chambers HV thresholds for detecting issues + double hvLimits[10] = {1550., 1550., 1600., 1600., 1600., 1600., 1600., 1600., 1600., 1600.}; + uint64_t hvMinDuration = 10000; ///< minimum duration of HV issues in ms + + uint64_t timeMargin = 2000; ///< time margin for comparing DCS and TF timestamps in ms + + bool isActive() const { return useBadChannels || useRejectList || useHV; } O2ParamDef(StatusMapCreatorParam, "MCHStatusMap"); }; diff --git a/Detectors/MUON/MCH/Status/src/HVStatusCreator.cxx b/Detectors/MUON/MCH/Status/src/HVStatusCreator.cxx new file mode 100644 index 0000000000000..2dd700b33ecc6 --- /dev/null +++ b/Detectors/MUON/MCH/Status/src/HVStatusCreator.cxx @@ -0,0 +1,155 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include + +#include "MCHStatus/HVStatusCreator.h" + +#include "MCHConditions/DCSAliases.h" +#include "MCHConditions/DetectionElement.h" +#include "MCHGlobalMapping/Mapper.h" +#include "MCHStatus/StatusMap.h" +#include "MCHStatus/StatusMapCreatorParam.h" + +using DPMAP2 = std::unordered_map>; + +/// Converts DCS data point value to double HV value +double dpConverter(o2::dcs::DataPointValue v) +{ + union Converter { + uint64_t raw_data; + double value; + } converter; + converter.raw_data = v.payload_pt1; + return converter.value; +}; + +/// Decode the DCS DPMAP to be processed for HV issues +DPMAP2 decodeDPMAP(const o2::mch::HVStatusCreator::DPMAP& dpMap) +{ + DPMAP2 dpsMapPerAlias{}; + + auto timeMargin = o2::mch::StatusMapCreatorParam::Instance().timeMargin; + + for (const auto& [dpId, dpsHV] : dpMap) { + std::string alias = dpId.get_alias(); + + if (alias.find("vMon") != std::string::npos && o2::mch::dcs::isValid(alias)) { + auto& dps2 = dpsMapPerAlias[alias]; + + // copy first point to the beginning of time + margin (will be subtracted later on) + dps2.emplace(timeMargin, dpConverter(dpsHV.front())); + + for (const auto& value : dpsHV) { + dps2.emplace(value.get_epoch_time(), dpConverter(value)); + } + + // copy last point to the end of time - margin (will be added later on) + dps2.emplace(std::numeric_limits::max() - timeMargin, dpConverter(dpsHV.back())); + } + } + + return dpsMapPerAlias; +} + +namespace o2::mch +{ + +void HVStatusCreator::findBadHVs(const DPMAP& dpMap) +{ + // clear current list of issues + mBadHVTimeRanges.clear(); + + // decode the DCS DPMAP + DPMAP2 dpsMapPerAlias = decodeDPMAP(dpMap); + + auto minDuration = StatusMapCreatorParam::Instance().hvMinDuration; + auto timeMargin = StatusMapCreatorParam::Instance().timeMargin; + + // find list of HV issues per alias + for (const auto& [alias, dpsHV] : dpsMapPerAlias) { + int chamber = o2::mch::dcs::toInt(o2::mch::dcs::aliasToChamber(alias)); + auto chamberThreshold = StatusMapCreatorParam::Instance().hvLimits[chamber]; + + std::vector hvIssuesList{}; + uint64_t tStart = 0; + uint64_t tStop = 0; + bool ongoingIssue = false; + + for (auto [timestamp, valueHV] : dpsHV) { + if (valueHV < chamberThreshold) { + if (!ongoingIssue) { + tStart = timestamp; + tStop = tStart; + ongoingIssue = true; + } else { + tStop = timestamp; + } + } else { + if (ongoingIssue) { + tStop = timestamp; + if (tStop - tStart > minDuration) { + hvIssuesList.emplace_back(tStart - timeMargin, tStop + timeMargin); + } + ongoingIssue = false; + } + } + } + + // ongoing issue at the end of the object + if (ongoingIssue && tStop - tStart > minDuration) { + hvIssuesList.emplace_back(tStart - timeMargin, tStop + timeMargin); + } + + // add issues for the alias if non-empty + if (!hvIssuesList.empty()) { + mBadHVTimeRanges.emplace(alias, hvIssuesList); + } + } +} + +bool HVStatusCreator::findCurrentBadHVs(uint64_t timestamp) +{ + // list issues at the given time stamp + std::set currentBadHVs{}; + for (const auto& [alias, timeRanges] : mBadHVTimeRanges) { + auto it = std::find_if(timeRanges.begin(), timeRanges.end(), + [timestamp](const TimeRange& r) { return r.contains(timestamp); }); + if (it != timeRanges.end()) { + currentBadHVs.emplace(alias); + } + } + + // check if the list of issues has changed and update it in this case + if (currentBadHVs != mCurrentBadHVs) { + mCurrentBadHVs.swap(currentBadHVs); + return true; + } + + return false; +} + +void HVStatusCreator::updateStatusMap(StatusMap& statusMap) const +{ + for (const auto& alias : mCurrentBadHVs) { + int deId = dcs::aliasToDetElemId(alias).value(); + if (deId < 500) { + for (auto dsIndex : dcs::aliasToDsIndices(alias)) { + statusMap.addDS(dsIndex, StatusMap::kBadHV); + } + } else { + statusMap.addDE(deId, StatusMap::kBadHV); + } + } +} + +} // namespace o2::mch diff --git a/Detectors/MUON/MCH/Status/src/StatusMapCreatorSpec.cxx b/Detectors/MUON/MCH/Status/src/StatusMapCreatorSpec.cxx index cd7422ee05ab5..6ce3ff1519ddd 100644 --- a/Detectors/MUON/MCH/Status/src/StatusMapCreatorSpec.cxx +++ b/Detectors/MUON/MCH/Status/src/StatusMapCreatorSpec.cxx @@ -11,16 +11,24 @@ #include "MCHStatus/StatusMapCreatorSpec.h" +#include "CommonConstants/LHCConstants.h" #include "DataFormatsMCH/DsChannelId.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "Framework/CCDBParamSpec.h" +#include "Framework/CallbackService.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/ControlService.h" #include "Framework/DataSpecUtils.h" +#include "Framework/InputSpec.h" #include "Framework/Logger.h" #include "Framework/OutputSpec.h" #include "Framework/Task.h" +#include "Framework/TimingInfo.h" #include "Framework/WorkflowSpec.h" +#include "MCHStatus/HVStatusCreator.h" #include "MCHStatus/StatusMap.h" #include "MCHStatus/StatusMapCreatorParam.h" +#include #include #include #include @@ -46,24 +54,30 @@ size_t size(const StatusMap& sm) class StatusMapCreatorTask { public: - StatusMapCreatorTask() = default; - - void updateStatusMap() + StatusMapCreatorTask(bool useBadChannels, bool useRejectList, bool useHV, + std::shared_ptr ggRequest) + : mUseBadChannels(useBadChannels), + mUseRejectList(useRejectList), + mUseHV(useHV), + mGGRequest(ggRequest) {} + + void init(InitContext& ic) { - mStatusMap.clear(); - mStatusMap.add(mBadChannels, StatusMap::kBadPedestal); - mStatusMap.add(mRejectList, StatusMap::kRejectList); - mStatusMapUpdated = true; - } - - void - init(InitContext& ic) - { - mUseBadChannels = StatusMapCreatorParam::Instance().useBadChannels; - mUseRejectList = StatusMapCreatorParam::Instance().useRejectList; + if (mGGRequest) { + base::GRPGeomHelper::instance().setRequest(mGGRequest); + } mBadChannels.clear(); mRejectList.clear(); - mStatusMapUpdated = true; + mHVStatusCreator.clear(); + mStatusMap.clear(); + mUpdateStatusMap = false; + + auto stop = [this]() { + auto fullTime = mFindBadHVsTime + mFindCurrentBadHVsTime + mUpdateStatusTime; + LOGP(info, "duration: {:g} ms (findBadHVs: {:g} ms, findCurrentBadHVs: {:g} ms, updateStatusMap: {:g} ms)", + fullTime.count(), mFindBadHVsTime.count(), mFindCurrentBadHVsTime.count(), mUpdateStatusTime.count()); + }; + ic.services().get().set(stop); } void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) @@ -71,69 +85,121 @@ class StatusMapCreatorTask if (matcher == ConcreteDataMatcher("MCH", "BADCHANNELS", 0)) { auto bad = static_cast*>(obj); mBadChannels = *bad; - updateStatusMap(); - } - if (matcher == ConcreteDataMatcher("MCH", "REJECTLIST", 0)) { + mUpdateStatusMap = true; + } else if (matcher == ConcreteDataMatcher("MCH", "REJECTLIST", 0)) { auto rl = static_cast*>(obj); mRejectList = *rl; - updateStatusMap(); + mUpdateStatusMap = true; + } else if (matcher == ConcreteDataMatcher("MCH", "HV", 0)) { + auto tStart = std::chrono::high_resolution_clock::now(); + auto hv = static_cast(obj); + mHVStatusCreator.findBadHVs(*hv); + mFindBadHVsTime += std::chrono::high_resolution_clock::now() - tStart; + } else if (mGGRequest) { + o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj); } } void run(ProcessingContext& pc) { + if (mGGRequest) { + o2::base::GRPGeomHelper::instance().checkUpdates(pc); + } + if (mUseBadChannels) { // to trigger call to finaliseCCDB pc.inputs().get*>("badchannels"); } + if (mUseRejectList) { // to trigger call to finaliseCCDB pc.inputs().get*>("rejectlist"); } - if (mStatusMapUpdated) { - // create the output message + if (mUseHV) { + // to trigger call to finaliseCCDB + pc.inputs().get("hv"); + + // check for update of bad HV channels + auto tStart = std::chrono::high_resolution_clock::now(); + auto orbitReset = base::GRPGeomHelper::instance().getOrbitResetTimeMS(); + auto firstTForbit = pc.services().get().firstTForbit; + auto timestamp = orbitReset + static_cast(firstTForbit * constants::lhc::LHCOrbitMUS * 1.e-3); + if (mHVStatusCreator.findCurrentBadHVs(timestamp)) { + LOGP(info, "HV status updated at timestamp {}", timestamp); + mUpdateStatusMap = true; + } + mFindCurrentBadHVsTime += std::chrono::high_resolution_clock::now() - tStart; + } + + // update the status map if needed + if (mUpdateStatusMap) { + updateStatusMap(); LOGP(info, "Sending updated StatusMap of size {}", size(mStatusMap)); - pc.outputs().snapshot(OutputRef{"statusmap"}, mStatusMap); - mStatusMapUpdated = false; } else { LOGP(info, "Sending unchanged StatusMap of size {}", size(mStatusMap)); - pc.outputs().snapshot(OutputRef{"statusmap"}, mStatusMap); } + + // create the output message + pc.outputs().snapshot(OutputRef{"statusmap"}, mStatusMap); } private: bool mUseBadChannels{false}; bool mUseRejectList{false}; - std::vector mBadChannels; - std::vector mRejectList; - StatusMap mStatusMap; - bool mStatusMapUpdated{false}; + bool mUseHV{false}; + std::shared_ptr mGGRequest{}; + std::vector mBadChannels{}; + std::vector mRejectList{}; + HVStatusCreator mHVStatusCreator{}; + StatusMap mStatusMap{}; + bool mUpdateStatusMap{false}; + std::chrono::duration mFindBadHVsTime{}; + std::chrono::duration mFindCurrentBadHVsTime{}; + std::chrono::duration mUpdateStatusTime{}; + + void updateStatusMap() + { + auto tStart = std::chrono::high_resolution_clock::now(); + mStatusMap.clear(); + mStatusMap.add(mBadChannels, StatusMap::kBadPedestal); + mStatusMap.add(mRejectList, StatusMap::kRejectList); + mHVStatusCreator.updateStatusMap(mStatusMap); + mUpdateStatusMap = false; + mUpdateStatusTime += std::chrono::high_resolution_clock::now() - tStart; + } }; framework::DataProcessorSpec getStatusMapCreatorSpec(std::string_view specName) { - std::string input; - - if (StatusMapCreatorParam::Instance().useBadChannels) { - input = "badchannels:MCH/BADCHANNELS/0?lifetime=condition&ccdb-path=MCH/Calib/BadChannel"; + auto useBadChannels = StatusMapCreatorParam::Instance().useBadChannels; + auto useRejectList = StatusMapCreatorParam::Instance().useRejectList; + auto useHV = StatusMapCreatorParam::Instance().useHV; + std::shared_ptr ggRequest{}; + + std::vector inputs{}; + if (useBadChannels) { + inputs.emplace_back(InputSpec{"badchannels", "MCH", "BADCHANNELS", 0, Lifetime::Condition, ccdbParamSpec("MCH/Calib/BadChannel")}); } - if (StatusMapCreatorParam::Instance().useRejectList) { - if (!input.empty()) { - input += ";"; - } - input += "rejectlist:MCH/REJECTLIST/0?lifetime=condition&ccdb-path=MCH/Calib/RejectList"; + if (useRejectList) { + inputs.emplace_back(InputSpec{"rejectlist", "MCH", "REJECTLIST", 0, Lifetime::Condition, ccdbParamSpec("MCH/Calib/RejectList")}); } - - std::string output = "statusmap:MCH/STATUSMAP/0"; - - std::vector outputs; - auto matchers = select(output.c_str()); - for (auto& matcher : matchers) { - outputs.emplace_back(DataSpecUtils::asOutputSpec(matcher)); + if (useHV) { + inputs.emplace_back(InputSpec{"hv", "MCH", "HV", 0, Lifetime::Condition, ccdbParamSpec("MCH/Calib/HV", {}, 1)}); // query every TF + + ggRequest = std::make_shared(true, // orbitResetTime + false, // GRPECS=true + false, // GRPLHCIF + false, // GRPMagField + false, // askMatLUT + base::GRPGeomRequest::None, // geometry + inputs); } - if (input.empty()) { + std::vector outputs{}; + outputs.emplace_back(OutputSpec{{"statusmap"}, "MCH", "STATUSMAP", 0, Lifetime::Timeframe}); + + if (inputs.empty()) { return DataProcessorSpec{ specName.data(), {}, @@ -148,9 +214,9 @@ framework::DataProcessorSpec getStatusMapCreatorSpec(std::string_view specName) return DataProcessorSpec{ specName.data(), - Inputs{select(input.c_str())}, + inputs, outputs, - AlgorithmSpec{adaptFromTask()}, + AlgorithmSpec{adaptFromTask(useBadChannels, useRejectList, useHV, ggRequest)}, Options{}}; } } // namespace o2::mch From cd1cb0de7ea5958b3f2b1a05f7f194750890c3e9 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:27:27 +0200 Subject: [PATCH 0024/2205] DPL: have helper which returns true if running online --- Framework/Core/include/Framework/DefaultsHelpers.h | 2 ++ Framework/Core/src/CommonServices.cxx | 8 +++----- Framework/Core/src/DefaultsHelpers.cxx | 12 ++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Framework/Core/include/Framework/DefaultsHelpers.h b/Framework/Core/include/Framework/DefaultsHelpers.h index 9905b2033d62d..16d41d03baa7f 100644 --- a/Framework/Core/include/Framework/DefaultsHelpers.h +++ b/Framework/Core/include/Framework/DefaultsHelpers.h @@ -18,6 +18,8 @@ enum struct DeploymentMode; struct DefaultsHelpers { static DeploymentMode deploymentMode(); + /// @true if running online + static bool onlineDeploymentMode(); /// get max number of timeslices in the queue static unsigned int pipelineLength(); }; diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index 7b3febca7be09..39c17599abb9d 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -848,8 +848,7 @@ o2::framework::ServiceSpec CommonServices::dataProcessingStats() bool enableDebugMetrics = true; #endif bool arrowAndResourceLimitingMetrics = false; - DeploymentMode deploymentMode = DefaultsHelpers::deploymentMode(); - if (deploymentMode != DeploymentMode::OnlineDDS && deploymentMode != DeploymentMode::OnlineECS && deploymentMode != DeploymentMode::OnlineAUX && deploymentMode != DeploymentMode::FST) { + if (!DefaultsHelpers::onlineDeploymentMode() && DefaultsHelpers::deploymentMode() != DeploymentMode::FST) { arrowAndResourceLimitingMetrics = true; } // Input proxies should not report cpu_usage_fraction, @@ -1243,8 +1242,7 @@ std::vector CommonServices::defaultServices(std::string extraPlugin objectCache(), ccdbSupportSpec()}; - DeploymentMode deploymentMode = DefaultsHelpers::deploymentMode(); - if (deploymentMode != DeploymentMode::OnlineDDS && deploymentMode != DeploymentMode::OnlineECS && deploymentMode != DeploymentMode::OnlineAUX && deploymentMode != DeploymentMode::FST) { + if (!DefaultsHelpers::onlineDeploymentMode() && DefaultsHelpers::deploymentMode() != DeploymentMode::FST) { specs.push_back(ArrowSupport::arrowBackendSpec()); } specs.push_back(CommonMessageBackends::fairMQBackendSpec()); @@ -1253,7 +1251,7 @@ std::vector CommonServices::defaultServices(std::string extraPlugin std::string loadableServicesStr = extraPlugins; // Do not load InfoLogger by default if we are not at P2. - if (deploymentMode == DeploymentMode::OnlineDDS || deploymentMode == DeploymentMode::OnlineECS || deploymentMode == DeploymentMode::OnlineAUX) { + if (DefaultsHelpers::onlineDeploymentMode()) { if (loadableServicesStr.empty() == false) { loadableServicesStr += ","; } diff --git a/Framework/Core/src/DefaultsHelpers.cxx b/Framework/Core/src/DefaultsHelpers.cxx index 88956b93a855d..4dcc734216f0c 100644 --- a/Framework/Core/src/DefaultsHelpers.cxx +++ b/Framework/Core/src/DefaultsHelpers.cxx @@ -64,4 +64,16 @@ DeploymentMode DefaultsHelpers::deploymentMode() return retVal; } +bool DefaultsHelpers::onlineDeploymentMode() +{ + switch (DefaultsHelpers::deploymentMode()) { + case DeploymentMode::OnlineAUX: + case DeploymentMode::OnlineECS: + case DeploymentMode::OnlineDDS: + return true; + default: + return false; + } +} + } // namespace o2::framework From f5bcf711a834777cff44146bb22bca8fc2268bc6 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:27:27 +0200 Subject: [PATCH 0025/2205] DPL: demote error to warning when dropping on a stop transition Data might be missing for real here, and dropping the processing of those timeslices is the unfortunate but correct thing to do. --- Framework/Core/src/DataRelayer.cxx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/DataRelayer.cxx b/Framework/Core/src/DataRelayer.cxx index b974a51fe82e1..ad085afac0b03 100644 --- a/Framework/Core/src/DataRelayer.cxx +++ b/Framework/Core/src/DataRelayer.cxx @@ -307,7 +307,12 @@ void DataRelayer::setOldestPossibleInput(TimesliceId proposed, ChannelIndex chan if (element.size() != 0) { if (input.lifetime != Lifetime::Condition && mCompletionPolicy.name != "internal-dpl-injected-dummy-sink") { didDrop = true; - LOGP(error, "Dropping incomplete {} Lifetime::{} data in slot {} with timestamp {} < {} as it can never be completed.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + auto& state = mContext.get(); + if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { + LOGP(warning, "Stop transition requested. Dropping incomplete {} Lifetime::{} data in slot {} with timestamp {} < {} as it will never be completed.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + } else { + LOGP(error, "Dropping incomplete {} Lifetime::{} data in slot {} with timestamp {} < {} as it can never be completed.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + } } else { LOGP(debug, "Silently dropping data {} in pipeline slot {} because it has timeslice {} < {} after receiving data from channel {}." @@ -326,7 +331,12 @@ void DataRelayer::setOldestPossibleInput(TimesliceId proposed, ChannelIndex chan } auto& element = mCache[si * mInputs.size() + mi]; if (element.size() == 0) { - LOGP(error, "Missing {} (lifetime:{}) while dropping incomplete data in slot {} with timestamp {} < {}.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + auto& state = mContext.get(); + if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { + LOGP(warning, "Missing {} (lifetime:{}) while dropping incomplete data in slot {} with timestamp {} < {}.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + } else { + LOGP(error, "Missing {} (lifetime:{}) while dropping incomplete data in slot {} with timestamp {} < {}.", DataSpecUtils::describe(input), input.lifetime, si, timestamp.value, newOldest.timeslice.value); + } } } } From cda0619ff354963acdd0993c4a1a491f99e3e7a2 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 23 Jul 2024 09:39:50 +0200 Subject: [PATCH 0026/2205] CCDB Downloader: example of how to use signposts Signposts, when properly configured, can provide stacktrace for each logging line. --- CCDB/src/CCDBDownloader.cxx | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/CCDB/src/CCDBDownloader.cxx b/CCDB/src/CCDBDownloader.cxx index eac0c07f03131..681f75941eda0 100644 --- a/CCDB/src/CCDBDownloader.cxx +++ b/CCDB/src/CCDBDownloader.cxx @@ -12,6 +12,7 @@ #include #include "CommonUtils/StringUtils.h" #include "CCDB/CCDBTimeStampUtils.h" +#include "Framework/Signpost.h" #include #include @@ -29,6 +30,8 @@ #include #include +O2_DECLARE_DYNAMIC_STACKTRACE_LOG(ccdb_downloader); + namespace o2::ccdb { @@ -37,21 +40,24 @@ void uvErrorCheck(int code) if (code != 0) { char buf[1000]; uv_strerror_r(code, buf, 1000); - LOG(error) << "CCDBDownloader: UV error - " << buf; + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "UV error - %{public}s", buf); } } void curlEasyErrorCheck(CURLcode code) { if (code != CURLE_OK) { - LOG(error) << "CCDBDownloader: CURL error - " << curl_easy_strerror(code); + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CURL error - %{public}s", curl_easy_strerror(code)); } } void curlMultiErrorCheck(CURLMcode code) { if (code != CURLM_OK) { - LOG(error) << "CCDBDownloader: CURL error - " << curl_multi_strerror(code); + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CURL error - %{public}s", curl_multi_strerror(code)); } } namespace @@ -155,12 +161,14 @@ void CCDBDownloader::closesocketCallback(void* clientp, curl_socket_t item) } CD->mSocketTimerMap.erase(item); if (close(item) == -1) { - LOG(error) << "CCDBDownloader: Socket failed to close"; + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CCDBDownloader: Socket failed to close"); } } } else { if (close(item) == -1) { - LOG(error) << "CCDBDownloader: Socket failed to close"; + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CCDBDownloader: Socket failed to close"); } } } @@ -170,7 +178,8 @@ curl_socket_t opensocketCallback(void* clientp, curlsocktype purpose, struct cur auto CD = (CCDBDownloader*)clientp; auto sock = socket(address->family, address->socktype, address->protocol); if (sock == -1) { - LOG(error) << "CCDBDownloader: Socket failed to open"; + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CCDBDownloader: Socket failed to open"); } if (CD->mExternalLoop) { @@ -197,7 +206,8 @@ void CCDBDownloader::closeSocketByTimer(uv_timer_t* handle) uvErrorCheck(uv_timer_stop(CD->mSocketTimerMap[sock])); CD->mSocketTimerMap.erase(sock); if (close(sock) == -1) { - LOG(error) << "CCDBDownloader: Socket failed to close"; + O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "CCDBDownloader: Socket failed to close"); } delete data; } From eeca1b05127e226d3fca202d82d01b1a7036139f Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:05:14 +0200 Subject: [PATCH 0027/2205] DPL: run data processing on separate thread --- .../include/Framework/DataProcessingDevice.h | 2 +- Framework/Core/src/DataProcessingDevice.cxx | 20 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Framework/Core/include/Framework/DataProcessingDevice.h b/Framework/Core/include/Framework/DataProcessingDevice.h index 779e1aeff5340..d9565ebef84a2 100644 --- a/Framework/Core/include/Framework/DataProcessingDevice.h +++ b/Framework/Core/include/Framework/DataProcessingDevice.h @@ -63,7 +63,7 @@ struct TaskStreamInfo { /// The registry associated to the task being run ServiceRegistry* registry; /// The libuv task handle - uv_work_t task; + uv_work_t* task; /// Wether or not this task is running bool running = false; }; diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 36f12156bab85..e0a0d1aad16e2 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1264,6 +1264,12 @@ void DataProcessingDevice::Run() bool firstLoop = true; O2_SIGNPOST_ID_FROM_POINTER(lid, device, state.loop); O2_SIGNPOST_START(device, lid, "device_state", "First iteration of the device loop"); + + bool dplEnableMultithreding = getenv("DPL_THREADPOOL_SIZE") != nullptr; + if (dplEnableMultithreding) { + setenv("UV_THREADPOOL_SIZE", "1", 1); + } + while (state.transitionHandling != TransitionHandlingState::Expired) { if (state.nextFairMQState.empty() == false) { (void)this->ChangeState(state.nextFairMQState.back()); @@ -1448,13 +1454,13 @@ void DataProcessingDevice::Run() stream.id = streamRef; stream.running = true; stream.registry = &mServiceRegistry; -#ifdef DPL_ENABLE_THREADING - stream.task.data = &handle; - uv_queue_work(state.loop, &stream.task, run_callback, run_completion); -#else - run_callback(&handle); - run_completion(&handle, 0); -#endif + if (dplEnableMultithreding) [[unlikely]] { + stream.task = &handle; + uv_queue_work(state.loop, stream.task, run_callback, run_completion); + } else { + run_callback(&handle); + run_completion(&handle, 0); + } } else { auto ref = ServiceRegistryRef{mServiceRegistry}; ref.get().handleExpired(reportExpiredOffer); From cbf54d030ebfde746042a7c201403a036c6b9333 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Thu, 25 Jul 2024 19:22:07 +0200 Subject: [PATCH 0028/2205] dev: adding counters to bookkeeping (#13224) --- DataFormats/Detectors/CTP/CMakeLists.txt | 5 +- .../include/DataFormatsCTP/Configuration.h | 2 + .../CTP/include/DataFormatsCTP/Scalers.h | 2 +- .../Detectors/CTP/src/Configuration.cxx | 11 ++ .../Detectors/CTP/src/DataFormatsCTPLinkDef.h | 1 - Detectors/CTP/macro/CreateCTPConfig.C | 3 +- Detectors/CTP/macro/GetAndSave.C | 3 +- Detectors/CTP/macro/GetScalers.C | 4 +- Detectors/CTP/macro/TestConfig.C | 5 +- Detectors/CTP/workflowScalers/CMakeLists.txt | 12 +- .../include/CTPWorkflowScalers}/RunManager.h | 36 ++-- .../CTPWorkflowScalers/ctpCCDBManager.h | 47 +++++ .../src/CTPWorkflowScalersLinkDef.h | 18 ++ .../CTP/workflowScalers}/src/RunManager.cxx | 187 ++++++++---------- .../CTP/workflowScalers/src/ctp-proxy.cxx | 13 +- .../workflowScalers/src/ctpCCDBManager.cxx | 114 +++++++++++ 16 files changed, 326 insertions(+), 137 deletions(-) rename {DataFormats/Detectors/CTP/include/DataFormatsCTP => Detectors/CTP/workflowScalers/include/CTPWorkflowScalers}/RunManager.h (63%) create mode 100644 Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h create mode 100644 Detectors/CTP/workflowScalers/src/CTPWorkflowScalersLinkDef.h rename {DataFormats/Detectors/CTP => Detectors/CTP/workflowScalers}/src/RunManager.cxx (72%) create mode 100644 Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx diff --git a/DataFormats/Detectors/CTP/CMakeLists.txt b/DataFormats/Detectors/CTP/CMakeLists.txt index 2a8ccbef3dee8..d07a4c65a7559 100644 --- a/DataFormats/Detectors/CTP/CMakeLists.txt +++ b/DataFormats/Detectors/CTP/CMakeLists.txt @@ -8,14 +8,12 @@ # In applying this license CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. - o2_add_library(DataFormatsCTP SOURCES src/Digits.cxx src/Configuration.cxx src/Scalers.cxx src/CTF.cxx src/TriggerOffsetsParam.cxx - src/RunManager.cxx src/LumiInfo.cxx PUBLIC_LINK_LIBRARIES O2::CommonDataFormat O2::Headers @@ -29,6 +27,5 @@ o2_target_root_dictionary(DataFormatsCTP include/DataFormatsCTP/Configuration.h include/DataFormatsCTP/Scalers.h include/DataFormatsCTP/LumiInfo.h - include/DataFormatsCTP/TriggerOffsetsParam.h - include/DataFormatsCTP/RunManager.h) + include/DataFormatsCTP/TriggerOffsetsParam.h) diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h index b9378d51872c3..e06c77ad3dfc2 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Configuration.h @@ -160,6 +160,8 @@ class CTPConfiguration const std::vector& getCTPClasses() const { return mCTPClasses; } // Read-only interface uint64_t getInputMask(const std::string& name) const; int getInputIndex(const std::string& name) const; + std::string getClassNameFromIndex(int index) { return mCTPClasses[index].name; }; + std::string getClassNameFromHWIndex(int index); bool isMaskInInputs(const uint64_t& mask) const; bool isBCMaskInConfig(const std::string maskname) const; const BCMask* isBCMaskInConfigP(const std::string bcmask) const; diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h index a9a831a07635e..4484046bd4cbd 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h @@ -106,7 +106,7 @@ class CTPRunScalers void setDetectorMask(o2::detectors::DetID::mask_t mask) { mDetectorMask = mask; }; void setRunNumber(uint32_t rnumber) { mRunNumber = rnumber; }; void addScalerRacordRaw(CTPScalerRecordRaw& scalerrecordraw) { mScalerRecordRaw.push_back(scalerrecordraw); }; - uint32_t getRunNUmber() { return mRunNumber; }; + uint32_t getRunNumber() { return mRunNumber; }; int printRates(); int printIntegrals(); int printInputRateAndIntegral(int inp); diff --git a/DataFormats/Detectors/CTP/src/Configuration.cxx b/DataFormats/Detectors/CTP/src/Configuration.cxx index a26feae5d7f85..c24e1a18c4718 100644 --- a/DataFormats/Detectors/CTP/src/Configuration.cxx +++ b/DataFormats/Detectors/CTP/src/Configuration.cxx @@ -773,6 +773,16 @@ int CTPConfiguration::getInputIndex(const std::string& name) const LOG(info) << "input:" << name << " index:" << index; return index; } +std::string CTPConfiguration::getClassNameFromHWIndex(int index) +{ + for (auto& cls : mCTPClasses) { + if (cls.classMask == (1ull << index)) { + return cls.name; + } + } + std::string ret = "not found"; + return ret; +} bool CTPConfiguration::isMaskInInputs(const uint64_t& mask) const { for (auto const& inp : mInputs) { @@ -877,6 +887,7 @@ uint64_t CTPConfiguration::getTriggerClassMask() const } return clsmask; } +// Hardware positions of classes std::vector CTPConfiguration::getTriggerClassList() const { uint64_t clsmask = getTriggerClassMask(); diff --git a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h index ecab7df8827d3..5dbabad4db7e7 100644 --- a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h +++ b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h @@ -44,7 +44,6 @@ #pragma link C++ class o2::ctp::CTPScalerRecordO2 + ; #pragma link C++ class vector < o2::ctp::CTPScalerRecordO2> + ; #pragma link C++ class o2::ctp::CTPRunScalers + ; -#pragma link C++ class o2::ctp::CTPRunManager + ; #pragma link C++ class o2::ctp::LumiInfo + ; #pragma link C++ class vector < o2::ctp::LumiInfo> + ; diff --git a/Detectors/CTP/macro/CreateCTPConfig.C b/Detectors/CTP/macro/CreateCTPConfig.C index bed4469dd566d..a3e4b0c8c35f1 100644 --- a/Detectors/CTP/macro/CreateCTPConfig.C +++ b/Detectors/CTP/macro/CreateCTPConfig.C @@ -19,6 +19,7 @@ #include "CCDB/CcdbApi.h" #include "CCDB/BasicCCDBManager.h" #include "DataFormatsCTP/Configuration.h" +#include "CTPWorkflowScalers/ctpCCDBManager.h" #include #include #include @@ -79,7 +80,7 @@ ferst 1 \n\ std::cout << "CTP config done" << std::endl; ctpcfg.checkConfigConsistency(); if (0) { - CTPRunManager* man = new CTPRunManager; + o2::ctp::ctpCCDBManager* man = new ctpCCDBManager; man->setCCDBHost("http://ccdb-test.cern.ch:8080"); man->saveRunConfigToCCDB(&ctpcfg, 1665784953); // uint64_t classmask = ctpcfg.getClassMaskForInputMask(0x4); diff --git a/Detectors/CTP/macro/GetAndSave.C b/Detectors/CTP/macro/GetAndSave.C index 1824726749575..345bb1caf4a96 100644 --- a/Detectors/CTP/macro/GetAndSave.C +++ b/Detectors/CTP/macro/GetAndSave.C @@ -19,6 +19,7 @@ #include "CCDB/BasicCCDBManager.h" #include "DataFormatsCTP/Scalers.h" #include "DataFormatsCTP/Configuration.h" +#include "CTPWorkflowScalers/ctpCCDBManager.h" #include "TFile.h" #include "TString.h" #include @@ -36,7 +37,7 @@ void GetAndSave(std::string ccdbHost = "http://ccdb-test.cern.ch:8080") // std::vector runs = {"518543"}; // std::vector timestamps = {1655118513690}; int i = 0; - CTPRunManager mng; + ctpCCDBManager mng; // mng.setCCDBHost(ccdbHost); auto& mgr = o2::ccdb::BasicCCDBManager::instance(); mgr.setURL(ccdbHost); diff --git a/Detectors/CTP/macro/GetScalers.C b/Detectors/CTP/macro/GetScalers.C index 05fce0b657f5a..1f104850c8c39 100644 --- a/Detectors/CTP/macro/GetScalers.C +++ b/Detectors/CTP/macro/GetScalers.C @@ -20,6 +20,8 @@ #include "CCDB/BasicCCDBManager.h" #include "DataFormatsCTP/Scalers.h" #include "DataFormatsCTP/Configuration.h" +// #include "BookkeepingApi/BkpClientFactory.h" +#include "CTPWorkflowScalers/ctpCCDBManager.h" #include #include #include @@ -34,7 +36,7 @@ void GetScalers(std::string srun, long time, std::string ccdbHost = "http://ccdb // std::cout << stol(hd["SOR"]) << "\n"; CTPConfiguration ctpcfg; CTPRunScalers scl; - CTPRunManager mng; + o2::ctp::ctpCCDBManager mng; mng.setCCDBHost(ccdbHost); bool ok; // ctpcfg = mng.getConfigFromCCDB(time, srun); diff --git a/Detectors/CTP/macro/TestConfig.C b/Detectors/CTP/macro/TestConfig.C index 48360996d3439..38da821ea4807 100644 --- a/Detectors/CTP/macro/TestConfig.C +++ b/Detectors/CTP/macro/TestConfig.C @@ -12,6 +12,7 @@ #if !defined(__CLING__) || defined(__ROOTCLING__) #include #include +#include "CTPWorkflowScalers/ctpCCDBManager.h" #endif using namespace o2::ctp; @@ -22,9 +23,9 @@ void TestConfig(bool test = 0) } uint64_t timestamp = 1660196771632; std::string run = "523148"; - o2::ctp::CTPRunManager::setCCDBHost("https://alice-ccdb.cern.ch"); + o2::ctp::ctpCCDBManager::setCCDBHost("https://alice-ccdb.cern.ch"); bool ok; - auto ctpcfg = o2::ctp::CTPRunManager::getConfigFromCCDB(timestamp, run, ok); + auto ctpcfg = o2::ctp::ctpCCDBManager::getConfigFromCCDB(timestamp, run, ok); if (ok == 0) { std::cout << "Can not get config for run:" << run << std::endl; } diff --git a/Detectors/CTP/workflowScalers/CMakeLists.txt b/Detectors/CTP/workflowScalers/CMakeLists.txt index 672bf328212cb..fe91ee2fec28b 100644 --- a/Detectors/CTP/workflowScalers/CMakeLists.txt +++ b/Detectors/CTP/workflowScalers/CMakeLists.txt @@ -8,12 +8,22 @@ # In applying this license CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +if (NOT APPLE) +o2_add_library(CTPWorkflowScalers + SOURCES src/ctpCCDBManager.cxx + SOURCES src/RunManager.cxx + PUBLIC_LINK_LIBRARIES O2::Framework + O2::DataFormatsCTP + AliceO2::BookkeepingApi) +o2_target_root_dictionary(CTPWorkflowScalers HEADERS + include/CTPWorkflowScalers/ctpCCDBManager.h) o2_add_executable( proxy COMPONENT_NAME ctp SOURCES src/ctp-proxy.cxx PUBLIC_LINK_LIBRARIES O2::DCStestWorkflow - O2::DataFormatsCTP) + O2::CTPWorkflowScalers) +endif() o2_add_executable( qc-proxy COMPONENT_NAME ctp diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/RunManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h similarity index 63% rename from DataFormats/Detectors/CTP/include/DataFormatsCTP/RunManager.h rename to Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h index 2df164474e4c4..e40c30ee04931 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/RunManager.h +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h @@ -14,19 +14,32 @@ /// \author Roman Lietava #ifndef _CTP_RUNMANAGER_H_ #define _CTP_RUNMANAGER_H_ +#include "CTPWorkflowScalers/ctpCCDBManager.h" #include "DataFormatsCTP/Configuration.h" +#include "BookkeepingApi/BkpClientFactory.h" +#include "BookkeepingApi/BkpClient.h" +using namespace o2::bkp::api; namespace o2 { namespace ctp { +typedef std::map> counters_t; +typedef std::map> counters64_t; struct CTPActiveRun { CTPActiveRun() = default; long timeStart; long timeStop; CTPConfiguration cfg; CTPRunScalers scalers; + void initBK(); + int send2BK(std::unique_ptr& BKClient, size_t ts, bool start); + // + counters_t cnts0; // first counters in run + counters_t cntslast0; // last minus one read counters needed for overflow correction + counters_t cntslast; // last read counters + counters64_t overflows; }; -class CTPRunManager +class CTPRunManager : public ctpCCDBManager { public: CTPRunManager() = default; @@ -34,33 +47,28 @@ class CTPRunManager int loadRun(const std::string& cfg); int startRun(const std::string& cfg); int stopRun(uint32_t irun, long timeStamp); - int addScalers(uint32_t irun, std::time_t time); + int addScalers(uint32_t irun, std::time_t time, bool start = 0); int processMessage(std::string& topic, const std::string& message); void printActiveRuns() const; - int saveRunScalersToCCDB(int i); - int saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart); - static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run, bool& ok); - static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); - CTPRunScalers getScalersFromCCDB(long timestamp, std::string, bool& ok); int loadScalerNames(); - // void setCCDBPathConfig(std::string path) { mCCDBPathCTPConfig = path;}; - void setCCDBPathScalers(std::string path) { mCCDBPathCTPScalers = path; }; - static void setCCDBHost(std::string host) { mCCDBHost = host; }; + int getNRuns(); + void setBKHost(std::string host) { mBKHost = host; }; + uint64_t checkOverflow(uint32_t lcnt0, uint32_t lcnt1, uint64_t lcntcor); void printCounters(); private: /// Database constants - // std::string mCCDBHost = "http://ccdb-test.cern.ch:8080"; - static std::string mCCDBHost; - std::string mCCDBPathCTPScalers = "CTP/Calib/Scalers"; + std::string mBKHost = ""; std::array mActiveRuns; std::array mActiveRunNumbers; std::array mCounters; std::map mScalerName2Position; std::map mRunsLoaded; + std::unique_ptr mBKClient; int mEOX = 0; // redundancy check int mNew = 1; // 1 - no CCDB: used for QC - ClassDefNV(CTPRunManager, 5); + + ClassDefNV(CTPRunManager, 6); }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h new file mode 100644 index 0000000000000..ce8b17498e7ef --- /dev/null +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h @@ -0,0 +1,47 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file RunManager.h +/// \brief Managing runs for config and scalers +/// \author Roman Lietava +#ifndef _CTP_CTPCCDB_H_ +#define _CTP_CTPCCDB_H_ +#include "DataFormatsCTP/Configuration.h" + +namespace o2 +{ +namespace ctp +{ +class ctpCCDBManager +{ + public: + ctpCCDBManager() = default; + int saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, long timeStop); + int saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart); + static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run, bool& ok); + static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); + CTPRunScalers getScalersFromCCDB(long timestamp, std::string, bool& ok); + void setCCDBPathConfig(std::string path) { mCCDBPathCTPConfig = path; }; + void setCCDBPathScalers(std::string path) { mCCDBPathCTPScalers = path; }; + static void setCCDBHost(std::string host) { mCCDBHost = host; }; + + protected: + /// Database constants + // std::string mCCDBHost = "http://ccdb-test.cern.ch:8080"; + static std::string mCCDBHost; + std::string mCCDBPathCTPScalers = "CTP/Calib/Scalers"; + std::string mCCDBPathCTPConfig = "CTP/Config/Config"; + + ClassDefNV(ctpCCDBManager, 0); +}; +} // namespace ctp +} // namespace o2 +#endif //_CTP_CTPCCDB_H_ diff --git a/Detectors/CTP/workflowScalers/src/CTPWorkflowScalersLinkDef.h b/Detectors/CTP/workflowScalers/src/CTPWorkflowScalersLinkDef.h new file mode 100644 index 0000000000000..284e64a5222b1 --- /dev/null +++ b/Detectors/CTP/workflowScalers/src/CTPWorkflowScalersLinkDef.h @@ -0,0 +1,18 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::ctp::ctpCCDBManager + ; +#endif diff --git a/DataFormats/Detectors/CTP/src/RunManager.cxx b/Detectors/CTP/workflowScalers/src/RunManager.cxx similarity index 72% rename from DataFormats/Detectors/CTP/src/RunManager.cxx rename to Detectors/CTP/workflowScalers/src/RunManager.cxx index a41af579d84e6..85bb0465974dc 100644 --- a/DataFormats/Detectors/CTP/src/RunManager.cxx +++ b/Detectors/CTP/workflowScalers/src/RunManager.cxx @@ -12,16 +12,60 @@ /// \file RunManager.cxx /// \author Roman Lietava -#include "DataFormatsCTP/Configuration.h" -#include "DataFormatsCTP/RunManager.h" -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" +#include "CTPWorkflowScalers/RunManager.h" +#include #include #include #include "CommonUtils/StringUtils.h" #include using namespace o2::ctp; -std::string CTPRunManager::mCCDBHost = "http://o2-ccdb.internal"; +/// +/// Active run to keep cfg and saclers of active runs +/// Also used for Bookkeeping counters managment; +/// +void CTPActiveRun::initBK() +{ + std::vector clslist = cfg.getTriggerClassList(); + for (auto const& cls : clslist) { + cntslast[cls] = {0, 0, 0, 0, 0, 0}; + cntslast0[cls] = {0, 0, 0, 0, 0, 0}; + overflows[cls] = {0, 0, 0, 0, 0, 0}; + } +} +int CTPActiveRun::send2BK(std::unique_ptr& BKClient, size_t ts, bool start) +{ + int runNumber = cfg.getRunNumber(); + // LOG(info) << "BK Filling run:" << runNumber; + // int runOri = runNumber; + // runNumber = 123; + if (start) { + for (auto const& cls : cntslast) { + for (int i = 0; i < 6; i++) { + cnts0[cls.first][i] = cls.second[i]; + } + } + } + std::array cntsbk{0}; + for (auto const& cls : cntslast) { + for (int i = 0; i < 6; i++) { + if (cls.second[i] < cntslast0[cls.first][i]) { + overflows[cls.first][i]++; + } + cntslast0[cls.first][i] = cls.second[i]; + cntsbk[i] = (uint64_t)cls.second[i] + 0xffffffffull * overflows[cls.first][i] - (uint64_t)cnts0[cls.first][i]; + } + std::string clsname = cfg.getClassNameFromHWIndex(cls.first); + // clsname = std::to_string(runOri) + "_" + clsname; + try { + BKClient->triggerCounters()->createOrUpdateForRun(runNumber, clsname, ts, cntsbk[0], cntsbk[1], cntsbk[2], cntsbk[3], cntsbk[4], cntsbk[5]); + } catch (std::runtime_error& error) { + std::cerr << "An error occurred: " << error.what() << std::endl; + return 1; + } + LOG(debug) << "Run BK:" << runNumber << " class:" << clsname << " cls.first" << cls.first << " ts:" << ts << " cnts:" << cntsbk[0] << " " << cntsbk[1] << " " << cntsbk[2] << " " << cntsbk[3] << " " << cntsbk[4] << " " << cntsbk[5]; + } + return 0; +} /// /// Run Manager to manage Config and Scalers /// @@ -31,6 +75,12 @@ void CTPRunManager::init() mActiveRuns[i] = nullptr; } loadScalerNames(); + if (mBKHost != "none") { + mBKClient = BkpClientFactory::create(mBKHost); + LOG(info) << "BK Client created with:" << mBKHost; + } else { + LOG(info) << "BK not sent"; + } LOG(info) << "CCDB host:" << mCCDBHost; LOG(info) << "CTP vNew:" << mNew; LOG(info) << "CTPRunManager initialised."; @@ -68,6 +118,7 @@ int CTPRunManager::loadRun(const std::string& cfg) // mRunsLoaded[runnumber] = activerun; saveRunConfigToCCDB(&activerun->cfg, timeStamp); + return 0; } int CTPRunManager::startRun(const std::string& cfg) @@ -84,12 +135,12 @@ int CTPRunManager::stopRun(uint32_t irun, long timeStamp) // const auto now = std::chrono::system_clock::now(); // const long timeStamp = std::chrono::duration_cast(now.time_since_epoch()).count(); mActiveRuns[irun]->timeStop = timeStamp * 1000.; - saveRunScalersToCCDB(irun); + saveRunScalersToCCDB(mActiveRuns[irun]->scalers, mActiveRuns[irun]->timeStart, mActiveRuns[irun]->timeStop); delete mActiveRuns[irun]; mActiveRuns[irun] = nullptr; return 0; } -int CTPRunManager::addScalers(uint32_t irun, std::time_t time) +int CTPRunManager::addScalers(uint32_t irun, std::time_t time, bool start) { if (mActiveRuns[irun] == nullptr) { LOG(error) << "No config for run index:" << irun; @@ -109,7 +160,7 @@ int CTPRunManager::addScalers(uint32_t irun, std::time_t time) std::string c1a = "cla1a" + std::to_string(cls + 1); CTPScalerRaw scalraw; scalraw.classIndex = (uint32_t)cls; - // std::cout << "cls:" << cls << " " << scalraw.classIndex << std::endl; + std::cout << "cls:" << cls << " " << scalraw.classIndex << std::endl; scalraw.lmBefore = mCounters[mScalerName2Position[cmb]]; scalraw.lmAfter = mCounters[mScalerName2Position[cma]]; scalraw.l0Before = mCounters[mScalerName2Position[c0b]]; @@ -119,23 +170,19 @@ int CTPRunManager::addScalers(uint32_t irun, std::time_t time) // std::cout << "positions:" << cmb << " " << mScalerName2Position[cmb] << std::endl; // std::cout << "positions:" << cma << " " << mScalerName2Position[cma] << std::endl; scalrec.scalers.push_back(scalraw); - } - // detectors - // std::vector detlist = mActiveRuns[irun]->cfg.getDetectorList(); - /* - o2::detectors::DetID::mask_t detmask = mActiveRuns[irun]->cfg.getDetectorMask(); - for (uint32_t i = 0; i < 32; i++) { - o2::detectors::DetID::mask_t deti = 1ul << i; - bool detin = (detmask & deti).count(); - if (detin) { - std::string detname(o2::detectors::DetID::getName(i)); - std::string countername = "ltg" + CTPConfiguration::detName2LTG.at(detname) + "_PH"; - uint32_t detcount = mCounters[mScalerName2Position[countername]]; - scalrec.scalersDets.push_back(detcount); - // LOG(info) << "Scaler for detector:" << countername << ":" << detcount; + // BK scalers to be corrected for overflow + if (mBKClient) { + CTPActiveRun* ar = mActiveRuns[irun]; + ar->cntslast[cls][0] = scalraw.lmBefore; + ar->cntslast[cls][1] = scalraw.lmAfter; + ar->cntslast[cls][2] = scalraw.l0Before; + ar->cntslast[cls][3] = scalraw.l0After; + ar->cntslast[cls][4] = scalraw.l1Before; + ar->cntslast[cls][5] = scalraw.l1After; } } - */ + mActiveRuns[irun]->send2BK(mBKClient, time, start); + // uint32_t NINPS = 48; int offset = 599; for (uint32_t i = 0; i < NINPS; i++) { @@ -236,7 +283,7 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message mActiveRunNumbers[i] = mCounters[i]; mActiveRuns[i] = run->second; mRunsLoaded.erase(run); - addScalers(i, tt); + addScalers(i, tt, 1); } else { LOG(error) << "Trying to start run which is not loaded:" << mCounters[i]; } @@ -267,88 +314,6 @@ void CTPRunManager::printActiveRuns() const } std::cout << std::endl; } -int CTPRunManager::saveRunScalersToCCDB(int i) -{ - // data base - CTPActiveRun* run = mActiveRuns[i]; - using namespace std::chrono_literals; - std::chrono::seconds days3 = 259200s; - std::chrono::seconds min10 = 600s; - long time3days = std::chrono::duration_cast(days3).count(); - long time10min = std::chrono::duration_cast(min10).count(); - long tmin = run->timeStart - time10min; - long tmax = run->timeStop + time3days; - o2::ccdb::CcdbApi api; - map metadata; // can be empty - metadata["runNumber"] = std::to_string(run->cfg.getRunNumber()); - api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation - // store abitrary user object in strongly typed manner - api.storeAsTFileAny(&(run->scalers), mCCDBPathCTPScalers, metadata, tmin, tmax); - LOG(info) << "CTP scalers saved in ccdb:" << mCCDBHost << " run:" << run->cfg.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; - return 0; -} -int CTPRunManager::saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart) -{ - // data base - using namespace std::chrono_literals; - std::chrono::seconds days3 = 259200s; - std::chrono::seconds min10 = 600s; - long time3days = std::chrono::duration_cast(days3).count(); - long time10min = std::chrono::duration_cast(min10).count(); - long tmin = timeStart - time10min; - long tmax = timeStart + time3days; - o2::ccdb::CcdbApi api; - map metadata; // can be empty - metadata["runNumber"] = std::to_string(cfg->getRunNumber()); - api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation - // store abitrary user object in strongly typed manner - api.storeAsTFileAny(cfg, CCDBPathCTPConfig, metadata, tmin, tmax); - LOG(info) << "CTP config saved in ccdb:" << mCCDBHost << " run:" << cfg->getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; - return 0; -} -CTPConfiguration CTPRunManager::getConfigFromCCDB(long timestamp, std::string run, bool& ok) -{ - auto& mgr = o2::ccdb::BasicCCDBManager::instance(); - mgr.setURL(mCCDBHost); - map metadata; // can be empty - metadata["runNumber"] = run; - auto ctpconfigdb = mgr.getSpecific(CCDBPathCTPConfig, timestamp, metadata); - if (ctpconfigdb == nullptr) { - LOG(info) << "CTP config not in database, timestamp:" << timestamp; - ok = 0; - } else { - // ctpconfigdb->printStream(std::cout); - LOG(info) << "CTP config found. Run:" << run; - ok = 1; - } - return *ctpconfigdb; -} -CTPConfiguration CTPRunManager::getConfigFromCCDB(long timestamp, std::string run) -{ - bool ok; - auto ctpconfig = getConfigFromCCDB(timestamp, run, ok); - if (ok == 0) { - LOG(error) << "CTP config not in CCDB"; - return CTPConfiguration(); - } - return ctpconfig; -} -CTPRunScalers CTPRunManager::getScalersFromCCDB(long timestamp, std::string run, bool& ok) -{ - auto& mgr = o2::ccdb::BasicCCDBManager::instance(); - mgr.setURL(mCCDBHost); - map metadata; // can be empty - metadata["runNumber"] = run; - auto ctpscalers = mgr.getSpecific(mCCDBPathCTPScalers, timestamp, metadata); - if (ctpscalers == nullptr) { - LOG(info) << "CTPRunScalers not in database, timestamp:" << timestamp; - ok = 0; - } else { - // ctpscalers->printStream(std::cout); - ok = 1; - } - return *ctpscalers; -} int CTPRunManager::loadScalerNames() { if (CTPRunScalers::NCOUNTERS != CTPRunScalers::scalerNames.size()) { @@ -361,6 +326,16 @@ int CTPRunManager::loadScalerNames() } return 0; } +int CTPRunManager::getNRuns() +{ + int n = 0; + for (int i = 0; i < NRUNS; i++) { + if (mActiveRuns[i] != nullptr) { + n++; + } + } + return n; +} void CTPRunManager::printCounters() { int NDET = 18; diff --git a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx index 1b90eb8c23d9d..6d4c6663b3b67 100644 --- a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx +++ b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx @@ -40,18 +40,19 @@ #include #include #include "CommonUtils/StringUtils.h" -#include "DataFormatsCTP/RunManager.h" +#include "CTPWorkflowScalers/RunManager.h" #include #include - +#include "BookkeepingApi/BkpClient.h" using namespace o2::framework; using DetID = o2::detectors::DetID; -InjectorFunction dcs2dpl(std::string& ccdbhost) -// InjectorFunction dcs2dpl() +InjectorFunction dcs2dpl(std::string& ccdbhost, std::string& bkhost) { auto runMgr = std::make_shared(); runMgr->setCCDBHost(ccdbhost); + runMgr->setBKHost(bkhost); runMgr->init(); + // runMgr->setClient(client); return [runMgr](TimingInfo&, ServiceRegistryRef const& services, fair::mq::Parts& parts, ChannelRetriever channelRetriever, size_t newTimesliceId, bool& stop) -> bool { // FIXME: Why isn't this function using the timeslice index? // make sure just 2 messages received @@ -73,6 +74,7 @@ void customize(std::vector& workflowOptions) { workflowOptions.push_back(ConfigParamSpec{"subscribe-to", VariantType::String, "type=sub,method=connect,address=tcp://188.184.30.57:5556,rateLogging=10,transport=zeromq", {"channel subscribe to"}}); workflowOptions.push_back(ConfigParamSpec{"ccdb-host", VariantType::String, "http://o2-ccdb.internal:8080", {"ccdb host"}}); + workflowOptions.push_back(ConfigParamSpec{"bk-host", VariantType::String, "none", {"bk host"}}); } #include "Framework/runDataProcessing.h" @@ -95,6 +97,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) const std::string devName = "ctp-proxy"; auto chan = config.options().get("subscribe-to"); std::string ccdbhost = config.options().get("ccdb-host"); + std::string bkhost = config.options().get("bk-host"); if (chan.empty()) { throw std::runtime_error("input channel is not provided"); } @@ -109,7 +112,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) std::move(ctpCountersOutputs), // this is just default, can be overriden by --ctp-config-proxy '--channel-config..' chan.c_str(), - dcs2dpl(ccdbhost)); + dcs2dpl(ccdbhost, bkhost)); ctpProxy.labels.emplace_back(DataProcessorLabel{"input-proxy"}); LOG(info) << "===> Proxy done"; WorkflowSpec workflow; diff --git a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx new file mode 100644 index 0000000000000..d5a82ca0923ec --- /dev/null +++ b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx @@ -0,0 +1,114 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ctpCCDBManager.cxx +/// \author Roman Lietava +#include "CTPWorkflowScalers/ctpCCDBManager.h" +#include "DataFormatsCTP/Configuration.h" +#include "CCDB/CcdbApi.h" +#include "CCDB/BasicCCDBManager.h" +#include +#include +#include "CommonUtils/StringUtils.h" +#include +using namespace o2::ctp; +std::string ctpCCDBManager::mCCDBHost = "http://o2-ccdb.internal"; +// +int ctpCCDBManager::saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, long timeStop) +{ + // data base + if (mCCDBHost == "none") { + LOG(info) << "Scalers not written to CCDB none"; + return 0; + } + // CTPActiveRun* run = mActiveRuns[i]; + using namespace std::chrono_literals; + std::chrono::seconds days3 = 259200s; + std::chrono::seconds min10 = 600s; + long time3days = std::chrono::duration_cast(days3).count(); + long time10min = std::chrono::duration_cast(min10).count(); + long tmin = timeStart - time10min; + long tmax = timeStop + time3days; + o2::ccdb::CcdbApi api; + map metadata; // can be empty + metadata["runNumber"] = std::to_string(scalers.getRunNumber()); + api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation + // store abitrary user object in strongly typed manner + int ret = api.storeAsTFileAny(&(scalers), mCCDBPathCTPScalers, metadata, tmin, tmax); + LOG(info) << "CTP scalers saved in ccdb:" << mCCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + return ret; +} +int ctpCCDBManager::saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart) +{ + // data base + if (mCCDBHost == "none") { + LOG(info) << "CTP config not written to CCDB none"; + return 0; + } + using namespace std::chrono_literals; + std::chrono::seconds days3 = 259200s; + std::chrono::seconds min10 = 600s; + long time3days = std::chrono::duration_cast(days3).count(); + long time10min = std::chrono::duration_cast(min10).count(); + long tmin = timeStart - time10min; + long tmax = timeStart + time3days; + o2::ccdb::CcdbApi api; + map metadata; // can be empty + metadata["runNumber"] = std::to_string(cfg->getRunNumber()); + api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation + // store abitrary user object in strongly typed manner + int ret = api.storeAsTFileAny(cfg, CCDBPathCTPConfig, metadata, tmin, tmax); + LOG(info) << "CTP config saved in ccdb:" << mCCDBHost << " run:" << cfg->getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + return ret; +} +CTPConfiguration ctpCCDBManager::getConfigFromCCDB(long timestamp, std::string run, bool& ok) +{ + auto& mgr = o2::ccdb::BasicCCDBManager::instance(); + mgr.setURL(mCCDBHost); + map metadata; // can be empty + metadata["runNumber"] = run; + auto ctpconfigdb = mgr.getSpecific(CCDBPathCTPConfig, timestamp, metadata); + if (ctpconfigdb == nullptr) { + LOG(info) << "CTP config not in database, timestamp:" << timestamp; + ok = 0; + } else { + // ctpconfigdb->printStream(std::cout); + LOG(info) << "CTP config found. Run:" << run; + ok = 1; + } + return *ctpconfigdb; +} +CTPConfiguration ctpCCDBManager::getConfigFromCCDB(long timestamp, std::string run) +{ + bool ok; + auto ctpconfig = getConfigFromCCDB(timestamp, run, ok); + if (ok == 0) { + LOG(error) << "CTP config not in CCDB"; + return CTPConfiguration(); + } + return ctpconfig; +} +CTPRunScalers ctpCCDBManager::getScalersFromCCDB(long timestamp, std::string run, bool& ok) +{ + auto& mgr = o2::ccdb::BasicCCDBManager::instance(); + mgr.setURL(mCCDBHost); + map metadata; // can be empty + metadata["runNumber"] = run; + auto ctpscalers = mgr.getSpecific(mCCDBPathCTPScalers, timestamp, metadata); + if (ctpscalers == nullptr) { + LOG(info) << "CTPRunScalers not in database, timestamp:" << timestamp; + ok = 0; + } else { + // ctpscalers->printStream(std::cout); + ok = 1; + } + return *ctpscalers; +} From 55e9bbfa86a20541c5c5fb0255061d39f0204ba4 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 26 Jul 2024 10:36:05 +0200 Subject: [PATCH 0029/2205] Framework/Core/src/HistogramSpec.cxx: increase MAX_DIM (#13309) --- Framework/Core/src/HistogramSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/src/HistogramSpec.cxx b/Framework/Core/src/HistogramSpec.cxx index db8fafac826e0..1ac3d2f920d5d 100644 --- a/Framework/Core/src/HistogramSpec.cxx +++ b/Framework/Core/src/HistogramSpec.cxx @@ -79,7 +79,7 @@ T* generateHist(const std::string& name, const std::string& title, const std::si template static std::unique_ptr createHistFull(const HistogramSpec& histSpec) { - constexpr std::size_t MAX_DIM{10}; + constexpr std::size_t MAX_DIM{20}; const std::size_t nAxes{histSpec.config.axes.size()}; if (nAxes == 0 || nAxes > MAX_DIM) { LOGF(fatal, "The histogram specification contains no (or too many) axes."); From a5fd85c39a3fab5f35a7d7b50b50497546b78d77 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Mon, 22 Jul 2024 11:46:13 +0200 Subject: [PATCH 0030/2205] Improve metadata for default MID calibration CCDB objects --- Detectors/MUON/MID/Calibration/macros/ccdbUtils.C | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C index 92938838cccb8..896cecbf5abfb 100644 --- a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C +++ b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C @@ -93,13 +93,18 @@ void writeDCSMasks(const char* ccdbUrl, long timestamp, const char* outFilename /// @brief Uploads the list of channels provided /// @param ccdbUrl CCDB url /// @param timestamp Timestamp -/// @param badChannels List of bad channels. Default is no bad channel /// @param path Calibration object path +/// @param channels List of bad channels. Default is no bad channel void uploadBadChannels(const char* ccdbUrl, long timestamp, const std::string path, std::vector channels = {}) { o2::ccdb::CcdbApi api; api.init(ccdbUrl); std::map md; + if (timestamp == 1 && channels.empty()) { + // This is the default + md["default"] = "true"; + md["Created"] = "1" + } std::cout << "Storing MID problematic channels (valid from " << timestamp << ") to " << path << "\n"; api.storeAsTFileAny(&channels, path, md, timestamp, o2::ccdb::CcdbObjectInfo::INFINITE_TIMESTAMP); From 3dc0a87c152e5400be4e26439b872d728a8e222a Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Mon, 22 Jul 2024 17:14:27 +0200 Subject: [PATCH 0031/2205] Add functions to query/upload MID reject list --- .../MUON/MID/Calibration/macros/ccdbUtils.C | 72 ++++++++++++++----- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C index 896cecbf5abfb..475a3e94d93db 100644 --- a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C +++ b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C @@ -103,7 +103,7 @@ void uploadBadChannels(const char* ccdbUrl, long timestamp, const std::string pa if (timestamp == 1 && channels.empty()) { // This is the default md["default"] = "true"; - md["Created"] = "1" + md["Created"] = "1"; } std::cout << "Storing MID problematic channels (valid from " << timestamp << ") to " << path << "\n"; @@ -233,30 +233,68 @@ void ccdbUtils(const char* what, long timestamp = 0, const char* inFilename = "m timestamp = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); } - std::vector whats = {"querybad", "uploadbad", "queryfake", "uploadfake", "querymasks", "writemasks", "uploadbadfrommasks"}; - const std::string fakeDeadChannelCCDBPath = "MID/Calib/FakeDeadChannels"; + const std::string rejectListCCDBPath = "MID/Calib/RejectList"; - if (what == whats[0]) { + std::vector whats; + whats.emplace_back("querybad"); + if (what == whats.back()) { queryBadChannels(ccdbUrl, timestamp, verbose, BadChannelCCDBPath); - } else if (what == whats[1]) { + return; + } + + whats.emplace_back("uploadbad"); + if (what == whats.back()) { uploadBadChannels(ccdbUrl, timestamp, BadChannelCCDBPath); - } else if (what == whats[2]) { + return; + } + + whats.emplace_back("queryrejectlist"); + if (what == whats.back()) { + queryBadChannels(ccdbUrl, timestamp, verbose, rejectListCCDBPath); + return; + } + + whats.emplace_back("uploadrejectlist"); + if (what == whats.back()) { + uploadBadChannels(ccdbUrl, timestamp, rejectListCCDBPath); + return; + } + + whats.emplace_back("queryfake"); + if (what == whats.back()) { queryBadChannels(ccdbUrl, timestamp, verbose, fakeDeadChannelCCDBPath); - } else if (what == whats[3]) { + return; + } + + whats.emplace_back("uploadfake"); + if (what == whats.back()) { uploadBadChannels(ccdbUrl, timestamp, fakeDeadChannelCCDBPath); - } else if (what == whats[4]) { + return; + } + + whats.emplace_back("querymasks"); + if (what == whats.back()) { queryDCSMasks(ccdbUrl, timestamp, verbose); - } else if (what == whats[5]) { + return; + } + + whats.emplace_back("writemasks"); + if (what == whats.back()) { writeDCSMasks(ccdbUrl, timestamp); - } else if (what == whats[6]) { + return; + } + + whats.emplace_back("uploadbadfrommasks"); + if (what == whats.back()) { uploadBadChannelsFromDCSMask(inFilename, timestamp, ccdbUrl, verbose); - } else { - std::cout << "Unimplemented option chosen " << what << std::endl; - std::cout << "Available:\n"; - for (auto& str : whats) { - std::cout << str << " "; - } - std::cout << std::endl; + return; + } + + std::cout << "Unimplemented option chosen " << what << std::endl; + std::cout << "Available:\n"; + for (auto& str : whats) { + std::cout << str << " "; } + std::cout << std::endl; } From bc871a07dd3079763835fa0e4144ba0155c6986e Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Wed, 3 Jul 2024 23:41:02 +0200 Subject: [PATCH 0032/2205] MID: add further fake dead channels --- .../MUON/MID/Calibration/macros/ccdbUtils.C | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C index 475a3e94d93db..12a0cce388a4b 100644 --- a/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C +++ b/Detectors/MUON/MID/Calibration/macros/ccdbUtils.C @@ -190,12 +190,12 @@ std::vector makeFakeDeadChannels() // - expected refers to the expected fake dead channels obtained by Baptiste // by comparing the masked channels with the default masks. std::vector fakeDeads; - // fakeDeads.push_back({0, 3, 0x81, 0x0, 0x0, 0x0, 0x0}); // 40; X1; expected: 0x0; data 10/2023 + fakeDeads.push_back({0, 3, 0x81, 0x0, 0x0, 0x0, 0x1}); // 40; X1; expected: 0x0; data 10/2023; data 06/2024; data 06/2024 fakeDeads.push_back({6, 5, 0x0, 0x2a00, 0x0, 0x0, 0x0}); // 6c; X1; expected: 0x0; data 12/2023: 0x2e00 fakeDeads.push_back({7, 5, 0x0, 0x6bff, 0x0, 0x0, 0x0}); // 6e; X1; expected: 0x0; data 10/2023: 0x28ff fakeDeads.push_back({9, 5, 0x0, 0x0, 0x0, 0x0, 0x2}); // 60; Y2; expected: 0x0 fakeDeads.push_back({10, 2, 0x0, 0x0, 0x0, 0x0, 0xe0}); // 31; Y2; - fakeDeads.push_back({10, 4, 0x805f, 0x0, 0x0, 0x0, 0x0}); // 51; X2; expected: 0x905e; data 12/2023: 0x5f + fakeDeads.push_back({10, 4, 0x905f, 0x0, 0x0, 0x0, 0x0}); // 51; X2; expected: 0x905e; data 12/2023: 0x5f; data 06/2024 fakeDeads.push_back({14, 5, 0x0, 0x0, 0x0, 0x0, 0x80}); // 69; Y2; fakeDeads.push_back({16, 2, 0x0, 0x0, 0x0, 0x0, 0xe0}); // 2c; Y2; expected: 0x80; data 10/2023: 0xa0 fakeDeads.push_back({16, 3, 0x0, 0xf00, 0x0, 0x0, 0x0}); // 4e; X2; expected: 0x0; data 10/2023: 0x300 @@ -208,14 +208,14 @@ std::vector makeFakeDeadChannels() fakeDeads.push_back({44, 5, 0x2000, 0x0, 0x0, 0x0, 0x0}); // ef; X1; expected: 0x0 fakeDeads.push_back({44, 6, 0x0, 0x0, 0x0, 0x0, 0xf}); // f8; Y1; expected: 0x0; data 10/2023: 0x7 fakeDeads.push_back({46, 1, 0x0, 0x0, 0x0, 0x0, 0xc0}); // 91; Y2; expected: 0xc0; data 12/2023: 0x40 - fakeDeads.push_back({46, 2, 0x0, 0x0, 0x0, 0x0, 0xc0}); // b1; Y2; expected: 0xe0; data 10/2023: 0xe0 + fakeDeads.push_back({46, 2, 0x0, 0x0, 0x0, 0x0, 0xe0}); // b1; Y2; expected: 0xe0; data 10/2023: 0xe0; data 06/2024 fakeDeads.push_back({46, 3, 0x0, 0x0, 0x0, 0x0, 0xc0}); // c1; Y2; - fakeDeads.push_back({46, 4, 0x0, 0x0, 0x0, 0x0, 0x58}); // d1; Y2; expected: 0xe8; data 10/2023: 0x60 + fakeDeads.push_back({46, 4, 0x0, 0x0, 0x0, 0x0, 0xf8}); // d1; Y2; expected: 0xe8; data 10/2023: 0x60; data 06/2024 fakeDeads.push_back({46, 5, 0x0, 0x0, 0x0, 0x0, 0x60}); // e1; Y2; - fakeDeads.push_back({47, 3, 0x1, 0x0, 0x0, 0x0, 0x0}); // c3; X2; expected: 0x9d; data 10/2023: 0x15 - // fakeDeads.push_back({47, 5, 0x1, 0x0, 0x0, 0x0, 0x0}); // e3; X2; 0 (expected only) - fakeDeads.push_back({52, 2, 0x0, 0x0, 0x0, 0x0, 0xf8}); // ac; Y2; expected: 0xb0; data 10/2023: 0xf0 - fakeDeads.push_back({52, 3, 0x0, 0x0, 0x0, 0x0, 0x80}); // cd; Y2; expected: 0x0 + fakeDeads.push_back({47, 3, 0x5d, 0x0, 0x0, 0x0, 0x0}); // c3; X2; expected: 0x9d; data 10/2023: 0x15; data 06/2024 + fakeDeads.push_back({47, 5, 0x1, 0x0, 0x0, 0x0, 0x0}); // e3; data 06/2023; data 06/2024 + fakeDeads.push_back({52, 2, 0x0, 0x0, 0x0, 0x0, 0xf8}); // ac; Y2; expected: 0xb0; data 10/2023: 0xf0 + fakeDeads.push_back({52, 3, 0x0, 0x0, 0x0, 0x0, 0x80}); // cd; Y2; expected: 0x0 // fakeDeads.push_back({64, 4, 0x0, 0x0, 0x0, 0x0, 0x40}); // d1; Y4; expected: 0x0; data 12/2023 fakeDeads.push_back({68, 5, 0x0, 0x0, 0x0, 0x0, 0xe2}); // e9; Y4; expected: 0x0; data 10/2023: 0xe0 @@ -269,7 +269,7 @@ void ccdbUtils(const char* what, long timestamp = 0, const char* inFilename = "m whats.emplace_back("uploadfake"); if (what == whats.back()) { - uploadBadChannels(ccdbUrl, timestamp, fakeDeadChannelCCDBPath); + uploadBadChannels(ccdbUrl, timestamp, fakeDeadChannelCCDBPath, makeFakeDeadChannels()); return; } From 573aec4646c38873de924f24d581430fe106dd09 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:46:41 +0200 Subject: [PATCH 0033/2205] DPL: factorise out backtrace support (#13333) --- Framework/Core/src/DataProcessingDevice.cxx | 8 +- Framework/Core/src/runDataProcessing.cxx | 9 +- Framework/Foundation/CMakeLists.txt | 1 + .../include/Framework/BacktraceHelpers.h | 22 +++ .../include/Framework/RuntimeError.h | 7 +- Framework/Foundation/src/BacktraceHelpers.cxx | 125 ++++++++++++++++++ Framework/Foundation/src/RuntimeError.cxx | 111 +--------------- .../Foundation/test/test_RuntimeError.cxx | 3 +- 8 files changed, 166 insertions(+), 120 deletions(-) create mode 100644 Framework/Foundation/include/Framework/BacktraceHelpers.h create mode 100644 Framework/Foundation/src/BacktraceHelpers.cxx diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index e0a0d1aad16e2..57010c27ffb09 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -431,7 +431,7 @@ void DataProcessingDevice::Init() auto& err = error_from_ref(e); O2_SIGNPOST_ID_FROM_POINTER(cid, device, &context); O2_SIGNPOST_EVENT_EMIT_ERROR(device, cid, "Init", "Exception caught while in Init: %{public}s. Invoking errorCallback.", err.what); - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); auto& stats = ref.get(); stats.updateStats({(int)ProcessingStatsId::EXCEPTION_COUNT, DataProcessingStats::Op::Add, 1}); InitErrorContext errorContext{ref, e}; @@ -446,7 +446,7 @@ void DataProcessingDevice::Init() auto& context = ref.get(); O2_SIGNPOST_ID_FROM_POINTER(cid, device, &context); O2_SIGNPOST_EVENT_EMIT_ERROR(device, cid, "Init", "Exception caught while in Init: %{public}s. Exiting with 1.", err.what); - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); auto& stats = ref.get(); stats.updateStats({(int)ProcessingStatsId::EXCEPTION_COUNT, DataProcessingStats::Op::Add, 1}); exit(1); @@ -1111,7 +1111,7 @@ void DataProcessingDevice::fillContext(DataProcessorContext& context, DeviceCont auto& context = ref.get(); O2_SIGNPOST_ID_FROM_POINTER(cid, device, &context); O2_SIGNPOST_EVENT_EMIT_ERROR(device, cid, "Run", "Exception while running: %{public}s. Invoking callback.", err.what); - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); auto& stats = ref.get(); stats.updateStats({(int)ProcessingStatsId::EXCEPTION_COUNT, DataProcessingStats::Op::Add, 1}); ErrorContext errorContext{record, ref, e}; @@ -1126,7 +1126,7 @@ void DataProcessingDevice::fillContext(DataProcessorContext& context, DeviceCont ServiceRegistryRef ref{serviceRegistry, ServiceRegistry::globalDeviceSalt()}; auto& context = ref.get(); O2_SIGNPOST_ID_FROM_POINTER(cid, device, &context); - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); auto& stats = ref.get(); stats.updateStats({(int)ProcessingStatsId::EXCEPTION_COUNT, DataProcessingStats::Op::Add, 1}); switch (errorPolicy) { diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 89737483fc813..6b95a073ed21d 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -11,6 +11,7 @@ #define BOOST_BIND_GLOBAL_PLACEHOLDERS #include #include "Framework/BoostOptionsRetriever.h" +#include "Framework/BacktraceHelpers.h" #include "Framework/CallbacksPolicy.h" #include "Framework/ChannelConfigurationPolicy.h" #include "Framework/ChannelMatching.h" @@ -656,7 +657,7 @@ void handle_crash(int sig) auto retVal = write(STDERR_FILENO, buffer, strlen(buffer)); (void)retVal; } - demangled_backtrace_symbols(array, size, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(array, size, STDERR_FILENO); { char const* msg = "Backtrace complete.\n"; int len = strlen(msg); /* the byte length of the string */ @@ -982,7 +983,7 @@ void doDPLException(RuntimeErrorRef& e, char const* processName) " Reason: {}" "\n Backtrace follow: \n", processName, err.what); - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); } else { LOGP(fatal, "Unhandled o2::framework::runtime_error reached the top of main of {}, device shutting down." @@ -1928,7 +1929,7 @@ int runStateMachine(DataProcessorSpecs const& workflow, } catch (o2::framework::RuntimeErrorRef ref) { auto& err = o2::framework::error_from_ref(ref); #ifdef DPL_ENABLE_BACKTRACE - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); #endif LOGP(error, "invalid workflow in {}: {}", driverInfo.argv[0], err.what); return 1; @@ -2059,7 +2060,7 @@ int runStateMachine(DataProcessorSpecs const& workflow, LOGP(error, "unable to merge configurations in {}: {}", driverInfo.argv[0], err.what); #ifdef DPL_ENABLE_BACKTRACE std::cerr << "\nStacktrace follows:\n\n"; - demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); #endif return 1; } diff --git a/Framework/Foundation/CMakeLists.txt b/Framework/Foundation/CMakeLists.txt index bcde0f7a69f34..1cffe7f0487ff 100644 --- a/Framework/Foundation/CMakeLists.txt +++ b/Framework/Foundation/CMakeLists.txt @@ -16,6 +16,7 @@ install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/Framework o2_add_library(FrameworkFoundation SOURCES src/RuntimeError.cxx src/Signpost.cxx + src/BacktraceHelpers.cxx TARGETVARNAME targetName PUBLIC_LINK_LIBRARIES O2::FrameworkFoundation3rdparty ) diff --git a/Framework/Foundation/include/Framework/BacktraceHelpers.h b/Framework/Foundation/include/Framework/BacktraceHelpers.h new file mode 100644 index 0000000000000..1f897d4d6f860 --- /dev/null +++ b/Framework/Foundation/include/Framework/BacktraceHelpers.h @@ -0,0 +1,22 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_BACKTRACE_HELPERS_H_ +#define O2_FRAMEWORK_BACKTRACE_HELPERS_H_ + +namespace o2::framework +{ +struct BacktraceHelpers { + static constexpr unsigned int MAX_BACKTRACE_SIZE = 100; + static void demangled_backtrace_symbols(void** backtrace, unsigned int total, int fd); +}; +} // namespace o2::framework + +#endif // O2_FRAMEWORK_BACKTRACE_HELPERS_H_ diff --git a/Framework/Foundation/include/Framework/RuntimeError.h b/Framework/Foundation/include/Framework/RuntimeError.h index a8335ae77c509..6c0cf601dfe2d 100644 --- a/Framework/Foundation/include/Framework/RuntimeError.h +++ b/Framework/Foundation/include/Framework/RuntimeError.h @@ -11,15 +11,16 @@ #ifndef O2_FRAMEWORK_RUNTIMEERROR_H_ #define O2_FRAMEWORK_RUNTIMEERROR_H_ +#include "BacktraceHelpers.h" + namespace o2::framework { struct RuntimeError { static constexpr unsigned int MAX_RUNTIME_ERRORS = 64; static constexpr unsigned int MAX_RUNTIME_ERROR_SIZE = 1024; - static constexpr unsigned int MAX_BACKTRACE_SIZE = 100; char what[MAX_RUNTIME_ERROR_SIZE]; - void* backtrace[MAX_BACKTRACE_SIZE]; + void* backtrace[BacktraceHelpers::MAX_BACKTRACE_SIZE]; int maxBacktrace = 0; }; @@ -27,8 +28,6 @@ struct RuntimeErrorRef { int index = 0; }; -void demangled_backtrace_symbols(void** backtrace, unsigned int total, int fd); - RuntimeErrorRef runtime_error(const char*); RuntimeErrorRef runtime_error_f(const char*, ...); RuntimeError& error_from_ref(RuntimeErrorRef); diff --git a/Framework/Foundation/src/BacktraceHelpers.cxx b/Framework/Foundation/src/BacktraceHelpers.cxx new file mode 100644 index 0000000000000..cf37464f7e0bd --- /dev/null +++ b/Framework/Foundation/src/BacktraceHelpers.cxx @@ -0,0 +1,125 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/BacktraceHelpers.h" +#include +#include +#include +#include +#include +#include +#include + +namespace o2::framework +{ + +void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned int stackDepth, int fd) +{ + char** stackStrings; + stackStrings = backtrace_symbols(stackTrace, stackDepth); + char exe[PATH_MAX]; + bool hasExe = false; + int exeSize = 0; + +#if __linux__ + exeSize = readlink("/proc/self/exe", exe, PATH_MAX); + if (exeSize == -1) { + dprintf(fd, "Unable to detect exectuable name\n"); + hasExe = false; + } else { + dprintf(fd, "Executable is %.*s\n", exeSize, exe); + hasExe = true; + } +#endif + + for (size_t i = 1; i < stackDepth; i++) { + + size_t sz = 64000; // 64K ought to be enough for our templates... + char* function = static_cast(malloc(sz)); + char *begin = nullptr, *end = nullptr; + // find the last space and address offset surrounding the mangled name +#if __APPLE__ + for (char* j = stackStrings[i]; *j; ++j) { + if (*j == ' ' && *(j + 1) != '+') { + begin = j; + } else if (*j == ' ' && *(j + 1) == '+') { + end = j; + break; + } + } + bool tryAddr2Line = false; +#else + for (char* j = stackStrings[i]; j && *j; ++j) { + if (*j == '(') { + begin = j; + } else if (*j == '+') { + end = j; + break; + } + } + bool tryAddr2Line = true; +#endif + if (begin && end) { + *begin++ = '\0'; + *end = '\0'; + // found our mangled name, now in [begin, end) + + int status; + char* ret = abi::__cxa_demangle(begin, function, &sz, &status); + if (ret) { + // return value may be a realloc() of the input + function = ret; + dprintf(fd, " %s: %s\n", stackStrings[i], function); + tryAddr2Line = false; + } + } + if (tryAddr2Line) { + // didn't find the mangled name, just print the whole line + dprintf(fd, " %s: ", stackStrings[i]); + if (stackTrace[i] && hasExe) { + char syscom[4096 + PATH_MAX]; + + // Find c++filt from the environment + // This is needed for platforms where we still need c++filt -r + char const* cxxfilt = getenv("CXXFILT"); + if (cxxfilt == nullptr) { + cxxfilt = "c++filt"; + } + // Do the same for addr2line, just in case we wanted to pass some options + char const* addr2line = getenv("ADDR2LINE"); + if (addr2line == nullptr) { + addr2line = "addr2line"; + } + snprintf(syscom, 4096, "%s %p -p -s -f -e %.*s 2>/dev/null | %s ", addr2line, stackTrace[i], exeSize, exe, cxxfilt); // last parameter is the name of this app + + FILE* fp; + char path[1024]; + + fp = popen(syscom, "r"); + if (fp == nullptr) { + dprintf(fd, "-- no source could be retrieved --\n"); + continue; + } + + while (fgets(path, sizeof(path) - 1, fp) != nullptr) { + dprintf(fd, " %s", path); + } + + pclose(fp); + } else { + dprintf(fd, "-- no source avaliable --\n"); + } + } + free(function); + } + free(stackStrings); // malloc()ed by backtrace_symbols + fsync(fd); +} +} // namespace o2::framework diff --git a/Framework/Foundation/src/RuntimeError.cxx b/Framework/Foundation/src/RuntimeError.cxx index 747b339cc6dbb..6f31fb40b86f5 100644 --- a/Framework/Foundation/src/RuntimeError.cxx +++ b/Framework/Foundation/src/RuntimeError.cxx @@ -15,11 +15,11 @@ #include #include #include -#include +#include #include #include -#include #include +#include #include namespace o2::framework @@ -71,7 +71,7 @@ RuntimeErrorRef runtime_error_f(const char* format, ...) va_start(args, format); vsnprintf(gError[i].what, RuntimeError::MAX_RUNTIME_ERROR_SIZE, format, args); va_end(args); - gError[i].maxBacktrace = canDumpBacktrace() ? backtrace(gError[i].backtrace, RuntimeError::MAX_BACKTRACE_SIZE) : 0; + gError[i].maxBacktrace = canDumpBacktrace() ? backtrace(gError[i].backtrace, BacktraceHelpers::MAX_BACKTRACE_SIZE) : 0; return RuntimeErrorRef{i}; } @@ -83,7 +83,7 @@ RuntimeErrorRef runtime_error(const char* s) ++i; } strncpy(gError[i].what, s, RuntimeError::MAX_RUNTIME_ERROR_SIZE); - gError[i].maxBacktrace = canDumpBacktrace() ? backtrace(gError[i].backtrace, RuntimeError::MAX_BACKTRACE_SIZE) : 0; + gError[i].maxBacktrace = canDumpBacktrace() ? backtrace(gError[i].backtrace, BacktraceHelpers::MAX_BACKTRACE_SIZE) : 0; return RuntimeErrorRef{i}; } @@ -92,107 +92,4 @@ void throw_error(RuntimeErrorRef ref) throw ref; } -void demangled_backtrace_symbols(void** stackTrace, unsigned int stackDepth, int fd) -{ - char** stackStrings; - stackStrings = backtrace_symbols(stackTrace, stackDepth); - char exe[PATH_MAX]; - bool hasExe = false; - int exeSize = 0; - -#if __linux__ - exeSize = readlink("/proc/self/exe", exe, PATH_MAX); - if (exeSize == -1) { - dprintf(fd, "Unable to detect exectuable name\n"); - hasExe = false; - } else { - dprintf(fd, "Executable is %.*s\n", exeSize, exe); - hasExe = true; - } -#endif - - for (size_t i = 1; i < stackDepth; i++) { - - size_t sz = 64000; // 64K ought to be enough for our templates... - char* function = static_cast(malloc(sz)); - char *begin = nullptr, *end = nullptr; - // find the last space and address offset surrounding the mangled name -#if __APPLE__ - for (char* j = stackStrings[i]; *j; ++j) { - if (*j == ' ' && *(j + 1) != '+') { - begin = j; - } else if (*j == ' ' && *(j + 1) == '+') { - end = j; - break; - } - } - bool tryAddr2Line = false; -#else - for (char* j = stackStrings[i]; j && *j; ++j) { - if (*j == '(') { - begin = j; - } else if (*j == '+') { - end = j; - break; - } - } - bool tryAddr2Line = true; -#endif - if (begin && end) { - *begin++ = '\0'; - *end = '\0'; - // found our mangled name, now in [begin, end) - - int status; - char* ret = abi::__cxa_demangle(begin, function, &sz, &status); - if (ret) { - // return value may be a realloc() of the input - function = ret; - dprintf(fd, " %s: %s\n", stackStrings[i], function); - tryAddr2Line = false; - } - } - if (tryAddr2Line) { - // didn't find the mangled name, just print the whole line - dprintf(fd, " %s: ", stackStrings[i]); - if (stackTrace[i] && hasExe) { - char syscom[4096 + PATH_MAX]; - - // Find c++filt from the environment - // This is needed for platforms where we still need c++filt -r - char const* cxxfilt = getenv("CXXFILT"); - if (cxxfilt == nullptr) { - cxxfilt = "c++filt"; - } - // Do the same for addr2line, just in case we wanted to pass some options - char const* addr2line = getenv("ADDR2LINE"); - if (addr2line == nullptr) { - addr2line = "addr2line"; - } - snprintf(syscom, 4096, "%s %p -p -s -f -e %.*s 2>/dev/null | %s ", addr2line, stackTrace[i], exeSize, exe, cxxfilt); // last parameter is the name of this app - - FILE* fp; - char path[1024]; - - fp = popen(syscom, "r"); - if (fp == nullptr) { - dprintf(fd, "-- no source could be retrieved --\n"); - continue; - } - - while (fgets(path, sizeof(path) - 1, fp) != nullptr) { - dprintf(fd, " %s", path); - } - - pclose(fp); - } else { - dprintf(fd, "-- no source avaliable --\n"); - } - } - free(function); - } - free(stackStrings); // malloc()ed by backtrace_symbols - fsync(fd); -} - } // namespace o2::framework diff --git a/Framework/Foundation/test/test_RuntimeError.cxx b/Framework/Foundation/test/test_RuntimeError.cxx index a628e84175bd0..cc0efa801908a 100644 --- a/Framework/Foundation/test/test_RuntimeError.cxx +++ b/Framework/Foundation/test/test_RuntimeError.cxx @@ -11,6 +11,7 @@ #include #include "Framework/RuntimeError.h" +#include "Framework/BacktraceHelpers.h" #include #include @@ -33,7 +34,7 @@ TEST_CASE("TestRuntimeError") REQUIRE(strncmp(err.what, "foo", 3) == 0); #ifdef DPL_ENABLE_BACKTRACE backtrace_symbols_fd(err.backtrace, err.maxBacktrace, STDERR_FILENO); - o2::framework::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); + o2::framework::BacktraceHelpers::demangled_backtrace_symbols(err.backtrace, err.maxBacktrace, STDERR_FILENO); #endif } } From aeb4d24528306032623c812ba99b68bb4558d011 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:00:25 +0200 Subject: [PATCH 0034/2205] Allow CTP scalers to work also on mac (#13335) --- Detectors/CTP/workflowScalers/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Detectors/CTP/workflowScalers/CMakeLists.txt b/Detectors/CTP/workflowScalers/CMakeLists.txt index fe91ee2fec28b..a31774ac66d69 100644 --- a/Detectors/CTP/workflowScalers/CMakeLists.txt +++ b/Detectors/CTP/workflowScalers/CMakeLists.txt @@ -8,7 +8,6 @@ # In applying this license CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -if (NOT APPLE) o2_add_library(CTPWorkflowScalers SOURCES src/ctpCCDBManager.cxx SOURCES src/RunManager.cxx @@ -23,7 +22,6 @@ o2_add_executable( SOURCES src/ctp-proxy.cxx PUBLIC_LINK_LIBRARIES O2::DCStestWorkflow O2::CTPWorkflowScalers) -endif() o2_add_executable( qc-proxy COMPONENT_NAME ctp From 5ba7ba4dbb0ab4a50af7acea2900b759ead29ec9 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:40:27 +0200 Subject: [PATCH 0035/2205] DPL: drop obsolete TRACY_PORT (#13334) --- Framework/Core/include/Framework/DeviceInfo.h | 2 -- Framework/Core/include/Framework/DriverInfo.h | 2 -- Framework/Core/src/runDataProcessing.cxx | 5 ----- 3 files changed, 9 deletions(-) diff --git a/Framework/Core/include/Framework/DeviceInfo.h b/Framework/Core/include/Framework/DeviceInfo.h index 49f96d90d87fb..9c789eaa71516 100644 --- a/Framework/Core/include/Framework/DeviceInfo.h +++ b/Framework/Core/include/Framework/DeviceInfo.h @@ -80,8 +80,6 @@ struct DeviceInfo { boost::property_tree::ptree currentConfig; /// Current provenance for the configuration keys boost::property_tree::ptree currentProvenance; - /// Port to use to connect to tracy profiler - short tracyPort; /// Timestamp of the last signal received size_t lastSignal; /// An incremental number for the state of the device diff --git a/Framework/Core/include/Framework/DriverInfo.h b/Framework/Core/include/Framework/DriverInfo.h index 45c4c85a32d01..41b868150e047 100644 --- a/Framework/Core/include/Framework/DriverInfo.h +++ b/Framework/Core/include/Framework/DriverInfo.h @@ -153,8 +153,6 @@ struct DriverInfo { unsigned short resourcesMonitoringDumpInterval = 0; /// Port used by the websocket control. 0 means not initialised. unsigned short port = 0; - /// Last port used for tracy - short tracyPort = 8086; /// The minimum level after which the device will exit with 1 LogParsingHelpers::LogLevel minFailureLevel = LogParsingHelpers::LogLevel::Fatal; diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 6b95a073ed21d..dbad0658412d5 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -691,8 +691,6 @@ void spawnDevice(uv_loop_t* loop, auto& spec = specs[ref.index]; auto& execution = executions[ref.index]; - driverInfo.tracyPort++; - for (auto& service : spec.services) { if (service.preFork != nullptr) { service.preFork(serviceRegistry, DeviceConfig{varmap}); @@ -738,8 +736,6 @@ void spawnDevice(uv_loop_t* loop, dup2(childFds[ref.index].childstdout[1], STDOUT_FILENO); dup2(childFds[ref.index].childstdout[1], STDERR_FILENO); - auto portS = std::to_string(driverInfo.tracyPort); - setenv("TRACY_PORT", portS.c_str(), 1); for (auto& service : spec.services) { if (service.postForkChild != nullptr) { service.postForkChild(serviceRegistry); @@ -792,7 +788,6 @@ void spawnDevice(uv_loop_t* loop, .readyToQuit = false, .inputChannelMetricsViewIndex = Metric2DViewIndex{"oldest_possible_timeslice", 0, 0, {}}, .outputChannelMetricsViewIndex = Metric2DViewIndex{"oldest_possible_output", 0, 0, {}}, - .tracyPort = driverInfo.tracyPort, .lastSignal = uv_hrtime() - 10000000}); // create the offset using uv_hrtime timespec now; From 8d21174ef5aa7f15359776f8149bc012b3f5b356 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:10:49 +0200 Subject: [PATCH 0036/2205] DPL: improve exitTransitionTimeout handling (#13331) --- Framework/Core/src/DataProcessingContext.cxx | 4 +++ Framework/Core/src/DataProcessingDevice.cxx | 31 +++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Framework/Core/src/DataProcessingContext.cxx b/Framework/Core/src/DataProcessingContext.cxx index 86409bf5434bb..394f50064bb37 100644 --- a/Framework/Core/src/DataProcessingContext.cxx +++ b/Framework/Core/src/DataProcessingContext.cxx @@ -11,9 +11,13 @@ #include "Framework/DataProcessingContext.h" #include "Framework/DataProcessorSpec.h" +#include "Framework/EndOfStreamContext.h" +#include "Framework/TimingInfo.h" #include "Framework/Signpost.h" O2_DECLARE_DYNAMIC_LOG(data_processor_context); +O2_DECLARE_DYNAMIC_LOG(calibration); + namespace o2::framework { diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 57010c27ffb09..7c45cd7e7a707 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -92,6 +92,8 @@ struct formatter : ostream_format O2_DECLARE_DYNAMIC_LOG(device); // Special log to keep track of the lifetime of the parts O2_DECLARE_DYNAMIC_LOG(parts); +// Stream which keeps track of the calibration lifetime logic +O2_DECLARE_DYNAMIC_LOG(calibration); // Special log to track the async queue behavior O2_DECLARE_DYNAMIC_LOG(async_queue); // Special log to track the forwarding requests @@ -131,11 +133,18 @@ bool hasOnlyGenerated(DeviceSpec const& spec) void on_transition_requested_expired(uv_timer_t* handle) { - auto* state = (DeviceState*)handle->data; - state->loopReason |= DeviceState::TIMER_EXPIRED; + auto* ref = (ServiceRegistryRef*)handle->data; + auto& state = ref->get(); + state.loopReason |= DeviceState::TIMER_EXPIRED; + // Check if this is a source device O2_SIGNPOST_ID_FROM_POINTER(cid, device, handle); - O2_SIGNPOST_EVENT_EMIT_WARN(device, cid, "callback", "Exit transition timer expired. Exiting."); - state->transitionHandling = TransitionHandlingState::Expired; + auto& spec = ref->get(); + if (hasOnlyGenerated(spec)) { + O2_SIGNPOST_EVENT_EMIT_INFO(calibration, cid, "callback", "Grace period for source expired. Exiting."); + } else { + O2_SIGNPOST_EVENT_EMIT_ERROR(calibration, cid, "callback", "Grace period for data / calibration expired. Exiting."); + } + state.transitionHandling = TransitionHandlingState::Expired; } void on_communication_requested(uv_async_t* s) @@ -928,7 +937,7 @@ void DataProcessingDevice::startPollers() } deviceContext.gracePeriodTimer = (uv_timer_t*)malloc(sizeof(uv_timer_t)); - deviceContext.gracePeriodTimer->data = &state; + deviceContext.gracePeriodTimer->data = new ServiceRegistryRef(mServiceRegistry); uv_timer_init(state.loop, deviceContext.gracePeriodTimer); } @@ -958,6 +967,7 @@ void DataProcessingDevice::stopPollers() } uv_timer_stop(deviceContext.gracePeriodTimer); + delete (ServiceRegistryRef*)deviceContext.gracePeriodTimer->data; free(deviceContext.gracePeriodTimer); deviceContext.gracePeriodTimer = nullptr; } @@ -1306,17 +1316,18 @@ void DataProcessingDevice::Run() if (state.transitionHandling == TransitionHandlingState::NoTransition && NewStatePending()) { state.transitionHandling = TransitionHandlingState::Requested; auto& deviceContext = ref.get(); - auto timeout = deviceContext.exitTransitionTimeout; // Check if we only have timers auto& spec = ref.get(); if (hasOnlyTimers(spec)) { state.streaming = StreamingState::EndOfStreaming; } - if (timeout != 0 && state.streaming != StreamingState::Idle) { + + if (deviceContext.exitTransitionTimeout != 0 && state.streaming != StreamingState::Idle) { state.transitionHandling = TransitionHandlingState::Requested; ref.get().call(ServiceRegistryRef{ref}); uv_update_time(state.loop); - uv_timer_start(deviceContext.gracePeriodTimer, on_transition_requested_expired, timeout * 1000, 0); + O2_SIGNPOST_EVENT_EMIT(calibration, lid, "timer_setup", "Starting %d s timer for exitTransitionTimeout.", deviceContext.exitTransitionTimeout); + uv_timer_start(deviceContext.gracePeriodTimer, on_transition_requested_expired, deviceContext.exitTransitionTimeout * 1000, 0); if (mProcessingPolicies.termination == TerminationPolicy::QUIT) { O2_SIGNPOST_EVENT_EMIT_INFO(device, lid, "run_loop", "New state requested. Waiting for %d seconds before quitting.", (int)deviceContext.exitTransitionTimeout); } else { @@ -1331,7 +1342,7 @@ void DataProcessingDevice::Run() } else if (mProcessingPolicies.termination == TerminationPolicy::QUIT) { O2_SIGNPOST_EVENT_EMIT_INFO(device, lid, "run_loop", "New state pending and we are already idle, quitting immediately as per --completion-policy"); } else { - O2_SIGNPOST_EVENT_EMIT_INFO(device, lid, "runb_loop", "New state pending and we are already idle, switching to READY immediately."); + O2_SIGNPOST_EVENT_EMIT_INFO(device, lid, "run_loop", "New state pending and we are already idle, switching to READY immediately."); } } } @@ -1721,6 +1732,7 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) // We should keep the data generated at end of stream only for those // which are not sources. timingInfo.keepAtEndOfStream = shouldProcess; + O2_SIGNPOST_EVENT_EMIT(calibration, dpid, "calibration", "TimingInfo.keepAtEndOfStream %d", timingInfo.keepAtEndOfStream); EndOfStreamContext eosContext{*context.registry, ref.get()}; @@ -2348,7 +2360,6 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v *context.registry}; ProcessingContext processContext{record, ref, ref.get()}; { - O2_SIGNPOST_EVENT_EMIT(device, aid, "device", "Invoking preProcessingCallbacks"); // Notice this should be thread safe and reentrant // as it is called from many threads. streamContext.preProcessingCallbacks(processContext); From c2776a807175b7594269b69d169a2ba7808111f7 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:44:44 +0200 Subject: [PATCH 0037/2205] Limit number of file descriptors which might be closed (#13336) --- Framework/Core/src/runDataProcessing.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index dbad0658412d5..2c5ef88fb767c 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -721,8 +721,11 @@ void spawnDevice(uv_loop_t* loop, struct rlimit rlim; getrlimit(RLIMIT_NOFILE, &rlim); // We close all FD, but the one which are actually - // used to communicate with the driver. - int rlim_cur = rlim.rlim_cur; + // used to communicate with the driver. This is a bad + // idea in the first place, because rlim_cur could be huge + // FIXME: I should understand which one is really to be closed and use + // CLOEXEC on it. + int rlim_cur = std::min((int)rlim.rlim_cur, 10000); for (int i = 0; i < rlim_cur; ++i) { if (childFds[ref.index].childstdin[0] == i) { continue; From e3567aa920f6d89c4112338a4cca5da76a6dd10a Mon Sep 17 00:00:00 2001 From: iravasen Date: Fri, 26 Jul 2024 15:35:53 +0200 Subject: [PATCH 0038/2205] ITS Threshold: new logic for row-by-row data extraction (#13337) * LOG info to important to make some useful logs to appear in infologger at the end of the run * change logic to extract data row by row to save all possible s-curves --- .../ITSWorkflow/ThresholdCalibratorSpec.h | 17 +- .../workflow/src/ThresholdCalibratorSpec.cxx | 319 ++++++------------ 2 files changed, 103 insertions(+), 233 deletions(-) diff --git a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h index 03340cd65faeb..a5064db424e5e 100644 --- a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h +++ b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h @@ -197,7 +197,6 @@ class ITSThresholdCalibrator : public Task bool findThresholdFit(const short int&, std::vector>, const float*, const short int&, float&, float&, int&, int); bool findThresholdDerivative(std::vector>, const float*, const short int&, float&, float&, int&, int); bool findThresholdHitcounting(std::vector>, const float*, const short int&, float&, int); - bool isScanFinished(const short int&, const short int&, const short int&); void findAverage(const std::array&, float&, float&, float&, float&); void saveThreshold(); @@ -207,9 +206,9 @@ class ITSThresholdCalibrator : public Task // Utils std::vector getIntegerVect(std::string&); short int getRUID(short int chipID); - std::vector getChipBoundariesFromRu(short int, bool*); + std::vector getChipListFromRu(short int, bool*); short int getLinkID(short int, short int); - short int getActiveLinks(bool*); + short int getNumberOfActiveLinks(bool*); std::string mSelfName; std::string mDictName; @@ -217,7 +216,6 @@ class ITSThresholdCalibrator : public Task int mTFCounter = 0; bool mVerboseOutput = false; - bool isForceEor = false; std::string mMetaType; std::string mOutputDir; std::string mMetafileDir = "/dev/null"; @@ -233,12 +231,10 @@ class ITSThresholdCalibrator : public Task short int mRunType = -1; short int mRunTypeUp = -1; short int mRunTypeRU[N_RU] = {0}; - short int mRunTypeChip[24120] = {0}; - short int mChipLastRow[24120] = {0}; + short int mCdwCntRU[N_RU] = {0}; + short int mRowRU[N_RU] = {0}; bool mActiveLinks[N_RU][3] = {{false}}; std::set mRuSet; - short int mRu = 0; - bool mIsChipDone[24120] = {false}; // Either "T" for threshold, "V" for VCASN, or "I" for ITHR char mScanType = '\0'; short int mMin = -1, mMax = -1, mMin2 = 0, mMax2 = 0; @@ -266,9 +262,6 @@ class ITSThresholdCalibrator : public Task // Flag to avoid that endOfStream and stop are both done bool isEnded = false; - // Flag to enable cw counter check - bool mCheckCw = false; - // Flag to tag single noisy pix in digital scan bool mTagSinglePix = false; @@ -284,7 +277,7 @@ class ITSThresholdCalibrator : public Task // To set min and max ITHR and VCASN in the tuning scans short int inMinVcasn = 30; short int inMaxVcasn = 100; - short int inMinIthr = 15; + short int inMinIthr = 25; short int inMaxIthr = 100; // Flag to enable most-probable value calculation diff --git a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx index e78c419b78879..0b3d67e515360 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx @@ -67,10 +67,6 @@ void ITSThresholdCalibrator::init(InitContext& ic) { LOGF(info, "ITSThresholdCalibrator init...", mSelfName); - for (int i = 0; i < 24120; i++) { - mChipLastRow[i] = -1; - } - mColStep = ic.options().get("s-curve-col-step"); if (mColStep >= N_COL) { LOG(warning) << "mColStep = " << mColStep << ": saving s-curves of only 1 pixel (pix 0) per row"; @@ -133,9 +129,6 @@ void ITSThresholdCalibrator::init(InitContext& ic) // Machine hostname this->mHostname = boost::asio::ip::host_name(); - // check cw counter flag - this->mCheckCw = ic.options().get("enable-cw-cnt-check"); - // check flag to tag single noisy pix in digital and analog scans this->mTagSinglePix = ic.options().get("enable-single-pix-tag"); @@ -204,9 +197,6 @@ void ITSThresholdCalibrator::init(InitContext& ic) nInj = ic.options().get("ninj"); nInjScaled = nInj; - // Flag to enable the call of the finalize() method at end of stream - isForceEor = ic.options().get("force-calculation-eor"); - // flag to set the url ccdb mgr this->mCcdbMgrUrl = ic.options().get("ccdb-mgr-url"); // FIXME: Temporary solution to retrieve ConfDBmap @@ -266,7 +256,7 @@ void ITSThresholdCalibrator::init(InitContext& ic) ////////////////////////////////////////////////////////////////////////////// // Get number of active links for a given RU -short int ITSThresholdCalibrator::getActiveLinks(bool* links) +short int ITSThresholdCalibrator::getNumberOfActiveLinks(bool* links) { int nL = 0; for (int i = 0; i < 3; i++) { @@ -292,7 +282,7 @@ short int ITSThresholdCalibrator::getLinkID(short int chipID, short int ruID) ////////////////////////////////////////////////////////////////////////////// // Get list of chipID (from 0 to 24119) attached to a RU based on the links which are active -std::vector ITSThresholdCalibrator::getChipBoundariesFromRu(short int ruID, bool* links) +std::vector ITSThresholdCalibrator::getChipListFromRu(short int ruID, bool* links) { std::vector cList; int a, b; @@ -321,7 +311,7 @@ std::vector ITSThresholdCalibrator::getChipBoundariesFromRu(short int // Get RU ID (from 0 to 191) from a given O2ChipID (from 0 to 24119) short int ITSThresholdCalibrator::getRUID(short int chipID) { - // below there are the inverse of the formulas in getChipBoundariesFromRu(...) + // below there are the inverse of the formulas in getChipListFromRu(...) if (chipID < 432) { // IB return chipID / 9; } else if (chipID >= 432 && chipID < 6480) { // ML @@ -977,7 +967,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype) // S-curve is backwards from VCASN case, otherwise same // 4 rows per chip this->mScanType = 'I'; - this->mMin = inMinIthr; // 30 is the default + this->mMin = inMinIthr; // 25 is the default this->mMax = inMaxIthr; // 100 is the default this->N_RANGE = mMax - mMin + 1; this->mCheckExactRow = true; @@ -1103,18 +1093,6 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype) return; } -////////////////////////////////////////////////////////////////////////////// -// Check if scan has finished for extracting thresholds -bool ITSThresholdCalibrator::isScanFinished(const short int& chipID, const short int& row, const short int& cwcnt) -{ - // Require that the last entry has at least half the number of expected hits - short int col = 0; // Doesn't matter which column - short int chg = (mScanType == 'I' || mScanType == 'D' || mScanType == 'A') ? 0 : (N_RANGE - 1); - - // check 2 pixels in case one of them is dead - return ((this->mPixelHits[chipID][row][col][0][chg] >= nInjScaled || this->mPixelHits[chipID][row][col + 100][0][chg] >= nInjScaled) && (!mCheckCw || cwcnt == nInj - 1)); -} - ////////////////////////////////////////////////////////////////////////////// // Calculate pulse parameters in 1D scan: time over threshold, rise time, ... std::vector ITSThresholdCalibrator::calculatePulseParams(const short int& chipID) @@ -1334,8 +1312,6 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) for (short int iRU = 0; iRU < this->N_RU; iRU++) { const auto& calib = calibs[iROF * this->N_RU + iRU]; if (calib.calibUserField != 0) { - - mRu = iRU; // save RU ID mRuSet.insert(iRU); isAllZero = false; @@ -1382,7 +1358,12 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) row = !mCdwVersion ? (short int)(calib.calibUserField & 0xffff) : (short int)(calib.calibUserField & 0x1ff); // cw counter cwcnt = (short int)(calib.calibCounter); - + // count the last N injections + short int checkVal = (mScanType == 'I') ? mMin : mMax; + if (loopval == checkVal && realcharge == mMin2) { // the second condition is relevant only for mScanType=p + mCdwCntRU[iRU]++; + mRowRU[iRU] = row; // keep the row + } if (this->mVerboseOutput) { LOG(info) << "RU: " << iRU << " CDWcounter: " << cwcnt << " row: " << row << " Loopval: " << loopval << " realcharge: " << realcharge << " confDBv: " << mCdwVersion; LOG(info) << "NDIGITS: " << digits.size(); @@ -1428,20 +1409,18 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) if ((chipID % mChipModBase) != mChipModSel) { continue; } - if (d.getRow() != row) { - if (this->mVerboseOutput) { - LOG(info) << "iROF: " << iROF << " ChipID " << chipID << ": current row is " << d.getRow() << " (col = " << d.getColumn() << ") but the one in CW is " << row; - } + if (d.getRow() != row && mVerboseOutput) { + LOG(info) << "iROF: " << iROF << " ChipID " << chipID << ": current row is " << d.getRow() << " (col = " << d.getColumn() << ") but the one in CW is " << row; } - if (std::find(mChips.begin(), mChips.end(), chipID) != mChips.end()) { - continue; + if (std::find(mChips.begin(), mChips.end(), chipID) == mChips.end()) { + mChips.push_back(chipID); } - mChips.push_back(chipID); } // loop to allocate memory only for allowed rows for (auto& chipID : mChips) { // mark active RU links - mActiveLinks[mRu][getLinkID(chipID, mRu)] = true; + short int ru = getRUID(chipID); + mActiveLinks[ru][getLinkID(chipID, ru)] = true; // check rows and allocate memory if (mForbiddenRows.count(chipID)) { for (int iforb = mForbiddenRows[chipID].size() - 1; iforb >= 0; iforb--) { @@ -1484,84 +1463,49 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) this->mPixelHits[chipID][d.getRow()][col][chgPoint][loopPoint]++; } } - // check collected chips in previous loop on digits - for (auto& chipID : mChips) { - // count the zeros per chip - if (!this->mRunTypeUp) { - this->mRunTypeChip[chipID]++; - } - - // check forbidden rows - if (mChipsForbRows[chipID]) { - continue; - } - - bool passCondition = false; - if (isDumpS) { - auto fndVal = std::find(chipDumpList.begin(), chipDumpList.end(), chipID); - int checkR = (mScanType == 'I') ? mMin : mMax; - if (loopval == checkR) { - countCdw[chipID]++; - } - passCondition = (countCdw[chipID] == nInj) && (loopval == checkR) && (fndVal != chipDumpList.end() || !chipDumpList.size()); // in this way we dump any s-curve, bad and good - if (mVerboseOutput) { - LOG(info) << "Loopval: " << loopval << " counter: " << cwcnt << " checkR: " << checkR << " chipID: " << chipID << " pass: " << passCondition; - } - } else { - passCondition = isScanFinished(chipID, row, cwcnt); - } - - if (mScanType == 'p') { - if (mChipLastRow[chipID] < 0) { - mChipLastRow[chipID] = row; - } - passCondition = row > mChipLastRow[chipID] + 1 && row > 1; - } - - if (mScanType != 'D' && mScanType != 'A' && mScanType != 'P' && mScanType != 'p' && mScanType != 'R' && mScanType != 'r' && passCondition) { // for D,A,P we do it at the end in finalize() - this->extractAndUpdate(chipID, row); - countCdw[chipID] = 0; - // remove entry for this row whose scan is completed - mPixelHits[chipID].erase(row); - mForbiddenRows[chipID].push_back(row); // due to the loose cut in isScanFinished, extra hits may come for this deleted row. In this way the row is ignored afterwards - } else if (mScanType == 'p' && passCondition) { - this->extractAndUpdate(chipID, mChipLastRow[chipID]); - // remove entry for this row whose scan is completed - mPixelHits[chipID].erase(mChipLastRow[chipID]); - mForbiddenRows[chipID].push_back(mChipLastRow[chipID]); // due to the loose cut in isScanFinished, extra hits may come for this deleted row. In this way the row is ignored afterwards - mChipLastRow[chipID] = row; - } - } - - for (auto& chipID : mChips) { - if (mRunTypeChip[chipID] == nInj && mScanType != 'P' && mScanType != 'p' && mScanType != 'r' && mScanType != 'R') { // for pulse length and vresetd scans we use the counters per RU and not per chip since last 0s come or might come without hits - this->addDatabaseEntry(chipID, "", std::vector(), true); // output for QC (mainly) - } - } } // if (charge) } // for (ROFs) - // Prepare the ChipDone object for QC (mainly) in case of pulse length scan - if (mScanType == 'P' || mScanType == 'p' || mScanType == 'R' || mScanType == 'r') { - for (auto& iRU : mRuSet) { - short int nL = 0; - for (int iL = 0; iL < 3; iL++) { - if (mActiveLinks[iRU][iL]) { - nL++; // count active links + // Prepare the ChipDone object for QC + extract data if the row is completed + for (auto& iRU : mRuSet) { + short int nL = 0; + for (int iL = 0; iL < 3; iL++) { + if (mActiveLinks[iRU][iL]) { + nL++; // count active links + } + } + std::vector chipEnabled = getChipListFromRu(iRU, mActiveLinks[iRU]); // chip boundaries + // Fill the chipDone info string + if (mRunTypeRU[iRU] == nInjScaled * nL) { + for (short int iChip = 0; iChip < chipEnabled.size(); iChip++) { + if ((chipEnabled[iChip] % mChipModBase) != mChipModSel) { + continue; } + addDatabaseEntry(chipEnabled[iChip], "", std::vector(), true); } - if (mRunTypeRU[iRU] == nInj * nL) { - short int chipStart, chipStop; - std::vector chipEnabled = getChipBoundariesFromRu(iRU, mActiveLinks[iRU]); - for (short int iChip = 0; iChip < chipEnabled.size(); iChip++) { - if ((chipEnabled[iChip] % mChipModBase) != mChipModSel) { - continue; + } + // Check if scan of a row is finished: only for specific scans! + bool passCondition = (mCdwCntRU[iRU] == nInjScaled * nL); + if (mScanType != 'D' && mScanType != 'A' && mScanType != 'P' && mScanType != 'p' && mScanType != 'R' && mScanType != 'r' && passCondition) { + // extract data from the row + for (short int iChip = 0; iChip < chipEnabled.size(); iChip++) { + short int chipID = chipEnabled[iChip]; + if ((chipID % mChipModBase) != mChipModSel) { + continue; + } + if (!isDumpS || (std::find(chipDumpList.begin(), chipDumpList.end(), chipID) != chipDumpList.end() || !chipDumpList.size())) { // to dump s-curves as histograms + if (mPixelHits.count(chipID)) { + if (mPixelHits[chipID].count(mRowRU[iRU])) { // make sure the row exists + extractAndUpdate(chipID, mRowRU[iRU]); + mPixelHits[chipID].erase(mRowRU[iRU]); + mForbiddenRows[chipID].push_back(mRowRU[iRU]); + } } - this->addDatabaseEntry(chipEnabled[iChip], "", std::vector(), true); } } + mCdwCntRU[iRU] = 0; // reset } - } + } // end loop on RuSet if (!(this->mRunTypeUp)) { finalize(); @@ -1580,7 +1524,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) } else if (pc.transitionState() == TransitionHandlingState::Requested) { LOG(info) << "Run stop requested during the scan, sending output to aggregator and then stopping to process new data"; mRunStopRequested = true; - finalize(); + finalize(); // calculating average thresholds based on what's collected up to this moment pc.outputs().snapshot(Output{"ITS", "TSTR", (unsigned int)mChipModSel}, this->mTuning); // dummy here pc.outputs().snapshot(Output{"ITS", "PIXTYP", (unsigned int)mChipModSel}, this->mPixStat); pc.outputs().snapshot(Output{"ITS", "RUNT", (unsigned int)mChipModSel}, this->mRunType); @@ -1803,67 +1747,35 @@ void ITSThresholdCalibrator::finalize() { // Add configuration item to output strings for CCDB const char* name = nullptr; - if (this->mScanType == 'V') { + std::set thisRUs; + + if (mScanType == 'V' || mScanType == 'I' || mScanType == 'T') { // Loop over each chip and calculate avg and rms - name = "VCASN"; - auto it = this->mThresholds.cbegin(); - while (it != this->mThresholds.cend()) { - int iRU = 0; - std::vector linkChips; - bool extractChip = false; - if (isForceEor && mRunTypeChip[it->first] < nInj) { - iRU = getRUID(it->first); - linkChips = getChipBoundariesFromRu(iRU, mActiveLinks[iRU]); - // check whether at least one chip on the same link reached the end of the scan - for (size_t i = 0; i < linkChips.size(); i++) { - if (mRunTypeChip[linkChips[i]] > nInj && linkChips[i] != it->first) { - extractChip = true; - break; + name = mScanType == 'V' ? "VCASN" : mScanType == 'I' ? "ITHR" + : "THR"; + if (mScanType == 'I') { + // Only ITHR scan: assign default ITHR = 50 if chip has no avg ITHR + for (auto& iRU : mRuSet) { + if (mRunTypeRU[iRU] >= nInjScaled * getNumberOfActiveLinks(mActiveLinks[iRU]) || mRunStopRequested) { + std::vector chipList = getChipListFromRu(iRU, mActiveLinks[iRU]); + for (size_t i = 0; i < chipList.size(); i++) { + if (!mThresholds.count(chipList[i])) { + std::vector data = {50, 0, 0, 0, 0}; + addDatabaseEntry(chipList[i], name, data, false); + } } } } - - if (!extractChip && (!mRunStopRequested && this->mRunTypeChip[it->first] < nInj)) { - ++it; - continue; - } - float avgT, rmsT, avgN, rmsN, mpvT, outVal; - this->findAverage(it->second, avgT, rmsT, avgN, rmsN); - outVal = avgT; - if (isMpv) { - mpvT = std::distance(mpvCounter[it->first].begin(), std::max_element(mpvCounter[it->first].begin(), mpvCounter[it->first].end())) + mMin; - outVal = mpvT; - } - float status = ((float)it->second[5] / (float)(it->second[4] + it->second[5])) * 100.; // percentage of unsuccessful threshold extractions - std::vector data = {outVal, rmsT, avgN, rmsN, status}; - this->addDatabaseEntry(it->first, name, data, false); - this->mRunTypeChip[it->first] = 0; // so that this chip will never appear again in the DCSconfigObject_t - it = this->mThresholds.erase(it); } - } else if (this->mScanType == 'I') { - // Loop over each chip and calculate avg and rms - name = "ITHR"; auto it = this->mThresholds.cbegin(); while (it != this->mThresholds.cend()) { - int iRU = 0; - std::vector linkChips; - bool extractChip = false; - if (isForceEor && mRunTypeChip[it->first] < nInj) { - iRU = getRUID(it->first); - linkChips = getChipBoundariesFromRu(iRU, mActiveLinks[iRU]); - // check whether at least one chip on the same link reached the end of the scan - for (size_t i = 0; i < linkChips.size(); i++) { - if (mRunTypeChip[linkChips[i]] > nInj && linkChips[i] != it->first) { - extractChip = true; - break; - } - } - } - if (!extractChip && (!mRunStopRequested && this->mRunTypeChip[it->first] < nInj)) { + short int iRU = getRUID(it->first); + if (!isCRUITS && (mRunTypeRU[iRU] < nInjScaled * getNumberOfActiveLinks(mActiveLinks[iRU]) && !mRunStopRequested)) { ++it; continue; } + thisRUs.insert(iRU); float avgT, rmsT, avgN, rmsN, mpvT, outVal; this->findAverage(it->second, avgT, rmsT, avgN, rmsN); outVal = avgT; @@ -1871,88 +1783,44 @@ void ITSThresholdCalibrator::finalize() mpvT = std::distance(mpvCounter[it->first].begin(), std::max_element(mpvCounter[it->first].begin(), mpvCounter[it->first].end())) + mMin; outVal = mpvT; } - float status = ((float)it->second[5] / (float)(it->second[4] + it->second[5])) * 100.; // percentage of unsuccessful threshold extractions - std::vector data = {outVal, rmsT, avgN, rmsN, status}; - this->addDatabaseEntry(it->first, name, data, false); - this->mRunTypeChip[it->first] = 0; // so that this chip will never appear again in the DCSconfigObject_t - it = this->mThresholds.erase(it); - } - - } else if (this->mScanType == 'T') { - // Loop over each chip and calculate avg and rms - name = "THR"; - auto it = this->mThresholds.cbegin(); - while (it != this->mThresholds.cend()) { - int iRU = 0; - std::vector linkChips; - bool extractChip = false; - if (isForceEor && mRunTypeChip[it->first] < nInj) { - iRU = getRUID(it->first); - linkChips = getChipBoundariesFromRu(iRU, mActiveLinks[iRU]); - // check whether at least one chip on the same link reached the end of the scan - for (size_t i = 0; i < linkChips.size(); i++) { - if (mRunTypeChip[linkChips[i]] > nInj && linkChips[i] != it->first) { - extractChip = true; - break; - } - } - } - if (!extractChip && (!mRunStopRequested && this->mRunTypeChip[it->first] < nInj)) { - ++it; - continue; - } - float avgT, rmsT, avgN, rmsN; if (mVerboseOutput) { - LOG(info) << "Finding average threshold of chip " << it->first; + LOG(info) << "Average or mpv " << name << " of chip " << it->first << " = " << outVal << " e-"; } - this->findAverage(it->second, avgT, rmsT, avgN, rmsN); float status = ((float)it->second[5] / (float)(it->second[4] + it->second[5])) * 100.; // percentage of unsuccessful threshold extractions - std::vector data = {avgT, rmsT, avgN, rmsN, status}; + std::vector data = {outVal, rmsT, avgN, rmsN, status}; this->addDatabaseEntry(it->first, name, data, false); - this->mRunTypeChip[it->first] = 0; // so that this chip will never appear again in the DCSconfigObject_t it = this->mThresholds.erase(it); } - } else if (this->mScanType == 'D' || this->mScanType == 'A') { // Loop over each chip and calculate avg and rms name = "PixID"; - // Extract hits from the full matrix auto itchip = this->mPixelHits.cbegin(); while (itchip != this->mPixelHits.cend()) { // loop over chips collected - int iRU = 0; - std::vector linkChips; - bool extractChip = false; - if (isForceEor && mRunTypeChip[itchip->first] < nInj) { - iRU = getRUID(itchip->first); - linkChips = getChipBoundariesFromRu(iRU, mActiveLinks[iRU]); - // check whether at least one chip on the same link reached the end of the scan - for (size_t i = 0; i < linkChips.size(); i++) { - if (mRunTypeChip[linkChips[i]] > nInj && linkChips[i] != itchip->first) { - extractChip = true; - break; - } - } - } - if (!extractChip && (!mRunStopRequested && this->mRunTypeChip[itchip->first] < nInj)) { + short int iRU = getRUID(itchip->first); + if (!isCRUITS && (mRunTypeRU[iRU] < nInjScaled * getNumberOfActiveLinks(mActiveLinks[iRU]) && !mRunStopRequested)) { ++itchip; continue; } - LOG(info) << "Extracting hits for the full matrix of chip " << itchip->first; + thisRUs.insert(iRU); + if (mVerboseOutput) { + LOG(info) << "Extracting hits for the full matrix of chip " << itchip->first; + } for (short int irow = 0; irow < 512; irow++) { this->extractAndUpdate(itchip->first, irow); } if (this->mVerboseOutput) { LOG(info) << "Chip " << itchip->first << " hits extracted"; } - mRunTypeChip[itchip->first] = 0; // to avoid multiple writes into the tree ++itchip; } auto it = this->mNoisyPixID.cbegin(); while (it != this->mNoisyPixID.cend()) { PixelType = "Noisy"; - LOG(info) << "Extracting noisy pixels in the full matrix of chip " << it->first; + if (mVerboseOutput) { + LOG(info) << "Extracting noisy pixels in the full matrix of chip " << it->first; + } this->addDatabaseEntry(it->first, name, std::vector(), false); // all zeros are not used here if (this->mVerboseOutput) { LOG(info) << "Chip " << it->first << " done"; @@ -1962,7 +1830,9 @@ void ITSThresholdCalibrator::finalize() auto it_d = this->mDeadPixID.cbegin(); while (it_d != this->mDeadPixID.cend()) { - LOG(info) << "Extracting dead pixels in the full matrix of chip " << it_d->first; + if (mVerboseOutput) { + LOG(info) << "Extracting dead pixels in the full matrix of chip " << it_d->first; + } PixelType = "Dead"; this->addDatabaseEntry(it_d->first, name, std::vector(), false); // all zeros are not used here it_d = this->mDeadPixID.erase(it_d); @@ -1970,7 +1840,9 @@ void ITSThresholdCalibrator::finalize() auto it_ineff = this->mIneffPixID.cbegin(); while (it_ineff != this->mIneffPixID.cend()) { - LOG(info) << "Extracting inefficient pixels in the full matrix of chip " << it_ineff->first; + if (mVerboseOutput) { + LOG(info) << "Extracting inefficient pixels in the full matrix of chip " << it_ineff->first; + } PixelType = "Ineff"; this->addDatabaseEntry(it_ineff->first, name, std::vector(), false); it_ineff = this->mIneffPixID.erase(it_ineff); @@ -1982,12 +1854,14 @@ void ITSThresholdCalibrator::finalize() auto itchip = this->mPixelHits.cbegin(); while (itchip != mPixelHits.cend()) { int iRU = getRUID(itchip->first); - if (!mRunStopRequested && mRunTypeRU[iRU] < nInj * getActiveLinks(mActiveLinks[iRU])) { + if (!mRunStopRequested && mRunTypeRU[iRU] < nInjScaled * getNumberOfActiveLinks(mActiveLinks[iRU])) { ++itchip; continue; } thisRUs.insert(iRU); - LOG(info) << "Extracting hits from pulse shape scan or vresetd scan, chip " << itchip->first; + if (mVerboseOutput) { + LOG(info) << "Extracting hits from pulse shape scan or vresetd scan, chip " << itchip->first; + } auto itrow = this->mPixelHits[itchip->first].cbegin(); while (itrow != mPixelHits[itchip->first].cend()) { // in case there are multiple rows, for now it's 1 row this->extractAndUpdate(itchip->first, itrow->first); // fill the tree @@ -2002,9 +1876,10 @@ void ITSThresholdCalibrator::finalize() ++itchip; } // reset RU counters so that the chips which are done will not appear again in the DCSConfigObject - for (auto& ru : thisRUs) { - mRunTypeRU[ru] = 0; - } + } + + for (auto& ru : thisRUs) { + mRunTypeRU[ru] = 0; // reset } return; @@ -2017,6 +1892,9 @@ void ITSThresholdCalibrator::endOfStream(EndOfStreamContext& ec) { if (!isEnded && !mRunStopRequested) { LOGF(info, "endOfStream report:", mSelfName); + if (isCRUITS) { + finalize(); + } this->finalizeOutput(); isEnded = true; } @@ -2071,7 +1949,7 @@ DataProcessorSpec getITSThresholdCalibratorSpec(const ITSCalibInpConf& inpConf) {"ccdb-mgr-url", VariantType::String, "", {"CCDB url to download confDBmap"}}, {"min-vcasn", VariantType::Int, 30, {"Min value of VCASN in vcasn scan, default is 30"}}, {"max-vcasn", VariantType::Int, 100, {"Max value of VCASN in vcasn scan, default is 80"}}, - {"min-ithr", VariantType::Int, 15, {"Min value of ITHR in ithr scan, default is 15"}}, + {"min-ithr", VariantType::Int, 25, {"Min value of ITHR in ithr scan, default is 30"}}, {"max-ithr", VariantType::Int, 100, {"Max value of ITHR in ithr scan, default is 100"}}, {"manual-mode", VariantType::Bool, false, {"Flag to activate the manual mode in case run type is not recognized"}}, {"manual-min", VariantType::Int, 0, {"Min value of the variable used for the scan: use only in manual mode"}}, @@ -2091,7 +1969,6 @@ DataProcessorSpec getITSThresholdCalibratorSpec(const ITSCalibInpConf& inpConf) {"max-dump", VariantType::Int, -1, {"Maximum number of s-curves to dump in ROOT file per chip. Works with fit option and dump-scurves flag enabled. Default: dump all"}}, {"chip-dump", VariantType::String, "", {"Dump s-curves only for these Chip IDs (0 to 24119). If multiple IDs, write them separated by comma. Default is empty string: dump all"}}, {"calculate-slope", VariantType::Bool, false, {"For Pulse Shape 2D: if enabled it calculate the slope of the charge vs strobe delay trend for each pixel and fill it in the output tree"}}, - {"force-calculation-eor", VariantType::Bool, false, {"Calculate the avg quantities (thr, noise, vcasn, etc) at EOR ignoring the number of EOR flags from ITSComm"}}, {"charge-a", VariantType::Int, 0, {"To use with --calculate-slope, it defines the charge (in DAC) for the 1st point used for the slope calculation"}}, {"charge-b", VariantType::Int, 0, {"To use with --calculate-slope, it defines the charge (in DAC) for the 2nd point used for the slope calculation"}}, {"meb-select", VariantType::Int, -1, {"Select from which multi-event buffer consider the hits: 0,1 or 2"}}, From 884bb082d3263496f7617e000553478b1c5591b4 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Wed, 24 Jul 2024 11:15:05 +0200 Subject: [PATCH 0039/2205] Use rejectlist in MID filtering --- .../include/MIDFiltering/ChannelMasksHandler.h | 3 +++ .../MUON/MID/Workflow/src/FilteringSpec.cxx | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Detectors/MUON/MID/Filtering/include/MIDFiltering/ChannelMasksHandler.h b/Detectors/MUON/MID/Filtering/include/MIDFiltering/ChannelMasksHandler.h index 1cc2dcd18847c..3dcee7405e339 100644 --- a/Detectors/MUON/MID/Filtering/include/MIDFiltering/ChannelMasksHandler.h +++ b/Detectors/MUON/MID/Filtering/include/MIDFiltering/ChannelMasksHandler.h @@ -71,6 +71,9 @@ class ChannelMasksHandler /// Comparison operator bool operator==(const ChannelMasksHandler& right) const { return mMasks == right.mMasks; } + /// Clear masks + void clear() { mMasks.clear(); } + private: /// Gets the mask /// \param deId Detection element ID diff --git a/Detectors/MUON/MID/Workflow/src/FilteringSpec.cxx b/Detectors/MUON/MID/Workflow/src/FilteringSpec.cxx index 1fc4007a66139..0ccbbe237b9a5 100644 --- a/Detectors/MUON/MID/Workflow/src/FilteringSpec.cxx +++ b/Detectors/MUON/MID/Workflow/src/FilteringSpec.cxx @@ -71,10 +71,20 @@ class FilteringDeviceDPL void finaliseCCDB(of::ConcreteDataMatcher matcher, void* obj) { + bool rebuildMasks = false; if (matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "BAD_CHANNELS", 0)) { LOG(info) << "Update MID_BAD_CHANNELS"; - auto* badChannels = static_cast*>(obj); - mMasksHandler.switchOffChannels(*badChannels); + mBadChannels = *static_cast*>(obj); + rebuildMasks = true; + } else if (matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "REJECTLIST", 0)) { + LOG(info) << "Update MID_REJECTLIST"; + mRejectList = *static_cast*>(obj); + rebuildMasks = true; + } + if (rebuildMasks) { + mMasksHandler.clear(); + mMasksHandler.switchOffChannels(mBadChannels); + mMasksHandler.switchOffChannels(mRejectList); } } @@ -82,6 +92,7 @@ class FilteringDeviceDPL { // Triggers finalizeCCDB pc.inputs().get*>("mid_bad_channels"); + pc.inputs().get*>("mid_rejectlist"); auto data = specs::getData(pc, "mid_filter_in", EventType::Standard); auto inROFRecords = specs::getRofs(pc, "mid_filter_in", EventType::Standard); @@ -125,6 +136,8 @@ class FilteringDeviceDPL bool mUseMC{false}; std::vector mOutputs; std::function*, o2::dataformats::MCTruthContainer&, const ColumnData& col)> mFillLabels{[](size_t, size_t, const o2::dataformats::MCTruthContainer*, o2::dataformats::MCTruthContainer&, const ColumnData&) {}}; + std::vector mBadChannels{}; + std::vector mRejectList{}; }; of::DataProcessorSpec getFilteringSpec(bool useMC, std::string_view inDesc, std::string_view outDesc) @@ -132,6 +145,7 @@ of::DataProcessorSpec getFilteringSpec(bool useMC, std::string_view inDesc, std: auto inputSpecs = specs::buildInputSpecs("mid_filter_in", inDesc, useMC); inputSpecs.emplace_back("mid_bad_channels", header::gDataOriginMID, "BAD_CHANNELS", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/BadChannels")); + inputSpecs.emplace_back("mid_rejectlist", header::gDataOriginMID, "REJECTLIST", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/RejectList")); auto outputSpecs = specs::buildStandardOutputSpecs("mid_filter_out", outDesc, useMC); From 000a9ddb58cc7211efbb20b5d6d5a1125af70dec Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Wed, 24 Jul 2024 11:15:36 +0200 Subject: [PATCH 0040/2205] Use rejectlist in MID hit map builder --- .../include/MIDTracking/HitMapBuilder.h | 3 +- .../MUON/MID/Tracking/src/HitMapBuilder.cxx | 6 ++-- .../MUON/MID/Workflow/src/TrackerSpec.cxx | 28 ++++++++++++++----- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Detectors/MUON/MID/Tracking/include/MIDTracking/HitMapBuilder.h b/Detectors/MUON/MID/Tracking/include/MIDTracking/HitMapBuilder.h index 73caf2011e8a6..93e7ebbbceece 100644 --- a/Detectors/MUON/MID/Tracking/include/MIDTracking/HitMapBuilder.h +++ b/Detectors/MUON/MID/Tracking/include/MIDTracking/HitMapBuilder.h @@ -55,7 +55,8 @@ class HitMapBuilder /// Sets the masked channels /// \param maskedChannels vector of masked channels - void setMaskedChannels(const std::vector& maskedChannels); + /// \param clear clear the current masks + void setMaskedChannels(const std::vector& maskedChannels, bool clear); private: /// Checks if the track crossed the same element diff --git a/Detectors/MUON/MID/Tracking/src/HitMapBuilder.cxx b/Detectors/MUON/MID/Tracking/src/HitMapBuilder.cxx index e8b1442ee68e2..384a0194b6365 100644 --- a/Detectors/MUON/MID/Tracking/src/HitMapBuilder.cxx +++ b/Detectors/MUON/MID/Tracking/src/HitMapBuilder.cxx @@ -23,9 +23,11 @@ namespace mid HitMapBuilder::HitMapBuilder(const GeometryTransformer& geoTrans) : mMapping(), mHitFinder(geoTrans) {} -void HitMapBuilder::setMaskedChannels(const std::vector& maskedChannels) +void HitMapBuilder::setMaskedChannels(const std::vector& maskedChannels, bool clear) { - mMaskedChannels.clear(); + if (clear) { + mMaskedChannels.clear(); + } std::array nLines{4, 1}; for (auto& mask : maskedChannels) { for (int icath = 0; icath < 2; ++icath) { diff --git a/Detectors/MUON/MID/Workflow/src/TrackerSpec.cxx b/Detectors/MUON/MID/Workflow/src/TrackerSpec.cxx index e1044768e8ea6..28536bdbf570e 100644 --- a/Detectors/MUON/MID/Workflow/src/TrackerSpec.cxx +++ b/Detectors/MUON/MID/Workflow/src/TrackerSpec.cxx @@ -102,15 +102,25 @@ class TrackerDeviceDPL void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) { - if (mCheckMasked && matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "MASKED_CHANNELS", 0)) { - LOG(info) << "Update MID_MASKED_CHANNELS"; - auto* badChannels = static_cast*>(obj); - mHitMapBuilder->setMaskedChannels(*badChannels); - return; - } if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { return; } + if (mCheckMasked) { + bool rebuildMaskedChannels = false; + if (matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "BAD_CH_TRK", 0)) { + LOG(info) << "Update MID_BAD_CH_TRK"; + mBadChannels = *static_cast*>(obj); + rebuildMaskedChannels = true; + } else if (matcher == of::ConcreteDataMatcher(header::gDataOriginMID, "REJECTLIST_TRK", 0)) { + LOG(info) << "Update MID_REJECTLIST_TRK"; + mRejectList = *static_cast*>(obj); + rebuildMaskedChannels = true; + } + if (rebuildMaskedChannels) { + mHitMapBuilder->setMaskedChannels(mBadChannels, true); + mHitMapBuilder->setMaskedChannels(mRejectList, false); + } + } } private: @@ -129,6 +139,7 @@ class TrackerDeviceDPL mHitMapBuilder = std::make_unique(geoTrans); } pc.inputs().get*>("mid_bad_channels_forTracks"); + pc.inputs().get*>("mid_rejectlist_forTracks"); } bool mIsMC = false; @@ -142,6 +153,8 @@ class TrackerDeviceDPL std::chrono::duration mTimerTracker{0}; ///< tracker timer std::chrono::duration mTimerBuilder{0}; ///< hit map builder timer unsigned int mNROFs{0}; /// Total number of processed ROFs + std::vector mBadChannels{}; ///< Bad channels + std::vector mRejectList{}; ///< Reject list }; framework::DataProcessorSpec getTrackerSpec(bool isMC, bool checkMasked) @@ -149,7 +162,8 @@ framework::DataProcessorSpec getTrackerSpec(bool isMC, bool checkMasked) std::vector inputSpecs; inputSpecs.emplace_back("mid_clusters", header::gDataOriginMID, "CLUSTERS"); inputSpecs.emplace_back("mid_clusters_rof", header::gDataOriginMID, "CLUSTERSROF"); - inputSpecs.emplace_back("mid_bad_channels_forTracks", header::gDataOriginMID, "MASKED_CHANNELS", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/BadChannels")); + inputSpecs.emplace_back("mid_bad_channels_forTracks", header::gDataOriginMID, "BAD_CH_TRK", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/BadChannels")); + inputSpecs.emplace_back("mid_rejectlist_forTracks", header::gDataOriginMID, "REJECTLIST_TRK", 0, of::Lifetime::Condition, of::ccdbParamSpec("MID/Calib/RejectList")); auto ggRequest = std::make_shared(false, // orbitResetTime false, // GRPECS=true false, // GRPLHCIF From eb5e8351ea44db9134a503d1d11b3ccb1c9e3e7a Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Sat, 27 Jul 2024 07:45:32 +0200 Subject: [PATCH 0041/2205] Macro to build the rejectlist for MID (#13330) * Macro to build the rejectlist for MID * Add instruction on how to use the macros --- .../MID/Calibration/macros/CMakeLists.txt | 7 +- .../MUON/MID/Calibration/macros/README.md | 50 +++ .../MID/Calibration/macros/build_rejectlist.C | 298 ++++++++++++++++++ 3 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 Detectors/MUON/MID/Calibration/macros/README.md create mode 100644 Detectors/MUON/MID/Calibration/macros/build_rejectlist.C diff --git a/Detectors/MUON/MID/Calibration/macros/CMakeLists.txt b/Detectors/MUON/MID/Calibration/macros/CMakeLists.txt index d665140902c43..e19d6a669a8aa 100644 --- a/Detectors/MUON/MID/Calibration/macros/CMakeLists.txt +++ b/Detectors/MUON/MID/Calibration/macros/CMakeLists.txt @@ -11,5 +11,10 @@ o2_add_test_root_macro( ccdbUtils.C - PUBLIC_LINK_LIBRARIES O2::MIDCalibration O2::MathUtils + PUBLIC_LINK_LIBRARIES O2::MIDFiltering O2::DataFormatsMID O2::CCDB + LABELS muon mid) + +o2_add_test_root_macro( + build_rejectlist.C + PUBLIC_LINK_LIBRARIES O2::MIDFiltering O2::MIDGlobalMapping O2::DataFormatsMID O2::CCDB O2::CommonUtils LABELS muon mid) diff --git a/Detectors/MUON/MID/Calibration/macros/README.md b/Detectors/MUON/MID/Calibration/macros/README.md new file mode 100644 index 0000000000000..7dc3e233afdbf --- /dev/null +++ b/Detectors/MUON/MID/Calibration/macros/README.md @@ -0,0 +1,50 @@ + + +# MID calibration macros + +This repository contains macros that can be used to handle calibration objects in the CCDB. + +## ccdbUtils.C + +This macro allows to query a series of MID CCDB objects in the CCDB as well as produce default objects. +The basic usage is the following: + +Query the list of bad channels from the official CCDB: + +```shell +root -l +.x ccdbUtils.C("querybad",1721252719000,"mask.txt",true,"http://alice-ccdb.cern.ch") +``` + +Upload the default list of fake dead channels to the local CCDB (assuming that an instance of the local CCDB is running): + +```shell +root -l +.x ccdbUtils.C("uploadfake",1,"mask.txt",true,"localhost:8080") +``` + +The macro is also used to keep track of the fake dead channels, which are generated in `makeFakeDeadChannels()`. + +## buils_rejectList.C + +This macro analyses the Quality flag and the Occupancy plot in the QCCDB and searches for issues appearing in the middle of the run, e.g. local board(s) that become noisy and are then excluded from the data taking by the user logic of the CRU. +It then correlate this information with the GRPECS object in the CCDB in order to create a reject list that will allow to mask the faulty local board(s) from slightly before the problem appeared till the end of the run. + +Notice that the QCDB is not directly reachable from outside CERN. In that case one needs to first create an ssh tunnel: + +```shell +ssh -L 8083:ali-qcdb-gpn.cern.ch:8083 lxtunnel.cern.ch +``` + +We also advice to have an instance of the local CCDB running, so that the reject list objects will be saved there. +One can then scan for issues with: + +```shell +root -l +build_rejectlist.C+(1716436103391,1721272208000,"localhost:8083") +``` + +Where the first number is the start timestamp for the scan, and the second is the end timestamp of the scan. +For each problem found, the macro will ask if one wants to upload the reject list to the (local) CCDB or not. diff --git a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C new file mode 100644 index 0000000000000..0782a08a3822d --- /dev/null +++ b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C @@ -0,0 +1,298 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file MID/Calibration/macros/build_rejectlist.C +/// \brief Analyse QC output and build reject list +/// \author Diego Stocco +/// \date 26 July 2024 + +#include +#include +#include +#include +#include +#include +#include +#include "TCanvas.h" +#include "TH1.h" +#include "TGraph.h" +#include "TTimeStamp.h" +#include "CCDB/CcdbApi.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DataFormatsMID/ColumnData.h" +#include "MIDGlobalMapping/ExtendedMappingInfo.h" +#include "MIDGlobalMapping/GlobalMapper.h" +#include "MIDFiltering/ChannelMasksHandler.h" +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "CCDB/BasicCCDBManager.h" +#endif + +static const std::string sPathQCQuality = "qc/MID/MO/MIDQuality/Trends/global/MIDQuality/MIDQuality"; + +/// @brief Get timestamp in milliseconds +/// @param timestamp Input timestamp (in s or ms) +/// @return Timestamp in ms +long getTSMS(long timestamp) +{ + if (timestamp < 1000000000000) { + return timestamp * 1000; + } + return timestamp; +} + +/// @brief Get timestamp in seconds +/// @param timestamp Input timestamp (in s or ms) +/// @return Timestamp in s +long getTSS(long timestamp) +{ + if (timestamp < 1000000000000) { + return timestamp; + } + return timestamp / 1000; +} + +/// @brief Converts timestamp to human-readable string +/// @param timestamp Timestamp as long +/// @return Timestamp as human-readable string +std::string tsToString(long timestamp) +{ + return TTimeStamp(getTSS(timestamp)).AsString("l"); +} + +/// @brief Converts time range in a human-readable string +/// @param start Start time +/// @param end End time +/// @return Time range as human-readable string +std::string timeRangeToString(long start, long end) +{ + std::stringstream ss; + ss << start << " - " << end << " (" << tsToString(start) << " - " << tsToString(end) << ")"; + return ss.str(); +} + +/// @brief Query the CDB path and search for initial validity of objects +/// @param start Query objects created not before +/// @param end Query objects created not after +/// @param api CDB api +/// @param path CDB path +/// @return Vector of start validity of each object sorted in ascending way +std::vector findObjectsTSInPeriod(long start, long end, const o2::ccdb::CcdbApi& api, const char* path) +{ + std::vector ts; + auto out = api.list(path, false, "text/plain", getTSMS(end), getTSMS(start)); + std::stringstream ss(out); + std::string token; + while (ss >> token) { + if (token.find("Validity") != std::string::npos) { + ss >> token; + ts.emplace_back(std::atol(token.c_str())); + } + } + ts.erase(std::unique(ts.begin(), ts.end()), ts.end()); + // Sort timestamps in ascending order + std::sort(ts.begin(), ts.end()); + return ts; +} + +/// @brief Find the first and last time when the quality was good or bad +/// @param qcQuality MID QC quality canvas +/// @param selectBad When true select bad quality +/// @return Pair with first and last time +std::pair findTSRange(TCanvas* qcQuality, bool selectBad = true) +{ + auto* gr = static_cast(qcQuality->GetListOfPrimitives()->FindObject("Graph")); + double xp, yp; + std::pair range{std::numeric_limits::max(), 0}; + for (int ip = 0; ip < gr->GetN(); ++ip) { + gr->GetPoint(ip, xp, yp); + if (selectBad == (yp > 1 && yp < 3)) { + uint64_t xpi = static_cast(1000 * xp); + range.first = std::min(range.first, xpi); + range.second = std::max(range.second, xpi); + } + } + if (range.first == std::numeric_limits::max()) { + range.first = 0; + } + return range; +} + +/// @brief Find bad channels from the occupancy histograms +/// @param hits Occupancy histogram +/// @param infos Mapping +/// @return Vector of bad channels +std::vector findBadChannels(TH1* hits, std::vector& infos) +{ + std::map badChannelsMap; + for (int ibin = 1; ibin <= hits->GetNbinsX(); ++ibin) { + if (hits->GetBinContent(ibin) == 0) { + auto info = infos[ibin - 1]; + auto uniqueId = o2::mid::getColumnDataUniqueId(info.deId, info.columnId); + o2::mid::ColumnData col; + col.deId = info.deId; + col.columnId = info.columnId; + auto result = badChannelsMap.emplace(uniqueId, col); + result.first->second.addStrip(info.stripId, info.cathode, info.lineId); + } + } + + std::vector badChannels; + for (auto& item : badChannelsMap) { + badChannels.emplace_back(item.second); + } + return badChannels; +} + +/// @brief Converts the bad channels from the occupancy into a reject list (removing the ones from CCDB) +/// @param badChannels Bad channels from the analysis of the occupancy histogram +/// @param badChannelsCCDB Bad channels in the CCDB +/// @return Reject list +std::vector getRejectList(std::vector badChannels, const std::vector& badChannelsCCDB) +{ + o2::mid::ChannelMasksHandler mh; + mh.switchOffChannels(badChannelsCCDB); + for (auto& bad : badChannels) { + mh.applyMask(bad); + } + badChannels.erase(std::remove_if(badChannels.begin(), badChannels.end(), [](const o2::mid::ColumnData col) { return col.isEmpty(); }), + badChannels.end()); + return badChannels; +} + +/// @brief Builds the reject list for the selected timestamp +/// @param timestamp Timestamp for query +/// @param qcdbApi QCDB api +/// @param ccdbApi CCDB api +/// @param outCCDBApi api of the CCDB where the reject list will be uploaded +/// @return Reject list +std::vector build_rejectlist(long timestamp, const o2::ccdb::CcdbApi& qcdbApi, const o2::ccdb::CcdbApi& ccdbApi, const o2::ccdb::CcdbApi& outCCDBApi) +{ + std::map metadata; + auto* qcQuality = qcdbApi.retrieveFromTFileAny(sPathQCQuality, metadata, getTSMS(timestamp)); + if (!qcQuality) { + std::cerr << "Cannot find QC quality for " << tsToString(timestamp) << std::endl; + return {}; + } + // Find the first and last timestamp where the quality was bad (if any) + auto badTSRange = findTSRange(qcQuality); + if (badTSRange.second == 0) { + std::cout << "All good" << std::endl; + return {}; + } + // Search for the last timestamp for which the run quality was good + auto goodTSRange = findTSRange(qcQuality, false); + // Query the CCDB to see to which run the timestamp corresponds + auto oldestTSInQCQuality = (goodTSRange.first == 0) ? badTSRange.first : goodTSRange.first; + auto grpecs = *ccdbApi.retrieveFromTFileAny("GLO/Config/GRPECS", metadata, getTSMS(oldestTSInQCQuality)); + if (!grpecs.isDetReadOut(o2::detectors::DetID::MID)) { + std::cout << "Error: we are probably reading a parallel run" << std::endl; + grpecs.print(); + return {}; + } + if (grpecs.getRunType() != o2::parameters::GRPECS::PHYSICS) { + std::cout << "This is not a physics run: skip" << std::endl; + grpecs.print(); + return {}; + } + + auto runRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, grpecs.getRun()); + long margin = 120000; // Add a two minutes safety margin + runRange.first -= margin; // Subtract margin + runRange.second += margin; // Add margin + + // Search for hits histogram in the period where the QC quality was bad + auto tsVector = findObjectsTSInPeriod(badTSRange.first, badTSRange.second, qcdbApi, "qc/MID/MO/QcTaskMIDDigits/Hits"); + if (tsVector.empty()) { + std::cerr << "Cannot find hits in period " << tsToString(badTSRange.first) << " - " << tsToString(badTSRange.second) << std::endl; + return {}; + } + // Focus on the first object found + TH1* occupancy = qcdbApi.retrieveFromTFileAny("qc/MID/MO/QcTaskMIDDigits/Hits", metadata, getTSMS(tsVector.front())); + o2::mid::GlobalMapper gm; + auto infos = gm.buildStripsInfo(); + auto badChannels = findBadChannels(occupancy, infos); + auto badChannelsCCDB = *ccdbApi.retrieveFromTFileAny>("MID/Calib/BadChannels", metadata, getTSMS(timestamp)); + auto rejectList = getRejectList(badChannels, badChannelsCCDB); + if (rejectList.empty()) { + std::cout << "Warning: reject list was empty. It probably means that an entire board is already masked in calibration for run " << grpecs.getRun() << std::endl; + return {}; + } + + // Print some useful information + std::cout << "Reject list:" << std::endl; + for (auto& col : rejectList) { + std::cout << col << std::endl; + } + std::cout << "Run number: " << grpecs.getRun() << std::endl; + std::cout << "SOR - EOR: " << timeRangeToString(grpecs.getTimeStart(), grpecs.getTimeEnd()) << std::endl; + std::cout << "SOT - EOT: " << timeRangeToString(runRange.first, runRange.second) << std::endl; + std::cout << "Good: " << timeRangeToString(goodTSRange.first, goodTSRange.second) << std::endl; + std::cout << "Bad: " << timeRangeToString(badTSRange.first, badTSRange.second) << std::endl; + + // Set the start of the reject list to the last timestamp in which the occupancy was ok + auto startRL = goodTSRange.second; + if (goodTSRange.first == 0) { + // If the quality was bad for the full run, set the start of the reject list to the SOR + std::cout << "CAVEAT: no good TS found. Will use SOT instead" << std::endl; + startRL = runRange.first; + } + // Set the end of the reject list to the end of run + auto endRL = runRange.second; + // Ask if you want to upload the object to the CCDB + std::cout << "Upload reject list with validity: " << startRL << " - " << endRL << " to " << outCCDBApi.getURL() << "? [y/n]" << std::endl; + std::string answer; + std::cin >> answer; + if (answer == "y") { + std::cout << "Storing RejectList valid from " << startRL << " to " << endRL << std::endl; + outCCDBApi.storeAsTFileAny(&rejectList, "MID/Calib/RejectList", metadata, startRL, endRL); + } + return rejectList; +} + +/// @brief Builds the reject list for the selected timestamp +/// @param timestamp Timestamp for query +/// @param qcdbUrl QCDB URL +/// @param ccdbUrl CCDB URL +/// @param outCCDBUrl URL of the CCDB where the reject list will be uploaded +/// @return Reject list +std::vector build_rejectlist(long timestamp, const char* qcdbUrl = "http://ali-qcdb-gpn.cern.ch:8083", const char* ccdbUrl = "http://alice-ccdb.cern.ch", const char* outCCDBUrl = "http://localhost:8080") +{ + // Get the QC quality object for the selected timestamp + o2::ccdb::CcdbApi qcdbApi; + qcdbApi.init(qcdbUrl); + o2::ccdb::CcdbApi ccdbApi; + ccdbApi.init(ccdbUrl); + o2::ccdb::CcdbApi outCCDBApi; + outCCDBApi.init(outCCDBUrl); + return build_rejectlist(timestamp, qcdbApi, ccdbApi, outCCDBApi); +} + +/// @brief Builds the reject list iin a time range +/// @param start Start time for query +/// @param end End time for query +/// @param qcdbUrl QCDB URL +/// @param ccdbUrl CCDB URL +/// @param outCCDBUrl URL of the CCDB where the reject lists will be uploaded +void build_rejectlist(long start, long end, const char* qcdbUrl = "http://ali-qcdb-gpn.cern.ch:8083", const char* ccdbUrl = "http://alice-ccdb.cern.ch", const char* outCCDBUrl = "http://localhost:8080") +{ + // Query the MID QC quality objects + o2::ccdb::CcdbApi qcdbApi; + qcdbApi.init(qcdbUrl); + o2::ccdb::CcdbApi ccdbApi; + ccdbApi.init(ccdbUrl); + o2::ccdb::CcdbApi outCCDBApi; + outCCDBApi.init(outCCDBUrl); + auto objectsTS = findObjectsTSInPeriod(start, end, qcdbApi, sPathQCQuality.c_str()); + for (auto ts : objectsTS) { + build_rejectlist(ts, qcdbApi, ccdbApi, outCCDBApi); + } +} \ No newline at end of file From 175e6acf280bcc5d1eaedfea6f19c8bd20829447 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 29 Jul 2024 08:25:47 +0200 Subject: [PATCH 0042/2205] GLO: Revert changes on CMakeLists (#13339) In #13069 these were mistakenly removed and changes are now reverted. --- Detectors/GlobalTracking/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Detectors/GlobalTracking/CMakeLists.txt b/Detectors/GlobalTracking/CMakeLists.txt index fce4a5370d612..ecf77ea741e21 100644 --- a/Detectors/GlobalTracking/CMakeLists.txt +++ b/Detectors/GlobalTracking/CMakeLists.txt @@ -22,6 +22,8 @@ o2_add_library(GlobalTracking src/MatchGlobalFwdAssessment.cxx src/MatchGlobalFwdParam.cxx src/MatchTOFParams.cxx + src/MatchITSTPCQC.cxx + src/ITSTPCMatchingQCParams.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsTPC O2::DataFormatsITSMFT From 193f7aa3f2b5452ab74afac0d3dc1ebb48a01935 Mon Sep 17 00:00:00 2001 From: Ruben Shahoyan Date: Mon, 29 Jul 2024 19:52:58 +0200 Subject: [PATCH 0043/2205] impose CompletionOrder::Timeslice policy on CCDBPopulator (#13319) --- Detectors/Calibration/workflow/ccdb-populator-workflow.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Detectors/Calibration/workflow/ccdb-populator-workflow.cxx b/Detectors/Calibration/workflow/ccdb-populator-workflow.cxx index 5432712dfdac3..d03920b7a657f 100644 --- a/Detectors/Calibration/workflow/ccdb-populator-workflow.cxx +++ b/Detectors/Calibration/workflow/ccdb-populator-workflow.cxx @@ -33,7 +33,8 @@ void customize(std::vector& policies) // we customize the pipeline processors to consume data as it comes using CompletionPolicy = o2::framework::CompletionPolicy; using CompletionPolicyHelpers = o2::framework::CompletionPolicyHelpers; - policies.push_back(CompletionPolicyHelpers::defineByName("ccdb-populator.*", CompletionPolicy::CompletionOp::Consume)); + auto& pol = policies.emplace_back(CompletionPolicyHelpers::defineByName("ccdb-populator.*", CompletionPolicy::CompletionOp::Consume)); + pol.order = CompletionPolicy::CompletionOrder::Slot; } // ------------------------------------------------------------------ From 1e78fb8d61b026c3e8d02481888f7f04d4b69af5 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Wed, 31 Jul 2024 10:16:02 +0200 Subject: [PATCH 0044/2205] Improve README for MID reject list macro --- .../MUON/MID/Calibration/macros/README.md | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/Detectors/MUON/MID/Calibration/macros/README.md b/Detectors/MUON/MID/Calibration/macros/README.md index 7dc3e233afdbf..7009e99086419 100644 --- a/Detectors/MUON/MID/Calibration/macros/README.md +++ b/Detectors/MUON/MID/Calibration/macros/README.md @@ -18,7 +18,7 @@ root -l .x ccdbUtils.C("querybad",1721252719000,"mask.txt",true,"http://alice-ccdb.cern.ch") ``` -Upload the default list of fake dead channels to the local CCDB (assuming that an instance of the local CCDB is running): +Upload the default list of fake dead channels to the local CCDB (assuming that an instance of the local CCDB is running, see below): ```shell root -l @@ -27,24 +27,53 @@ root -l The macro is also used to keep track of the fake dead channels, which are generated in `makeFakeDeadChannels()`. -## buils_rejectList.C +## build_rejectList.C -This macro analyses the Quality flag and the Occupancy plot in the QCCDB and searches for issues appearing in the middle of the run, e.g. local board(s) that become noisy and are then excluded from the data taking by the user logic of the CRU. -It then correlate this information with the GRPECS object in the CCDB in order to create a reject list that will allow to mask the faulty local board(s) from slightly before the problem appeared till the end of the run. +This macro analyses the quality flag and the occupancy plots in the QCCDB and searches for issues appearing in the middle of the run, e.g. local board(s) that become noisy and are then excluded from the data taking by the user logic of the CRU. +It then correlates this information with the GRPECS object in the CCDB in order to create a reject list that will allow to mask the faulty local board(s) from slightly before the problem appeared till the end of the run. -Notice that the QCDB is not directly reachable from outside CERN. In that case one needs to first create an ssh tunnel: +If a problem is found, the macro will ask to upload the reject list in the local CCDB. +For this, one needs to have the local CCDB up and running (see below). + +The scan can be then performed with: + +```shell +root -l +.x build_rejectlist.C+(1716436103391,1721272208000) +``` + +Where the first number is the start timestamp for the scan, and the second is the end timestamp of the scan. + +### Running outside CERN network + +Notice that the QCDB is not directly reachable from outside CERN network. +In that case one needs to first create an ssh tunnel: ```shell ssh -L 8083:ali-qcdb-gpn.cern.ch:8083 lxtunnel.cern.ch ``` -We also advice to have an instance of the local CCDB running, so that the reject list objects will be saved there. -One can then scan for issues with: +and then tell the macro to reach the QCDB via the tunneled local port: ```shell root -l -build_rejectlist.C+(1716436103391,1721272208000,"localhost:8083") +.x build_rejectlist.C+(1716436103391,1721272208000,"localhost:8083") ``` -Where the first number is the start timestamp for the scan, and the second is the end timestamp of the scan. -For each problem found, the macro will ask if one wants to upload the reject list to the (local) CCDB or not. +## Running the local CCDB + +The local CCDB server can be easily built through alibuild. +As usual, one needs to be in the directory containing alidist and then run: + +```shell +aliBuild build localccdb +``` + +The CCDB server can be then run with: + +```shell +alienv enter localccdb/latest +startccdb -r "path_to_local_ccdb" +``` + +where `path_to_local_ccdb` is a directory in your local pc where the CCDB objects will be located. From 8a7ef25d24ee3952472e82028bb88567c103745a Mon Sep 17 00:00:00 2001 From: pillot Date: Wed, 31 Jul 2024 15:02:51 +0200 Subject: [PATCH 0045/2205] add possibility to update existing objects (#13341) --- Detectors/MUON/MCH/Conditions/README.md | 12 +- .../MCH/Conditions/src/bad-channels-ccdb.cxx | 150 ++++++++++++++++-- 2 files changed, 147 insertions(+), 15 deletions(-) diff --git a/Detectors/MUON/MCH/Conditions/README.md b/Detectors/MUON/MCH/Conditions/README.md index dcea47d201867..fda90ba8c9ca9 100644 --- a/Detectors/MUON/MCH/Conditions/README.md +++ b/Detectors/MUON/MCH/Conditions/README.md @@ -30,7 +30,11 @@ Usage: (default=now) --endtimestamp arg (=1677773918645) end of validity (for put) - default=1 day from now - -p [ --put ] upload bad channel default object + -l [ --list ] list timestamps, within the given + range, when the bad channels change + -p [ --put ] upload bad channel object + -r [ --referenceccdb ] arg (=http://alice-ccdb.cern.ch) + reference ccdb url -u [ --upload-default-values ] upload default values -t [ --type ] arg (=BadChannel) type of bad channel (BadChannel or RejectList) @@ -40,12 +44,12 @@ Usage: -d [ --ds ] arg dual sampas indices to reject -e [ --de ] arg DE ids to reject -a [ --alias ] arg DCS alias (HV or LV) to reject - ``` -For instance, to create a debug RejectList object which declares solar number 32 as bad within a local CCDB, from Tuesday 1 November 2022 00:00:01 UTC to Saturday 31 December 2022 23:59:59, use : +For instance, to create in a local CCDB a RejectList object which declares solar number 32 as bad, from Tuesday 1 November 2022 00:00:01 UTC to Saturday 31 December 2022 23:59:59, use : ```shell $ o2-mch-bad-channels-ccdb -p -s 32 -t RejectList --starttimestamp 1667260801000 --endtimestamp 1672531199000 -storing default MCH bad channels (valid from 1667260801000 to 1672531199000) to MCH/Calib/RejectList ``` + +The program will search the reference CCDB (defined with `--referenceccdb`) for existing objects valid during this period and propose you to either overwrite them or update them. In the first case, a single object will be created, valid for the whole period, containing only the new bad channels. In the second case, as many objects as necessary will be created with appropriate validity ranges, adding the new bad channels to the existing ones. diff --git a/Detectors/MUON/MCH/Conditions/src/bad-channels-ccdb.cxx b/Detectors/MUON/MCH/Conditions/src/bad-channels-ccdb.cxx index db1cb53f51c5a..d453277aa644c 100644 --- a/Detectors/MUON/MCH/Conditions/src/bad-channels-ccdb.cxx +++ b/Detectors/MUON/MCH/Conditions/src/bad-channels-ccdb.cxx @@ -9,13 +9,16 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "CCDB/CcdbApi.h" #include #include +#include +#include #include #include +#include #include #include +#include "CCDB/CcdbApi.h" #include "DataFormatsMCH/DsChannelId.h" #include "MCHConditions/DCSAliases.h" #include "MCHConstants/DetectionElements.h" @@ -33,20 +36,105 @@ std::string ccdbPath(const std::string badChannelType) return fmt::format("MCH/Calib/{}", badChannelType); } -void queryBadChannels(const std::string ccdbUrl, - const std::string badChannelType, uint64_t timestamp, bool verbose) +std::set listTSWhenBadChannelsChange(const std::string ccdbUrl, const std::string badChannelType, + uint64_t startTimestamp, uint64_t endTimestamp, bool verbose) +{ + std::set tsChanges{startTimestamp}; + + std::cout << std::endl; + o2::ccdb::CcdbApi api; + api.init(ccdbUrl); + auto source = ccdbPath(badChannelType); + + // store every timestamps in the time range when the bad channels potentially change + if (verbose) { + std::cout << fmt::format("\nlist of {} files potentially valid in the range {} - {}:\n", source, startTimestamp, endTimestamp); + } + std::istringstream fileInfo(api.list(source, false, "text/plain")); + std::string dummy{}; + std::string path{}; + uint64_t begin = 0; + uint64_t end = 0; + uint64_t creation = 0; + bool inRange = false; + for (std::string line; std::getline(fileInfo, line);) { + if (line.find("Validity:") == 0) { + std::istringstream in(line); + in >> dummy >> begin >> dummy >> end; + if (begin < endTimestamp && end > startTimestamp) { + if (begin >= startTimestamp) { + tsChanges.emplace(begin); + } + if (end < endTimestamp) { + tsChanges.emplace(end); + } + inRange = true; + } + } else if (verbose) { + if (line.find("ID:") == 0) { + std::istringstream in(line); + in >> dummy >> path; + } else if (inRange && line.find("Created:") == 0) { + std::istringstream in(line); + in >> dummy >> creation; + std::cout << fmt::format("- {}\n", path); + std::cout << fmt::format(" validity range: {} - {}\n", begin, end); + std::cout << fmt::format(" creation time: {}\n", creation); + inRange = false; + } + } + } + if (verbose) { + std::cout << fmt::format("\nlist of timestamps when the bad channels potentially change:\n"); + for (auto ts : tsChanges) { + std::cout << fmt::format(" {}\n", ts); + } + } + + // select timestamps when the bad channels actually change + if (verbose) { + std::cout << fmt::format("\nlist of {} files actually valid in the range {} - {}:\n", source, startTimestamp, endTimestamp); + } + std::map metadata{}; + std::string currentETag{}; + for (auto itTS = tsChanges.begin(); itTS != tsChanges.end();) { + auto headers = api.retrieveHeaders(source, metadata, *itTS); + if (headers["ETag"] == currentETag) { + itTS = tsChanges.erase(itTS); + } else { + if (verbose) { + std::cout << fmt::format("- {}\n", headers["Location"]); + std::cout << fmt::format(" validity range: {} - {}\n", headers["Valid-From"], headers["Valid-Until"]); + std::cout << fmt::format(" creation time: {}\n", headers["Created"]); + } + currentETag = headers["ETag"]; + ++itTS; + } + } + std::cout << fmt::format("\nlist of timestamps when the bad channels actually change:\n"); + for (auto ts : tsChanges) { + std::cout << fmt::format(" {}\n", ts); + } + + return tsChanges; +} + +BadChannelsVector queryBadChannels(const std::string ccdbUrl, + const std::string badChannelType, uint64_t timestamp, bool verbose) { + std::cout << std::endl; o2::ccdb::CcdbApi api; api.init(ccdbUrl); std::map metadata; auto source = ccdbPath(badChannelType); - auto* badChannels = api.retrieveFromTFileAny(source.c_str(), metadata, timestamp); + auto* badChannels = api.retrieveFromTFileAny(source, metadata, timestamp); std::cout << "number of bad channels = " << badChannels->size() << std::endl; if (verbose) { for (const auto& badChannel : *badChannels) { std::cout << badChannel.asString() << "\n"; } } + return *badChannels; } void rejectDS(const o2::mch::raw::DsDetId& dsDetId, BadChannelsVector& bv) @@ -124,13 +212,13 @@ void uploadBadChannels(const std::string ccdbUrl, const BadChannelsVector& bv, bool makeDefault) { + std::cout << std::endl; o2::ccdb::CcdbApi api; api.init(ccdbUrl); std::map md; auto dest = ccdbPath(badChannelType); - std::cout << "storing default MCH bad channels (valid from " - << startTimestamp << " to " << endTimestamp << ") to " - << dest << "\n"; + std::cout << fmt::format("storing {} {}bad channels (valid from {} to {}) to {}\n", bv.size(), + makeDefault ? "default " : "", startTimestamp, endTimestamp, dest); if (makeDefault) { md["default"] = "true"; @@ -145,10 +233,12 @@ int main(int argc, char** argv) po::options_description usage("Usage"); std::string ccdbUrl; + std::string ccdbRefUrl; std::string dpConfName; std::string badChannelType; uint64_t startTimestamp; uint64_t endTimestamp; + bool list; bool put; bool query; bool verbose; @@ -165,9 +255,11 @@ int main(int argc, char** argv) usage.add_options() ("help,h", "produce help message") ("ccdb,c",po::value(&ccdbUrl)->default_value("http://localhost:6464"),"ccdb url") - ("starttimestamp,st",po::value(&startTimestamp)->default_value(now),"timestamp for query or put - (default=now)") - ("endtimestamp,et", po::value(&endTimestamp)->default_value(end), "end of validity (for put) - default=1 day from now") - ("put,p",po::bool_switch(&put),"upload bad channel default object") + ("starttimestamp",po::value(&startTimestamp)->default_value(now),"timestamp for query or put - (default=now)") + ("endtimestamp", po::value(&endTimestamp)->default_value(end), "end of validity (for put) - default=1 day from now") + ("list,l", po::bool_switch(&list),"list timestamps, within the given range, when the bad channels change") + ("put,p",po::bool_switch(&put),"upload bad channel object") + ("referenceccdb,r",po::value(&ccdbRefUrl)->default_value("http://alice-ccdb.cern.ch"),"reference ccdb url") ("upload-default-values,u",po::bool_switch(&uploadDefault),"upload default values") ("type,t",po::value(&badChannelType)->default_value("BadChannel"),"type of bad channel (BadChannel or RejectList)") ("query,q",po::bool_switch(&query),"dump bad channel object from CCDB") @@ -202,6 +294,10 @@ int main(int argc, char** argv) exit(2); } + if (list) { + auto tsChanges = listTSWhenBadChannelsChange(ccdbUrl, badChannelType, startTimestamp, endTimestamp, verbose); + } + if (query) { queryBadChannels(ccdbUrl, badChannelType, startTimestamp, verbose); } @@ -221,7 +317,39 @@ int main(int argc, char** argv) rejectHVLVs(vm["alias"].as>(), bv); } - uploadBadChannels(ccdbUrl, badChannelType, startTimestamp, endTimestamp, bv, uploadDefault); + if (uploadDefault) { + uploadBadChannels(ccdbUrl, badChannelType, startTimestamp, endTimestamp, bv, true); + } else { + auto tsChanges = listTSWhenBadChannelsChange(ccdbRefUrl, badChannelType, startTimestamp, endTimestamp, false); + + std::cout << fmt::format("\n{} object{} valid in the reference CCDB ({}) for this time range. What do you want to do?\n", + tsChanges.size(), (tsChanges.size() > 1) ? "s are" : " is", ccdbRefUrl); + std::cout << fmt::format("[a] abort: do nothing\n"); + std::cout << fmt::format("[o] overwrite: create 1 new object for the whole time range to supersede the existing one{}\n", + (tsChanges.size() > 1) ? "s" : ""); + std::cout << fmt::format("[u] update: create {} new object{} within the time range adding new bad channels to existing ones\n", + tsChanges.size(), (tsChanges.size() > 1) ? "s" : ""); + std::string response{}; + std::cin >> response; + + if (response == "a" || response == "abort") { + return 0; + } else if (response == "o" || response == "overwrite") { + uploadBadChannels(ccdbUrl, badChannelType, startTimestamp, endTimestamp, bv, false); + } else if (response == "u" || response == "update") { + tsChanges.emplace(endTimestamp); + auto itStartTS = tsChanges.begin(); + for (auto itStopTS = std::next(itStartTS); itStopTS != tsChanges.end(); ++itStartTS, ++itStopTS) { + auto bv2 = queryBadChannels(ccdbRefUrl, badChannelType, *itStartTS, false); + bv2.insert(bv2.end(), bv.begin(), bv.end()); + uploadBadChannels(ccdbUrl, badChannelType, *itStartTS, *itStopTS, bv2, false); + } + } else { + std::cout << "invalid response (must be a, o or u) --> abort\n"; + exit(3); + } + } } + return 0; } From 6d6ac031defbaa0142f9aff841bda38f35aa4836 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 1 Aug 2024 14:30:14 +0200 Subject: [PATCH 0046/2205] Flow mapper tool: improve handling of input objects (#13320) --- Generators/include/Generators/FlowMapper.h | 8 +------- Generators/src/FlowMapper.cxx | 19 +++++-------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/Generators/include/Generators/FlowMapper.h b/Generators/include/Generators/FlowMapper.h index ede2ccea0bebb..c0635defd767d 100644 --- a/Generators/include/Generators/FlowMapper.h +++ b/Generators/include/Generators/FlowMapper.h @@ -45,14 +45,11 @@ class FlowMapper // Constructor FlowMapper(); - void Setv2VsPt(TH1D hv2VsPtProvided); - void SetEccVsB(TH1D hEccVsBProvided); - void SetNBinsPhi(long mBinsPhiProvided) { mBinsPhi = mBinsPhiProvided; }; void SetPrecision(long mPrecisionProvided) { mPrecision = mPrecisionProvided; }; void SetDerivative(long mDerivativeProvided) { mDerivative = mDerivativeProvided; }; - void CreateLUT(); // to be called if all is set + void CreateLUT(TH1D* mhv2vsPt, TH1D* mhEccVsB); Double_t MapPhi(Double_t lPhiInput, Double_t b, Double_t pt); @@ -60,9 +57,6 @@ class FlowMapper double mPrecision = 1e-6; // precision threshold for numerical inversion success double mDerivative = 1e-4; // delta-X for derivative calculation - std::unique_ptr mhv2vsPt; // input v2 vs pT from measurement - std::unique_ptr mhEccVsB; // ecc vs B (from Glauber MC or elsewhere) - // Cumulative function to be inverted std::unique_ptr mCumulative; diff --git a/Generators/src/FlowMapper.cxx b/Generators/src/FlowMapper.cxx index 7cfeb6bbe3d94..d3d84cf34bd0b 100644 --- a/Generators/src/FlowMapper.cxx +++ b/Generators/src/FlowMapper.cxx @@ -30,24 +30,14 @@ FlowMapper::FlowMapper() mBinsPhi = 4000; // a first guess } -void FlowMapper::Setv2VsPt(TH1D hv2VsPtProvided) -{ - // Sets the v2 vs pT to be used. - mhv2vsPt = std::make_unique(hv2VsPtProvided); -} -void FlowMapper::SetEccVsB(TH1D hEccVsBProvided) -{ - // Sets the v2 vs pT to be used. - mhEccVsB = std::make_unique(hEccVsBProvided); -} -void FlowMapper::CreateLUT() +void FlowMapper::CreateLUT(TH1D* mhv2vsPt, TH1D* mhEccVsB) { if (!mhv2vsPt) { - LOG(fatal) << "You did not specify a v2 vs pT histogram!"; + LOG(fatal) << "You did not specify a valid v2 vs pT histogram!"; return; } if (!mhEccVsB) { - LOG(fatal) << "You did not specify an ecc vs B histogram!"; + LOG(fatal) << "You did not specify a valid ecc vs B histogram!"; return; } LOG(info) << "Proceeding to creating a look-up table..."; @@ -71,6 +61,7 @@ void FlowMapper::CreateLUT() // std::make_unique("hSign", "Sign of electric charge;charge sign", 3, -1.5, 1.5); mhLUT = std::make_unique("mhLUT", "", nbinsB, binsB.data(), nbinsPt, binsPt.data(), nbinsPhi, binsPhi.data()); + mhLUT->SetDirectory(nullptr); // just in case context is incorrect // loop over each centrality (b) bin for (int ic = 0; ic < nbinsB; ic++) { @@ -147,4 +138,4 @@ Double_t FlowMapper::MapPhi(Double_t lPhiInput, Double_t b, Double_t pt) } /* namespace eventgen */ } /* namespace o2 */ -ClassImp(o2::eventgen::FlowMapper); \ No newline at end of file +ClassImp(o2::eventgen::FlowMapper); From deff6cedd15064cffcdc17b9661019a1effaa5ba Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 30 Jul 2024 17:56:47 +0200 Subject: [PATCH 0047/2205] GPU: Code simplification working around ROCm compiler problems --- GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx index 8945f8bef889c..fe3157bfae3ae 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx @@ -217,12 +217,11 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in bool lastSide = trackClusters[tracks[i].FirstClusterRef()].slice < MAXSECTOR / 2; float delta = 0.f; for (unsigned int iCl = 1; iCl < tracks[i].NClusters(); iCl++) { - if (lastSide ^ (trackClusters[tracks[i].FirstClusterRef() + iCl].slice < MAXSECTOR / 2)) { - auto& cacl1 = trackClusters[tracks[i].FirstClusterRef() + iCl]; - auto& cacl2 = trackClusters[tracks[i].FirstClusterRef() + iCl - 1]; + auto& cacl1 = trackClusters[tracks[i].FirstClusterRef() + iCl]; + if (lastSide ^ (cacl1.slice < MAXSECTOR / 2)) { auto& cl1 = clusters->clustersLinear[cacl1.num]; - auto& cl2 = clusters->clustersLinear[cacl2.num]; - delta = fabs(cl1.getTime() - cl2.getTime()) * 0.5f; + auto& cl2 = clusters->clustersLinear[trackClusters[tracks[i].FirstClusterRef() + iCl - 1].num]; + delta = CAMath::Abs(cl1.getTime() - cl2.getTime()) * 0.5f; if (delta < MinDelta) { delta = MinDelta; } From 05f14570393f39a592eaf2dc8e7a1d70649a4488 Mon Sep 17 00:00:00 2001 From: Joshua Koenig Date: Fri, 2 Aug 2024 15:04:56 +0200 Subject: [PATCH 0048/2205] [EMCAL-1135] Throw exception in case of to large starttime for TRU channel (#13326) - A case was found where the starttime was larger than the maximum possible bunch length of a TRU channel - For REC channel, the maximum length is 15, while for TRU channel, it is 14. - A possible bit-flip could cause a FEC channel to be flagged as TRU channel, however if that channel than has a starttime of 14, it will write into unallocated memory as it exceeds the length of the vector - Added an exception and implemented a unit test for the exception Co-authored-by: jokonig --- .../include/EMCALBase/TRUDecodingErrors.h | 60 +++++++++++++++++++ .../reconstruction/src/FastORTimeSeries.cxx | 5 +- .../test/testFastORTimeSeries.cxx | 7 +++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h diff --git a/Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h b/Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h new file mode 100644 index 0000000000000..a4a0d5d4d8584 --- /dev/null +++ b/Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h @@ -0,0 +1,60 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ALICEO2_EMCAL_TRUDECODINGERRORS_H +#define ALICEO2_EMCAL_TRUDECODINGERRORS_H + +#include +#include + +namespace o2 +{ + +namespace emcal +{ + +/// \class FastOrStartTimeInvalidException +/// \brief Handling of error if starttime is to large (>=14). This is most likely caused by a corrupted channel header where a FEC channel is identified as a TRU channel +/// \ingroup EMCALbase +class FastOrStartTimeInvalidException : public std::exception +{ + public: + /// \brief Constructor + /// \param l0size Size of the L0 patch + FastOrStartTimeInvalidException(unsigned int time) : std::exception(), mErrorMessage(), mStartTime(time) + { + mErrorMessage = "FastOr starttime invalid: " + std::to_string(time); + } + + /// \brief Destructor + ~FastOrStartTimeInvalidException() noexcept final = default; + + /// \brief Access to error message + /// \return Error message + const char* what() const noexcept final + { + return mErrorMessage.data(); + } + + /// \brief Get the size of the L0 patch + /// \return Size of the L0 patch + unsigned int getStartTime() const noexcept { return mStartTime; } + + private: + std::string mErrorMessage; ///< Buffer for error message + int mStartTime; ///< Size of the L0 patch +}; + +} // namespace emcal + +} // namespace o2 + +#endif // ALICEO2_EMCAL_TRUDECODINGERRORS_H \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx b/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx index d23d982047f2b..9146d9ed92b96 100644 --- a/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx +++ b/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx @@ -12,12 +12,15 @@ #include #include #include "EMCALReconstruction/FastORTimeSeries.h" +#include "EMCALBase/TRUDecodingErrors.h" using namespace o2::emcal; void FastORTimeSeries::fillReversed(const gsl::span samples, uint8_t starttime) { - + if (starttime >= 14) { + throw FastOrStartTimeInvalidException(starttime); + } for (std::size_t isample = 0; isample < samples.size(); isample++) { mTimeSamples[starttime - isample] = samples[isample]; } diff --git a/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx b/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx index 3b1dfcb4c240e..5f512fc287967 100644 --- a/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx +++ b/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx @@ -16,6 +16,7 @@ #include #include #include +#include "EMCALBase/TRUDecodingErrors.h" namespace o2 { @@ -139,6 +140,12 @@ BOOST_AUTO_TEST_CASE(FastORTimeSeries_test) BOOST_CHECK_EQUAL_COLLECTIONS(adcs.begin(), adcs.end(), reference.begin(), reference.end()); BOOST_CHECK_EQUAL(testcase.calculateL1TimeSum(8), calculateTimesum(reference, 8)); } + + // test case where a normal FEC channel is identified as TRU channel. FEC channel can have lenght of 15 and would therefore cause an overflow in the FEC channel (max lenght 14) + auto starttime = 14; + auto bunch = generateSmallBunch(14); + BOOST_CHECK_EXCEPTION(FastORTimeSeries(14, bunch, starttime), FastOrStartTimeInvalidException, [starttime](const FastOrStartTimeInvalidException& e) { return e.getStartTime() == starttime; }); + return; // test adding 2 bunches From 8234357cb2e2fa2bf8aa53629a4b7fe5cc6732b1 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi Date: Fri, 2 Aug 2024 11:47:50 +0200 Subject: [PATCH 0049/2205] [StrangenessTracking] Pass ITS cluster info to AO2Ds --- .../ReconstructionDataFormats/StrangeTrack.h | 43 ++++++++++++++++++- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 7 +-- .../src/StrangenessTracker.cxx | 15 +++---- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/StrangeTrack.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/StrangeTrack.h index c2af20fc93fa2..12e376f10f3d8 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/StrangeTrack.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/StrangeTrack.h @@ -35,10 +35,49 @@ struct StrangeTrack { unsigned int mDecayRef = -1; std::array mDecayVtx; std::array mDecayMom; - std::array mMasses; // V0: hypertriton and hyperhydrongen4, cascade: Xi and Omega. - float mITSClusSize; + std::array mMasses; // V0: hypertriton and hyperhydrongen4, cascade: Xi and Omega. + unsigned int mClusterSizes = 0u; // same encoding used for the ITS track float mMatchChi2; float mTopoChi2; + + void setClusterSize(int l, int size) + { + if (l >= 8) { + return; + } + if (size > 15) { + size = 15; + } + mClusterSizes &= ~(0xf << (l * 4)); + mClusterSizes |= (size << (l * 4)); + } + + int getClusterSize(int l) const + { + if (l >= 7) { + return 0; + } + return (mClusterSizes >> (l * 4)) & 0xf; + } + + int getClusterSizes() const + { + return mClusterSizes; + } + + float getAverageClusterSize() const + { + int nClusters = 0; + int nClustersSize = 0; + for (int i = 0; i < 7; ++i) { + int size = getClusterSize(i); + if (size > 0) { + nClustersSize += size; + nClusters++; + } + } + return nClusters > 0 ? static_cast(nClustersSize) / nClusters : 0.f; + } }; } // namespace dataformats diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 9c67212cb1a1f..5d821fa3a971c 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -545,6 +545,7 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, auto& sTrk = sTracks[collStrTrk.second]; TrackExtraInfo extraInfo; extraInfo.itsChi2NCl = sTrk.mTopoChi2; // TODO: this is the total chi2 of adding the ITS clusters, the topology chi2 meaning might change in the future + extraInfo.itsClusterSizes = sTrk.getClusterSizes(); addToTracksTable(tracksCursor, tracksCovCursor, sTrk.mMother, collisionID, aod::track::StrangeTrack); addToTracksExtraTable(tracksExtraCursor, extraInfo); mStrTrkIndices[collStrTrk.second] = mTableTrID; @@ -1378,7 +1379,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack sTrk.mMasses[1], sTrk.mMatchChi2, sTrk.mTopoChi2, - sTrk.mITSClusSize); + sTrk.getAverageClusterSize()); } else if (sTrk.mPartType == dataformats::kStrkCascade) { cascCurs(mStrTrkIndices[sTrkID++], itsTableIdx, @@ -1390,7 +1391,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack sTrk.mMasses[1], sTrk.mMatchChi2, sTrk.mTopoChi2, - sTrk.mITSClusSize); + sTrk.getAverageClusterSize()); } else { d3BodyCurs(mStrTrkIndices[sTrkID++], itsTableIdx, @@ -1402,7 +1403,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack sTrk.mMasses[1], sTrk.mMatchChi2, sTrk.mTopoChi2, - sTrk.mITSClusSize); + sTrk.getAverageClusterSize()); } } } diff --git a/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx b/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx index fe8f15971ac72..d5d4951b1c707 100644 --- a/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx +++ b/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx @@ -351,7 +351,6 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR, StrangeTrack& strang auto nMinClusMother = trackClusters.size() < 4 ? 2 : mStrParams->mMinMotherClus; std::vector motherClusters; - std::vector motherClusSizes; std::array nAttachments; nAttachments.fill(-1); // fill arr with -1 @@ -365,14 +364,15 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR, StrangeTrack& strang double clusRad = sqrt(clus.getX() * clus.getX() - clus.getY() * clus.getY()); auto diffR = decayR - clusRad; auto relDiffR = diffR / decayR; + auto lay = geom->getLayer(clus.getSensorID()); // Look for the Mother if the Decay radius allows for it, within a tolerance LOG(debug) << "decayR: " << decayR << ", diffR: " << diffR << ", clus rad: " << clusRad << ", radTol: " << radTol; if (relDiffR > -radTol) { - LOG(debug) << "Try to attach cluster to Mother, layer: " << geom->getLayer(clus.getSensorID()); + LOG(debug) << "Try to attach cluster to Mother, layer: " << lay; if (updateTrack(clus, strangeTrack.mMother)) { motherClusters.push_back(clus); - motherClusSizes.push_back(compClus); - nAttachments[geom->getLayer(clus.getSensorID())] = 0; + strangeTrack.setClusterSize(lay, compClus); + nAttachments[lay] = 0; isMotherUpdated = true; nUpdates++; LOG(debug) << "Cluster attached to Mother"; @@ -383,11 +383,11 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR, StrangeTrack& strang // if Mother is not found, check for V0 daughters compatibility if (relDiffR < radTol && !isMotherUpdated) { bool isDauUpdated = false; - LOG(debug) << "Try to attach cluster to Daughters, layer: " << geom->getLayer(clus.getSensorID()); + LOG(debug) << "Try to attach cluster to Daughters, layer: " << lay; for (int iDau{0}; iDau < daughterTracks.size(); iDau++) { auto& dauTrack = daughterTracks[iDau]; if (updateTrack(clus, dauTrack)) { - nAttachments[geom->getLayer(clus.getSensorID())] = iDau + 1; + nAttachments[lay] = iDau + 1; isDauUpdated = true; break; } @@ -419,9 +419,6 @@ bool StrangenessTracker::matchDecayToITStrack(float decayR, StrangeTrack& strang } } - // compute mother average cluster size - strangeTrack.mITSClusSize = float(std::accumulate(motherClusSizes.begin(), motherClusSizes.end(), 0)) / motherClusSizes.size(); - LOG(debug) << "Inward-outward refit finished, starting final topology refit"; // final Topology refit From 300fa70293d63f8c4f17a0900e7996e326dc19e7 Mon Sep 17 00:00:00 2001 From: Julian Myrcha Date: Thu, 1 Aug 2024 21:38:54 +0200 Subject: [PATCH 0050/2205] o2-eve: fixes (event creation time, GID from old root files) --- .../ConfigurationManager.h | 2 +- .../EventVisualisationBase/DirectoryLoader.h | 6 +- EventVisualisation/Base/src/DataSource.cxx | 2 +- .../Base/src/DirectoryLoader.cxx | 17 ++-- .../VisualisationEventOpenGLSerializer.h | 2 +- .../VisualisationEventOpenGLSerializer.cxx | 78 ++++++++++++------- .../src/VisualisationEventSerializer.cxx | 15 +++- 7 files changed, 73 insertions(+), 49 deletions(-) diff --git a/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h b/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h index 9fd5a16ea8112..c24c553511e16 100644 --- a/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h +++ b/EventVisualisation/Base/include/EventVisualisationBase/ConfigurationManager.h @@ -25,7 +25,7 @@ namespace o2 namespace event_visualisation { /// Version of the software -const static int o2_eve_version = 171; +const static int o2_eve_version = 172; /// Configuration Manager allows an easy access to the config file. /// diff --git a/EventVisualisation/Base/include/EventVisualisationBase/DirectoryLoader.h b/EventVisualisation/Base/include/EventVisualisationBase/DirectoryLoader.h index d361e60927526..383bbdfa01cdb 100644 --- a/EventVisualisation/Base/include/EventVisualisationBase/DirectoryLoader.h +++ b/EventVisualisation/Base/include/EventVisualisationBase/DirectoryLoader.h @@ -28,8 +28,8 @@ namespace event_visualisation class DirectoryLoader { private: - static int getNumberOfFiles(std::string& path, std::vector& ext); - static std::string getLatestFile(std::string& path, std::vector& ext); + static int getNumberOfFiles(const std::string& path, std::vector& ext); + static std::string getLatestFile(const std::string& path, std::vector& ext); public: static std::deque load(const std::string& path, const std::string& marker, const std::vector& ext); @@ -37,7 +37,7 @@ class DirectoryLoader static std::vector allFolders(const std::string& location); static bool canCreateNextFile(const std::vector& paths, const std::string& marker, const std::vector& ext, long long millisec, long capacityAllowed); static void reduceNumberOfFiles(const std::string& path, const std::deque& files, std::size_t filesInFolder); - static void removeOldestFiles(std::string& path, std::vector& ext, int remaining); + static void removeOldestFiles(const std::string& path, std::vector& ext, int remaining); }; } // namespace event_visualisation diff --git a/EventVisualisation/Base/src/DataSource.cxx b/EventVisualisation/Base/src/DataSource.cxx index 12918f4d59cd5..9e16c6f0fd169 100644 --- a/EventVisualisation/Base/src/DataSource.cxx +++ b/EventVisualisation/Base/src/DataSource.cxx @@ -24,7 +24,7 @@ namespace o2::event_visualisation std::string DataSource::getCreationTimeAsString() const { char buffer[90]; - time_t time = this->mCreationTime; + time_t time = this->mCreationTime / 1000; const char* format = "%a %b %-d %H:%M:%S %Y"; struct tm* timeinfo = localtime(&time); strftime(buffer, sizeof(buffer), format, timeinfo); diff --git a/EventVisualisation/Base/src/DirectoryLoader.cxx b/EventVisualisation/Base/src/DirectoryLoader.cxx index 041fa49e79b99..1b0135428806f 100644 --- a/EventVisualisation/Base/src/DirectoryLoader.cxx +++ b/EventVisualisation/Base/src/DirectoryLoader.cxx @@ -36,7 +36,7 @@ deque DirectoryLoader::load(const std::string& path, const std::string& } // comparison with safety if marker not in the filename (-1+1 gives 0) std::sort(result.begin(), result.end(), - [marker](std::string a, std::string b) { + [marker](const std::string& a, const std::string& b) { return a.substr(a.find_first_of(marker) + 1) < b.substr(b.find_first_of(marker) + 1); }); @@ -118,7 +118,7 @@ void DirectoryLoader::reduceNumberOfFiles(const std::string& path, const std::de if (filesInFolder == -1) { return; // do not reduce } - int items = files.size() - std::min(files.size(), filesInFolder); + const auto items = files.size() - std::min(files.size(), filesInFolder); for (int i = 0; i < items; i++) { std::remove((path + "/" + files[i]).c_str()); // delete file } @@ -132,7 +132,7 @@ std::time_t to_time_t(TP tp) return system_clock::to_time_t(sctp); } -int DirectoryLoader::getNumberOfFiles(std::string& path, std::vector& ext) +int DirectoryLoader::getNumberOfFiles(const std::string& path, std::vector& ext) { int res = 0; for (const auto& entry : std::filesystem::directory_iterator(path)) { @@ -142,24 +142,23 @@ int DirectoryLoader::getNumberOfFiles(std::string& path, std::vector& ext) +std::string DirectoryLoader::getLatestFile(const std::string& path, std::vector& ext) { std::string oldest_file_name = ""; std::time_t oldest_file_time = LONG_MAX; for (const auto& entry : std::filesystem::directory_iterator(path)) { if (std::find(ext.begin(), ext.end(), entry.path().extension()) != ext.end()) { - auto file_time = entry.last_write_time(); - std::time_t tt = to_time_t(file_time); - if (tt < oldest_file_time) { + const auto file_time = entry.last_write_time(); + if (const std::time_t tt = to_time_t(file_time); tt < oldest_file_time) { oldest_file_time = tt; - oldest_file_name = entry.path().filename(); + oldest_file_name = entry.path().filename().string(); } } } return oldest_file_name; } -void DirectoryLoader::removeOldestFiles(std::string& path, std::vector& ext, const int remaining) +void DirectoryLoader::removeOldestFiles(const std::string& path, std::vector& ext, const int remaining) { while (getNumberOfFiles(path, ext) > remaining) { LOGF(info, "removing oldest file in folder: %s : %s", path, getLatestFile(path, ext)); diff --git a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h index 4730cc75f1c64..3e6d3809cb709 100644 --- a/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h +++ b/EventVisualisation/DataConverter/include/EventVisualisationDataConverter/VisualisationEventOpenGLSerializer.h @@ -33,7 +33,7 @@ class VisualisationEventOpenGLSerializer : public VisualisationEventSerializer static float* asFloat(void* chunk) { return (float*)((char*)chunk + 8); } static unsigned char* asByte(void* chunk) { return (unsigned char*)((char*)chunk + 8); } static signed char* asSignedByte(void* chunk) { return (signed char*)((char*)chunk + 8); } - unsigned chunkSize(void* chunk); + static unsigned chunkSize(void* chunk); public: const std::string serializerName() const override { return std::string("VisualisationEventOpenGLSerializer"); } diff --git a/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx index a1c4ed7758f05..4c907eeda0291 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEventOpenGLSerializer.cxx @@ -21,15 +21,13 @@ #include #include -namespace o2 -{ -namespace event_visualisation +namespace o2::event_visualisation { enum Header : uint8_t { version, runNumber, - creationTime, + creationTimeUnused, firstTForbit, runType, trkMask, @@ -40,6 +38,8 @@ enum Header : uint8_t { emcCount, primaryVertex, tfCounter, + creationTimeLow, + creationTimeHigh, last // number of fields }; @@ -89,7 +89,7 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, "TPC-TOF", "TPC-TRD", "MFT-MCH", "ITS-TPC-TRD", "ITS-TPC-TOF", "TPC-TRD-TOF", "MFT-MCH-MID", "ITS-TPC-TRD-TOF", "ITS-AB", "CTP", "MCH-MID"}; std::ostringstream buf; - const auto SIGSIZE = 512; + constexpr auto SIGSIZE = 512; unsigned char data[SIGSIZE]; std::ofstream out(fileName, std::ios::out | std::ios::binary); // head --bytes 512 fileName.eve @@ -126,7 +126,10 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, const auto head = asUnsigned(chunkHEAD); head[Header::version] = event.mEveVersion; head[Header::runNumber] = event.getRunNumber(); - head[Header::creationTime] = event.getCreationTime(); + unsigned long creationTime = event.getCreationTime(); + head[Header::creationTimeLow] = creationTime; + head[Header::creationTimeHigh] = creationTime / (1L << 32); + ; head[Header::firstTForbit] = event.getFirstTForbit(); head[Header::runType] = event.getRunType(); head[Header::trkMask] = event.getTrkMask(); @@ -137,7 +140,7 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, head[Header::emcCount] = emcCount; head[Header::primaryVertex] = event.getPrimaryVertex(); head[Header::tfCounter] = event.getTfCounter(); - out.write((char*)chunkHEAD, chunkSize(chunkHEAD)); // <----1 HEAD + out.write(static_cast(chunkHEAD), chunkSize(chunkHEAD)); // <----1 HEAD free(chunkHEAD); } @@ -168,15 +171,15 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, celm[index] = track.getClusterCount(); index++; } - out.write((char*)chunkTTYP, chunkSize(chunkTTYP)); // <----2 TTYP + out.write(static_cast(chunkTTYP), chunkSize(chunkTTYP)); // <----2 TTYP free(chunkTTYP); - out.write((char*)chunkTELM, chunkSize(chunkTELM)); // <----3 TELM + out.write(static_cast(chunkTELM), chunkSize(chunkTELM)); // <----3 TELM free(chunkTELM); - out.write((char*)chunkCELM, chunkSize(chunkCELM)); // <----3 CELM + out.write(static_cast(chunkCELM), chunkSize(chunkCELM)); // <----3 CELM free(chunkCELM); - out.write((char*)chunkTGID, chunkSize(chunkTGID)); // <----3 GIND + out.write(static_cast(chunkTGID), chunkSize(chunkTGID)); // <----3 GIND free(chunkTGID); - out.write((char*)chunkTPID, chunkSize(chunkTPID)); // <----3 TPID (tracks pid) + out.write(static_cast(chunkTPID), chunkSize(chunkTPID)); // <----3 TPID (tracks pid) free(chunkTPID); } @@ -206,7 +209,7 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, for (const auto& track : event.getTracksSpan()) { time[tno] = track.getTime(); - crge[tno] = track.getCharge(); + crge[tno] = static_cast(track.getCharge()); tno++; sxyz[sxyzidx++] = track.getStartCoordinates()[0]; sxyz[sxyzidx++] = track.getStartCoordinates()[1]; @@ -227,17 +230,17 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, cxyz[cidx++] = track.getClustersSpan()[i].Z(); } } - out.write((char*)chunkTXYZ, chunkSize(chunkTXYZ)); // <----4 TXYZ + out.write(static_cast(chunkTXYZ), chunkSize(chunkTXYZ)); // <----4 TXYZ free(chunkTXYZ); - out.write((char*)chunkCXYZ, chunkSize(chunkCXYZ)); // <----4 CXYZ + out.write(static_cast(chunkCXYZ), chunkSize(chunkCXYZ)); // <----4 CXYZ free(chunkCXYZ); - out.write((char*)chunkTIME, chunkSize(chunkTIME)); // <----4 TIME + out.write(static_cast(chunkTIME), chunkSize(chunkTIME)); // <----4 TIME free(chunkTIME); - out.write((char*)chunkSXYZ, chunkSize(chunkSXYZ)); // <----4 SXYZ + out.write(static_cast(chunkSXYZ), chunkSize(chunkSXYZ)); // <----4 SXYZ free(chunkSXYZ); - out.write((char*)chunkCRGE, chunkSize(chunkCRGE)); // <----4 CRGE + out.write(static_cast(chunkCRGE), chunkSize(chunkCRGE)); // <----4 CRGE free(chunkCRGE); - out.write((char*)chunkATPE, chunkSize(chunkATPE)); // <----4 CRGE + out.write(static_cast(chunkATPE), chunkSize(chunkATPE)); // <----4 CRGE free(chunkATPE); } @@ -257,11 +260,11 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, uxyz[idx++] = c.Y(); uxyz[idx++] = c.Z(); } - out.write((char*)chunkUGID, chunkSize(chunkUGID)); // + out.write(static_cast(chunkUGID), chunkSize(chunkUGID)); // free(chunkUGID); - out.write((char*)chunkUTIM, chunkSize(chunkUTIM)); // + out.write(static_cast(chunkUTIM), chunkSize(chunkUTIM)); // free(chunkUTIM); - out.write((char*)chunkUXYZ, chunkSize(chunkUXYZ)); // + out.write(static_cast(chunkUXYZ), chunkSize(chunkUXYZ)); // free(chunkUXYZ); } @@ -309,7 +312,7 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, { const auto chunkFINE = createChunk(FINE, 0); - out.write((char*)chunkFINE, chunkSize(chunkFINE)); // <----5 FINE + out.write(static_cast(chunkFINE), chunkSize(chunkFINE)); // <----5 FINE free(chunkFINE); } out.close(); @@ -317,25 +320,40 @@ void VisualisationEventOpenGLSerializer::toFile(const VisualisationEvent& event, void* VisualisationEventOpenGLSerializer::createChunk(const char* lbl, unsigned size) { - auto result = (unsigned char*)calloc(4 * ((size + 3) / 4) + 8, 1); + const auto result = static_cast(calloc(4 * ((size + 3) / 4) + 8, 1)); result[0] = lbl[0]; result[1] = lbl[1]; result[2] = lbl[2]; result[3] = lbl[3]; - auto uResult = (unsigned*)&result[4]; + const auto uResult = (unsigned*)&result[4]; *uResult = 4 * ((size + 3) / 4); return result; } unsigned VisualisationEventOpenGLSerializer::chunkSize(void* chunk) { - auto uResult = (unsigned*)((char*)chunk + 4); + const auto uResult = (unsigned*)((char*)chunk + 4); return *uResult + 8; } -bool VisualisationEventOpenGLSerializer::fromFile(VisualisationEvent& event, std::string fileName) +long timestamp_from_filename(const std::string& s) { + const auto pos1 = s.find("tracks_"); + if (pos1 == std::string::npos) { + return 0; + } + const auto pos2 = s.find('_', pos1 + 7); + if (pos2 == std::string::npos) { + return 0; + } + std::string::size_type sz; // alias of size_t + const auto str_dec = s.substr(pos1 + 7, pos2 - pos1 - 7); + const long li_dec = std::strtol(str_dec.c_str(), nullptr, 10); + return li_dec; +} +bool VisualisationEventOpenGLSerializer::fromFile(VisualisationEvent& event, std::string fileName) +{ std::filesystem::path inputFilePath{fileName}; auto length = (long)std::filesystem::file_size(inputFilePath); if (length == 0) { @@ -389,7 +407,8 @@ bool VisualisationEventOpenGLSerializer::fromFile(VisualisationEvent& event, std auto head = words; event.mEveVersion = head[Header::version]; event.setRunNumber(head[Header::runNumber]); - event.setCreationTime(head[Header::creationTime]); + // event.setCreationTime(head[Header::creationTimeLow]+head[Header::creationTimeHigh]*(1L<<32)); + event.setCreationTime(timestamp_from_filename(fileName)); event.setFirstTForbit(head[Header::firstTForbit]); event.setRunType((parameters::GRPECS::RunType)head[Header::runType]); event.setTrkMask((int)head[Header::trkMask]); @@ -513,5 +532,4 @@ bool VisualisationEventOpenGLSerializer::fromFile(VisualisationEvent& event, std return false; } -} // namespace event_visualisation -} // namespace o2 +} // namespace o2::event_visualisation diff --git a/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx b/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx index 286be66f3891d..2c519d70bb7eb 100644 --- a/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx +++ b/EventVisualisation/DataConverter/src/VisualisationEventSerializer.cxx @@ -87,10 +87,17 @@ o2::dataformats::GlobalTrackID VisualisationEventSerializer::gidFromString(const {"ITSAB", 24}, // ITS AfterBurner tracklets {"CTP", 25}}; const auto first = gid.find('/'); - const auto second = gid.find('/', first + 1); - auto source = sources[gid.substr(1, first - 1)]; - auto index = std::stoi(gid.substr(first + 1, second - 1)); - auto flags = std::stoi(gid.substr(second + 1, gid.size() - 1)); + int source = 0; + int index = 0; + int flags = 0; + if (first == -1) { + source = sources[gid]; + } else { + const auto second = gid.find('/', first + 1); + source = sources[gid.substr(1, first - 1)]; + index = std::stoi(gid.substr(first + 1, second - 1)); + flags = std::stoi(gid.substr(second + 1, gid.size() - 1)); + } return index + source * (1 << 25) + flags * (1 << 30); } From dace8c4156929021d035b9792c3438596e6f797d Mon Sep 17 00:00:00 2001 From: Kirill Naumov Date: Fri, 26 Jul 2024 04:07:13 +0200 Subject: [PATCH 0051/2205] ITS: Added structure for ITS data simulator The new binary will be used to simulate APLIDE chip data to be used to search for potential errors in the decoder's operation. --- .../ITSMFT/ITS/simulation/CMakeLists.txt | 18 ++- .../include/ITSSimulation/ITSDataSimulator.h | 54 +++++++ .../ITS/simulation/src/ITSDataSimulator.cxx | 147 ++++++++++++++++++ 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSDataSimulator.h create mode 100644 Detectors/ITSMFT/ITS/simulation/src/ITSDataSimulator.cxx diff --git a/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt b/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt index 2406390944f06..78a93bdc7232d 100644 --- a/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt @@ -12,12 +12,13 @@ o2_add_library(ITSSimulation SOURCES src/V11Geometry.cxx src/V1Layer.cxx src/V3Layer.cxx src/Detector.cxx src/V3Services.cxx src/V3Cage.cxx - src/DescriptorInnerBarrelITS2.cxx + src/DescriptorInnerBarrelITS2.cxx src/ITSDataSimulator.cxx PUBLIC_LINK_LIBRARIES O2::ITSBase O2::ITSMFTSimulation ROOT::Physics $<$:O2::ITS3Base> $<$:O2::ITS3Simulation>) o2_target_root_dictionary(ITSSimulation HEADERS include/ITSSimulation/Detector.h + include/ITSSimulation/ITSDataSimulator.h include/ITSSimulation/V1Layer.h include/ITSSimulation/V3Layer.h include/ITSSimulation/V3Cage.h @@ -40,8 +41,23 @@ o2_add_executable(digi2raw O2::CommonUtils Boost::program_options) +o2_add_executable(sim-data + COMPONENT_NAME its + TARGETVARNAME itssimdata_exe + SOURCES src/ITSDataSimulator.cxx + PUBLIC_LINK_LIBRARIES O2::ITSMFTReconstruction + O2::DataFormatsITSMFT + O2::ITSMFTBase + O2::ITSMFTSimulation + O2::DetectorsRaw + O2::DetectorsCommonDataFormats + O2::CommonUtils + O2::ITSSimulation + Boost::program_options) + if(NOT APPLE) set_property(TARGET ${itsdigi2raw_exe} PROPERTY LINK_WHAT_YOU_USE ON) + set_property(TARGET ${itssimData_exe} PROPERTY LINK_WHAT_YOU_USE ON) endif() diff --git a/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSDataSimulator.h b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSDataSimulator.h new file mode 100644 index 0000000000000..c8bb9becbd2da --- /dev/null +++ b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSDataSimulator.h @@ -0,0 +1,54 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ITSDataSimulator.h +/// \brief Infrastructure to simulate ALPIDE chip data. +/// \author knaumov@cern.ch + +#include "ITSMFTBase/SegmentationAlpide.h" +#include "ITSMFTReconstruction/PixelData.h" + +namespace o2 +{ +namespace itsmft +{ + +class ITSDataSimulator +{ + public: + const static uint32_t MaxChipID = 24119; + const static uint32_t MaxPixelsPerChip = + SegmentationAlpide::NRows * SegmentationAlpide::NCols; + + ITSDataSimulator(int32_t seed, uint32_t numberOfChips, + uint32_t maxPixelsPerChip, bool doDigits, bool doErrors) + : mSeed(seed), mNumberOfChips(numberOfChips), mMaxPixelsPerChip(maxPixelsPerChip), mDoDigits(doDigits), mDoErrors(doErrors) + { + srand(mSeed); + } + + ~ITSDataSimulator() = default; + + // Simulate fired pixels for a chip + std::vector generateChipData(); + + void simulate(); + + private: + int32_t mSeed; + uint32_t mMaxPixelsPerChip; + uint32_t mNumberOfChips; + bool mDoDigits; + bool mDoErrors; +}; + +} // namespace itsmft +} // namespace o2 diff --git a/Detectors/ITSMFT/ITS/simulation/src/ITSDataSimulator.cxx b/Detectors/ITSMFT/ITS/simulation/src/ITSDataSimulator.cxx new file mode 100644 index 0000000000000..9f7ba12a3c677 --- /dev/null +++ b/Detectors/ITSMFT/ITS/simulation/src/ITSDataSimulator.cxx @@ -0,0 +1,147 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ITSDataSimulator.cxx +/// \author knaumov@cern.ch + +#include "DataFormatsITSMFT/Digit.h" +#include "ITSSimulation/ITSDataSimulator.h" + +#include +#include +#include + +namespace bpo = boost::program_options; +using namespace o2::itsmft; + +std::vector ITSDataSimulator::generateChipData() +{ + std::vector vec; + uint32_t numOfPixels = rand() % mMaxPixelsPerChip; + while (vec.size() < numOfPixels) { + int row = rand() % SegmentationAlpide::NRows; + int col = rand() % SegmentationAlpide::NCols; + PixelData pixel(row, col); + vec.push_back(pixel); + } + std::sort(vec.begin(), vec.end()); + if (!mDoErrors) { + // If errors are disabled, chips should not contain + // pixels fired multiple times + auto iter = std::unique(vec.begin(), vec.end()); + vec.erase(iter, vec.end()); + } + return vec; +} + +void ITSDataSimulator::simulate() +{ + // Generate the chip data + std::map> chipData; + while (chipData.size() < mNumberOfChips) { + uint32_t chipID = rand() % MaxChipID; + if (!chipData.contains(chipID)) { + chipData.emplace(chipID, generateChipData()); + } + } + + if (mDoDigits) { + std::vector digVec; + for (auto const& chip : chipData) { + uint32_t chipID = chip.first; + const std::vector& pixels = chip.second; + for (auto pixel : pixels) { + Digit dig(chipID, pixel.getRow(), pixel.getCol()); + digVec.push_back(dig); + } + } + // TODO: Save the digits to a file + } +} + +int main(int argc, char** argv) +{ + bpo::variables_map vm; + bpo::options_description opt_general("Usage:\n " + std::string(argv[0]) + + "Simulates ALPIDE data\n"); + bpo::options_description opt_hidden(""); + bpo::options_description opt_all; + bpo::positional_options_description opt_pos; + + try { + auto add_option = opt_general.add_options(); + add_option("help,h", "Print this help message"); + add_option("verbosity,v", bpo::value()->default_value(0), + "verbosity level [0 = no output]"); + add_option("digits", + bpo::value()->default_value(false)->implicit_value(true), + "generate the data in the digits format"); + add_option("enable-errors", + bpo::value()->default_value(false)->implicit_value(true), + "enable additon of errors to the raw data"); + add_option("seed", bpo::value()->default_value(0), + "random seed for data generation"); + add_option( + "max-pixels-per-chip", bpo::value()->default_value(100), + ("maximum number of fired pixels per chip (0 - " + + std::to_string(ITSDataSimulator::MaxPixelsPerChip) + + ")") + .c_str()); + add_option("number-of-chip", bpo::value()->default_value(10), + ("number of chips to be present in the data (0 - " + + std::to_string(ITSDataSimulator::MaxChipID) + ")") + .c_str()); + add_option("configKeyValues", bpo::value()->default_value(""), + "comma-separated configKeyValues"); + + opt_all.add(opt_general).add(opt_hidden); + bpo::store(bpo::command_line_parser(argc, argv) + .options(opt_all) + .positional(opt_pos) + .run(), + vm); + + if (vm.count("help")) { + std::cout << opt_general << std::endl; + exit(0); + } + + if (vm["max-pixels-per-chip"].as() > + ITSDataSimulator::MaxPixelsPerChip) { + std::cerr << "Invalid max pixels per chip, valid range (0, " + << ITSDataSimulator::MaxPixelsPerChip << ")" << std::endl; + exit(1); + } + + if (vm["number-of-chip"].as() > ITSDataSimulator::MaxChipID) { + std::cerr << "Invalid number of chips, valid range (0, " + << ITSDataSimulator::MaxChipID << ")" << std::endl; + exit(1); + } + + bpo::notify(vm); + } catch (bpo::error& e) { + std::cerr << "ERROR: " << e.what() << std::endl + << std::endl; + std::cerr << opt_general << std::endl; + exit(1); + } catch (std::exception& e) { + std::cerr << e.what() << ", application will now exit" << std::endl; + exit(2); + } + + ITSDataSimulator simulator( + vm["seed"].as(), vm["number-of-chip"].as(), + vm["max-pixels-per-chip"].as(), vm["digits"].as(), + vm["enable-errors"].as()); + + simulator.simulate(); +} From 64166fab4ecdc1785caf3be0418c3880cdc5ac55 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 3 Aug 2024 12:05:10 +0200 Subject: [PATCH 0052/2205] Add missing include --- GPU/TPCFastTransformation/Spline1DSpec.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/GPU/TPCFastTransformation/Spline1DSpec.cxx b/GPU/TPCFastTransformation/Spline1DSpec.cxx index 7febf3c09b580..25f25cb4e7a54 100644 --- a/GPU/TPCFastTransformation/Spline1DSpec.cxx +++ b/GPU/TPCFastTransformation/Spline1DSpec.cxx @@ -18,6 +18,7 @@ #if !defined(GPUCA_GPUCODE) #include +#include #endif #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation From 9ad8facf43055c6674f1e7e7bea87a1e172dce3a Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Mon, 5 Aug 2024 10:42:34 +0200 Subject: [PATCH 0053/2205] Data Model change: bump McCollisions to 001 (#13321) * Bump McCollisions to 001 * Fill McCollisions cursor, version 001 * Standalone producer cursor fill change * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot --- Detectors/AOD/src/AODMcProducerHelpers.cxx | 5 ++--- Detectors/AOD/src/StandaloneAODProducer.cxx | 2 +- Framework/Core/include/Framework/AnalysisDataModel.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Detectors/AOD/src/AODMcProducerHelpers.cxx b/Detectors/AOD/src/AODMcProducerHelpers.cxx index 3ce07a312713f..1a01f103dcfdb 100644 --- a/Detectors/AOD/src/AODMcProducerHelpers.cxx +++ b/Detectors/AOD/src/AODMcProducerHelpers.cxx @@ -65,9 +65,8 @@ short updateMCCollisions(const CollisionCursor& cursor, truncateFloatFraction(header.GetZ(), mask), truncateFloatFraction(time, mask), truncateFloatFraction(weight, mask), - header.GetB() /*, - getEventInfo(header, Key::planeAngle, header.GetRotZ())*/ - ); + header.GetB(), + getEventInfo(header, Key::planeAngle, header.GetRotZ())); return encodedGeneratorId; } //-------------------------------------------------------------------- diff --git a/Detectors/AOD/src/StandaloneAODProducer.cxx b/Detectors/AOD/src/StandaloneAODProducer.cxx index fe9b147804c03..a9f5a09141d8c 100644 --- a/Detectors/AOD/src/StandaloneAODProducer.cxx +++ b/Detectors/AOD/src/StandaloneAODProducer.cxx @@ -86,7 +86,7 @@ void fillMCollisionTable(o2::steer::MCKinematicsReader const& mcreader) // mccollision::PosX, mccollision::PosY, mccollision::PosZ, mccollision::T, mccollision::Weight, // mccollision::ImpactParameter); - mcCollCursor(0, 0 /*bcID*/, 0 /*genID*/, header.GetX(), header.GetY(), header.GetZ(), time, 1. /*weight*/, header.GetB() /*, 0.0*/); + mcCollCursor(0, 0 /*bcID*/, 0 /*genID*/, header.GetX(), header.GetY(), header.GetZ(), time, 1. /*weight*/, header.GetB(), 0.0); index++; } diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 1b03cbb304c0b..26df12c008bee 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -1579,7 +1579,7 @@ DECLARE_SOA_TABLE_VERSIONED(McCollisions_001, "AOD", "MCCOLLISION", 1, //! MC co mccollision::GetSubGeneratorId, mccollision::GetSourceId); -using McCollisions = McCollisions_000; +using McCollisions = McCollisions_001; using McCollision = McCollisions::iterator; namespace mcparticle From 04570829bfbfa70314329a6f4990a283d0483805 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 30 Jul 2024 17:56:09 +0200 Subject: [PATCH 0054/2205] GPU CMake: Bugfix: fix hardcoded old llvm version in case of manually specified clang binary --- dependencies/FindO2GPU.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index 52d3276c2ec85..9e5bc6d3d06a9 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -177,7 +177,7 @@ if(ENABLE_OPENCL2) endif() if (GPUCA_OPENCL_CLANGBIN) set(LLVM_CLANG ${GPUCA_OPENCL_CLANGBIN}) - execute_process(COMMAND "which" "/usr/lib/llvm/15/bin/clang-15" OUTPUT_VARIABLE TMP_LLVM_SPIRV_PATH COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND "which" "${GPUCA_OPENCL_CLANGBIN}" OUTPUT_VARIABLE TMP_LLVM_SPIRV_PATH COMMAND_ERROR_IS_FATAL ANY) cmake_path(GET TMP_LLVM_SPIRV_PATH PARENT_PATH TMP_LLVM_SPIRV_PATH) find_program(LLVM_SPIRV llvm-spirv HINTS "${TMP_LLVM_SPIRV_PATH}") else() From 2cf3b47d49dad45cd08d294e352f08b6170435ca Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 5 Aug 2024 10:01:06 +0200 Subject: [PATCH 0055/2205] Fix compiler warnings --- .../DataCompression/GPUTPCDecompressionKernels.cxx | 6 +++--- GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index 7cad6b4377f92..7a58cad637514 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -30,7 +30,7 @@ GPUdii() void GPUTPCDecompressionKernels::ThreadclusterOffset[iSlice][iRow]; if (decompressor.mNativeClustersIndex[linearIndex] != 0) { diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 955b54645f6ad..af603035bd017 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -286,7 +286,7 @@ int GPUChainTracking::RunTPCDecompression() runKernel({GetGridAutoStep(inputStream, RecoStep::TPCDecompression), krnlRunRangeNone, &mEvents->init}, DecompressorShadow.mNativeClustersIndex, NSLICES * GPUCA_ROW_COUNT * sizeof(DecompressorShadow.mNativeClustersIndex[0])); std::exclusive_scan(cmprClsHost.nTrackClusters, cmprClsHost.nTrackClusters + cmprClsHost.nTracks, Decompressor.mAttachedClustersOffsets, 0u); // computing clusters offsets for first kernel int nStreams = doGPU ? mRec->NStreams() - 1 : 1; - for (unsigned int iStream = 0; iStream < nStreams; ++iStream) { + for (int iStream = 0; iStream < nStreams; ++iStream) { unsigned int startTrack = cmprClsHost.nTracks / nStreams * iStream; unsigned int endTrack = cmprClsHost.nTracks / nStreams * (iStream + 1) + (iStream < nStreams - 1 ? 0 : cmprClsHost.nTracks % nStreams); // index of last track (excluded from computation) unsigned int numTracks = endTrack - startTrack; From bf35985e40db836e8816742520e8a2bd12e4f9d3 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 5 Aug 2024 10:01:51 +0200 Subject: [PATCH 0056/2205] GPU CMake: Workaround for CMake adding old cmake library paths implicitly if we request an old GCC for CUDA --- dependencies/FindO2GPU.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index 9e5bc6d3d06a9..af7da049e0ff6 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -130,6 +130,9 @@ if(ENABLE_CUDA) if(CMAKE_CXX_FLAGS MATCHES "(^| )-Werror( |$)") set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Werror=cross-execution-space-call") endif() + if(GPUCA_CUDA_GCCBIN) + list(FILTER CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES EXCLUDE REGEX "^/usr/lib.*/gcc/") # Workaround, since CMake adds old GCC lib paths implicitly if we request that gcc for CUDA + endif() set(CUDA_ENABLED ON) message(STATUS "CUDA found (Version ${CMAKE_CUDA_COMPILER_VERSION})") From c19105802b967b640888633288d8594eb2ef89ad Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Tue, 6 Aug 2024 13:29:51 +0200 Subject: [PATCH 0057/2205] Ctpdev: counters to QCDB (#13350) * dev:scalers to qcdb * clang --- .../Detectors/CTP/src/Configuration.cxx | 28 ++++++------- .../include/CTPWorkflowScalers/RunManager.h | 7 +++- .../CTPWorkflowScalers/ctpCCDBManager.h | 9 +++- .../CTP/workflowScalers/src/RunManager.cxx | 15 ++++++- .../CTP/workflowScalers/src/ctp-proxy.cxx | 10 ++++- .../workflowScalers/src/ctpCCDBManager.cxx | 42 ++++++++++++++++++- 6 files changed, 87 insertions(+), 24 deletions(-) diff --git a/DataFormats/Detectors/CTP/src/Configuration.cxx b/DataFormats/Detectors/CTP/src/Configuration.cxx index c24e1a18c4718..57272d70ed9e3 100644 --- a/DataFormats/Detectors/CTP/src/Configuration.cxx +++ b/DataFormats/Detectors/CTP/src/Configuration.cxx @@ -510,8 +510,8 @@ int CTPConfiguration::processConfigurationLineRun3(std::string& line, int& level } int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& level, std::map>& descInputsIndex) { - LOG(info) << "Processing line"; - LOG(info) << "line:" << line << " lev:" << level; + LOG(debug) << "Processing line"; + LOG(debug) << "line:" << line << " lev:" << level; // std::vector tokens = o2::utils::Str::tokenize(line, ' '); size_t ntokens = tokens.size(); @@ -557,7 +557,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev level = UNKNOWN; } } - LOG(info) << "Level:" << level; + LOG(debug) << "Level:" << level; switch (level) { case VERSION: { break; @@ -585,7 +585,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev uint32_t index = std::stoul(tokens[2]); ctpinp.inputMask = (1ull << (index - 1)); mInputs.push_back(ctpinp); - LOG(info) << "Input:" << ctpinp.name << " index:" << index; + LOG(debug) << "Input:" << ctpinp.name << " index:" << index; break; } case MASKS: { @@ -596,7 +596,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev } bcmask.setBCmask(tokens); mBCMasks.push_back(bcmask); - LOG(info) << "BC mask added:" << bcmask.name; + LOG(debug) << "BC mask added:" << bcmask.name; break; } case GENS: { @@ -604,7 +604,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev gen.name = tokens[0]; gen.frequency = tokens[1]; mGenerators.push_back(gen); - LOG(info) << "Gen added:" << line; + LOG(debug) << "Gen added:" << line; break; } case DESCRIPTORS: { @@ -630,9 +630,9 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev o2::detectors::DetID det(detname.c_str()); if (isDetector(det)) { ctpdet.detID = det.getID(); - LOG(info) << "Detector found:" << det.getID() << " " << detname; + LOG(debug) << "Detector found:" << det.getID() << " " << detname; } else { - LOG(info) << "Unknown detectors:" << line; + LOG(error) << "Unknown detectors:" << line; } mDetectors.push_back(ctpdet); level = LTGitems; @@ -642,7 +642,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev if (ntokens == 1) { mDetectors.back().mode = tokens[0]; } - LOG(info) << "LTGitem:" << line; + LOG(debug) << "LTGitem:" << line; break; } case CLUSTER: { @@ -650,10 +650,10 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev try { cluster.hwMask = std::stoull(tokens[0]); } catch (...) { - LOG(info) << "Cluster syntax error:" << line; + LOG(error) << "Cluster syntax error:" << line; return level; } - LOG(info) << "Cluster:" << line; + LOG(debug) << "Cluster:" << line; cluster.name = tokens[2]; o2::detectors::DetID::mask_t mask; for (uint32_t item = 3; item < ntokens; item++) { @@ -680,10 +680,10 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev try { index = std::stoull(tokens[1]); } catch (...) { - LOG(info) << "Class syntax error:" << line; + LOG(error) << "Class syntax error:" << line; return level; } - LOG(info) << "Class:" << line; + LOG(debug) << "Class:" << line; CTPClass cls; cls.classMask = 1ull << index; cls.name = tokens[0]; @@ -716,7 +716,7 @@ int CTPConfiguration::processConfigurationLineRun3v2(std::string& line, int& lev break; } default: { - LOG(info) << "unknown line:" << line; + LOG(warning) << "unknown line:" << line; } } return 0; diff --git a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h index e40c30ee04931..0d624ecd8b892 100644 --- a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/RunManager.h @@ -38,6 +38,8 @@ struct CTPActiveRun { counters_t cntslast0; // last minus one read counters needed for overflow correction counters_t cntslast; // last read counters counters64_t overflows; + // QC + int qcwpcount = 0; }; class CTPRunManager : public ctpCCDBManager { @@ -53,6 +55,7 @@ class CTPRunManager : public ctpCCDBManager int loadScalerNames(); int getNRuns(); void setBKHost(std::string host) { mBKHost = host; }; + void setQCWritePeriod(int period) { mQCWritePeriod = period; }; uint64_t checkOverflow(uint32_t lcnt0, uint32_t lcnt1, uint64_t lcntcor); void printCounters(); @@ -67,8 +70,8 @@ class CTPRunManager : public ctpCCDBManager std::unique_ptr mBKClient; int mEOX = 0; // redundancy check int mNew = 1; // 1 - no CCDB: used for QC - - ClassDefNV(CTPRunManager, 6); + int mQCWritePeriod = 3; // Time in 10secs between two writes to QCCD + ClassDefNV(CTPRunManager, 7); }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h index ce8b17498e7ef..5fb6d3678f0ba 100644 --- a/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h +++ b/Detectors/CTP/workflowScalers/include/CTPWorkflowScalers/ctpCCDBManager.h @@ -25,22 +25,27 @@ class ctpCCDBManager public: ctpCCDBManager() = default; int saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, long timeStop); + int saveRunScalersToQCDB(CTPRunScalers& scalers, long timeStart, long timeStop); int saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart); static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run, bool& ok); static CTPConfiguration getConfigFromCCDB(long timestamp, std::string run); CTPRunScalers getScalersFromCCDB(long timestamp, std::string, bool& ok); void setCCDBPathConfig(std::string path) { mCCDBPathCTPConfig = path; }; void setCCDBPathScalers(std::string path) { mCCDBPathCTPScalers = path; }; + void setQCDBPathScalers(std::string path) { mQCDBPathCTPScalers = path; }; static void setCCDBHost(std::string host) { mCCDBHost = host; }; + static void setQCDBHost(std::string host) { mQCDBHost = host; }; protected: /// Database constants // std::string mCCDBHost = "http://ccdb-test.cern.ch:8080"; + // std::string mQCDBHost = "http://ali-qcdb.cern.ch:8083"; static std::string mCCDBHost; + static std::string mQCDBHost; std::string mCCDBPathCTPScalers = "CTP/Calib/Scalers"; std::string mCCDBPathCTPConfig = "CTP/Config/Config"; - - ClassDefNV(ctpCCDBManager, 0); + std::string mQCDBPathCTPScalers = "qc/CTP/Scalers"; + ClassDefNV(ctpCCDBManager, 1); }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/workflowScalers/src/RunManager.cxx b/Detectors/CTP/workflowScalers/src/RunManager.cxx index 85bb0465974dc..e6861e6cb4b38 100644 --- a/Detectors/CTP/workflowScalers/src/RunManager.cxx +++ b/Detectors/CTP/workflowScalers/src/RunManager.cxx @@ -81,8 +81,11 @@ void CTPRunManager::init() } else { LOG(info) << "BK not sent"; } + setQCDBHost(mQCDBHost); + LOG(info) << "QC host:" << mQCDBHost; + LOG(info) << "QCDB writing every:" << mQCWritePeriod << " 10 secs"; LOG(info) << "CCDB host:" << mCCDBHost; - LOG(info) << "CTP vNew:" << mNew; + LOG(info) << "CTP vNew cfg:" << mNew; LOG(info) << "CTPRunManager initialised."; } int CTPRunManager::loadRun(const std::string& cfg) @@ -136,6 +139,7 @@ int CTPRunManager::stopRun(uint32_t irun, long timeStamp) // const long timeStamp = std::chrono::duration_cast(now.time_since_epoch()).count(); mActiveRuns[irun]->timeStop = timeStamp * 1000.; saveRunScalersToCCDB(mActiveRuns[irun]->scalers, mActiveRuns[irun]->timeStart, mActiveRuns[irun]->timeStop); + saveRunScalersToQCDB(mActiveRuns[irun]->scalers, mActiveRuns[irun]->timeStart, mActiveRuns[irun]->timeStop); delete mActiveRuns[irun]; mActiveRuns[irun] = nullptr; return 0; @@ -160,7 +164,7 @@ int CTPRunManager::addScalers(uint32_t irun, std::time_t time, bool start) std::string c1a = "cla1a" + std::to_string(cls + 1); CTPScalerRaw scalraw; scalraw.classIndex = (uint32_t)cls; - std::cout << "cls:" << cls << " " << scalraw.classIndex << std::endl; + // std::cout << "cls:" << cls << " " << scalraw.classIndex << std::endl; scalraw.lmBefore = mCounters[mScalerName2Position[cmb]]; scalraw.lmAfter = mCounters[mScalerName2Position[cma]]; scalraw.l0Before = mCounters[mScalerName2Position[c0b]]; @@ -276,6 +280,12 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message // active , do scalers LOG(info) << "Run continue:" << mCounters[i]; addScalers(i, tt); + // LOG(info) << " QC period:" << mActiveRunNumbers[i] << " " << mActiveRuns[i]->qcwpcount << " " << mQCWritePeriod; + if (mActiveRuns[i]->qcwpcount > mQCWritePeriod) { + saveRunScalersToQCDB(mActiveRuns[i]->scalers, tt * 1000, tt * 1000); + mActiveRuns[i]->qcwpcount = 0; + } + mActiveRuns[i]->qcwpcount++; } else if ((mCounters[i] != 0) && (mActiveRunNumbers[i] == 0)) { LOG(info) << "Run started:" << mCounters[i]; auto run = mRunsLoaded.find(mCounters[i]); @@ -284,6 +294,7 @@ int CTPRunManager::processMessage(std::string& topic, const std::string& message mActiveRuns[i] = run->second; mRunsLoaded.erase(run); addScalers(i, tt, 1); + saveRunScalersToQCDB(mActiveRuns[i]->scalers, tt * 1000, tt * 1000); } else { LOG(error) << "Trying to start run which is not loaded:" << mCounters[i]; } diff --git a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx index 6d4c6663b3b67..b2896215d1c6a 100644 --- a/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx +++ b/Detectors/CTP/workflowScalers/src/ctp-proxy.cxx @@ -46,11 +46,13 @@ #include "BookkeepingApi/BkpClient.h" using namespace o2::framework; using DetID = o2::detectors::DetID; -InjectorFunction dcs2dpl(std::string& ccdbhost, std::string& bkhost) +InjectorFunction dcs2dpl(std::string& ccdbhost, std::string& bkhost, std::string& qchost, int qcwriteperiod) { auto runMgr = std::make_shared(); runMgr->setCCDBHost(ccdbhost); runMgr->setBKHost(bkhost); + runMgr->setQCDBHost(qchost); + runMgr->setQCWritePeriod(qcwriteperiod); runMgr->init(); // runMgr->setClient(client); return [runMgr](TimingInfo&, ServiceRegistryRef const& services, fair::mq::Parts& parts, ChannelRetriever channelRetriever, size_t newTimesliceId, bool& stop) -> bool { @@ -75,6 +77,8 @@ void customize(std::vector& workflowOptions) workflowOptions.push_back(ConfigParamSpec{"subscribe-to", VariantType::String, "type=sub,method=connect,address=tcp://188.184.30.57:5556,rateLogging=10,transport=zeromq", {"channel subscribe to"}}); workflowOptions.push_back(ConfigParamSpec{"ccdb-host", VariantType::String, "http://o2-ccdb.internal:8080", {"ccdb host"}}); workflowOptions.push_back(ConfigParamSpec{"bk-host", VariantType::String, "none", {"bk host"}}); + workflowOptions.push_back(ConfigParamSpec{"qc-host", VariantType::String, "none", {"qc host"}}); + workflowOptions.push_back(ConfigParamSpec{"qc-writeperiod", VariantType::Int, 30, {"Period of writing to QCDB in units of 10secs, default = 30 (5 mins)"}}); } #include "Framework/runDataProcessing.h" @@ -98,6 +102,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) auto chan = config.options().get("subscribe-to"); std::string ccdbhost = config.options().get("ccdb-host"); std::string bkhost = config.options().get("bk-host"); + std::string qchost = config.options().get("qc-host"); + int qcwriteperiod = config.options().get("qc-writeperiod"); if (chan.empty()) { throw std::runtime_error("input channel is not provided"); } @@ -112,7 +118,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) std::move(ctpCountersOutputs), // this is just default, can be overriden by --ctp-config-proxy '--channel-config..' chan.c_str(), - dcs2dpl(ccdbhost, bkhost)); + dcs2dpl(ccdbhost, bkhost, qchost, qcwriteperiod)); ctpProxy.labels.emplace_back(DataProcessorLabel{"input-proxy"}); LOG(info) << "===> Proxy done"; WorkflowSpec workflow; diff --git a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx index d5a82ca0923ec..0a462726deb01 100644 --- a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx +++ b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx @@ -21,6 +21,8 @@ #include using namespace o2::ctp; std::string ctpCCDBManager::mCCDBHost = "http://o2-ccdb.internal"; +std::string ctpCCDBManager::mQCDBHost = "http://ali-qcdb.cern.ch:8083"; +// std::string ctpCCDBManager::mQCDBHost = "none"; // int ctpCCDBManager::saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, long timeStop) { @@ -43,7 +45,39 @@ int ctpCCDBManager::saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation // store abitrary user object in strongly typed manner int ret = api.storeAsTFileAny(&(scalers), mCCDBPathCTPScalers, metadata, tmin, tmax); - LOG(info) << "CTP scalers saved in ccdb:" << mCCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + if (ret == 0) { + LOG(info) << "CTP scalers saved in ccdb:" << mCCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + } else { + LOG(FATAL) << "Problem writing to database ret:" << ret; + } + return ret; +} +int ctpCCDBManager::saveRunScalersToQCDB(CTPRunScalers& scalers, long timeStart, long timeStop) +{ + // data base + if (mQCDBHost == "none") { + LOG(info) << "Scalers not written to QCDB none"; + return 0; + } + // CTPActiveRun* run = mActiveRuns[i];q + using namespace std::chrono_literals; + std::chrono::seconds days3 = 259200s; + std::chrono::seconds min10 = 600s; + long time3days = std::chrono::duration_cast(days3).count(); + long time10min = std::chrono::duration_cast(min10).count(); + long tmin = timeStart - time10min; + long tmax = timeStop + time3days; + o2::ccdb::CcdbApi api; + map metadata; // can be empty + metadata["runNumber"] = std::to_string(scalers.getRunNumber()); + api.init(mQCDBHost.c_str()); // or http://localhost:8080 for a local installation + // store abitrary user object in strongly typed manner + int ret = api.storeAsTFileAny(&(scalers), mQCDBPathCTPScalers, metadata, tmin, tmax); + if (ret == 0) { + LOG(info) << "CTP scalers saved in qcdb:" << mQCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + } else { + LOG(FATAL) << "CTP scalers Problem writing to database qcdb ret:" << ret; + } return ret; } int ctpCCDBManager::saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart) @@ -66,7 +100,11 @@ int ctpCCDBManager::saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart) api.init(mCCDBHost.c_str()); // or http://localhost:8080 for a local installation // store abitrary user object in strongly typed manner int ret = api.storeAsTFileAny(cfg, CCDBPathCTPConfig, metadata, tmin, tmax); - LOG(info) << "CTP config saved in ccdb:" << mCCDBHost << " run:" << cfg->getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + if (ret == 0) { + LOG(info) << "CTP config saved in ccdb:" << mCCDBHost << " run:" << cfg->getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; + } else { + LOG(FATAL) << "CTPConfig: Problem writing to database ret:" << ret; + } return ret; } CTPConfiguration ctpCCDBManager::getConfigFromCCDB(long timestamp, std::string run, bool& ok) From 2ba8cfc627f15749ceed8b330cb5e764b84f6f19 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 6 Aug 2024 15:49:33 +0200 Subject: [PATCH 0058/2205] Propagate digitizer interaction rate via DigitizationContext (#13296) Some digitizer (EMCAL) aim to use the interaction rate for flow-control in digitization. This is now possible from a new member in DigitizationContext which will be filled in digitizer workflows. --- .../DigitizationContext.h | 14 +++++++++++++- .../EMCAL/workflow/src/EMCALDigitizerSpec.cxx | 3 +++ Steer/DigitizerWorkflow/src/SimReaderSpec.cxx | 19 +++++++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h index f531cf6e7f870..de8d89e6b1b72 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h +++ b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h @@ -82,6 +82,9 @@ class DigitizationContext void setMuPerBC(float m) { mMuBC = m; } float getMuPerBC() const { return mMuBC; } + /// returns the main (hadronic interaction rate) associated to this digitization context + float getCalculatedInteractionRate() const { return getMuPerBC() * getBunchFilling().getNBunches() * o2::constants::lhc::LHCRevFreq; } + void printCollisionSummary(bool withQED = false, int truncateOutputTo = -1) const; // we need a method to fill the file names @@ -150,6 +153,9 @@ class DigitizationContext } } + void setDigitizerInteractionRate(float intRate) { mDigitizerInteractionRate = intRate; } + float getDigitizerInteractionRate() const { return mDigitizerInteractionRate; } + std::vector const* getCTPDigits() const { return mCTPTrigger; } bool hasTriggerInput() const { return mHasTrigger; } @@ -184,7 +190,13 @@ class DigitizationContext mutable std::vector const* mCTPTrigger = nullptr; // CTP trigger info associated to this digitization context mutable bool mHasTrigger = false; // - ClassDefNV(DigitizationContext, 5); + // The global ALICE interaction hadronic interaction rate as applied in digitization. + // It should be consistent with mMuPerBC but it might be easier to handle. + // The value will be filled/inserted by the digitization workflow so that digiters can access it. + // There is no guarantee that the value is available elsewhere. + float mDigitizerInteractionRate{-1}; + + ClassDefNV(DigitizationContext, 6); }; /// function reading the hits from a chain (previously initialized with initSimChains diff --git a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx index 3d83968b84670..06c42c146097b 100644 --- a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx +++ b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx @@ -82,6 +82,9 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) // read collision context from input auto context = ctx.inputs().get("collisioncontext"); + + // get interaction rate ... so that it can be used in digitization + auto intRate = context->getDigitizerInteractionRate(); context->initSimChains(o2::detectors::DetID::EMC, mSimChains); auto& timesview = context->getEventRecords(); LOG(debug) << "GOT " << timesview.size() << " COLLISSION TIMES"; diff --git a/Steer/DigitizerWorkflow/src/SimReaderSpec.cxx b/Steer/DigitizerWorkflow/src/SimReaderSpec.cxx index 6f8502f74a85b..6759f5f8022be 100644 --- a/Steer/DigitizerWorkflow/src/SimReaderSpec.cxx +++ b/Steer/DigitizerWorkflow/src/SimReaderSpec.cxx @@ -45,6 +45,7 @@ namespace steer { std::vector* ctptrigger = nullptr; +float gIntRate = -1.; DataProcessorSpec getSimReaderSpec(SubspecRange range, const std::vector& simprefixes, const std::vector& tpcsectors, bool withTrigger) { @@ -55,7 +56,7 @@ DataProcessorSpec getSimReaderSpec(SubspecRange range, const std::vector("interactionRate"); // is interaction rate requested? + if (gIntRate < 1.f) { + gIntRate = 1.f; + } // do we start from an existing context auto incontextstring = ctx.options().get("incontext"); LOG(info) << "INCONTEXTSTRING " << incontextstring; @@ -137,13 +145,8 @@ DataProcessorSpec getSimReaderSpec(SubspecRange range, const std::vector("interactionRate"); // is interaction rate requested? - if (intRate < 1.f) { - intRate = 1.f; - } - LOG(info) << "Imposing hadronic interaction rate " << intRate << "Hz"; - mgr.getInteractionSampler().setInteractionRate(intRate); + LOG(info) << "Imposing hadronic interaction rate " << gIntRate << "Hz"; + mgr.getInteractionSampler().setInteractionRate(gIntRate); o2::raw::HBFUtils::Instance().print(); o2::raw::HBFUtils::Instance().checkConsistency(); mgr.getInteractionSampler().setFirstIR({0, o2::raw::HBFUtils::Instance().orbitFirstSampled}); From eac229bf5f414b1191b0b76a748b5f44612f6e69 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 6 Aug 2024 15:49:57 +0200 Subject: [PATCH 0059/2205] Ability to access MCEventHeader information in digitization (#13294) This commit provides: * Modifications to MCKinematicsReader to allow construction from an existing DigitizationContext object * Demonstrating use of MCKinematicsReader in EMCAL digitization to access the Monte-Carlo header information. --- .../EMCALWorkflow/EMCALDigitizerSpec.h | 6 +++++ .../EMCAL/workflow/src/EMCALDigitizerSpec.cxx | 11 +++++++++ Steer/include/Steer/MCKinematicsReader.h | 9 ++++++++ Steer/src/MCKinematicsReader.cxx | 23 ++++++++++++++----- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h b/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h index 2bc16244a391a..fe58dd75bdbde 100644 --- a/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h +++ b/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h @@ -29,6 +29,11 @@ class TChain; namespace o2 { +namespace steer +{ +class MCKinematicsReader; +} + namespace ctp { class CTPConfiguration; @@ -84,6 +89,7 @@ class DigitizerSpec final : public o2::base::BaseDPLDigitizer, public o2::framew std::vector mHits; ///< Vector with input hits std::vector mSimChains; o2::ctp::CTPConfiguration* mCTPConfig; ///< CTP configuration + o2::steer::MCKinematicsReader* mcReader; ///< reader to access MC collision information }; /// \brief Create new digitizer spec diff --git a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx index 06c42c146097b..8690956650664 100644 --- a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx +++ b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx @@ -32,6 +32,7 @@ #include "DataFormatsEMCAL/TriggerRecord.h" #include "DataFormatsFT0/Digit.h" #include "DataFormatsFV0/Digit.h" +#include using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -86,6 +87,12 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) // get interaction rate ... so that it can be used in digitization auto intRate = context->getDigitizerInteractionRate(); context->initSimChains(o2::detectors::DetID::EMC, mSimChains); + + // init the MCKinematicsReader from the digitization context + if (mcReader == nullptr) { + mcReader = new o2::steer::MCKinematicsReader(context.get()); + } + auto& timesview = context->getEventRecords(); LOG(debug) << "GOT " << timesview.size() << " COLLISSION TIMES"; @@ -195,6 +202,10 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) mSumDigitizer.setCurrEvID(part.entryID); mSumDigitizer.setCurrSrcID(part.sourceID); + // retrieve information about the MC collision via the MCEventHeader + auto& mcEventHeader = mcReader->getMCEventHeader(part.sourceID, part.entryID); + mcEventHeader.print(); + // get the hits for this event and this source mHits.clear(); context->retrieveHits(mSimChains, "EMCHit", part.sourceID, part.entryID, &mHits); diff --git a/Steer/include/Steer/MCKinematicsReader.h b/Steer/include/Steer/MCKinematicsReader.h index e8f4de3f4f313..6f12e9570528c 100644 --- a/Steer/include/Steer/MCKinematicsReader.h +++ b/Steer/include/Steer/MCKinematicsReader.h @@ -55,10 +55,18 @@ class MCKinematicsReader } } + /// constructing directly from a digitization context + MCKinematicsReader(o2::steer::DigitizationContext const* context) + { + initFromDigitContext(context); + } + /// inits the reader from a digitization context /// returns true if successful bool initFromDigitContext(std::string_view filename); + bool initFromDigitContext(o2::steer::DigitizationContext const* digicontext); + /// inits the reader from a simple kinematics file bool initFromKinematics(std::string_view filename); @@ -120,6 +128,7 @@ class MCKinematicsReader void initIndexedTrackRefs(std::vector& refs, o2::dataformats::MCTruthContainer& indexedrefs) const; DigitizationContext const* mDigitizationContext = nullptr; + bool mOwningDigiContext = false; // chains for each source std::vector mInputChains; diff --git a/Steer/src/MCKinematicsReader.cxx b/Steer/src/MCKinematicsReader.cxx index 4791d5921421d..116693f2063ee 100644 --- a/Steer/src/MCKinematicsReader.cxx +++ b/Steer/src/MCKinematicsReader.cxx @@ -26,7 +26,7 @@ MCKinematicsReader::~MCKinematicsReader() } mInputChains.clear(); - if (mDigitizationContext) { + if (mDigitizationContext && mOwningDigiContext) { delete mDigitizationContext; } } @@ -132,17 +132,13 @@ void MCKinematicsReader::loadTrackRefsForSource(int source) const } } -bool MCKinematicsReader::initFromDigitContext(std::string_view name) +bool MCKinematicsReader::initFromDigitContext(o2::steer::DigitizationContext const* context) { if (mInitialized) { LOG(info) << "MCKinematicsReader already initialized; doing nothing"; return false; } - auto context = DigitizationContext::loadFromFile(name); - if (!context) { - return false; - } mInitialized = true; mDigitizationContext = context; @@ -160,6 +156,21 @@ bool MCKinematicsReader::initFromDigitContext(std::string_view name) return true; } +bool MCKinematicsReader::initFromDigitContext(std::string_view name) +{ + if (mInitialized) { + LOG(info) << "MCKinematicsReader already initialized; doing nothing"; + return false; + } + + auto context = DigitizationContext::loadFromFile(name); + if (!context) { + return false; + } + mOwningDigiContext = true; + return initFromDigitContext(context); +} + bool MCKinematicsReader::initFromKinematics(std::string_view name) { if (mInitialized) { From 4b29caebf0da685b68f1c627f01af23ea2936a89 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 5 Aug 2024 11:26:53 +0200 Subject: [PATCH 0060/2205] Added severity flag to uvErrorCheck in CcdbDownloader --- CCDB/include/CCDB/CCDBDownloader.h | 5 +++++ CCDB/src/CCDBDownloader.cxx | 34 +++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CCDB/include/CCDB/CCDBDownloader.h b/CCDB/include/CCDB/CCDBDownloader.h index e53421dcc26fc..0bda186e308c6 100644 --- a/CCDB/include/CCDB/CCDBDownloader.h +++ b/CCDB/include/CCDB/CCDBDownloader.h @@ -87,6 +87,11 @@ curl_socket_t opensocketCallback(void* clientp, curlsocktype purpose, struct cur */ void onUVClose(uv_handle_t* handle); +enum DownloaderErrorLevel { + MINOR, + SEVERE +}; + /// A class encapsulating and performing simple CURL requests in terms of a so-called CURL multi-handle. /// A multi-handle allows to use a connection pool (connection cache) in the CURL layer even /// with short-lived CURL easy-handles. Thereby the overhead of connection to servers can be diff --git a/CCDB/src/CCDBDownloader.cxx b/CCDB/src/CCDBDownloader.cxx index 681f75941eda0..a8f2766caf3b7 100644 --- a/CCDB/src/CCDBDownloader.cxx +++ b/CCDB/src/CCDBDownloader.cxx @@ -35,13 +35,17 @@ O2_DECLARE_DYNAMIC_STACKTRACE_LOG(ccdb_downloader); namespace o2::ccdb { -void uvErrorCheck(int code) +void uvErrorCheck(int code, DownloaderErrorLevel level) { if (code != 0) { char buf[1000]; uv_strerror_r(code, buf, 1000); O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); - O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "UV error - %{public}s", buf); + if (level == SEVERE) { + O2_SIGNPOST_EVENT_EMIT_ERROR(ccdb_downloader, sid, "CCDBDownloader", "UV error - %{public}s", buf); + } else { + O2_SIGNPOST_EVENT_EMIT_WARN(ccdb_downloader, sid, "CCDBDownloader", "UV minor error - %{public}s", buf); + } } } @@ -88,7 +92,7 @@ CCDBDownloader::CCDBDownloader(uv_loop_t* uv_loop) // Preparing timer to be used by curl mTimeoutTimer = (uv_timer_t*)malloc(sizeof(*mTimeoutTimer)); mTimeoutTimer->data = this; - uvErrorCheck(uv_timer_init(mUVLoop, mTimeoutTimer)); + uvErrorCheck(uv_timer_init(mUVLoop, mTimeoutTimer), SEVERE); mHandleMap[(uv_handle_t*)mTimeoutTimer] = true; initializeMultiHandle(); @@ -97,7 +101,7 @@ CCDBDownloader::CCDBDownloader(uv_loop_t* uv_loop) void CCDBDownloader::setupInternalUVLoop() { mUVLoop = new uv_loop_t(); - uvErrorCheck(uv_loop_init(mUVLoop)); + uvErrorCheck(uv_loop_init(mUVLoop), SEVERE); } void CCDBDownloader::initializeMultiHandle() @@ -153,7 +157,7 @@ void CCDBDownloader::closesocketCallback(void* clientp, curl_socket_t item) // If external uv loop is used then the keepalive mechanism is active. if (CD->mSocketTimerMap.find(item) != CD->mSocketTimerMap.end()) { auto timer = CD->mSocketTimerMap[item]; - uvErrorCheck(uv_timer_stop(timer)); + uvErrorCheck(uv_timer_stop(timer), SEVERE); // we are getting rid of the uv_timer_t pointer ... so we need // to free possibly attached user data pointers as well. Counteracts action of opensocketCallback if (timer->data) { @@ -184,7 +188,7 @@ curl_socket_t opensocketCallback(void* clientp, curlsocktype purpose, struct cur if (CD->mExternalLoop) { CD->mSocketTimerMap[sock] = (uv_timer_t*)malloc(sizeof(*CD->mSocketTimerMap[sock])); - uvErrorCheck(uv_timer_init(CD->mUVLoop, CD->mSocketTimerMap[sock])); + uvErrorCheck(uv_timer_init(CD->mUVLoop, CD->mSocketTimerMap[sock]), SEVERE); CD->mHandleMap[(uv_handle_t*)CD->mSocketTimerMap[sock]] = true; auto data = new DataForClosingSocket(); @@ -203,7 +207,7 @@ void CCDBDownloader::closeSocketByTimer(uv_timer_t* handle) auto sock = data->socket; if (CD->mSocketTimerMap.find(sock) != CD->mSocketTimerMap.end()) { - uvErrorCheck(uv_timer_stop(CD->mSocketTimerMap[sock])); + uvErrorCheck(uv_timer_stop(CD->mSocketTimerMap[sock]), SEVERE); CD->mSocketTimerMap.erase(sock); if (close(sock) == -1) { O2_SIGNPOST_ID_GENERATE(sid, ccdb_downloader); @@ -223,7 +227,7 @@ void CCDBDownloader::curlTimeout(uv_timer_t* handle) void CCDBDownloader::curlPerform(uv_poll_t* handle, int status, int events) { - uvErrorCheck(status); + uvErrorCheck(status, MINOR); int running_handles; int flags = 0; if (events & UV_READABLE) { @@ -262,20 +266,20 @@ int CCDBDownloader::handleSocket(CURL* easy, curl_socket_t s, int action, void* } if (CD->mExternalLoop && CD->mSocketTimerMap.find(s) != CD->mSocketTimerMap.end()) { - uvErrorCheck(uv_timer_stop(CD->mSocketTimerMap[s])); + uvErrorCheck(uv_timer_stop(CD->mSocketTimerMap[s]), SEVERE); } - uvErrorCheck(uv_poll_start(curl_context->poll_handle, events, curlPerform)); + uvErrorCheck(uv_poll_start(curl_context->poll_handle, events, curlPerform), SEVERE); break; case CURL_POLL_REMOVE: if (socketp) { if (CD->mExternalLoop) { // If external loop is used then start the keepalive timeout. if (CD->mSocketTimerMap.find(s) != CD->mSocketTimerMap.end()) { - uvErrorCheck(uv_timer_start(CD->mSocketTimerMap[s], closeSocketByTimer, CD->mKeepaliveTimeoutMS, 0)); + uvErrorCheck(uv_timer_start(CD->mSocketTimerMap[s], closeSocketByTimer, CD->mKeepaliveTimeoutMS, 0), SEVERE); } } - uvErrorCheck(uv_poll_stop(((CCDBDownloader::curl_context_t*)socketp)->poll_handle)); + uvErrorCheck(uv_poll_stop(((CCDBDownloader::curl_context_t*)socketp)->poll_handle), SEVERE); CD->destroyCurlContext((CCDBDownloader::curl_context_t*)socketp); curlMultiErrorCheck(curl_multi_assign(socketData->curlm, s, nullptr)); } @@ -335,7 +339,7 @@ CCDBDownloader::curl_context_t* CCDBDownloader::createCurlContext(curl_socket_t context->sockfd = sockfd; context->poll_handle = (uv_poll_t*)malloc(sizeof(*context->poll_handle)); - uvErrorCheck(uv_poll_init_socket(mUVLoop, context->poll_handle, sockfd)); + uvErrorCheck(uv_poll_init_socket(mUVLoop, context->poll_handle, sockfd), SEVERE); mHandleMap[(uv_handle_t*)(context->poll_handle)] = true; context->poll_handle->data = context; @@ -589,12 +593,12 @@ int CCDBDownloader::startTimeout(CURLM* multi, long timeout_ms, void* userp) auto timeout = (uv_timer_t*)userp; if (timeout_ms < 0) { - uvErrorCheck(uv_timer_stop(timeout)); + uvErrorCheck(uv_timer_stop(timeout), SEVERE); } else { if (timeout_ms == 0) { timeout_ms = 1; // Calling curlTimeout when timeout = 0 could create an infinite loop } - uvErrorCheck(uv_timer_start(timeout, curlTimeout, timeout_ms, 0)); + uvErrorCheck(uv_timer_start(timeout, curlTimeout, timeout_ms, 0), SEVERE); } return 0; } From a2e7b8efe9414452959a61b9a436b55cdb20f34f Mon Sep 17 00:00:00 2001 From: Daniel Battistini <60930860+danielbattistini@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:44:43 +0200 Subject: [PATCH 0061/2205] Add option to use a segmented OT (#13325) * [WIP] Add staves in the naming [WIP] Add staves to the tracker * [WIP] Add segmentation of the layers into staves Add possibility to switch on/off the layer segmentation * Minor format changes * Update Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h --------- Co-authored-by: Matteo Concas --- .../TRK/base/include/TRKBase/GeometryTGeo.h | 3 + .../TRK/base/include/TRKBase/TRKBaseParam.h | 6 ++ .../ALICE3/TRK/base/src/GeometryTGeo.cxx | 8 +- .../include/TRKSimulation/TRKLayer.h | 8 +- .../ALICE3/TRK/simulation/src/Detector.cxx | 5 ++ .../ALICE3/TRK/simulation/src/TRKLayer.cxx | 90 +++++++++++++++---- 6 files changed, 102 insertions(+), 18 deletions(-) diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index 1ef9468b26436..66326fe3c377d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -29,6 +29,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static const char* getTRKVolPattern() { return sVolumeName.c_str(); } static const char* getTRKLayerPattern() { return sLayerName.c_str(); } + static const char* getTRKStavePattern() { return sStaveName.c_str(); } static const char* getTRKChipPattern() { return sChipName.c_str(); } static const char* getTRKSensorPattern() { return sSensorName.c_str(); } @@ -37,12 +38,14 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::TRK).getName(), d); } static const char* composeSymNameLayer(int d, int layer); + static const char* composeSymNameStave(int d, int layer); static const char* composeSymNameChip(int d, int lr); static const char* composeSymNameSensor(int d, int layer); protected: static std::string sVolumeName; static std::string sLayerName; + static std::string sStaveName; static std::string sChipName; static std::string sSensorName; diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h index 5caee7af9f48a..6c655571b3e4e 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h @@ -20,9 +20,15 @@ namespace o2 namespace trk { +enum eLayout { + kCylinder = 0, + kTurboStaves, +}; + struct TRKBaseParam : public o2::conf::ConfigurableParamHelper { std::string configFile = ""; float serviceTubeX0 = 0.02f; // X0 Al2O3 + eLayout layout = kCylinder; // Type of segmentation of the layers into staves O2ParamDef(TRKBaseParam, "TRKBase"); }; diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index e12fb70e892d2..525b40fe29c4f 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -20,6 +20,7 @@ std::unique_ptr GeometryTGeo::sInstance; // Names std::string GeometryTGeo::sVolumeName = "TRKV"; +std::string GeometryTGeo::sStaveName = "TRKStave"; std::string GeometryTGeo::sLayerName = "TRKLayer"; std::string GeometryTGeo::sChipName = "TRKChip"; std::string GeometryTGeo::sSensorName = "TRKSensor"; @@ -65,9 +66,14 @@ const char* GeometryTGeo::composeSymNameLayer(int d, int lr) return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), lr); } +const char* GeometryTGeo::composeSymNameStave(int d, int lr) +{ + return Form("%s/%s%d", composeSymNameLayer(d, lr), getTRKStavePattern(), lr); +} + const char* GeometryTGeo::composeSymNameChip(int d, int lr) { - return Form("%s/%s%d", composeSymNameLayer(d, lr), getTRKChipPattern(), lr); + return Form("%s/%s%d", composeSymNameStave(d, lr), getTRKChipPattern(), lr); } const char* GeometryTGeo::composeSymNameSensor(int d, int lr) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h index 9db0a1cfe347f..2ddf38352ae8c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h @@ -15,6 +15,8 @@ #include #include +#include "TRKBase/TRKBaseParam.h" + namespace o2 { namespace trk @@ -27,6 +29,8 @@ class TRKLayer TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick); ~TRKLayer() = default; + void setLayout(eLayout layout) { mLayout = layout; }; + auto getInnerRadius() const { return mInnerRadius; } auto getOuterRadius() const { return mOuterRadius; } auto getZ() const { return mZ; } @@ -45,8 +49,10 @@ class TRKLayer float mZ; float mX2X0; float mChipThickness; + float mModuleWidth; // u.m. = cm + eLayout mLayout; - ClassDef(TRKLayer, 0); + ClassDef(TRKLayer, 1); }; } // namespace trk diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx index 7a16d0643942c..9e69a3bd8a88f 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx @@ -114,6 +114,11 @@ void Detector::buildTRKNewVacuumVessel() mLayers.emplace_back(8, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(8)}, 45.f, 258.f, 100.e-3); mLayers.emplace_back(9, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(9)}, 60.f, 258.f, 100.e-3); mLayers.emplace_back(10, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(10)}, 80.f, 258.f, 100.e-3); + + auto& trkPars = TRKBaseParam::Instance(); + mLayers[8].setLayout(trkPars.layout); + mLayers[9].setLayout(trkPars.layout); + mLayers[10].setLayout(trkPars.layout); } void Detector::configFromFile(std::string fileName) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx index a8aafb3ee8d08..0d7930c77bb49 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx @@ -15,14 +15,17 @@ #include "Framework/Logger.h" #include +#include #include +#include + namespace o2 { namespace trk { TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0) - : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0) + : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mModuleWidth(4.54), mLayout(kCylinder) { float Si_X0 = 9.5f; mChipThickness = mX2X0 * Si_X0; @@ -30,7 +33,7 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOu } TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick) - : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick) + : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mModuleWidth(4.54), mLayout(kCylinder) { float Si_X0 = 9.5f; mOuterRadius = rInn + thick; @@ -40,29 +43,84 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLe void TRKLayer::createLayer(TGeoVolume* motherVolume) { - std::string chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber), + TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); + TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + + std::string staveName = o2::trk::GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber), + chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber), sensName = Form("%s%d", GeometryTGeo::getTRKSensorPattern(), mLayerNumber); - TGeoTube* sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); - TGeoTube* chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); TGeoTube* layer = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); - TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); - TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); - - TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); - sensVol->SetLineColor(kYellow); - TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); - chipVol->SetLineColor(kYellow); TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); layerVol->SetLineColor(kYellow); - LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); - chipVol->AddNode(sensVol, 1, nullptr); + if (mLayout == eLayout::kCylinder) { + TGeoTube* stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + TGeoTube* chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + TGeoTube* sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2); + + TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); + sensVol->SetLineColor(kYellow); + TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + chipVol->SetLineColor(kYellow); + TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi); + staveVol->SetLineColor(kYellow); + + LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); + chipVol->AddNode(sensVol, 1, nullptr); + + LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName()); + staveVol->AddNode(chipVol, 1, nullptr); + + LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName()); + layerVol->AddNode(staveVol, 1, nullptr); + } else if (mLayout == eLayout::kTurboStaves) { + // Compute the number of staves + double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design) + int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width); + nStaves += nStaves % 2; // Require an even number of staves + + // Compute the size of the overlap region + double theta = 2 * TMath::Pi() / nStaves; + double theta1 = std::atan(width / 2 / mInnerRadius); + double st = std::sin(theta); + double ct = std::cos(theta); + double theta2 = std::atan((mInnerRadius * st - width / 2 * ct) / (mInnerRadius * ct + width / 2 * st)); + double overlap = (theta1 - theta2) * mInnerRadius; + LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10); + + for (int iStave = 0; iStave < nStaves; iStave++) { + TGeoBBox* sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + TGeoBBox* chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + TGeoBBox* stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2); + + TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); + sensVol->SetLineColor(kYellow); + TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + chipVol->SetLineColor(kYellow); + TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi); + staveVol->SetLineColor(kYellow); + + // Put the staves in the correct position and orientation + TGeoCombiTrans* trans = new TGeoCombiTrans(); + double theta = 360. * iStave / nStaves; + TGeoRotation* rot = new TGeoRotation("rot", theta + 90 + 2, 0, 0); + trans->SetRotation(rot); + trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0); + + LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName()); + chipVol->AddNode(sensVol, 1, nullptr); - LOGP(info, "Inserting {} in {} ", chipVol->GetName(), layerVol->GetName()); - layerVol->AddNode(chipVol, 1, nullptr); + LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName()); + staveVol->AddNode(chipVol, 1, nullptr); + LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName()); + layerVol->AddNode(staveVol, iStave, trans); + } + } else { + LOGP(fatal, "Layout not implemented"); + } LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName()); motherVolume->AddNode(layerVol, 1, nullptr); } From 2d4b0a1a548652a24110814fdc2c28811c5355e1 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:54:11 +0200 Subject: [PATCH 0062/2205] DPL: provide stacktrace for errors also on Linux, if requested. (#13338) --- Framework/Foundation/include/Framework/Signpost.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Framework/Foundation/include/Framework/Signpost.h b/Framework/Foundation/include/Framework/Signpost.h index 1ddaaa6fb793f..5e844ce01b20c 100644 --- a/Framework/Foundation/include/Framework/Signpost.h +++ b/Framework/Foundation/include/Framework/Signpost.h @@ -234,7 +234,9 @@ inline _o2_signpost_id_t _o2_signpost_id_make_with_pointer(_o2_log_t* log, void #include #include #include +#include #include "Framework/RuntimeError.h" +#include "Framework/BacktraceHelpers.h" void _o2_signpost_interval_end_v(_o2_log_t* log, _o2_signpost_id_t id, char const* name, char const* const format, va_list args); // returns true if the push was successful, false if the stack was full @@ -377,6 +379,11 @@ void _o2_signpost_event_emit(_o2_log_t* log, _o2_signpost_id_t id, char const* n vsnprintf(prebuffer + s, 4096 - s, format, args); va_end(args); O2_LOG_MACRO("%s", prebuffer); + if (log->stacktrace > 1) { + void* traces[o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE]; + int maxBacktrace = backtrace(traces, o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE); + o2::framework::BacktraceHelpers::demangled_backtrace_symbols(traces, maxBacktrace, STDERR_FILENO); + } } // This will look at the slot in the log associated to the ID. From 83c51e1822c2565038dffd1050ee34d612dfc906 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:55:57 +0200 Subject: [PATCH 0063/2205] DPL: add test for backtrace on error --- Framework/Foundation/test/test_SignpostLogger.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Framework/Foundation/test/test_SignpostLogger.cxx b/Framework/Foundation/test/test_SignpostLogger.cxx index ed917ea7cadf5..e5e401dd8f854 100644 --- a/Framework/Foundation/test/test_SignpostLogger.cxx +++ b/Framework/Foundation/test/test_SignpostLogger.cxx @@ -19,6 +19,7 @@ #include O2_DECLARE_LOG(test_Signpost2, "my category2"); +O2_DECLARE_DYNAMIC_STACKTRACE_LOG(SignpostStacktrace); int main(int argc, char** argv) { @@ -57,4 +58,9 @@ int main(int argc, char** argv) O2_SIGNPOST_START(test_SignpostDynamic, id, "Test category", "This is dynamic signpost which you will see, because we turned them on"); O2_SIGNPOST_END(test_SignpostDynamic, id, "Test category", "This is dynamic signpost which you will see, because we turned them on"); #endif + + // Test stacktraces + O2_SIGNPOST_ID_GENERATE(idStacktrace, SignpostStacktrace); + O2_LOG_ENABLE(SignpostStacktrace); + O2_SIGNPOST_EVENT_EMIT_ERROR(SignpostStacktrace, idStacktrace, "Test category", "An error with stacktrace %d \n", 1); } From 2e86715a4e1a50a8aa207565129d8cb761698569 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:55:57 +0200 Subject: [PATCH 0064/2205] DPL: improve backtrace handling In case demangling does not work, still try with addr2line. In case that fails as well, print what we have from backtrace. --- Framework/Foundation/src/BacktraceHelpers.cxx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Framework/Foundation/src/BacktraceHelpers.cxx b/Framework/Foundation/src/BacktraceHelpers.cxx index cf37464f7e0bd..a7e8a4b90d700 100644 --- a/Framework/Foundation/src/BacktraceHelpers.cxx +++ b/Framework/Foundation/src/BacktraceHelpers.cxx @@ -39,6 +39,7 @@ void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned i } #endif + // We skip the level 0, which is the actual logging function. for (size_t i = 1; i < stackDepth; i++) { size_t sz = 64000; // 64K ought to be enough for our templates... @@ -67,17 +68,20 @@ void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned i bool tryAddr2Line = true; #endif if (begin && end) { + // The first byte is a ' ' which we need to skip. *begin++ = '\0'; *end = '\0'; // found our mangled name, now in [begin, end) int status; char* ret = abi::__cxa_demangle(begin, function, &sz, &status); - if (ret) { + if (status == 0) { // return value may be a realloc() of the input function = ret; dprintf(fd, " %s: %s\n", stackStrings[i], function); tryAddr2Line = false; + } else { + tryAddr2Line = true; } } if (tryAddr2Line) { @@ -88,12 +92,12 @@ void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned i // Find c++filt from the environment // This is needed for platforms where we still need c++filt -r - char const* cxxfilt = getenv("CXXFILT"); + static char const* cxxfilt = getenv("CXXFILT"); if (cxxfilt == nullptr) { cxxfilt = "c++filt"; } // Do the same for addr2line, just in case we wanted to pass some options - char const* addr2line = getenv("ADDR2LINE"); + static char const* addr2line = getenv("ADDR2LINE"); if (addr2line == nullptr) { addr2line = "addr2line"; } @@ -104,7 +108,10 @@ void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned i fp = popen(syscom, "r"); if (fp == nullptr) { - dprintf(fd, "-- no source could be retrieved --\n"); + // We could not run addr2line, print whatever we have. + // Also free function, which is allocated at the beginning of the loop. + dprintf(fd, "%s\n", begin); + free(function); continue; } @@ -114,7 +121,7 @@ void BacktraceHelpers::demangled_backtrace_symbols(void** stackTrace, unsigned i pclose(fp); } else { - dprintf(fd, "-- no source avaliable --\n"); + dprintf(fd, "%s\n", begin); } } free(function); From f5de18ee01701c0e2983661c9fbb1f8ba8c8e01d Mon Sep 17 00:00:00 2001 From: avojarot <64825394+avojarot@users.noreply.github.com> Date: Thu, 8 Aug 2024 10:49:42 +0300 Subject: [PATCH 0065/2205] MatRepStdGPU and SMatrixImpCUDA tests (#13166) * tests for GPU added * Tests modified * refactoring * boost::test_tools::tolerance removed * tests update * formatting * final adjustments * binnary printing added * formatting --------- Co-authored-by: Maksym Kizitskyi --- GPU/Common/CMakeLists.txt | 2 +- GPU/Common/test/testSMatrixImp.cu | 335 +++++++++++++++++++++++++----- 2 files changed, 288 insertions(+), 49 deletions(-) diff --git a/GPU/Common/CMakeLists.txt b/GPU/Common/CMakeLists.txt index c37ec3f5f5a13..2a31747b3673e 100644 --- a/GPU/Common/CMakeLists.txt +++ b/GPU/Common/CMakeLists.txt @@ -88,4 +88,4 @@ if(ALIGPU_BUILD_TYPE STREQUAL "ALIROOT") install(TARGETS Ali${MODULE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) install(FILES ${HDRS_INSTALL} DESTINATION include) -endif() +endif() \ No newline at end of file diff --git a/GPU/Common/test/testSMatrixImp.cu b/GPU/Common/test/testSMatrixImp.cu index 08ca0b823488d..2bdcdd720cdc5 100644 --- a/GPU/Common/test/testSMatrixImp.cu +++ b/GPU/Common/test/testSMatrixImp.cu @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file testGPUSMatrixImp.cu -/// \author Matteo Concas +/// \author Matteo Concas, Maksym KIzitskyi #define BOOST_TEST_MODULE Test GPUSMatrixImpl #ifdef __HIPCC__ @@ -21,11 +21,39 @@ #include #endif -#include #include - +#include #include #include +#include + +// Macro for checking CUDA errors +#define CUDA_CHECK(call) \ + do { \ + cudaError_t error = call; \ + if (error != cudaSuccess) { \ + fprintf(stderr, "CUDA Error: %s (error code %d)\n", cudaGetErrorString(error), error); \ + return; \ + } \ + } while (0) + +// RAII class for CUDA resources +class CudaMemory +{ + public: + CudaMemory(size_t size) + { + CUDA_CHECK(cudaMalloc(&device_ptr, size)); + } + ~CudaMemory() + { + CUDA_CHECK(cudaFree(device_ptr)); + } + void* get() const { return device_ptr; } + + private: + void* device_ptr; +}; template void discardResult(const T&) @@ -35,97 +63,308 @@ void discardResult(const T&) void prologue() { int deviceCount; - discardResult(cudaGetDeviceCount(&deviceCount)); - if (!deviceCount) { + cudaError_t error = cudaGetDeviceCount(&deviceCount); + if (error != cudaSuccess || !deviceCount) { std::cerr << "No " << GPUPLATFORM << " devices found" << std::endl; + return; } + for (int iDevice = 0; iDevice < deviceCount; ++iDevice) { cudaDeviceProp deviceProp; - discardResult(cudaGetDeviceProperties(&deviceProp, iDevice)); - std::cout << GPUPLATFORM << " Device " << iDevice << ": " << deviceProp.name << std::endl; + cudaGetDeviceProperties(&deviceProp, iDevice); + printf("%s Device %d: %s\n", GPUPLATFORM, iDevice, deviceProp.name); } } using MatSym3DGPU = o2::math_utils::SMatrixGPU>; using MatSym3D = ROOT::Math::SMatrix>; +using Mat3DGPU = o2::math_utils::SMatrixGPU>; +using Mat3D = ROOT::Math::SMatrix>; + +__device__ void floatToBinaryString(float number, char* buffer) +{ + unsigned char* bytePointer = reinterpret_cast(&number); + for (int byteIndex = 3; byteIndex >= 0; --byteIndex) { + unsigned char byte = bytePointer[byteIndex]; + for (int bitIndex = 7; bitIndex >= 0; --bitIndex) { + buffer[(3 - byteIndex) * 8 + (7 - bitIndex)] = (byte & (1 << bitIndex)) ? '1' : '0'; + } + } + buffer[32] = '\0'; // Null terminator +} + +template +__device__ void printMatrix(const MatrixType& matrix, const char* name, const bool IsBinary) +{ + char buffer[33]; + if (IsBinary) { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + floatToBinaryString(matrix(i, j), buffer); + printf("%s(%d,%d) = %s\n", name, i, j, buffer); + } + } + } else { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + printf("%s(%i,%i) = %f\n", name, i, j, matrix(i, j)); + } + } + } +} + +// Function to compare two matrices element-wise with a specified tolerance +template +void compareMatrices(const MatrixType& mat1, const MatrixType& mat2, float tolerance) +{ + auto tol = boost::test_tools::tolerance(tolerance); + + for (unsigned int i = 0; i < mat1.kRows; ++i) { + for (unsigned int j = 0; j < mat1.kCols; ++j) { + BOOST_TEST(mat1(i, j) == mat2(i, j), tol); + } + } +} +// Invert test for symmetric matrix template -__global__ void invertSymMatrixKernel(o2::math_utils::SMatrixGPU>* matrix) +__global__ void invertSymMatrixKernel(MatSym3DGPU* matrix) { + const bool IsBinary = true; + printf("\nStart inverting symmetric matrix\n"); MatSym3DGPU smat2 = *matrix; - printf("A(0,0) = %f, A(0,1) = %f, A(0,2) = %f\n", (*matrix)(0, 0), (*matrix)(0, 1), (*matrix)(0, 2)); - printf("A(1,0) = %f, A(1,1) = %f, A(1,2) = %f\n", (*matrix)(1, 0), (*matrix)(1, 1), (*matrix)(1, 2)); - printf("A(2,0) = %f, A(2,1) = %f, A(2,2) = %f\n", (*matrix)(2, 0), (*matrix)(2, 1), (*matrix)(2, 2)); - - printf("B(0,0) = %f, B(0,1) = %f, B(0,2) = %f\n", smat2(0, 0), smat2(0, 1), smat2(0, 2)); - printf("B(1,0) = %f, B(1,1) = %f, B(1,2) = %f\n", smat2(1, 0), smat2(1, 1), smat2(1, 2)); - printf("B(2,0) = %f, B(2,1) = %f, B(2,2) = %f\n", smat2(2, 0), smat2(2, 1), smat2(2, 2)); + printMatrix(*matrix, "A", IsBinary); + printMatrix(smat2, "B", IsBinary); printf("\nInverting A...\n"); matrix->Invert(); - printf("A(0,0) = %f, A(0,1) = %f, A(0,2) = %f\n", (*matrix)(0, 0), (*matrix)(0, 1), (*matrix)(0, 2)); - printf("A(1,0) = %f, A(1,1) = %f, A(1,2) = %f\n", (*matrix)(1, 0), (*matrix)(1, 1), (*matrix)(1, 2)); - printf("A(2,0) = %f, A(2,1) = %f, A(2,2) = %f\n", (*matrix)(2, 0), (*matrix)(2, 1), (*matrix)(2, 2)); + printMatrix(*matrix, "A", IsBinary); printf("\nC = (A^-1) * B...\n"); auto smat3 = (*matrix) * smat2; - printf("C(0,0) = %f, C(0,1) = %f, C(0,2) = %f\n", smat3(0, 0), smat3(0, 1), smat3(0, 2)); - printf("C(1,0) = %f, C(1,1) = %f, C(1,2) = %f\n", smat3(1, 0), smat3(1, 1), smat3(1, 2)); - printf("C(2,0) = %f, C(2,1) = %f, C(2,2) = %f\n", smat3(2, 0), smat3(2, 1), smat3(2, 2)); + printMatrix(smat3, "C", IsBinary); printf("\nEvaluating...\n"); MatSym3DGPU tmp; o2::math_utils::AssignSym::Evaluate(tmp, smat3); - printf("A(0,0) = %f, A(0,1) = %f, A(0,2) = %f\n", tmp(0, 0), tmp(0, 1), tmp(0, 2)); - printf("A(1,0) = %f, A(1,1) = %f, A(1,2) = %f\n", tmp(1, 0), tmp(1, 1), tmp(1, 2)); - printf("A(2,0) = %f, A(2,1) = %f, A(2,2) = %f\n", tmp(2, 0), tmp(2, 1), tmp(2, 2)); - (*matrix) = tmp; + printMatrix(tmp, "A", IsBinary); + *matrix = tmp; + printf("\n-------------------------------------------------------\n"); +} + +// Invert test for general matrix +template +__global__ void invertMatrixKernel(Mat3DGPU* matrix) +{ + const bool IsBinary = true; + printf("\nStart inverting general matrix\n"); + Mat3DGPU smat2 = *matrix; + + printMatrix(*matrix, "A", IsBinary); + printMatrix(smat2, "B", IsBinary); + + printf("\nInverting A...\n"); + matrix->Invert(); + + printMatrix(*matrix, "A", IsBinary); + + printf("\nC = (A^-1) * B...\n"); + auto smat3 = (*matrix) * smat2; + + printMatrix(smat3, "C", IsBinary); + + printf("\nEvaluating...\n"); + Mat3DGPU tmp; + o2::math_utils::Assign, o2::math_utils::MatRepStdGPU>::Evaluate(tmp, smat3); + + printMatrix(tmp, "A", IsBinary); + *matrix = tmp; + printf("\n-------------------------------------------------------\n"); } -struct GPUSMatrixImplFixture { - GPUSMatrixImplFixture() : SMatrix3D_d(nullptr) +struct GPUSMatrixImplFixtureSolo { + GPUSMatrixImplFixtureSolo() : i(3), SMatrixSym3D_d(sizeof(MatSym3DGPU)), SMatrixSym3D_h(), SMatrix3D_d(sizeof(Mat3DGPU)), SMatrix3D_h() { prologue(); + initializeMatrices(); + printMatrixSizes(); + } - SMatrix3D_h(0, 0) = 1; - SMatrix3D_h(1, 1) = 2; - SMatrix3D_h(2, 2) = 3; - SMatrix3D_h(0, 1) = 4; - SMatrix3D_h(0, 2) = 5; - SMatrix3D_h(1, 2) = 6; + ~GPUSMatrixImplFixtureSolo() = default; - discardResult(cudaMalloc(&SMatrix3D_d, sizeof(MatSym3DGPU))); - discardResult(cudaMemcpy(SMatrix3D_d, &SMatrix3D_h, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + void initializeMatrices() + { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution dis(1.0, 10.0); + + // Initialize host matrices with random values + for (int i = 0; i < 3; ++i) { + for (int j = i; j < 3; ++j) { + SMatrixSym3D_h(i, j) = dis(gen); + SMatrix3D_h(i, j) = dis(gen); + } + } - std::cout << "sizeof(MatSym3DGPU) = " << sizeof(MatSym3DGPU) << std::endl; - std::cout << "sizeof(MatSym3D) = " << sizeof(MatSym3D) << std::endl; - i = 3; + // Copy host matrices to device + CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d.get(), &SMatrixSym3D_h, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + CUDA_CHECK(cudaMemcpy(SMatrix3D_d.get(), &SMatrix3D_h, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); } - ~GPUSMatrixImplFixture() + void printMatrixSizes() const { - discardResult(cudaFree(SMatrix3D_d)); + printf("sizeof(MatSym3DGPU) = %zu\n", sizeof(MatSym3DGPU)); + printf("sizeof(MatSym3D) = %zu\n", sizeof(MatSym3D)); + printf("sizeof(Mat3DGPU) = %zu\n", sizeof(Mat3DGPU)); + printf("sizeof(Mat3D) = %zu\n", sizeof(Mat3D)); } int i; - MatSym3DGPU* SMatrix3D_d; // device ptr - MatSym3D SMatrix3D_h; + CudaMemory SMatrixSym3D_d; + MatSym3D SMatrixSym3D_h; + CudaMemory SMatrix3D_d; + Mat3D SMatrix3D_h; }; -BOOST_FIXTURE_TEST_CASE(DummyFixtureUsage, GPUSMatrixImplFixture) +BOOST_FIXTURE_TEST_CASE(MatrixInversion, GPUSMatrixImplFixtureSolo) { - invertSymMatrixKernel<<<1, 1>>>(SMatrix3D_d); - discardResult(cudaDeviceSynchronize()); + float tolerance = 0.00001f; + + invertSymMatrixKernel<<<1, 1>>>(static_cast(SMatrixSym3D_d.get())); + cudaDeviceSynchronize(); + CUDA_CHECK(cudaGetLastError()); + + CUDA_CHECK(cudaMemcpy(&SMatrixSym3D_h, SMatrixSym3D_d.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + + MatSym3D identitySym; + identitySym(0, 0) = 1; + identitySym(1, 1) = 1; + identitySym(2, 2) = 1; + compareMatrices(SMatrixSym3D_h, identitySym, tolerance); + + invertMatrixKernel<<<1, 1>>>(static_cast(SMatrix3D_d.get())); + cudaDeviceSynchronize(); + CUDA_CHECK(cudaGetLastError()); - discardResult(cudaMemcpy(&SMatrix3D_h, SMatrix3D_d, sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + CUDA_CHECK(cudaMemcpy(&SMatrix3D_h, SMatrix3D_d.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); - MatSym3D identity; + Mat3D identity; identity(0, 0) = 1; identity(1, 1) = 1; identity(2, 2) = 1; - BOOST_TEST(SMatrix3D_h == identity); + compareMatrices(SMatrix3D_h, identity, tolerance); +} + +struct GPUSMatrixImplFixtureDuo { + GPUSMatrixImplFixtureDuo() : i(3), SMatrixSym3D_d_A(sizeof(MatSym3DGPU)), SMatrixSym3D_h_A(), SMatrix3D_d_A(sizeof(Mat3DGPU)), SMatrix3D_h_A(), SMatrixSym3D_d_B(sizeof(MatSym3DGPU)), SMatrixSym3D_h_B(), SMatrix3D_d_B(sizeof(Mat3DGPU)), SMatrix3D_h_B() + { + prologue(); + initializeMatrices(); + printMatrixSizes(); + } + + ~GPUSMatrixImplFixtureDuo() = default; + + void initializeMatrices() + { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution dis(1.0, 10.0); + + // Initialize host matrices with random values + for (int i = 0; i < 3; ++i) { + for (int j = i; j < 3; ++j) { + SMatrixSym3D_h_A(i, j) = dis(gen); + SMatrix3D_h_A(i, j) = dis(gen); + + SMatrixSym3D_h_B(i, j) = dis(gen); + SMatrix3D_h_B(i, j) = dis(gen); + } + } + + // Copy host matrices to device + CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d_A.get(), &SMatrixSym3D_h_A, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + CUDA_CHECK(cudaMemcpy(SMatrix3D_d_A.get(), &SMatrix3D_h_A, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); + + CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d_B.get(), &SMatrixSym3D_h_B, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + CUDA_CHECK(cudaMemcpy(SMatrix3D_d_B.get(), &SMatrix3D_h_B, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); + } + + void printMatrixSizes() const + { + printf("sizeof(MatSym3DGPU) = %zu\n", sizeof(MatSym3DGPU)); + printf("sizeof(MatSym3D) = %zu\n", sizeof(MatSym3D)); + printf("sizeof(Mat3DGPU) = %zu\n", sizeof(Mat3DGPU)); + printf("sizeof(Mat3D) = %zu\n", sizeof(Mat3D)); + } + + int i; + CudaMemory SMatrixSym3D_d_A; + MatSym3D SMatrixSym3D_h_A; + + CudaMemory SMatrixSym3D_d_B; + MatSym3D SMatrixSym3D_h_B; + + CudaMemory SMatrix3D_d_A; + Mat3D SMatrix3D_h_A; + + CudaMemory SMatrix3D_d_B; + Mat3D SMatrix3D_h_B; +}; + +// Copy test for symmetric matrix +template +__global__ void copySymMatrixKernel( + MatSym3DGPU* srcMatrix, + MatSym3DGPU* dstMatrix) +{ + const bool IsBinary = true; + printf("\nStart copying general matrix\n"); + printMatrix(*dstMatrix, "Before copying: ", IsBinary); + printf("\nCopied values:\n"); + printMatrix(*srcMatrix, "Copied values: ", IsBinary); + printf("\nResult:\n"); + *dstMatrix = *srcMatrix; + printMatrix(*dstMatrix, "After copying: ", IsBinary); + printf("\n-------------------------------------------------------\n"); +} + +// Copy test for general matrix +template +__global__ void copyMatrixKernel( + Mat3DGPU* srcMatrix, + Mat3DGPU* dstMatrix) +{ + const bool IsBinary = true; + printf("\nStart copying general matrix\n"); + printMatrix(*dstMatrix, "Before copying: ", IsBinary); + printf("\nCopied values:\n"); + printMatrix(*srcMatrix, "Copied values: ", IsBinary); + printf("\nResult:\n"); + *dstMatrix = *srcMatrix; + printMatrix(*dstMatrix, "After copying: ", IsBinary); + printf("\n-------------------------------------------------------\n"); +} + +BOOST_FIXTURE_TEST_CASE(TestMatrixCopyingAndComparison, GPUSMatrixImplFixtureDuo) +{ + copySymMatrixKernel<<<1, 1>>>(static_cast(SMatrixSym3D_d_A.get()), static_cast(SMatrixSym3D_d_B.get())); + cudaDeviceSynchronize(); + CUDA_CHECK(cudaGetLastError()); + + CUDA_CHECK(cudaMemcpy(&SMatrixSym3D_h_B, SMatrixSym3D_d_B.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + + compareMatrices(SMatrixSym3D_h_A, SMatrixSym3D_h_B, 0.0); + + copyMatrixKernel<<<1, 1>>>(static_cast(SMatrix3D_d_A.get()), static_cast(SMatrix3D_d_B.get())); + cudaDeviceSynchronize(); + CUDA_CHECK(cudaGetLastError()); + + CUDA_CHECK(cudaMemcpy(&SMatrix3D_h_B, SMatrix3D_d_B.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); + + compareMatrices(SMatrix3D_h_A, SMatrix3D_h_B, 0.0); } \ No newline at end of file From 91dd4df3c7a3a8b8f7e723b0325d18fa053aedc3 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner <48915672+matthias-kleiner@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:02:05 +0200 Subject: [PATCH 0066/2205] TPC: improving simulation of distortions in MC (#13345) * TPC: improving simulation of distortions in MC - adding option to recalculate (merging) the distortions in case of large scaling - accessing the distortions of the derivative map at the distorted position for better consistency with corrections * TPC: Renaming variables --- .../include/TPCSimulation/Digitizer.h | 6 +- Detectors/TPC/simulation/src/Digitizer.cxx | 32 ++++++- .../include/TPCSpaceCharge/SpaceCharge.h | 17 +++- Detectors/TPC/spacecharge/src/SpaceCharge.cxx | 95 ++++++++++++++++--- .../src/TPCDigitizerSpec.cxx | 9 ++ 5 files changed, 144 insertions(+), 15 deletions(-) diff --git a/Detectors/TPC/simulation/include/TPCSimulation/Digitizer.h b/Detectors/TPC/simulation/include/TPCSimulation/Digitizer.h index e2c7e9ec7d175..1c76dcaaeedd3 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/Digitizer.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/Digitizer.h @@ -138,6 +138,9 @@ class Digitizer void setMeanLumiDistortions(float meanLumi); void setMeanLumiDistortionsDerivative(float meanLumi); + /// in case of scaled distortions, the distortions can be recalculated to ensure consistent distortions and corrections + void recalculateDistortions(); + private: DigitContainer mDigitContainer; ///< Container for the Digits std::unique_ptr mSpaceCharge; ///< Handler of full distortions (static + IR dependant) @@ -151,7 +154,8 @@ class Digitizer bool mUseSCDistortions = false; ///< Flag to switch on the use of space-charge distortions int mDistortionScaleType = 0; ///< type=0: no scaling of distortions, type=1 distortions without any scaling, type=2 distortions scaling with lumi float mLumiScaleFactor = 0; ///< value used to scale the derivative map - ClassDefNV(Digitizer, 2); + bool mUseScaledDistortions = false; ///< whether the distortions are already scaled + ClassDefNV(Digitizer, 3); }; } // namespace tpc } // namespace o2 diff --git a/Detectors/TPC/simulation/src/Digitizer.cxx b/Detectors/TPC/simulation/src/Digitizer.cxx index 38968b3b38bb9..290cd84df9a6b 100644 --- a/Detectors/TPC/simulation/src/Digitizer.cxx +++ b/Detectors/TPC/simulation/src/Digitizer.cxx @@ -83,7 +83,7 @@ void Digitizer::process(const std::vector& hits, if (mDistortionScaleType == 1) { mSpaceCharge->distortElectron(posEle); } else if (mDistortionScaleType == 2) { - mSpaceCharge->distortElectron(posEle, mSpaceChargeDer.get(), mLumiScaleFactor); + mSpaceCharge->distortElectron(posEle, (mUseScaledDistortions ? nullptr : mSpaceChargeDer.get()), mLumiScaleFactor); } /// Remove electrons that end up more than three sigma of the hit's average diffusion away from the current sector @@ -237,3 +237,33 @@ void Digitizer::setMeanLumiDistortionsDerivative(float meanLumi) { mSpaceChargeDer->setMeanLumi(meanLumi); } + +void Digitizer::recalculateDistortions() +{ + if (!mSpaceCharge || !mSpaceChargeDer) { + LOGP(info, "Average or derivative distortions not set"); + return; + } + + // recalculate distortions only in case the inst lumi differs from the avg lumi + if (mSpaceCharge->getMeanLumi() != CorrMapParam::Instance().lumiInst) { + for (int iside = 0; iside < 2; ++iside) { + const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C; + // this needs to be done only once + LOGP(info, "Calculating corrections for average distortions"); + mSpaceCharge->calcGlobalCorrWithGlobalDistIterative(side, nullptr, 0); + + LOGP(info, "Calculating corrections for derivative distortions"); + mSpaceChargeDer->calcGlobalCorrWithGlobalDistIterative(side, nullptr, 0); + + LOGP(info, "Calculating scaled distortions with scaling factor {}", mLumiScaleFactor); + mSpaceCharge->calcGlobalDistWithGlobalCorrIterative(side, mSpaceChargeDer.get(), mLumiScaleFactor); + } + // set new lumi of avg map + mSpaceCharge->setMeanLumi(CorrMapParam::Instance().lumiInst); + } else { + LOGP(info, "Inst. lumi {} is same as mean lumi {}. Skip recalculation of distortions", CorrMapParam::Instance().lumiInst, mSpaceCharge->getMeanLumi()); + } + + mUseScaledDistortions = true; +} diff --git a/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h b/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h index deed612e846f8..4362d95738692 100644 --- a/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h +++ b/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h @@ -354,7 +354,20 @@ class SpaceCharge /// \param approachR when the difference between the desired r coordinate and the position of the global correction is deltaR, approach the desired r coordinate by deltaR * \p approachR. /// \param approachPhi when the difference between the desired phi coordinate and the position of the global correction is deltaPhi, approach the desired phi coordinate by deltaPhi * \p approachPhi. /// \param diffCorr if the absolute differences from the interpolated values for the global corrections from the last iteration compared to the current iteration is smaller than this value, set converged to true for current global distortion - void calcGlobalDistWithGlobalCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter = 100, const DataT approachZ = 0.5, const DataT approachR = 0.5, const DataT approachPhi = 0.5, const DataT diffCorr = 1e-6); + /// \param type whether to calculate distortions or corrections + void calcGlobalDistWithGlobalCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6, const SpaceCharge* scSCale = nullptr, float scale = 0); + + /// step 5: calculate global distortions using the global corrections (FAST) + /// \param scSCale possible second sc object + /// \param scale scaling for second sc object + void calcGlobalDistWithGlobalCorrIterative(const Side side, const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); + void calcGlobalDistWithGlobalCorrIterative(const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); + + /// calculate global corrections from global distortions + /// \param scSCale possible second sc object + /// \param scale scaling for second sc object + void calcGlobalCorrWithGlobalDistIterative(const Side side, const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); + void calcGlobalCorrWithGlobalDistIterative(const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); /// \return returns number of vertices in z direction unsigned short getNZVertices() const { return mParamGrid.NZVertices; } @@ -1359,6 +1372,8 @@ class SpaceCharge /// set potentialsdue to ROD misalignment void initRodAlignmentVoltages(const MisalignmentType misalignmentType, const FCType fcType, const int sector, const Side side, const float deltaPot); + void calcGlobalDistCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr, const SpaceCharge* scSCale, float scale, const Type type); + ClassDefNV(SpaceCharge, 6); }; diff --git a/Detectors/TPC/spacecharge/src/SpaceCharge.cxx b/Detectors/TPC/spacecharge/src/SpaceCharge.cxx index e51b8de0850f6..6748de7ae9916 100644 --- a/Detectors/TPC/spacecharge/src/SpaceCharge.cxx +++ b/Detectors/TPC/spacecharge/src/SpaceCharge.cxx @@ -697,12 +697,59 @@ void SpaceCharge::calcEField(const Side side) } template -void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr) +void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr, const SpaceCharge* scSCale, float scale) +{ + calcGlobalDistCorrIterative(globCorr, maxIter, approachZ, approachR, approachPhi, diffCorr, scSCale, scale, Type::Distortions); +} + +template +void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const Side side, const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr) +{ + calcGlobalDistCorrIterative(getGlobalCorrInterpolator(side), maxIter, approachZ, approachR, approachPhi, diffCorr, scSCale, scale, Type::Distortions); +} + +template +void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr) +{ +#pragma omp parallel for num_threads(sNThreads) + for (int iside = 0; iside < FNSIDES; ++iside) { + const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C; + calcGlobalDistWithGlobalCorrIterative(side, scSCale, scale, maxIter, approachZ, approachR, approachPhi, diffCorr); + } +} + +template +void SpaceCharge::calcGlobalCorrWithGlobalDistIterative(const Side side, const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr) +{ + calcGlobalDistCorrIterative(getGlobalDistInterpolator(side), maxIter, approachZ, approachR, approachPhi, diffCorr, scSCale, scale, Type::Corrections); +} + +template +void SpaceCharge::calcGlobalCorrWithGlobalDistIterative(const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr) +{ +#pragma omp parallel for num_threads(sNThreads) + for (int iside = 0; iside < FNSIDES; ++iside) { + const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C; + calcGlobalCorrWithGlobalDistIterative(side, scSCale, scale, maxIter, approachZ, approachR, approachPhi, diffCorr); + } +} + +template +void SpaceCharge::calcGlobalDistCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr, const SpaceCharge* scSCale, float scale, const Type type) { const Side side = globCorr.getSide(); - initContainer(mGlobalDistdR[side], true); - initContainer(mGlobalDistdZ[side], true); - initContainer(mGlobalDistdRPhi[side], true); + if (type == Type::Distortions) { + initContainer(mGlobalDistdR[side], true); + initContainer(mGlobalDistdZ[side], true); + initContainer(mGlobalDistdRPhi[side], true); + } else { + initContainer(mGlobalCorrdR[side], true); + initContainer(mGlobalCorrdZ[side], true); + initContainer(mGlobalCorrdRPhi[side], true); + } + + const auto& scSCaleInterpolator = (type == Type::Distortions) ? scSCale->mInterpolatorGlobalCorr[side] : scSCale->mInterpolatorGlobalDist[side]; + #pragma omp parallel for num_threads(sNThreads) for (unsigned int iPhi = 0; iPhi < mParamGrid.NPhiVertices; ++iPhi) { const DataT phi = getPhiVertex(iPhi, side); @@ -754,13 +801,25 @@ void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const DistCorrInt // interpolate global correction at new point and calculate position of global correction corrdR = globCorr.evaldR(zCurrPos, rCurrPos, phiCurrPos); + if (scSCale && scale != 0) { + corrdR += scale * scSCaleInterpolator.evaldR(zCurrPos, rCurrPos, phiCurrPos); + } const DataT rNewPos = rCurrPos + corrdR; - const DataT corrPhi = globCorr.evaldRPhi(zCurrPos, rCurrPos, phiCurrPos) / rCurrPos; + DataT corrPhi = 0; + if (scSCale && scale != 0) { + corrPhi = scale * scSCaleInterpolator.evaldRPhi(zCurrPos, rCurrPos, phiCurrPos); + } + corrPhi += globCorr.evaldRPhi(zCurrPos, rCurrPos, phiCurrPos); + corrPhi /= rCurrPos; + corrdRPhi = corrPhi * rNewPos; // normalize to new r coordinate const DataT phiNewPos = phiCurrPos + corrPhi; corrdZ = globCorr.evaldZ(zCurrPos, rCurrPos, phiCurrPos); + if (scSCale && scale != 0) { + corrdZ += scale * scSCaleInterpolator.evaldZ(zCurrPos, rCurrPos, phiCurrPos); + } const DataT zNewPos = zCurrPos + corrdZ; // approach desired coordinate @@ -783,15 +842,27 @@ void SpaceCharge::calcGlobalDistWithGlobalCorrIterative(const DistCorrInt lastCorrdRPhi = corrdRPhi; } // set global distortions if algorithm converged or iterations exceed max numbers of iterations - mGlobalDistdR[side](iZ, iR, iPhi) = -corrdR; - mGlobalDistdRPhi[side](iZ, iR, iPhi) = -corrdRPhi; - mGlobalDistdZ[side](iZ, iR, iPhi) = -corrdZ; + if (type == Type::Distortions) { + mGlobalDistdR[side](iZ, iR, iPhi) = -corrdR; + mGlobalDistdRPhi[side](iZ, iR, iPhi) = -corrdRPhi; + mGlobalDistdZ[side](iZ, iR, iPhi) = -corrdZ; + } else { + mGlobalCorrdR[side](iZ, iR, iPhi) = -corrdR; + mGlobalCorrdRPhi[side](iZ, iR, iPhi) = -corrdRPhi; + mGlobalCorrdZ[side](iZ, iR, iPhi) = -corrdZ; + } } } for (unsigned int iR = 0; iR < mParamGrid.NRVertices; ++iR) { - mGlobalDistdR[side](0, iR, iPhi) = 3 * (mGlobalDistdR[side](1, iR, iPhi) - mGlobalDistdR[side](2, iR, iPhi)) + mGlobalDistdR[side](3, iR, iPhi); - mGlobalDistdRPhi[side](0, iR, iPhi) = 3 * (mGlobalDistdRPhi[side](1, iR, iPhi) - mGlobalDistdRPhi[side](2, iR, iPhi)) + mGlobalDistdRPhi[side](3, iR, iPhi); - mGlobalDistdZ[side](0, iR, iPhi) = 3 * (mGlobalDistdZ[side](1, iR, iPhi) - mGlobalDistdZ[side](2, iR, iPhi)) + mGlobalDistdZ[side](3, iR, iPhi); + if (type == Type::Distortions) { + mGlobalDistdR[side](0, iR, iPhi) = 3 * (mGlobalDistdR[side](1, iR, iPhi) - mGlobalDistdR[side](2, iR, iPhi)) + mGlobalDistdR[side](3, iR, iPhi); + mGlobalDistdRPhi[side](0, iR, iPhi) = 3 * (mGlobalDistdRPhi[side](1, iR, iPhi) - mGlobalDistdRPhi[side](2, iR, iPhi)) + mGlobalDistdRPhi[side](3, iR, iPhi); + mGlobalDistdZ[side](0, iR, iPhi) = 3 * (mGlobalDistdZ[side](1, iR, iPhi) - mGlobalDistdZ[side](2, iR, iPhi)) + mGlobalDistdZ[side](3, iR, iPhi); + } else { + mGlobalCorrdR[side](0, iR, iPhi) = 3 * (mGlobalCorrdR[side](1, iR, iPhi) - mGlobalCorrdR[side](2, iR, iPhi)) + mGlobalCorrdR[side](3, iR, iPhi); + mGlobalCorrdRPhi[side](0, iR, iPhi) = 3 * (mGlobalCorrdRPhi[side](1, iR, iPhi) - mGlobalCorrdRPhi[side](2, iR, iPhi)) + mGlobalCorrdRPhi[side](3, iR, iPhi); + mGlobalCorrdZ[side](0, iR, iPhi) = 3 * (mGlobalCorrdZ[side](1, iR, iPhi) - mGlobalCorrdZ[side](2, iR, iPhi)) + mGlobalCorrdZ[side](3, iR, iPhi); + } } } } @@ -1535,7 +1606,7 @@ void SpaceCharge::distortElectron(GlobalPosition3D& point, const SpaceCha // scale distortions if requested if (scSCale && scale != 0) { - scSCale->getDistortions(point.X(), point.Y(), point.Z(), side, distXTmp, distYTmp, distZTmp); + scSCale->getDistortions(point.X() + distX, point.Y() + distY, point.Z() + distZ, side, distXTmp, distYTmp, distZTmp); distX += distXTmp * scale; distY += distYTmp * scale; distZ += distZTmp * scale; diff --git a/Steer/DigitizerWorkflow/src/TPCDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/TPCDigitizerSpec.cxx index 3f24bb1a9ee12..e1f366080fd9f 100644 --- a/Steer/DigitizerWorkflow/src/TPCDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/TPCDigitizerSpec.cxx @@ -120,6 +120,9 @@ class TPCDPLDigitizerTask : public BaseDPLDigitizer mWithMCTruth = o2::conf::DigiParams::Instance().mctruth; auto triggeredMode = ic.options().get("TPCtriggered"); + mRecalcDistortions = !(ic.options().get("do-not-recalculate-distortions")); + const int nthreadsDist = ic.options().get("n-threads-distortions"); + SC::setNThreads(nthreadsDist); mUseCalibrationsFromCCDB = ic.options().get("TPCuseCCDB"); mMeanLumiDistortions = ic.options().get("meanLumiDistortions"); mMeanLumiDistortionsDerivative = ic.options().get("meanLumiDistortionsDerivative"); @@ -220,6 +223,9 @@ class TPCDPLDigitizerTask : public BaseDPLDigitizer if (mDistortionType == 2) { pc.inputs().get("tpcdistortionsderiv"); mDigitizer.setLumiScaleFactor(); + if (mRecalcDistortions) { + mDigitizer.recalculateDistortions(); + } } } @@ -475,6 +481,7 @@ class TPCDPLDigitizerTask : public BaseDPLDigitizer int mDistortionType = 0; float mMeanLumiDistortions = -1; float mMeanLumiDistortionsDerivative = -1; + bool mRecalcDistortions = false; }; o2::framework::DataProcessorSpec getTPCDigitizerSpec(int channel, bool writeGRP, bool mctruth, bool internalwriter, int distortionType) @@ -513,6 +520,8 @@ o2::framework::DataProcessorSpec getTPCDigitizerSpec(int channel, bool writeGRP, {"TPCuseCCDB", VariantType::Bool, false, {"true: load calibrations from CCDB; false: use random calibratoins"}}, {"meanLumiDistortions", VariantType::Float, -1.f, {"override lumi of distortion object if >=0"}}, {"meanLumiDistortionsDerivative", VariantType::Float, -1.f, {"override lumi of derivative distortion object if >=0"}}, + {"do-not-recalculate-distortions", VariantType::Bool, false, {"Do not recalculate the distortions"}}, + {"n-threads-distortions", VariantType::Int, 4, {"Number of threads used for the calculation of the distortions"}}, }}; } From 7e0303096b77142c466cf52080cdea19eed29f05 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 7 Aug 2024 13:39:15 +0200 Subject: [PATCH 0067/2205] Improve error message --- GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index af603035bd017..3c06bb7a3a3c5 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -115,13 +115,12 @@ int GPUChainTracking::RunTPCCompression() getKernelTimer(RecoStep::TPCCompression, 0, outputSize); break; case 4: - static_assert((nBlocksMulti & 1) && nBlocksMulti >= 3); runKernel(GetGridBlkStep(nBlocksMulti, outputStream, RecoStep::TPCCompression)); getKernelTimer(RecoStep::TPCCompression, 0, outputSize); break; default: - GPUError("Invalid compression kernel selected."); + GPUError("Invalid compression kernel %d selected.", (int)ProcessingSettings().tpcCompressionGatherModeKernel); return 1; } if (ProcessingSettings().tpcCompressionGatherMode == 3) { From f406895da277dddc587e329234eaa75ea8d00205 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 8 Aug 2024 19:21:13 +0200 Subject: [PATCH 0068/2205] Fix compiler warnings for FATAL -> fatal (#13362) --- Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx index 0a462726deb01..3484cb97279b5 100644 --- a/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx +++ b/Detectors/CTP/workflowScalers/src/ctpCCDBManager.cxx @@ -48,7 +48,7 @@ int ctpCCDBManager::saveRunScalersToCCDB(CTPRunScalers& scalers, long timeStart, if (ret == 0) { LOG(info) << "CTP scalers saved in ccdb:" << mCCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; } else { - LOG(FATAL) << "Problem writing to database ret:" << ret; + LOG(fatal) << "Problem writing to database ret:" << ret; } return ret; } @@ -76,7 +76,7 @@ int ctpCCDBManager::saveRunScalersToQCDB(CTPRunScalers& scalers, long timeStart, if (ret == 0) { LOG(info) << "CTP scalers saved in qcdb:" << mQCDBHost << " run:" << scalers.getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; } else { - LOG(FATAL) << "CTP scalers Problem writing to database qcdb ret:" << ret; + LOG(fatal) << "CTP scalers Problem writing to database qcdb ret:" << ret; } return ret; } @@ -103,7 +103,7 @@ int ctpCCDBManager::saveRunConfigToCCDB(CTPConfiguration* cfg, long timeStart) if (ret == 0) { LOG(info) << "CTP config saved in ccdb:" << mCCDBHost << " run:" << cfg->getRunNumber() << " tmin:" << tmin << " tmax:" << tmax; } else { - LOG(FATAL) << "CTPConfig: Problem writing to database ret:" << ret; + LOG(fatal) << "CTPConfig: Problem writing to database ret:" << ret; } return ret; } From 6c44a3f03fa0ab8fd248470dcbf1faece44390c0 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 8 Aug 2024 18:35:58 +0200 Subject: [PATCH 0069/2205] GPU CMake: Make compatible to ROCm >= 6.2 --- dependencies/FindO2GPU.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index af7da049e0ff6..739b57c9c7eeb 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -268,7 +268,7 @@ if(ENABLE_HIP) set_target_properties(roc::rocthrust PROPERTIES IMPORTED_GLOBAL TRUE) message(STATUS "HIP Found (${hip_HIPCC_EXECUTABLE} version ${hip_VERSION})") set(O2_HIP_CMAKE_CXX_FLAGS "-fgpu-defer-diag -mllvm -amdgpu-enable-lower-module-lds=false -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -Wno-invalid-constexpr -Wno-ignored-optimization-argument -Wno-unused-private-field -Wno-pass-failed") - if(hip_VERSION VERSION_GREATER_EQUAL "6.0") + if(hip_VERSION VERSION_GREATER_EQUAL "6.0" AND NOT hip_VERSION VERSION_GREATER_EQUAL "6.2") set(O2_HIP_CMAKE_CXX_FLAGS "${O2_HIP_CMAKE_CXX_FLAGS} -mllvm -amdgpu-legacy-sgpr-spill-lowering=true") # TODO: Cleanup endif() set(O2_HIP_CMAKE_LINK_FLAGS "-Wno-pass-failed") From feb58729b0d5f88217a3c521b783c45fed26449b Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 8 Aug 2024 14:39:22 +0200 Subject: [PATCH 0070/2205] Consistency fix in G4 physics model - fix EMCAL sampling factor improvement for G4 physics model (options): - offer all physics lists with and without EMV (fast em physics) mode - better consistency between enum name and actual physics string - possibility that user gives own string for physics list EMCAL detector: - provide a reasonable sampling factor also for Geant4 physics lists not mentioned so far (fixing a problem when we switch from FTFP_BERT_EMV to FTFP_BERT for instance) --- Common/SimConfig/include/SimConfig/G4Params.h | 17 ++++++++++++----- Common/SimConfig/src/G4Params.cxx | 11 ++++++++++- Detectors/EMCAL/base/src/Geometry.cxx | 6 ++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Common/SimConfig/include/SimConfig/G4Params.h b/Common/SimConfig/include/SimConfig/G4Params.h index c6a5bc0882320..fd36ae046d520 100644 --- a/Common/SimConfig/include/SimConfig/G4Params.h +++ b/Common/SimConfig/include/SimConfig/G4Params.h @@ -22,17 +22,24 @@ namespace conf // enumerating the possible G4 physics settings enum class EG4Physics { - kFTFP_BERT_optical = 0, /* just ordinary */ - kFTFP_BERT_optical_biasing = 1, /* with biasing enabled */ - kFTFP_INCLXX_optical = 2, /* special INCL++ version */ - kFTFP_BERT_HP_optical = 3 /* enable low energy neutron transport */ + kFTFP_BERT_optical = 0, /* just ordinary */ + kFTFP_BERT_optical_biasing = 1, /* with biasing enabled */ + kFTFP_INCLXX_optical = 2, /* special INCL++ version */ + kFTFP_BERT_HP_optical = 3, /* enable low energy neutron transport */ + kFTFP_BERT_EMV_optical = 4, /* just ordinary with faster electromagnetic physics */ + kFTFP_BERT_EMV_optical_biasing = 5, /* with biasing enabled with faster electromagnetic physics */ + kFTFP_INCLXX_EMV_optical = 6, /* special INCL++ version */ + kFTFP_BERT_EMV_HP_optical = 7, /* enable low energy neutron transport */ + kUSER = 8 /* allows to give own string combination */ }; // parameters to influence the G4 engine struct G4Params : public o2::conf::ConfigurableParamHelper { - EG4Physics physicsmode = EG4Physics::kFTFP_BERT_optical; // physics mode with which to configure G4 + EG4Physics physicsmode = EG4Physics::kFTFP_BERT_EMV_optical; // default physics mode with which to configure G4 std::string configMacroFile = ""; // a user provided g4Config.in file (otherwise standard one fill be taken) + std::string userPhysicsList = ""; // possibility to directly give physics list as string + std::string const& getPhysicsConfigString() const; O2ParamDef(G4Params, "G4"); diff --git a/Common/SimConfig/src/G4Params.cxx b/Common/SimConfig/src/G4Params.cxx index 48f7a1c240d7b..37625d914a85b 100644 --- a/Common/SimConfig/src/G4Params.cxx +++ b/Common/SimConfig/src/G4Params.cxx @@ -19,12 +19,21 @@ namespace conf namespace { -static const std::string confstrings[4] = {"FTFP_BERT_EMV+optical", "FTFP_BERT_EMV+optical+biasing", "FTFP_INCLXX_EMV+optical", +static const std::string confstrings[8] = {"FTFP_BERT+optical", + "FTFP_BERT+optical+biasing", + "FTFP_INCLXX+optical", + "FTFP_BERT_HP+optical", + "FTFP_BERT_EMV+optical", + "FTFP_BERT_EMV+optical+biasing", + "FTFP_INCLXX_EMV+optical", "FTFP_BERT_HP_EMV+optical"}; } std::string const& G4Params::getPhysicsConfigString() const { + if (physicsmode == o2::conf::EG4Physics::kUSER) { + return userPhysicsList; + } return confstrings[(int)physicsmode]; } diff --git a/Detectors/EMCAL/base/src/Geometry.cxx b/Detectors/EMCAL/base/src/Geometry.cxx index 5d4b793525e20..920dc24823e83 100644 --- a/Detectors/EMCAL/base/src/Geometry.cxx +++ b/Detectors/EMCAL/base/src/Geometry.cxx @@ -309,6 +309,9 @@ void Geometry::DefineSamplingFraction(const std::string_view mcname, const std:: } Float_t samplingFactorTranportModel = 1.; + // Note: The sampling factors are chosen so that results from the simulation + // engines correspond well with testbeam data + if (contains(mcname, "Geant3")) { samplingFactorTranportModel = 1.; // 0.988 // Do nothing } else if (contains(mcname, "Fluka")) { @@ -318,6 +321,9 @@ void Geometry::DefineSamplingFraction(const std::string_view mcname, const std:: LOG(info) << "Selected physics list: " << physicslist; // sampling factors for different Geant4 physics list // GEANT4 10.7 -> EMCAL-784 + + // set a default (there may be many physics list strings) + samplingFactorTranportModel = 0.81; if (physicslist == "FTFP_BERT_EMV+optical") { samplingFactorTranportModel = 0.821; } else if (physicslist == "FTFP_BERT_EMV+optical+biasing") { From ded3e55a697cfc15f478e05097cddadeeda5b45c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 9 Aug 2024 10:33:27 +0200 Subject: [PATCH 0071/2205] GPU Cmake: allow unsupported GCC only if we don't autodetect CUDA --- dependencies/FindO2GPU.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index 739b57c9c7eeb..f023a90847409 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -111,10 +111,13 @@ if(ENABLE_CUDA) endif() endif() if(CMAKE_CUDA_COMPILER) - set(CMAKE_CUDA_FLAGS "-Xcompiler \"${O2_GPU_CMAKE_CXX_FLAGS_NOSTD}\" ${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --extended-lambda --allow-unsupported-compiler -Xptxas -v -Xcompiler -Wno-attributes") + set(CMAKE_CUDA_FLAGS "-Xcompiler \"${O2_GPU_CMAKE_CXX_FLAGS_NOSTD}\" ${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --extended-lambda -Xptxas -v -Xcompiler -Wno-attributes") if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.3") string(APPEND CMAKE_CUDA_FLAGS " -Xcudafe --diag_suppress=20257") # TODO: Cleanup endif() + if (NOT ENABLE_CUDA STREQUAL "AUTO") + string(APPEND CMAKE_CUDA_FLAGS " --allow-unsupported-compiler") + endif() set(CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE_UPPER} "-Xcompiler \"${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}\" ${CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}") if(CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG") set(CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE_UPPER} "${CMAKE_CUDA_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} -lineinfo -Xptxas -O0 -Xcompiler -O0") From d40ccfa9e2947469eef5f2d3ddd77222e598bffb Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 9 Aug 2024 10:34:35 +0200 Subject: [PATCH 0072/2205] GPU CMake: Set amdgpu-function-calls=true, in case not set by the ROCm scripts / cmake files --- dependencies/FindO2GPU.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index f023a90847409..1e8e72609d16c 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -270,7 +270,7 @@ if(ENABLE_HIP) set(HIP_ENABLED ON) set_target_properties(roc::rocthrust PROPERTIES IMPORTED_GLOBAL TRUE) message(STATUS "HIP Found (${hip_HIPCC_EXECUTABLE} version ${hip_VERSION})") - set(O2_HIP_CMAKE_CXX_FLAGS "-fgpu-defer-diag -mllvm -amdgpu-enable-lower-module-lds=false -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -Wno-invalid-constexpr -Wno-ignored-optimization-argument -Wno-unused-private-field -Wno-pass-failed") + set(O2_HIP_CMAKE_CXX_FLAGS "-fgpu-defer-diag -mllvm -amdgpu-enable-lower-module-lds=false -mllvm -amdgpu-function-calls=true -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -Wno-invalid-constexpr -Wno-ignored-optimization-argument -Wno-unused-private-field -Wno-pass-failed") if(hip_VERSION VERSION_GREATER_EQUAL "6.0" AND NOT hip_VERSION VERSION_GREATER_EQUAL "6.2") set(O2_HIP_CMAKE_CXX_FLAGS "${O2_HIP_CMAKE_CXX_FLAGS} -mllvm -amdgpu-legacy-sgpr-spill-lowering=true") # TODO: Cleanup endif() From 15f38fb5697b4e26152f89b0d323d0da29715ab1 Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 31 Jul 2024 14:33:30 +0200 Subject: [PATCH 0073/2205] Use proper token for creating datamodel-doc PR --- .github/workflows/datamodel-doc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/datamodel-doc.yml b/.github/workflows/datamodel-doc.yml index 0146fbd35fe46..6717a5b08570c 100644 --- a/.github/workflows/datamodel-doc.yml +++ b/.github/workflows/datamodel-doc.yml @@ -70,7 +70,7 @@ jobs: # Send pull request # We need to use "gh" ourselves because alisw/pull-request gets # confused when multiple repos are checked out. - GH_TOKEN=${{ secrets.GITHUB_TOKEN }} gh pr create -B \ + GH_TOKEN="$GITHUB_TOKEN" gh pr create -B \ AliceO2Group:master -H alibuild:auto-datamodel-doc \ --no-maintainer-edit -t 'Automatic data model update' -b "This update \ to the data model documentation was automatically created from \ From 29a6c3991414ce36ca623249c13ce44f247748c6 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner <48915672+matthias-kleiner@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:43:17 +0200 Subject: [PATCH 0074/2205] TPC: adding function to make polynomial fits from scatter points (#13355) --- .../NDPiecewisePolynomials.h | 98 ++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h index 13ce49a142470..6df5ac8c99cab 100644 --- a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h +++ b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h @@ -71,7 +71,7 @@ struct NDPiecewisePolynomialContainer { /// /// For usage see: testMultivarPolynomials.cxx /// -/// TODO: add possibillity to perform the fits on scattered data points (+add weighting of points) +/// TODO: add possibillity to perform the fits with weighting of points /// /// \tparam Dim number of dimensions /// \tparam Degree degree of the polynomials @@ -184,6 +184,11 @@ class NDPiecewisePolynomials : public FlatObject /// \param nAuxiliaryPoints number of points which will be used for the fits (should be at least 2) void performFits(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */]); + /// perform the polynomial fits on scatter points + /// \param x scatter points used to make the fits of size 'y.size() * Dim' as in TLinearFitter + /// \param y response values + void performFits(const std::vector& x, const std::vector& y); + /// load parameters from input file (which were written using the writeToFile method) /// \param inpf input file /// \param name name of the object in the file @@ -537,7 +542,7 @@ void NDPiecewisePolynomials::performFits(const std const bool debug = !(++counter % printDebugForNFits); if (debug) { #ifndef GPUCA_ALIROOT_LIB - LOGP(info, "Peforming fit {} out of {}", counter, nTotalFits); + LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); #endif } @@ -554,6 +559,95 @@ void NDPiecewisePolynomials::performFits(const std } } +template +void NDPiecewisePolynomials::performFits(const std::vector& x, const std::vector& y) +{ + const int nTotalFits = getNPolynomials(); +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); +#endif + + // approximate number of points + unsigned int nPoints = 2 * y.size() / nTotalFits; + + // polynomial index -> indices to datapoints + std::unordered_map> dataPointsIndices; + for (int i = 0; i < nTotalFits; ++i) { + dataPointsIndices[i].reserve(nPoints); + } + + // check for each data point which polynomial to use + for (size_t i = 0; i < y.size(); ++i) { + std::array index; + float xVal[Dim]; + std::copy(x.begin() + i * Dim, x.begin() + i * Dim + Dim, xVal); + setIndex(xVal, index.data()); + + std::array indexClamped{index}; + clamp(xVal, indexClamped.data()); + + // check if data points are in the grid + if (index == indexClamped) { + // index of the polyniomial + const unsigned int idx = getDataIndex(index.data()) / MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); + + // store index to data point + dataPointsIndices[idx].emplace_back(i); + } + } + + // for fitting + MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); + TLinearFitter fitter = pol.getTLinearFitter(); + + unsigned int counter = 0; + const int printDebugForNFits = int(nTotalFits / 20) + 1; + + // temp storage for x and y values for fitting + std::vector xCords; + std::vector response; + + for (int i = 0; i < nTotalFits; ++i) { + const bool debug = !(++counter % printDebugForNFits); + if (debug) { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); +#endif + } + + // store values for fitting + if (dataPointsIndices[i].empty()) { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "No data points to fit"); +#endif + continue; + } + + const auto nP = dataPointsIndices[i].size(); + xCords.reserve(Dim * nP); + response.reserve(nP); + xCords.clear(); + response.clear(); + + // add datapoints to fit + for (size_t j = 0; j < nP; ++j) { + const size_t idxOrig = dataPointsIndices[i][j]; + + // insert x values at the end of xCords + const int idxXStart = idxOrig * Dim; + xCords.insert(xCords.end(), x.begin() + idxXStart, x.begin() + idxXStart + Dim); + response.emplace_back(y[idxOrig]); + } + + // perform the fit on the points TODO make errors configurable + std::vector error; + const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); + + // store parameters + std::copy(params.begin(), params.end(), &mParams[i * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly)]); + } +} + template void NDPiecewisePolynomials::fitInnerGrid(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */], const int currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response) { From e3d6fdde3f1b551a562f3578d4332767f18afed0 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Fri, 9 Aug 2024 15:36:43 +0200 Subject: [PATCH 0075/2205] Add benchmarks and improve test consistency (#13357) --- GPU/Common/test/.gitignore | 1 - GPU/Common/test/testSMatrixImp.cu | 481 +++++++++++++++++------------- 2 files changed, 280 insertions(+), 202 deletions(-) delete mode 100644 GPU/Common/test/.gitignore diff --git a/GPU/Common/test/.gitignore b/GPU/Common/test/.gitignore deleted file mode 100644 index 43fd5862f17c1..0000000000000 --- a/GPU/Common/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.hip \ No newline at end of file diff --git a/GPU/Common/test/testSMatrixImp.cu b/GPU/Common/test/testSMatrixImp.cu index 2bdcdd720cdc5..1e1ba9b8cf6dc 100644 --- a/GPU/Common/test/testSMatrixImp.cu +++ b/GPU/Common/test/testSMatrixImp.cu @@ -12,7 +12,7 @@ /// \file testGPUSMatrixImp.cu /// \author Matteo Concas, Maksym KIzitskyi -#define BOOST_TEST_MODULE Test GPUSMatrixImpl +#define BOOST_TEST_MODULE Test GPUSMatrixImplementation #ifdef __HIPCC__ #define GPUPLATFORM "HIP" #include "hip/hip_runtime.h" @@ -27,8 +27,12 @@ #include #include -// Macro for checking CUDA errors -#define CUDA_CHECK(call) \ +using MatSym3DGPU = o2::math_utils::SMatrixGPU>; +using MatSym3D = ROOT::Math::SMatrix>; +using Mat3DGPU = o2::math_utils::SMatrixGPU>; +using Mat3D = ROOT::Math::SMatrix>; + +#define GPU_CHECK(call) \ do { \ cudaError_t error = call; \ if (error != cudaSuccess) { \ @@ -37,50 +41,14 @@ } \ } while (0) -// RAII class for CUDA resources -class CudaMemory +namespace gpu { - public: - CudaMemory(size_t size) - { - CUDA_CHECK(cudaMalloc(&device_ptr, size)); - } - ~CudaMemory() - { - CUDA_CHECK(cudaFree(device_ptr)); - } - void* get() const { return device_ptr; } - - private: - void* device_ptr; +enum PrintMode { + Decimal, + Binary, + Hexadecimal }; -template -void discardResult(const T&) -{ -} - -void prologue() -{ - int deviceCount; - cudaError_t error = cudaGetDeviceCount(&deviceCount); - if (error != cudaSuccess || !deviceCount) { - std::cerr << "No " << GPUPLATFORM << " devices found" << std::endl; - return; - } - - for (int iDevice = 0; iDevice < deviceCount; ++iDevice) { - cudaDeviceProp deviceProp; - cudaGetDeviceProperties(&deviceProp, iDevice); - printf("%s Device %d: %s\n", GPUPLATFORM, iDevice, deviceProp.name); - } -} - -using MatSym3DGPU = o2::math_utils::SMatrixGPU>; -using MatSym3D = ROOT::Math::SMatrix>; -using Mat3DGPU = o2::math_utils::SMatrixGPU>; -using Mat3D = ROOT::Math::SMatrix>; - __device__ void floatToBinaryString(float number, char* buffer) { unsigned char* bytePointer = reinterpret_cast(&number); @@ -94,28 +62,75 @@ __device__ void floatToBinaryString(float number, char* buffer) } template -__device__ void printMatrix(const MatrixType& matrix, const char* name, const bool IsBinary) +GPUd() void printMatrix(const MatrixType& matrix, const char* name, const PrintMode mode) { - char buffer[33]; - if (IsBinary) { + if (mode == PrintMode::Binary) { + char buffer[33]; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { floatToBinaryString(matrix(i, j), buffer); printf("%s(%d,%d) = %s\n", name, i, j, buffer); } } - } else { + } + if (mode == PrintMode::Decimal) { for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { printf("%s(%i,%i) = %f\n", name, i, j, matrix(i, j)); } } } + if (mode == PrintMode::Hexadecimal) { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + printf("%s(%d,%d) = %x\n", name, i, j, o2::gpu::CAMath::Float2UIntReint(matrix(i, j))); + } + } + } +} + +// Invert test for a single square matrix +template +GPUg() void invertMatrixKernelSingle(T* matrix) +{ + matrix->Invert(); +} + +// Copy test for a single square matrix +template +GPUg() void copyMatrixKernelSingle( + T* srcMatrix, + T* dstMatrix) +{ + *dstMatrix = *srcMatrix; +} + +// Invert test for an array of square matrices +template +GPUg() void invertMatrixKernelArray(T* matrices, + const int numMatrices) +{ + for (auto iMatrix = blockIdx.x * blockDim.x + threadIdx.x; iMatrix < numMatrices; iMatrix += blockDim.x * gridDim.x) { + matrices[iMatrix].Invert(); + } +} + +// Copy test for an array of square matrices +template +GPUg() void copyMatrixKernelArray( + T* srcMatrices, + T* dstMatrices, + const int numMatrices) +{ + for (auto iMatrix = blockIdx.x * blockDim.x + threadIdx.x; iMatrix < numMatrices; iMatrix += blockDim.x * gridDim.x) { + srcMatrices[iMatrix] = dstMatrices[iMatrix]; + } } +} // namespace gpu // Function to compare two matrices element-wise with a specified tolerance template -void compareMatrices(const MatrixType& mat1, const MatrixType& mat2, float tolerance) +void compareMatricesElementWise(const MatrixType& mat1, const MatrixType& mat2, float tolerance) { auto tol = boost::test_tools::tolerance(tolerance); @@ -126,76 +141,89 @@ void compareMatrices(const MatrixType& mat1, const MatrixType& mat2, float toler } } -// Invert test for symmetric matrix -template -__global__ void invertSymMatrixKernel(MatSym3DGPU* matrix) +// RAII class for CUDA resources +class GPUMemory { - const bool IsBinary = true; - printf("\nStart inverting symmetric matrix\n"); - MatSym3DGPU smat2 = *matrix; - - printMatrix(*matrix, "A", IsBinary); - printMatrix(smat2, "B", IsBinary); - - printf("\nInverting A...\n"); - matrix->Invert(); - - printMatrix(*matrix, "A", IsBinary); + public: + GPUMemory(size_t size) + { + GPU_CHECK(cudaMalloc(&device_ptr, size)); + } + ~GPUMemory() + { + GPU_CHECK(cudaFree(device_ptr)); + } + void* get() const { return device_ptr; } - printf("\nC = (A^-1) * B...\n"); - auto smat3 = (*matrix) * smat2; + private: + void* device_ptr; +}; - printMatrix(smat3, "C", IsBinary); +class GPUBenchmark +{ + public: + GPUBenchmark(const std::string& testName = "") : title(testName) + { + GPU_CHECK(cudaEventCreate(&startEvent)); + GPU_CHECK(cudaEventCreate(&stopEvent)); + } + ~GPUBenchmark() + { + GPU_CHECK(cudaEventDestroy(startEvent)); + GPU_CHECK(cudaEventDestroy(stopEvent)); + } + void start() + { + GPU_CHECK(cudaEventRecord(startEvent)); + } + void stop() + { + GPU_CHECK(cudaEventRecord(stopEvent)); + GPU_CHECK(cudaEventSynchronize(stopEvent)); + GPU_CHECK(cudaEventElapsedTime(&duration, startEvent, stopEvent)); + } + void setTitle(const std::string& newTitle) { title = newTitle; } + float getDuration() const { return duration; } + void printDuration() const + { + std::cout << "\t - " << title << " kernel execution time: " << duration << " ms" << std::endl; + } - printf("\nEvaluating...\n"); - MatSym3DGPU tmp; - o2::math_utils::AssignSym::Evaluate(tmp, smat3); + private: + std::string title = ""; + cudaEvent_t startEvent, stopEvent; + float duration; +}; - printMatrix(tmp, "A", IsBinary); - *matrix = tmp; - printf("\n-------------------------------------------------------\n"); +template +void discardResult(const T&) +{ } -// Invert test for general matrix -template -__global__ void invertMatrixKernel(Mat3DGPU* matrix) +void prologue() { - const bool IsBinary = true; - printf("\nStart inverting general matrix\n"); - Mat3DGPU smat2 = *matrix; - - printMatrix(*matrix, "A", IsBinary); - printMatrix(smat2, "B", IsBinary); - - printf("\nInverting A...\n"); - matrix->Invert(); - - printMatrix(*matrix, "A", IsBinary); - - printf("\nC = (A^-1) * B...\n"); - auto smat3 = (*matrix) * smat2; - - printMatrix(smat3, "C", IsBinary); - - printf("\nEvaluating...\n"); - Mat3DGPU tmp; - o2::math_utils::Assign, o2::math_utils::MatRepStdGPU>::Evaluate(tmp, smat3); + int deviceCount; + cudaError_t error = cudaGetDeviceCount(&deviceCount); + if (error != cudaSuccess || !deviceCount) { + std::cerr << "No " << GPUPLATFORM << " devices found" << std::endl; + return; + } - printMatrix(tmp, "A", IsBinary); - *matrix = tmp; - printf("\n-------------------------------------------------------\n"); + for (int iDevice = 0; iDevice < deviceCount; ++iDevice) { + cudaDeviceProp deviceProp; + discardResult(cudaGetDeviceProperties(&deviceProp, iDevice)); + printf("Testing on: %s, Device %d: %s\n", GPUPLATFORM, iDevice, deviceProp.name); + } } struct GPUSMatrixImplFixtureSolo { - GPUSMatrixImplFixtureSolo() : i(3), SMatrixSym3D_d(sizeof(MatSym3DGPU)), SMatrixSym3D_h(), SMatrix3D_d(sizeof(Mat3DGPU)), SMatrix3D_h() + GPUSMatrixImplFixtureSolo() : SMatrixSym_d(sizeof(MatSym3DGPU)), SMatrixSym_h(), SMatrix_d(sizeof(Mat3DGPU)), SMatrix_h() { prologue(); initializeMatrices(); - printMatrixSizes(); } ~GPUSMatrixImplFixtureSolo() = default; - void initializeMatrices() { std::random_device rd; @@ -205,66 +233,72 @@ struct GPUSMatrixImplFixtureSolo { // Initialize host matrices with random values for (int i = 0; i < 3; ++i) { for (int j = i; j < 3; ++j) { - SMatrixSym3D_h(i, j) = dis(gen); - SMatrix3D_h(i, j) = dis(gen); + SMatrixSym_h(i, j) = dis(gen); + SMatrix_h(i, j) = dis(gen); } } + SMatrixSym_original_h = SMatrixSym_h; + SMatrix_original_h = SMatrix_h; // Copy host matrices to device - CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d.get(), &SMatrixSym3D_h, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); - CUDA_CHECK(cudaMemcpy(SMatrix3D_d.get(), &SMatrix3D_h, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrixSym_d.get(), &SMatrixSym_h, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrix_d.get(), &SMatrix_h, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); } - void printMatrixSizes() const - { - printf("sizeof(MatSym3DGPU) = %zu\n", sizeof(MatSym3DGPU)); - printf("sizeof(MatSym3D) = %zu\n", sizeof(MatSym3D)); - printf("sizeof(Mat3DGPU) = %zu\n", sizeof(Mat3DGPU)); - printf("sizeof(Mat3D) = %zu\n", sizeof(Mat3D)); - } - - int i; - CudaMemory SMatrixSym3D_d; - MatSym3D SMatrixSym3D_h; - CudaMemory SMatrix3D_d; - Mat3D SMatrix3D_h; + GPUMemory SMatrixSym_d; + MatSym3D SMatrixSym_h; + MatSym3D SMatrixSym_original_h; + GPUMemory SMatrix_d; + Mat3D SMatrix_h; + Mat3D SMatrix_original_h; }; BOOST_FIXTURE_TEST_CASE(MatrixInversion, GPUSMatrixImplFixtureSolo) { float tolerance = 0.00001f; - - invertSymMatrixKernel<<<1, 1>>>(static_cast(SMatrixSym3D_d.get())); - cudaDeviceSynchronize(); - CUDA_CHECK(cudaGetLastError()); - - CUDA_CHECK(cudaMemcpy(&SMatrixSym3D_h, SMatrixSym3D_d.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + const int nBlocks{1}, nThreads{1}; + GPUBenchmark benchmark("Single symmetric matrix inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::invertMatrixKernelSingle<<>>(static_cast(SMatrixSym_d.get())); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + GPU_CHECK(cudaMemcpy(&SMatrixSym_h, SMatrixSym_d.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); MatSym3D identitySym; identitySym(0, 0) = 1; identitySym(1, 1) = 1; identitySym(2, 2) = 1; - compareMatrices(SMatrixSym3D_h, identitySym, tolerance); - - invertMatrixKernel<<<1, 1>>>(static_cast(SMatrix3D_d.get())); - cudaDeviceSynchronize(); - CUDA_CHECK(cudaGetLastError()); - - CUDA_CHECK(cudaMemcpy(&SMatrix3D_h, SMatrix3D_d.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); + auto operationSym = SMatrixSym_h * SMatrixSym_original_h; + MatSym3D resultSym; + ROOT::Math::AssignSym::Evaluate(resultSym, operationSym); + compareMatricesElementWise(resultSym, identitySym, tolerance); + + benchmark.setTitle("Single general matrix inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::invertMatrixKernelSingle<<>>(static_cast(SMatrix_d.get())); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + GPU_CHECK(cudaMemcpy(&SMatrix_h, SMatrix_d.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); Mat3D identity; identity(0, 0) = 1; identity(1, 1) = 1; identity(2, 2) = 1; - compareMatrices(SMatrix3D_h, identity, tolerance); + auto operation = SMatrix_h * SMatrix_original_h; + Mat3D result; + ROOT::Math::Assign, ROOT::Math::MatRepStd>::Evaluate(result, operation); + compareMatricesElementWise(result, identity, tolerance); } struct GPUSMatrixImplFixtureDuo { - GPUSMatrixImplFixtureDuo() : i(3), SMatrixSym3D_d_A(sizeof(MatSym3DGPU)), SMatrixSym3D_h_A(), SMatrix3D_d_A(sizeof(Mat3DGPU)), SMatrix3D_h_A(), SMatrixSym3D_d_B(sizeof(MatSym3DGPU)), SMatrixSym3D_h_B(), SMatrix3D_d_B(sizeof(Mat3DGPU)), SMatrix3D_h_B() + GPUSMatrixImplFixtureDuo() : SMatrixSym_d_A(sizeof(MatSym3DGPU)), SMatrixSym_h_A(), SMatrix_d_A(sizeof(Mat3DGPU)), SMatrix_h_A(), SMatrixSym_d_B(sizeof(MatSym3DGPU)), SMatrixSym_h_B(), SMatrix_d_B(sizeof(Mat3DGPU)), SMatrix_h_B() { prologue(); initializeMatrices(); - printMatrixSizes(); } ~GPUSMatrixImplFixtureDuo() = default; @@ -278,93 +312,138 @@ struct GPUSMatrixImplFixtureDuo { // Initialize host matrices with random values for (int i = 0; i < 3; ++i) { for (int j = i; j < 3; ++j) { - SMatrixSym3D_h_A(i, j) = dis(gen); - SMatrix3D_h_A(i, j) = dis(gen); + SMatrixSym_h_A(i, j) = dis(gen); + SMatrix_h_A(i, j) = dis(gen); - SMatrixSym3D_h_B(i, j) = dis(gen); - SMatrix3D_h_B(i, j) = dis(gen); + SMatrixSym_h_B(i, j) = dis(gen); + SMatrix_h_B(i, j) = dis(gen); } } // Copy host matrices to device - CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d_A.get(), &SMatrixSym3D_h_A, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); - CUDA_CHECK(cudaMemcpy(SMatrix3D_d_A.get(), &SMatrix3D_h_A, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrixSym_d_A.get(), &SMatrixSym_h_A, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrix_d_A.get(), &SMatrix_h_A, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); - CUDA_CHECK(cudaMemcpy(SMatrixSym3D_d_B.get(), &SMatrixSym3D_h_B, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); - CUDA_CHECK(cudaMemcpy(SMatrix3D_d_B.get(), &SMatrix3D_h_B, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); - } - - void printMatrixSizes() const - { - printf("sizeof(MatSym3DGPU) = %zu\n", sizeof(MatSym3DGPU)); - printf("sizeof(MatSym3D) = %zu\n", sizeof(MatSym3D)); - printf("sizeof(Mat3DGPU) = %zu\n", sizeof(Mat3DGPU)); - printf("sizeof(Mat3D) = %zu\n", sizeof(Mat3D)); + GPU_CHECK(cudaMemcpy(SMatrixSym_d_B.get(), &SMatrixSym_h_B, sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrix_d_B.get(), &SMatrix_h_B, sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); } - int i; - CudaMemory SMatrixSym3D_d_A; - MatSym3D SMatrixSym3D_h_A; + GPUMemory SMatrixSym_d_A; + MatSym3D SMatrixSym_h_A; - CudaMemory SMatrixSym3D_d_B; - MatSym3D SMatrixSym3D_h_B; + GPUMemory SMatrixSym_d_B; + MatSym3D SMatrixSym_h_B; - CudaMemory SMatrix3D_d_A; - Mat3D SMatrix3D_h_A; + GPUMemory SMatrix_d_A; + Mat3D SMatrix_h_A; - CudaMemory SMatrix3D_d_B; - Mat3D SMatrix3D_h_B; + GPUMemory SMatrix_d_B; + Mat3D SMatrix_h_B; }; -// Copy test for symmetric matrix -template -__global__ void copySymMatrixKernel( - MatSym3DGPU* srcMatrix, - MatSym3DGPU* dstMatrix) +BOOST_FIXTURE_TEST_CASE(TestMatrixCopyingAndComparison, GPUSMatrixImplFixtureDuo) { - const bool IsBinary = true; - printf("\nStart copying general matrix\n"); - printMatrix(*dstMatrix, "Before copying: ", IsBinary); - printf("\nCopied values:\n"); - printMatrix(*srcMatrix, "Copied values: ", IsBinary); - printf("\nResult:\n"); - *dstMatrix = *srcMatrix; - printMatrix(*dstMatrix, "After copying: ", IsBinary); - printf("\n-------------------------------------------------------\n"); + const int nBlocks{1}, nThreads{1}; + GPUBenchmark benchmark("Single symmetric matrix copy (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::copyMatrixKernelSingle<<>>(static_cast(SMatrixSym_d_A.get()), static_cast(SMatrixSym_d_B.get())); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + GPU_CHECK(cudaMemcpy(&SMatrixSym_h_B, SMatrixSym_d_B.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + + compareMatricesElementWise(SMatrixSym_h_A, SMatrixSym_h_B, 0.0); + + benchmark.setTitle("Single general matrix copy (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::copyMatrixKernelSingle<<>>(static_cast(SMatrix_d_A.get()), static_cast(SMatrix_d_B.get())); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + + GPU_CHECK(cudaMemcpy(&SMatrix_h_B, SMatrix_d_B.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); + + compareMatricesElementWise(SMatrix_h_A, SMatrix_h_B, 0.0); } +template +struct GPUSmatrixImplFixtureSoloArray { + GPUSmatrixImplFixtureSoloArray() : SMatrixSymArray_d(D * sizeof(MatSym3DGPU)), SMatrixArray_d(D * sizeof(Mat3DGPU)) + { + SMatrixSymVector_h.resize(D); + SMatrixVector_h.resize(D); + SMatrixSym_original_h.resize(D); + SMatrix_original_h.resize(D); + prologue(); + initializeMatrices(); + } -// Copy test for general matrix -template -__global__ void copyMatrixKernel( - Mat3DGPU* srcMatrix, - Mat3DGPU* dstMatrix) -{ - const bool IsBinary = true; - printf("\nStart copying general matrix\n"); - printMatrix(*dstMatrix, "Before copying: ", IsBinary); - printf("\nCopied values:\n"); - printMatrix(*srcMatrix, "Copied values: ", IsBinary); - printf("\nResult:\n"); - *dstMatrix = *srcMatrix; - printMatrix(*dstMatrix, "After copying: ", IsBinary); - printf("\n-------------------------------------------------------\n"); -} + ~GPUSmatrixImplFixtureSoloArray() = default; + void initializeMatrices() + { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution dis(1.0, 10.0); -BOOST_FIXTURE_TEST_CASE(TestMatrixCopyingAndComparison, GPUSMatrixImplFixtureDuo) -{ - copySymMatrixKernel<<<1, 1>>>(static_cast(SMatrixSym3D_d_A.get()), static_cast(SMatrixSym3D_d_B.get())); - cudaDeviceSynchronize(); - CUDA_CHECK(cudaGetLastError()); + // Initialize host matrices with random values + for (size_t iMatrix{0}; iMatrix < D; ++iMatrix) { + for (int i = 0; i < 3; ++i) { + for (int j = i; j < 3; ++j) { + SMatrixSymVector_h[iMatrix](i, j) = dis(gen); + SMatrixVector_h[iMatrix](i, j) = dis(gen); + } + } - CUDA_CHECK(cudaMemcpy(&SMatrixSym3D_h_B, SMatrixSym3D_d_B.get(), sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + SMatrixSym_original_h[iMatrix] = SMatrixSymVector_h[iMatrix]; + SMatrix_original_h[iMatrix] = SMatrixVector_h[iMatrix]; + } - compareMatrices(SMatrixSym3D_h_A, SMatrixSym3D_h_B, 0.0); + // Copy host matrices to device + GPU_CHECK(cudaMemcpy(SMatrixSymArray_d.get(), SMatrixSymVector_h.data(), D * sizeof(MatSym3DGPU), cudaMemcpyHostToDevice)); + GPU_CHECK(cudaMemcpy(SMatrixArray_d.get(), SMatrixVector_h.data(), D * sizeof(Mat3DGPU), cudaMemcpyHostToDevice)); + } - copyMatrixKernel<<<1, 1>>>(static_cast(SMatrix3D_d_A.get()), static_cast(SMatrix3D_d_B.get())); - cudaDeviceSynchronize(); - CUDA_CHECK(cudaGetLastError()); + GPUMemory SMatrixSymArray_d; + std::vector SMatrixSymVector_h; + std::vector SMatrixSym_original_h; + GPUMemory SMatrixArray_d; + std::vector SMatrixVector_h; + std::vector SMatrix_original_h; +}; - CUDA_CHECK(cudaMemcpy(&SMatrix3D_h_B, SMatrix3D_d_B.get(), sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); +BOOST_FIXTURE_TEST_CASE(MatrixInversionArray, GPUSmatrixImplFixtureSoloArray<1'000'000>) +{ + float tolerance = 0.00001f; + const int nBlocks{20}, nThreads{512}; + + GPUBenchmark benchmark("Array of 1'000'000 symmetric matrices inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::invertMatrixKernelArray<<>>(static_cast(SMatrixSymArray_d.get()), 1'000'000); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + GPU_CHECK(cudaMemcpy(SMatrixSymVector_h.data(), SMatrixSymArray_d.get(), 1'000'000 * sizeof(MatSym3DGPU), cudaMemcpyDeviceToHost)); + + for (size_t iMatrix{0}; iMatrix < 1'000'000; ++iMatrix) { + // Cross-check with the CPU implementation + SMatrixSym_original_h[iMatrix].Invert(); + compareMatricesElementWise(SMatrixSymVector_h[iMatrix], SMatrixSym_original_h[iMatrix], tolerance); + } - compareMatrices(SMatrix3D_h_A, SMatrix3D_h_B, 0.0); + benchmark.setTitle("Array of 1'000'000 general matrices inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); + benchmark.start(); + gpu::invertMatrixKernelArray<<>>(static_cast(SMatrixArray_d.get()), 1'000'000); + benchmark.stop(); + benchmark.printDuration(); + discardResult(cudaDeviceSynchronize()); + GPU_CHECK(cudaGetLastError()); + GPU_CHECK(cudaMemcpy(SMatrixVector_h.data(), SMatrixArray_d.get(), 1'000'000 * sizeof(Mat3DGPU), cudaMemcpyDeviceToHost)); + + for (size_t iMatrix{0}; iMatrix < 1'000'000; ++iMatrix) { + // Cross-check with the CPU implementation + SMatrix_original_h[iMatrix].Invert(); + compareMatricesElementWise(SMatrixVector_h[iMatrix], SMatrix_original_h[iMatrix], tolerance); + } } \ No newline at end of file From 0abf8fb405934e427ddd0b890ec5a3ad40193282 Mon Sep 17 00:00:00 2001 From: Bhawani Singh Date: Thu, 8 Aug 2024 16:23:30 +0200 Subject: [PATCH 0076/2205] TPCQC:fixes bug on dEdx vs pTPC/z plots --- Detectors/TPC/qc/src/PID.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/TPC/qc/src/PID.cxx b/Detectors/TPC/qc/src/PID.cxx index 556dcb273b627..76d747165ea32 100644 --- a/Detectors/TPC/qc/src/PID.cxx +++ b/Detectors/TPC/qc/src/PID.cxx @@ -131,8 +131,8 @@ bool PID::processTrack(const o2::tpc::TrackTPC& track, size_t nTracks) { // ===| variables required for cutting and filling |=== const auto& dEdx = track.getdEdx(); - const auto magCharge = track.getAbsCharge(); - const auto pTPC = track.getP() * magCharge; // charge magnitude is divided getP() via getPtInv therefore magCharge is required to be multiplied [fix for He3] + const auto absCharge = track.getAbsCharge(); + const auto pTPC = (absCharge > 0) ? (track.getP() / absCharge) : track.getP(); // charge magnitude is divided getP() via getPtInv for pTPC/Z [fix for He3] const auto tgl = track.getTgl(); const auto snp = track.getSnp(); const auto phi = track.getPhi(); From 3269ab559d1fd434500d14602a75449ddbd05778 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sat, 10 Aug 2024 16:30:24 +0200 Subject: [PATCH 0077/2205] DPL: do not flush metrics from threads This avoids having to have a mutex for the flushing. --- Framework/Core/src/CommonServices.cxx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index 39c17599abb9d..0e84333afe115 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -783,8 +783,13 @@ O2_DECLARE_DYNAMIC_LOG(monitoring_service); /// This will flush metrics only once every second. auto flushMetrics(ServiceRegistryRef registry, DataProcessingStats& stats) -> void { + // Flushing metrics should only happen on main thread to avoid + // having to have a mutex for the communication with the driver. O2_SIGNPOST_ID_GENERATE(sid, monitoring_service); O2_SIGNPOST_START(monitoring_service, sid, "flush", "flushing metrics"); + if (registry.isMainThread() == false) { + LOGP(fatal, "Flushing metrics should only happen on the main thread."); + } auto& monitoring = registry.get(); auto& relayer = registry.get(); @@ -1071,13 +1076,9 @@ o2::framework::ServiceSpec CommonServices::dataProcessingStats() return ServiceHandle{TypeIdHelpers::uniqueId(), stats}; }, .configure = noConfiguration(), - .preProcessing = [](ProcessingContext& context, void* service) { - auto* stats = (DataProcessingStats*)service; - flushMetrics(context.services(), *stats); }, .postProcessing = [](ProcessingContext& context, void* service) { auto* stats = (DataProcessingStats*)service; - stats->updateStats({(short)ProcessingStatsId::PERFORMED_COMPUTATIONS, DataProcessingStats::Op::Add, 1}); - flushMetrics(context.services(), *stats); }, + stats->updateStats({(short)ProcessingStatsId::PERFORMED_COMPUTATIONS, DataProcessingStats::Op::Add, 1}); }, .preDangling = [](DanglingContext& context, void* service) { auto* stats = (DataProcessingStats*)service; sendRelayerMetrics(context.services(), *stats); @@ -1090,9 +1091,6 @@ o2::framework::ServiceSpec CommonServices::dataProcessingStats() auto* stats = (DataProcessingStats*)service; sendRelayerMetrics(context.services(), *stats); flushMetrics(context.services(), *stats); }, - .postDispatching = [](ProcessingContext& context, void* service) { - auto* stats = (DataProcessingStats*)service; - flushMetrics(context.services(), *stats); }, .preLoop = [](ServiceRegistryRef ref, void* service) { auto* stats = (DataProcessingStats*)service; flushMetrics(ref, *stats); }, From 0d384ae051ece7c261db6342f7d309e5d6ebea29 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Mon, 12 Aug 2024 23:29:47 +0200 Subject: [PATCH 0078/2205] Fix useless log in cosmics run (#13373) --- .../ITS/tracking/src/TrackingInterface.cxx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx index fd4c5bdc56486..6419f5072c480 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx @@ -235,14 +235,16 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) mTimeFrame->addPrimaryVertices(vtxVecLoc); } } - LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}, upc.sel:{}", cutRandomMult + cutVertexMult + cutUPCVertex, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult, cutUPCVertex); - LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} ({} + {}) vertices found in {}/{} ROFs", - vertexerElapsedTime, - mTimeFrame->getPrimaryVerticesNum(), - mTimeFrame->getTotVertIteration()[0], - o2::its::VertexerParamConfig::Instance().nIterations > 1 ? mTimeFrame->getTotVertIteration()[1] : 0, - rofspan.size() - mTimeFrame->getNoVertexROF(), - rofspan.size()); + if (mRunVertexer) { + LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}, upc.sel:{}", cutRandomMult + cutVertexMult + cutUPCVertex, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult, cutUPCVertex); + LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} ({} + {}) vertices found in {}/{} ROFs", + vertexerElapsedTime, + mTimeFrame->getPrimaryVerticesNum(), + mTimeFrame->getTotVertIteration()[0], + o2::its::VertexerParamConfig::Instance().nIterations > 1 ? mTimeFrame->getTotVertIteration()[1] : 0, + rofspan.size() - mTimeFrame->getNoVertexROF(), + rofspan.size()); + } if (mOverrideBeamEstimation) { LOG(info) << fmt::format(" - Beam position set to: {}, {} from meanvertex object", mTimeFrame->getBeamX(), mTimeFrame->getBeamY()); From 29217ed5b2ecd024637e58dc807a808ea8f2246b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 12 Aug 2024 14:51:45 +0200 Subject: [PATCH 0079/2205] GPU: Add option to set some O2 defaults in standalone benchmark --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/GPUTracking/Standalone/Benchmark/standalone.cxx | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index fba8539bc4fc7..422533b883b04 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -498,6 +498,7 @@ AddOption(rundEdx, int, -1, "", 0, "Enable dEdx processing") AddOption(runCompression, int, 1, "", 0, "Enable TPC Compression") AddOption(runTransformation, int, 1, "", 0, "Enable TPC Transformation") AddOption(runRefit, bool, false, "", 0, "Enable final track refit") +AddOption(setO2Settings, bool, false, "", 0, "Set O2 defaults for outerParam, output of shared cluster map, referenceX") AddHelp("help", 'h') AddHelpAll("helpall", 'H') AddSubConfig(GPUSettingsRec, rec) diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index 92199f06a5f68..d6c01e061c236 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -228,6 +228,12 @@ int ReadConfiguration(int argc, char** argv) configStandalone.proc.ompThreads = 1; } } + if (configStandalone.setO2Settings) { + configStandalone.proc.forceHostMemoryPoolSize = 1024 * 1024 * 1024; + configStandalone.rec.tpc.nWaysOuter = 1; + configStandalone.rec.tpc.trackReferenceX = 83; + configStandalone.proc.outputSharedClusterMap = 1; + } if (configStandalone.outputcontrolmem) { bool forceEmptyMemory = getenv("LD_PRELOAD") && strstr(getenv("LD_PRELOAD"), "valgrind") != nullptr; From bb12ce2d7e1850f1a2af20569e0c6ebda7d2d78b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 7 Aug 2024 13:39:18 +0200 Subject: [PATCH 0080/2205] GPU: Improve configuration dump --- GPU/GPUTracking/Base/GPUReconstruction.cxx | 44 +++++++++----- GPU/GPUTracking/Base/GPUReconstruction.h | 15 ++--- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 2 +- .../Base/opencl/GPUReconstructionOCL1.h | 2 +- GPU/GPUTracking/CMakeLists.txt | 2 +- GPU/GPUTracking/DataTypes/GPUConfigDump.cxx | 59 +++++++++++++++++++ GPU/GPUTracking/DataTypes/GPUConfigDump.h | 37 ++++++++++++ GPU/GPUTracking/DataTypes/GPUDataTypes.h | 2 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 3 +- GPU/GPUTracking/Global/GPUChainTracking.h | 2 + .../GPUO2InterfaceConfigurableParam.cxx | 21 +------ .../Standalone/Benchmark/standalone.cxx | 16 ++++- GPU/Workflow/src/GPUWorkflowSpec.cxx | 5 +- 13 files changed, 158 insertions(+), 52 deletions(-) create mode 100644 GPU/GPUTracking/DataTypes/GPUConfigDump.cxx create mode 100644 GPU/GPUTracking/DataTypes/GPUConfigDump.h diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index 9246fc5df348f..3de469227bdec 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -40,6 +40,8 @@ #include "GPUReconstruction.h" #include "GPUReconstructionIncludes.h" #include "GPUROOTDumpCore.h" +#include "GPUConfigDump.h" +#include "GPUChainTracking.h" #include "GPUMemoryResource.h" #include "GPUChain.h" @@ -212,18 +214,30 @@ int GPUReconstruction::Init() int GPUReconstruction::InitPhaseBeforeDevice() { + if (mProcessingSettings.printSettings) { + if (mSlaves.size() || mMaster) { + printf("\nConfig Dump %s\n", mMaster ? "Slave" : "Master"); + } + const GPUChainTracking* chTrk; + for (unsigned int i = 0; i < mChains.size(); i++) { + if ((chTrk = dynamic_cast(mChains[i].get()))) { + break; + } + } + GPUConfigDump::dumpConfig(¶m().rec, &mProcessingSettings, chTrk ? chTrk->GetQAConfig() : nullptr, chTrk ? chTrk->GetEventDisplayConfig() : nullptr, &mDeviceBackendSettings, &mRecoSteps); + } #ifndef GPUCA_HAVE_O2HEADERS - mRecoSteps.setBits(RecoStep::ITSTracking, false); - mRecoSteps.setBits(RecoStep::TRDTracking, false); - mRecoSteps.setBits(RecoStep::TPCConversion, false); - mRecoSteps.setBits(RecoStep::TPCCompression, false); - mRecoSteps.setBits(RecoStep::TPCdEdx, false); + mRecoSteps.steps.setBits(RecoStep::ITSTracking, false); + mRecoSteps.steps.setBits(RecoStep::TRDTracking, false); + mRecoSteps.steps.setBits(RecoStep::TPCConversion, false); + mRecoSteps.steps.setBits(RecoStep::TPCCompression, false); + mRecoSteps.steps.setBits(RecoStep::TPCdEdx, false); mProcessingSettings.createO2Output = false; #endif - mRecoStepsGPU &= mRecoSteps; - mRecoStepsGPU &= AvailableRecoSteps(); + mRecoSteps.stepsGPUMask &= mRecoSteps.steps; + mRecoSteps.stepsGPUMask &= AvailableGPURecoSteps(); if (!IsGPU()) { - mRecoStepsGPU.set((unsigned char)0); + mRecoSteps.stepsGPUMask.set((unsigned char)0); } if (mProcessingSettings.forceMemoryPoolSize >= 1024 || mProcessingSettings.forceHostMemoryPoolSize >= 1024) { @@ -286,7 +300,7 @@ int GPUReconstruction::InitPhaseBeforeDevice() if (!mProcessingSettings.createO2Output || !IsGPU()) { mProcessingSettings.clearO2OutputFromGPU = false; } - if (!(mRecoStepsGPU & GPUDataTypes::RecoStep::TPCMerging)) { + if (!(mRecoSteps.stepsGPUMask & GPUDataTypes::RecoStep::TPCMerging)) { mProcessingSettings.mergerSortTracks = false; } if (!IsGPU()) { @@ -296,7 +310,7 @@ int GPUReconstruction::InitPhaseBeforeDevice() if (param().rec.nonConsecutiveIDs) { param().rec.tpc.disableRefitAttachment = 0xFF; } - if (!(mRecoStepsGPU & RecoStep::TPCMerging) || !param().rec.tpc.mergerReadFromTrackerDirectly) { + if (!(mRecoSteps.stepsGPUMask & RecoStep::TPCMerging) || !param().rec.tpc.mergerReadFromTrackerDirectly) { mProcessingSettings.fullMergerOnGPU = false; } if (mProcessingSettings.debugLevel > 3 || !mProcessingSettings.fullMergerOnGPU || mProcessingSettings.deterministicGPUReconstruction) { @@ -1113,7 +1127,7 @@ void GPUReconstruction::UpdateSettings(const GPUSettingsGRP* g, const GPUSetting mProcessingSettings.debugLevel = p->debugLevel; mProcessingSettings.resetTimers = p->resetTimers; } - GPURecoStepConfiguration w = {mRecoSteps, mRecoStepsGPU, mRecoStepsInputs, mRecoStepsOutputs}; + GPURecoStepConfiguration w = mRecoSteps; param().UpdateSettings(g, p, &w); if (mInitialized) { WriteConstantParams(); @@ -1161,10 +1175,10 @@ void GPUReconstruction::SetSettings(const GPUSettingsGRP* grp, const GPUSettings mProcessingSettings = *proc; } if (workflow) { - mRecoSteps = workflow->steps; - mRecoStepsGPU &= workflow->stepsGPUMask; - mRecoStepsInputs = workflow->inputs; - mRecoStepsOutputs = workflow->outputs; + mRecoSteps.steps = workflow->steps; + mRecoSteps.stepsGPUMask &= workflow->stepsGPUMask; + mRecoSteps.inputs = workflow->inputs; + mRecoSteps.outputs = workflow->outputs; } param().SetDefaults(&mGRPSettings, rec, proc, workflow); } diff --git a/GPU/GPUTracking/Base/GPUReconstruction.h b/GPU/GPUTracking/Base/GPUReconstruction.h index 324304ae8c2f6..00e4dace84f21 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.h +++ b/GPU/GPUTracking/Base/GPUReconstruction.h @@ -210,10 +210,10 @@ class GPUReconstruction int NStreams() const { return mNStreams; } const void* DeviceMemoryBase() const { return mDeviceMemoryBase; } - RecoStepField GetRecoSteps() const { return mRecoSteps; } - RecoStepField GetRecoStepsGPU() const { return mRecoStepsGPU; } - InOutTypeField GetRecoStepsInputs() const { return mRecoStepsInputs; } - InOutTypeField GetRecoStepsOutputs() const { return mRecoStepsOutputs; } + RecoStepField GetRecoSteps() const { return mRecoSteps.steps; } + RecoStepField GetRecoStepsGPU() const { return mRecoSteps.stepsGPUMask; } + InOutTypeField GetRecoStepsInputs() const { return mRecoSteps.inputs; } + InOutTypeField GetRecoStepsOutputs() const { return mRecoSteps.outputs; } int getRecoStepNum(RecoStep step, bool validCheck = true); int getGeneralStepNum(GeneralStep step, bool validCheck = true); @@ -286,7 +286,7 @@ class GPUReconstruction int ReadStructFromFile(const char* file, T* obj); // Others - virtual RecoStepField AvailableRecoSteps() { return RecoStep::AllRecoSteps; } + virtual RecoStepField AvailableGPURecoSteps() { return RecoStep::AllRecoSteps; } virtual bool CanQueryMaxMemory() { return false; } // Pointers to tracker classes @@ -304,10 +304,7 @@ class GPUReconstruction GPUOutputControl mInputControl; // Prefefined input memory location for reading standalone dumps std::unique_ptr mMemoryScalers; // Scalers how much memory will be needed - RecoStepField mRecoSteps = RecoStep::AllRecoSteps; - RecoStepField mRecoStepsGPU = RecoStep::AllRecoSteps; - InOutTypeField mRecoStepsInputs = 0; - InOutTypeField mRecoStepsOutputs = 0; + GPURecoStepConfiguration mRecoSteps; std::string mDeviceName = "CPU"; diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index 7778c56292ed5..378743dc8ef0c 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -198,7 +198,7 @@ inline int GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args) if (myStep == GPUCA_RECO_STEP::NoRecoStep) { throw std::runtime_error("Failure running general kernel without defining RecoStep"); } - int cpuFallback = IsGPU() ? (setup.x.device == krnlDeviceType::CPU ? 2 : (mRecoStepsGPU & myStep) != myStep) : 0; + int cpuFallback = IsGPU() ? (setup.x.device == krnlDeviceType::CPU ? 2 : (mRecoSteps.stepsGPUMask & myStep) != myStep) : 0; unsigned int& nThreads = setup.x.nThreads; unsigned int& nBlocks = setup.x.nBlocks; const unsigned int stream = setup.x.stream; diff --git a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h index c91a52d533b7a..ab09dab50a084 100644 --- a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h +++ b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h @@ -40,7 +40,7 @@ class GPUReconstructionOCL1Backend : public GPUReconstructionOCL template S& getKernelObject(); - RecoStepField AvailableRecoSteps() override { return (RecoStep::TPCSliceTracking); } + RecoStepField AvailableGPURecoSteps() override { return (RecoStep::TPCSliceTracking); } bool ContextForAllPlatforms() override { return true; } bool CheckPlatform(unsigned int i) override; int GetOCLPrograms() override; diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index 6266d4962b88e..0eb9f4311ef80 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -68,7 +68,7 @@ set(SRCS TRDTracking/GPUTRDTrackerKernels.cxx Base/GPUParam.cxx) -set(SRCS_DATATYPES DataTypes/GPUDataTypes.cxx) +set(SRCS_DATATYPES DataTypes/GPUDataTypes.cxx DataTypes/GPUConfigDump.cxx) set(SRCS_DATATYPE_HEADERS DataTypes/GPUTPCGMPolynomialField.cxx) set(HDRS_CINT_O2 Merger/GPUTPCGMMergedTrack.h Merger/GPUTPCGMSliceTrack.h Merger/GPUTPCGMBorderTrack.h) diff --git a/GPU/GPUTracking/DataTypes/GPUConfigDump.cxx b/GPU/GPUTracking/DataTypes/GPUConfigDump.cxx new file mode 100644 index 0000000000000..3a05e73c6db6f --- /dev/null +++ b/GPU/GPUTracking/DataTypes/GPUConfigDump.cxx @@ -0,0 +1,59 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUConfigDump.cxx +/// \author David Rohr + +#include "GPUConfigDump.h" +#include "GPUDataTypes.h" +#include "GPUSettings.h" + +#include +#include +#include + +#include "utils/qconfig_helpers.h" + +using namespace GPUCA_NAMESPACE::gpu; + +namespace +{ +GPUSettingsStandalone configStandalone; +std::vector> qprint_global; +#define QCONFIG_PRINT +#include "utils/qconfig.h" +#undef QCONFIG_PRINT +} // namespace + +void GPUConfigDump::dumpConfig(const GPUSettingsRec* rec, const GPUSettingsProcessing* proc, const GPUSettingsQA* qa, const GPUSettingsDisplay* display, const GPUSettingsDeviceBackend* device, const GPURecoStepConfiguration* workflow) +{ + if (rec) { + qConfigPrint(*rec, "rec."); + } + if (proc) { + qConfigPrint(*proc, "proc."); + } + if (qa) { + qConfigPrint(*qa, "QA."); + } + if (display) { + qConfigPrint(*display, "display."); + } + if (device) { + std::cout << "\n\tGPUSettingsDeviceBackend:\n" + << "\tdeviceType = " << (int)device->deviceType << "\n" + << "\tforceDeviceType = " << (device->forceDeviceType ? "true" : "false") << "\n" + << "\tslave = " << (device->master ? "true" : "false") << "\n"; + } + if (workflow) { + printf("\n\tReconstruction steps / inputs / outputs:\n\tReco Steps = 0x%08x\n\tReco Steps GPU = 0x%08x\n\tInputs = 0x%08x\n\tOutputs = 0x%08x\n", (unsigned int)workflow->steps, (unsigned int)workflow->stepsGPUMask, (unsigned int)workflow->inputs, (unsigned int)workflow->outputs); + } +} diff --git a/GPU/GPUTracking/DataTypes/GPUConfigDump.h b/GPU/GPUTracking/DataTypes/GPUConfigDump.h new file mode 100644 index 0000000000000..300499f6180b7 --- /dev/null +++ b/GPU/GPUTracking/DataTypes/GPUConfigDump.h @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUConfigDump.h +/// \author David Rohr + +#ifndef GPUCONFIGDUMP_H +#define GPUCONFIGDUMP_H + +#include "GPUCommonDef.h" + +namespace GPUCA_NAMESPACE::gpu +{ +struct GPUSettingsRec; +struct GPUSettingsProcessing; +struct GPUSettingsQA; +struct GPUSettingsDisplay; +struct GPUSettingsDeviceBackend; +struct GPURecoStepConfiguration; + +class GPUConfigDump +{ + public: + static void dumpConfig(const GPUSettingsRec* rec, const GPUSettingsProcessing* proc, const GPUSettingsQA* qa, const GPUSettingsDisplay* display, const GPUSettingsDeviceBackend* device, const GPURecoStepConfiguration* workflow); +}; + +} // namespace GPUCA_NAMESPACE::gpu + +#endif diff --git a/GPU/GPUTracking/DataTypes/GPUDataTypes.h b/GPU/GPUTracking/DataTypes/GPUDataTypes.h index 7eeab55b5c242..b16d8c15f9985 100644 --- a/GPU/GPUTracking/DataTypes/GPUDataTypes.h +++ b/GPU/GPUTracking/DataTypes/GPUDataTypes.h @@ -17,7 +17,7 @@ #include "GPUCommonDef.h" -// These are basic and non-comprex data types, which will also be visible on the GPU. +// These are basic and non-complex data types, which will also be visible on the GPU. // Please add complex data types required on the host but not GPU to GPUHostDataTypes.h and forward-declare! #ifndef GPUCA_GPUCODE_DEVICE #include diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 422533b883b04..4a8d95d0cf371 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -282,6 +282,7 @@ AddOption(tpcDownscaledEdx, unsigned char, 0, "", 0, "If != 0, downscale dEdx pr AddOption(tpcMaxAttachedClustersPerSectorRow, unsigned int, 51000, "", 0, "Maximum number of TPC attached clusters which can be decoded per SectorRow") AddOption(tpcUseOldCPUDecoding, bool, false, "", 0, "Enable old CPU-based TPC decoding") AddOption(RTCcacheFolder, std::string, "./rtccache/", "", 0, "Folder in which the cache file is stored") +AddOption(printSettings, bool, false, "", 0, "Print all settings when initializing") AddVariable(eventDisplay, GPUCA_NAMESPACE::gpu::GPUDisplayFrontendInterface*, nullptr) AddSubConfig(GPUSettingsProcessingRTC, rtc) AddSubConfig(GPUSettingsProcessingParam, param) @@ -503,9 +504,9 @@ AddHelp("help", 'h') AddHelpAll("helpall", 'H') AddSubConfig(GPUSettingsRec, rec) AddSubConfig(GPUSettingsProcessing, proc) -AddSubConfig(GPUSettingsTFSim, TF) AddSubConfig(GPUSettingsQA, QA) AddSubConfig(GPUSettingsDisplay, display) +AddSubConfig(GPUSettingsTFSim, TF) AddSubConfig(GPUSettingsEG, EG) EndConfig() #endif // BeginConfig diff --git a/GPU/GPUTracking/Global/GPUChainTracking.h b/GPU/GPUTracking/Global/GPUChainTracking.h index 89f2ecd10f65f..4963aaf728a04 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.h +++ b/GPU/GPUTracking/Global/GPUChainTracking.h @@ -159,6 +159,8 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega GPUQA* GetQA() { return mQAFromForeignChain ? mQAFromForeignChain->mQA.get() : mQA.get(); } int ForceInitQA(); void SetQAFromForeignChain(GPUChainTracking* chain) { mQAFromForeignChain = chain; } + const GPUSettingsDisplay* GetEventDisplayConfig() const { return mConfigDisplay; } + const GPUSettingsQA* GetQAConfig() const { return mConfigQA; } // Processing functions int RunTPCClusterizer(bool synchronizeOutput = true); diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx index 06aadc2b09484..764424d50362c 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx @@ -15,6 +15,7 @@ #include "GPUO2InterfaceConfigurableParam.h" #include "GPUO2InterfaceConfiguration.h" #include "GPUDataTypes.h" +#include "GPUConfigDump.h" using namespace o2::gpu; #define BeginNamespace(name) @@ -124,25 +125,7 @@ GPUSettingsO2 GPUO2InterfaceConfiguration::ReadConfigurableParam(GPUO2InterfaceC return global; } -#include "utils/qconfig_helpers.h" - -namespace -{ -GPUSettingsStandalone configStandalone; -std::vector> qprint_global; -#define QCONFIG_PRINT -#include "utils/qconfig.h" -#undef QCONFIG_PRINT -} // namepsace - void GPUO2InterfaceConfiguration::PrintParam_internal() { - qConfigPrint(configProcessing, "proc."); - qConfigPrint(configReconstruction, "rec."); - qConfigPrint(configQA, "QA."); - qConfigPrint(configDisplay, "display."); - std::cout << "\n\tGPUSettingsDeviceBackend:\n" - << "\tdeviceType = " << (int)configDeviceBackend.deviceType << "\n" - << "\tforceDeviceType = " << (configDeviceBackend.forceDeviceType ? "true" : "false") << "\n" - << "\tslave = " << (configDeviceBackend.master ? "true" : "false") << "\n"; + GPUConfigDump::dumpConfig(&configReconstruction, &configProcessing, &configQA, &configDisplay, &configDeviceBackend, &configWorkflow); } diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index d6c01e061c236..be886c3aa4438 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -114,6 +114,7 @@ int ReadConfiguration(int argc, char** argv) return 1; } if (configStandalone.printSettings > 1) { + printf("Config Dump before ReadConfiguration\n"); qConfigPrint(); } if (configStandalone.proc.debugLevel < 0) { @@ -270,6 +271,10 @@ int ReadConfiguration(int argc, char** argv) } if (configStandalone.printSettings) { + configStandalone.proc.printSettings = true; + } + if (configStandalone.printSettings > 1) { + printf("Config Dump after ReadConfiguration\n"); qConfigPrint(); } @@ -731,14 +736,19 @@ int main(int argc, char** argv) return 1; } - recUnique.reset(GPUReconstruction::CreateInstance(configStandalone.runGPU ? configStandalone.gpuType.c_str() : GPUDataTypes::DEVICE_TYPE_NAMES[GPUDataTypes::DeviceType::CPU], configStandalone.runGPUforce)); + GPUSettingsDeviceBackend deviceSet; + deviceSet.deviceType = configStandalone.runGPU ? GPUDataTypes::GetDeviceType(configStandalone.gpuType.c_str()) : GPUDataTypes::DeviceType::CPU; + deviceSet.forceDeviceType = configStandalone.runGPUforce; + deviceSet.master = nullptr; + recUnique.reset(GPUReconstruction::CreateInstance(deviceSet)); rec = recUnique.get(); + deviceSet.master = rec; if (configStandalone.testSyncAsync) { - recUniqueAsync.reset(GPUReconstruction::CreateInstance(configStandalone.runGPU ? configStandalone.gpuType.c_str() : GPUDataTypes::DEVICE_TYPE_NAMES[GPUDataTypes::DeviceType::CPU], configStandalone.runGPUforce, rec)); + recUniqueAsync.reset(GPUReconstruction::CreateInstance(deviceSet)); recAsync = recUniqueAsync.get(); } if (configStandalone.proc.doublePipeline) { - recUniquePipeline.reset(GPUReconstruction::CreateInstance(configStandalone.runGPU ? configStandalone.gpuType.c_str() : GPUDataTypes::DEVICE_TYPE_NAMES[GPUDataTypes::DeviceType::CPU], configStandalone.runGPUforce, rec)); + recUniquePipeline.reset(GPUReconstruction::CreateInstance(deviceSet)); recPipeline = recUniquePipeline.get(); } if (rec == nullptr || (configStandalone.testSyncAsync && recAsync == nullptr)) { diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index 1898e2e939295..d9e558972e95d 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -275,7 +275,10 @@ void GPURecoWorkflowSpec::init(InitContext& ic) mConfig->configProcessing.o2PropagatorUseGPUField = true; if (mConfParam->printSettings && (mConfParam->printSettings > 1 || ic.services().get().inputTimesliceId == 0)) { - mConfig->PrintParam(); + mConfig->configProcessing.printSettings = true; + if (mConfParam->printSettings > 1) { + mConfig->PrintParam(); + } } // Configuration is prepared, initialize the tracker. From f8804784a6ab56303afbfd13fd0995e22418fd7e Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Mon, 12 Aug 2024 14:43:55 +0200 Subject: [PATCH 0081/2205] Geant4: Disable TransportationWithMsc mode The combined transportation + multiple scattering stepping mode was introduced in Geant4 11.1 and made the default for physics list FTFP_BERT_EMV. For ALICE, this mode does not work as spotted here: https://its.cern.ch/jira/browse/O2-5212 Disabling this mode fixed the issue and restores the behaviour from Geant4 11.0.4 --- Detectors/gconfig/g4config.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Detectors/gconfig/g4config.in b/Detectors/gconfig/g4config.in index cf7c1129cc148..df9376a9dda8f 100644 --- a/Detectors/gconfig/g4config.in +++ b/Detectors/gconfig/g4config.in @@ -43,6 +43,9 @@ /mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ /mcPhysics/emModel/setParticles e- e+ +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + # # Adding extra lines for fixing tracking bias # From 902c976b3d16c6147ec71e0d91fe752127f33e33 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 13 Aug 2024 15:19:44 +0200 Subject: [PATCH 0082/2205] Update README.md The link to the O2 Jira was wrong (lead to "DMC" project) --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f7105ed8c5c0..3dc6061a39351 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ Users can ask for support in [ALICE Talk](https://alice-talk.web.cern.ch). ### Issue tracking system -We use JIRA to track issues. [Report a bug here](https://alice.its.cern.ch/jira/secure/CreateIssue.jspa?pid=11201&issuetype=1). -Add the JIRA issue key (e.g. `O2-XYZ`) to the PR title or in a commit message to have the PR/commit appear in the JIRA ticket. +We use JIRA to track issues. [Report issues (bugs,...) in the O2 JIRA project](https://its.cern.ch/jira/projects/O2) by using the "Create" button to submit a bug report or feature request. Add the JIRA issue key (e.g. `O2-XYZ`) to the PR title or in a commit message to have the PR/commit appear in the JIRA ticket. ### Coding guidelines @@ -67,4 +66,4 @@ Currently O2 is built with minimal compiler warnings enabled. This is going to c ```bash aliBuild build --debug -e ALIBUILD_O2_WARNINGS=1 --defaults o2 O2 ``` -A helper script that extracts warnings from the build log skipping duplicates is available [here](https://github.com/AliceO2Group/AliceO2/blob/dev/scripts/filter-warnings.sh) \ No newline at end of file +A helper script that extracts warnings from the build log skipping duplicates is available [here](https://github.com/AliceO2Group/AliceO2/blob/dev/scripts/filter-warnings.sh) From ab9bfac445f81ba774f26faa942cf6aad9fe81ce Mon Sep 17 00:00:00 2001 From: root Date: Tue, 13 Aug 2024 13:56:01 +0200 Subject: [PATCH 0083/2205] Use correct precision to compare --- Detectors/TPC/base/test/testTPCCalDet.cxx | 40 ++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Detectors/TPC/base/test/testTPCCalDet.cxx b/Detectors/TPC/base/test/testTPCCalDet.cxx index 3fcfae6bc3a52..b93e952084396 100644 --- a/Detectors/TPC/base/test/testTPCCalDet.cxx +++ b/Detectors/TPC/base/test/testTPCCalDet.cxx @@ -28,21 +28,45 @@ namespace o2::tpc { -//templated euqality check -// for integer one would need a specialisation to check for == instead of < +// templated euqality check +// for integer one would need a specialisation to check for == instead of < template +bool isEqualAbs(T x, T y, int n = 1) +{ + // Since `epsilon()` is the gap size (ULP, unit in the last place) + // of floating-point numbers in interval [1, 2), we can scale it to + // the gap size in interval [2^e, 2^{e+1}), where `e` is the exponent + // of `x` and `y`. + + // If `x` and `y` have different gap sizes (which means they have + // different exponents), we take the smaller one. Taking the bigger + // one is also reasonable, I guess. + const T m = std::min(std::fabs(x), std::fabs(y)); + + // Subnormal numbers have fixed exponent, which is `min_exponent - 1`. + const int exp = m < std::numeric_limits::min() + ? std::numeric_limits::min_exponent - 1 + : std::ilogb(m); + + // We consider `x` and `y` equal if the difference between them is + // within `n` ULPs. + return std::fabs(x - y) <= n * std::ldexp(std::numeric_limits::epsilon(), exp); +} + +template + requires(std::integral) bool isEqualAbs(T val1, T val2) { - return std::abs(val1 - val2) < std::numeric_limits::epsilon(); + return val1 == val2; } BOOST_AUTO_TEST_CASE(CalArray_ROOTIO) { - //CalROC roc(PadSubset::ROC, 10); + // CalROC roc(PadSubset::ROC, 10); CalArray roc(PadSubset::ROC, 10); int iter = 0; - //unsigned iter=0; + // unsigned iter=0; for (auto& val : roc.getData()) { val = iter++; } @@ -51,7 +75,7 @@ BOOST_AUTO_TEST_CASE(CalArray_ROOTIO) f->WriteObject(&roc, "roc"); delete f; - //CalROC *rocRead = nullptr; + // CalROC *rocRead = nullptr; CalArray* rocRead = nullptr; f = TFile::Open("CalArray_ROOTIO.root"); f->GetObject("roc", rocRead); @@ -201,7 +225,7 @@ BOOST_AUTO_TEST_CASE(CalDet_Arithmetics) // // ===| test operators with simple numbers |================================== // - const float number = 0.2; + const float number = 0.2f; bool isEqual = true; // + operator @@ -320,4 +344,4 @@ BOOST_AUTO_TEST_CASE(CalDetTypeTest) BOOST_CHECK(testDict == true); } -} // namespace o2 +} // namespace o2::tpc From 740e425eb49f56c16cb51e7653a87f580900f5f8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 13 Aug 2024 21:22:27 +0200 Subject: [PATCH 0084/2205] SMatrixGPU test: make tested type to be double (#13382) --- GPU/Common/test/testSMatrixImp.cu | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/GPU/Common/test/testSMatrixImp.cu b/GPU/Common/test/testSMatrixImp.cu index 1e1ba9b8cf6dc..4be45c145ce60 100644 --- a/GPU/Common/test/testSMatrixImp.cu +++ b/GPU/Common/test/testSMatrixImp.cu @@ -27,10 +27,12 @@ #include #include -using MatSym3DGPU = o2::math_utils::SMatrixGPU>; -using MatSym3D = ROOT::Math::SMatrix>; -using Mat3DGPU = o2::math_utils::SMatrixGPU>; -using Mat3D = ROOT::Math::SMatrix>; +using MatSym3DGPU = o2::math_utils::SMatrixGPU>; +using MatSym3D = ROOT::Math::SMatrix>; +using Mat3DGPU = o2::math_utils::SMatrixGPU>; +using Mat3D = ROOT::Math::SMatrix>; + +static constexpr double tolerance = 1e-8; #define GPU_CHECK(call) \ do { \ @@ -130,7 +132,7 @@ GPUg() void copyMatrixKernelArray( // Function to compare two matrices element-wise with a specified tolerance template -void compareMatricesElementWise(const MatrixType& mat1, const MatrixType& mat2, float tolerance) +void compareMatricesElementWise(const MatrixType& mat1, const MatrixType& mat2, double tolerance) { auto tol = boost::test_tools::tolerance(tolerance); @@ -228,7 +230,7 @@ struct GPUSMatrixImplFixtureSolo { { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_real_distribution dis(1.0, 10.0); + std::uniform_real_distribution dis(1.0, 10.0); // Initialize host matrices with random values for (int i = 0; i < 3; ++i) { @@ -255,7 +257,6 @@ struct GPUSMatrixImplFixtureSolo { BOOST_FIXTURE_TEST_CASE(MatrixInversion, GPUSMatrixImplFixtureSolo) { - float tolerance = 0.00001f; const int nBlocks{1}, nThreads{1}; GPUBenchmark benchmark("Single symmetric matrix inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); benchmark.start(); @@ -290,7 +291,7 @@ BOOST_FIXTURE_TEST_CASE(MatrixInversion, GPUSMatrixImplFixtureSolo) identity(2, 2) = 1; auto operation = SMatrix_h * SMatrix_original_h; Mat3D result; - ROOT::Math::Assign, ROOT::Math::MatRepStd>::Evaluate(result, operation); + ROOT::Math::Assign, ROOT::Math::MatRepStd>::Evaluate(result, operation); compareMatricesElementWise(result, identity, tolerance); } @@ -307,7 +308,7 @@ struct GPUSMatrixImplFixtureDuo { { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_real_distribution dis(1.0, 10.0); + std::uniform_real_distribution dis(1.0, 10.0); // Initialize host matrices with random values for (int i = 0; i < 3; ++i) { @@ -384,7 +385,7 @@ struct GPUSmatrixImplFixtureSoloArray { { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_real_distribution dis(1.0, 10.0); + std::uniform_real_distribution dis(1.0, 10.0); // Initialize host matrices with random values for (size_t iMatrix{0}; iMatrix < D; ++iMatrix) { @@ -414,9 +415,7 @@ struct GPUSmatrixImplFixtureSoloArray { BOOST_FIXTURE_TEST_CASE(MatrixInversionArray, GPUSmatrixImplFixtureSoloArray<1'000'000>) { - float tolerance = 0.00001f; const int nBlocks{20}, nThreads{512}; - GPUBenchmark benchmark("Array of 1'000'000 symmetric matrices inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); benchmark.start(); gpu::invertMatrixKernelArray<<>>(static_cast(SMatrixSymArray_d.get()), 1'000'000); From 8cd55566e89553f43feb299a50016d9dab201900 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:22:58 +0200 Subject: [PATCH 0085/2205] Make it explicit we are currently using a signed char (#13375) --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 80 +++++++++---------- GPU/GPUTracking/utils/qconfig.cxx | 6 +- GPU/GPUTracking/utils/qconfig_helpers.h | 5 ++ 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 4a8d95d0cf371..074d73f4d7bdb 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -126,12 +126,12 @@ AddOptionRTC(cfInnerThreshold, unsigned char, 0, "", 0, "Cluster Finder extends AddOptionRTC(cfMinSplitNum, unsigned char, 1, "", 0, "Minimum number of split charges in a cluster for the cluster to be marked as split") AddOptionRTC(cfNoiseSuppressionEpsilon, unsigned char, 10, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression") AddOptionRTC(cfNoiseSuppressionEpsilonRelative, unsigned char, 76, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression, relative as fraction of 255") -AddOptionRTC(nWays, char, 3, "", 0, "Do N fit passes in final fit of merger") -AddOptionRTC(nWaysOuter, char, 0, "", 0, "Store outer param") -AddOptionRTC(trackFitRejectMode, char, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits, <0: reject at max -n hits") +AddOptionRTC(nWays, signed char, 3, "", 0, "Do N fit passes in final fit of merger") +AddOptionRTC(nWaysOuter, signed char, 0, "", 0, "Store outer param") +AddOptionRTC(trackFitRejectMode, signed char, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits, <0: reject at max -n hits") AddOptionRTC(dEdxTruncLow, unsigned char, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, unsigned char, 77, "", 0, "High truncation threshold, fraction of 128") -AddOptionRTC(globalTracking, char, 1, "", 0, "Enable Global Tracking (prolong tracks to adjacent sectors to find short segments)") +AddOptionRTC(globalTracking, signed char, 1, "", 0, "Enable Global Tracking (prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, unsigned char, 0, "", 0, "Bitmask to disable certain attachment steps during refit (1: attachment, 2: propagation, 4: loop following, 8: mirroring)") AddOptionRTC(rejectionStrategy, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression (0 = no, 1 = strategy A, 2 = strategy B)") AddOptionRTC(mergeLoopersAfterburner, unsigned char, 1, "", 0, "Run afterburner for additional looper merging") @@ -139,21 +139,21 @@ AddOptionRTC(compressionTypeMask, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettin AddOptionRTC(compressionSortOrder, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression (0 = time, 1 = pad, 2 = Z-time-pad, 3 = Z-pad-time, 4 = no sorting (use incoming order))") AddOptionRTC(sigBitsCharge, unsigned char, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, unsigned char, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") -AddOptionRTC(forceEarlyTransform, char, -1, "", 0, "Force early TPC transformation also for continuous data (-1 = auto)") +AddOptionRTC(forceEarlyTransform, signed char, -1, "", 0, "Force early TPC transformation also for continuous data (-1 = auto)") AddOptionRTC(dropLoopers, unsigned char, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerCovSource, unsigned char, 2, "", 0, "Method to obtain covariance in track merger: 0 = simple filterErrors method, 1 = use cov from track following, 2 = refit (default)") AddOptionRTC(mergerInterpolateErrors, unsigned char, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergeCE, unsigned char, 1, "", 0, "Merge tracks accross the central electrode") -AddOptionRTC(retryRefit, char, 1, "", 0, "Retry refit with seeding errors and without cluster rejection when fit fails (=2 means retry in same kernel, =1 for separate kernel") -AddOptionRTC(looperInterpolationInExtraPass, char, -1, "", 0, "Perform looper interpolation in an extra pass") -AddOptionRTC(mergerReadFromTrackerDirectly, char, 1, "", 0, "Forward data directly from tracker to merger on GPU") -AddOptionRTC(dropSecondaryLegsInOutput, char, 1, "", 0, "Do not store secondary legs of looping track in TrackTPC") -AddOptionRTC(enablePID, char, 1, "", 0, "Enable PID response") -AddOptionRTC(PID_useNsigma, char, 1, "", 0, "Use nSigma instead of absolute distance in PID response") -AddOptionRTC(adddEdxSubThresholdClusters, char, 1, "", 0, "Add sub threshold clusters in TPC dEdx computation") -AddOptionRTC(rejectEdgeClustersInSeeding, char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during seeding") -AddOptionRTC(rejectEdgeClustersInTrackFit, char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit") -AddOptionArray(PID_remap, char, 9, (0, 1, 2, 3, 4, 5, 6, 7, 8), "", 0, "Remap Ipid to PID_reamp[Ipid] (no remap if<0)") // BUG: CUDA cannot yet hand AddOptionArrayRTC +AddOptionRTC(retryRefit, signed char, 1, "", 0, "Retry refit with seeding errors and without cluster rejection when fit fails (=2 means retry in same kernel, =1 for separate kernel") +AddOptionRTC(looperInterpolationInExtraPass, signed char, -1, "", 0, "Perform looper interpolation in an extra pass") +AddOptionRTC(mergerReadFromTrackerDirectly, signed char, 1, "", 0, "Forward data directly from tracker to merger on GPU") +AddOptionRTC(dropSecondaryLegsInOutput, signed char, 1, "", 0, "Do not store secondary legs of looping track in TrackTPC") +AddOptionRTC(enablePID, signed char, 1, "", 0, "Enable PID response") +AddOptionRTC(PID_useNsigma, signed char, 1, "", 0, "Use nSigma instead of absolute distance in PID response") +AddOptionRTC(adddEdxSubThresholdClusters, signed char, 1, "", 0, "Add sub threshold clusters in TPC dEdx computation") +AddOptionRTC(rejectEdgeClustersInSeeding, signed char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during seeding") +AddOptionRTC(rejectEdgeClustersInTrackFit, signed char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit") +AddOptionArray(PID_remap, signed char, 9, (0, 1, 2, 3, 4, 5, 6, 7, 8), "", 0, "Remap Ipid to PID_reamp[Ipid] (no remap if<0)") // BUG: CUDA cannot yet hand AddOptionArrayRTC AddHelp("help", 'h') EndConfig() @@ -180,13 +180,13 @@ EndConfig() BeginSubConfig(GPUSettingsRec, rec, configStandalone, "REC", 0, "Reconstruction settings", rec) AddOptionRTC(maxTrackQPtB5, float, 1.f / GPUCA_MIN_TRACK_PTB5_DEFAULT, "", 0, "required max Q/Pt (==min Pt) of tracks") -AddOptionRTC(nonConsecutiveIDs, char, false, "", 0, "Non-consecutive cluster IDs as in HLT, disables features that need access to slice data in TPC merger") +AddOptionRTC(nonConsecutiveIDs, signed char, false, "", 0, "Non-consecutive cluster IDs as in HLT, disables features that need access to slice data in TPC merger") AddOptionRTC(fwdTPCDigitsAsClusters, unsigned char, 0, "", 0, "Forward TPC digits as clusters (if they pass the ZS threshold)") AddOptionRTC(bz0Pt10MeV, unsigned char, 60, "", 0, "Nominal Pt to set when bz = 0 (in 10 MeV)") -AddOptionRTC(fitInProjections, char, -1, "", 0, "Fit in projection, -1 to enable full fit for all but passes but the first one") -AddOptionRTC(fitPropagateBzOnly, char, -1, "", 0, "Propagate using Bz only for n passes") -AddOptionRTC(useMatLUT, char, 0, "", 0, "Use material lookup table for TPC refit") -AddOptionRTC(trackingRefitGPUModel, char, 1, "", 0, "Use GPU track model for the Global Track Refit") +AddOptionRTC(fitInProjections, signed char, -1, "", 0, "Fit in projection, -1 to enable full fit for all but passes but the first one") +AddOptionRTC(fitPropagateBzOnly, signed char, -1, "", 0, "Propagate using Bz only for n passes") +AddOptionRTC(useMatLUT, signed char, 0, "", 0, "Use material lookup table for TPC refit") +AddOptionRTC(trackingRefitGPUModel, signed char, 1, "", 0, "Use GPU track model for the Global Track Refit") AddCustomCPP(void SetMinTrackPtB5(float v) { maxTrackQPtB5 = v > 0.001f ? (1.f / v) : (1.f / 0.001f); }) AddSubConfig(GPUSettingsRecTPC, tpc) AddSubConfig(GPUSettingsRecTRD, trd) @@ -228,12 +228,12 @@ AddOption(checkKernelFailures, bool, false, "", 0, "Synchronize after each kerne AddOption(deterministicGPUReconstruction, int, -1, "", 0, "Make CPU and GPU debug output comparable (sort / skip concurrent parts), -1 = automatic if debugLevel >= 6") AddOption(showOutputStat, bool, false, "", 0, "Print some track output statistics") AddOption(runCompressionStatistics, bool, false, "compressionStat", 0, "Run statistics and verification for cluster compression") -AddOption(resetTimers, char, 1, "", 0, "Reset timers every event") +AddOption(resetTimers, signed char, 1, "", 0, "Reset timers every event") AddOption(deviceTimers, bool, true, "", 0, "Use device timers instead of host-based time measurement") AddOption(keepAllMemory, bool, false, "", 0, "Allocate all memory on both device and host, and do not reuse") AddOption(keepDisplayMemory, bool, false, "", 0, "Like keepAllMemory, but only for memory required for event display") AddOption(disableMemoryReuse, bool, false, "", 0, "Disable memory reusage (for debugging only)") -AddOption(memoryAllocationStrategy, char, 0, "", 0, "Memory Allocation Stragegy (0 = auto, 1 = individual allocations, 2 = single global allocation)") +AddOption(memoryAllocationStrategy, signed char, 0, "", 0, "Memory Allocation Stragegy (0 = auto, 1 = individual allocations, 2 = single global allocation)") AddOption(forceMemoryPoolSize, unsigned long, 1, "memSize", 0, "Force size of allocated GPU / page locked host memory", min(0ul)) AddOption(forceHostMemoryPoolSize, unsigned long, 0, "hostMemSize", 0, "Force size of allocated host page locked host memory (overriding memSize)", min(0ul)) AddOption(memoryScalingFactor, float, 1.f, "", 0, "Factor to apply to all memory scalers") @@ -245,28 +245,28 @@ AddOption(ompThreads, int, -1, "omp", 't', "Number of OMP threads to run (-1: al AddOption(ompKernels, unsigned char, 2, "", 0, "Parallelize with OMP inside kernels instead of over slices, 2 for nested parallelization over TPC sectors and inside kernels") AddOption(ompAutoNThreads, bool, true, "", 0, "Auto-adjust number of OMP threads, decreasing the number for small input data") AddOption(nDeviceHelperThreads, int, 1, "", 0, "Number of CPU helper threads for CPU processing") -AddOption(nStreams, char, 8, "", 0, "Number of GPU streams / command queues") -AddOption(nTPCClustererLanes, char, -1, "", 0, "Number of TPC clusterers that can run in parallel (-1 = autoset)") +AddOption(nStreams, signed char, 8, "", 0, "Number of GPU streams / command queues") +AddOption(nTPCClustererLanes, signed char, -1, "", 0, "Number of TPC clusterers that can run in parallel (-1 = autoset)") AddOption(overrideClusterizerFragmentLen, int, -1, "", 0, "Force the cluster max fragment len to a certain value (-1 = autodetect)") -AddOption(trackletSelectorSlices, char, -1, "", 0, "Number of slices to processes in parallel at max") -AddOption(trackletConstructorInPipeline, char, -1, "", 0, "Run tracklet constructor in the pipeline") -AddOption(trackletSelectorInPipeline, char, -1, "", 0, "Run tracklet selector in the pipeline") +AddOption(trackletSelectorSlices, signed char, -1, "", 0, "Number of slices to processes in parallel at max") +AddOption(trackletConstructorInPipeline, signed char, -1, "", 0, "Run tracklet constructor in the pipeline") +AddOption(trackletSelectorInPipeline, signed char, -1, "", 0, "Run tracklet selector in the pipeline") AddOption(fullMergerOnGPU, bool, true, "", 0, "Perform full TPC track merging on GPU instead of only refit") AddOption(delayedOutput, bool, true, "", 0, "Delay output to be parallel to track fit") -AddOption(mergerSortTracks, char, -1, "", 0, "Sort track indizes for GPU track fit") -AddOption(alternateBorderSort, char, -1, "", 0, "Alternative implementation for sorting of border tracks") -AddOption(tpcCompressionGatherMode, char, -1, "", 0, "TPC Compressed Clusters Gather Mode (0: DMA transfer gather gpu to host, 1: serial DMA to host and gather by copy on CPU, 2. gather via GPU kernal DMA access, 3. gather on GPU via kernel, dma afterwards") -AddOption(tpcCompressionGatherModeKernel, char, -1, "", 0, "TPC Compressed Clusters Gather Mode Kernel (0: unbufferd, 1-3: buffered, 4: multi-block)") +AddOption(mergerSortTracks, signed char, -1, "", 0, "Sort track indizes for GPU track fit") +AddOption(alternateBorderSort, signed char, -1, "", 0, "Alternative implementation for sorting of border tracks") +AddOption(tpcCompressionGatherMode, signed char, -1, "", 0, "TPC Compressed Clusters Gather Mode (0: DMA transfer gather gpu to host, 1: serial DMA to host and gather by copy on CPU, 2. gather via GPU kernal DMA access, 3. gather on GPU via kernel, dma afterwards") +AddOption(tpcCompressionGatherModeKernel, signed char, -1, "", 0, "TPC Compressed Clusters Gather Mode Kernel (0: unbufferd, 1-3: buffered, 4: multi-block)") AddOption(tpccfGatherKernel, bool, true, "", 0, "Use a kernel instead of the DMA engine to gather the clusters") AddOption(doublePipeline, bool, false, "", 0, "Double pipeline mode") AddOption(doublePipelineClusterizer, bool, true, "", 0, "Include the input data of the clusterizer in the double-pipeline") -AddOption(prefetchTPCpageScan, char, 0, "", 0, "Prefetch Data for TPC page scan in CPU cache") +AddOption(prefetchTPCpageScan, signed char, 0, "", 0, "Prefetch Data for TPC page scan in CPU cache") AddOption(runMC, bool, false, "", 0, "Process MC labels") AddOption(runQA, int, 0, "qa", 'q', "Enable tracking QA (negative number to provide bitmask for QA tasks)", message("Running QA: %s"), def(1)) AddOption(qcRunFraction, float, 100.f, "", 0, "Percentage of events to process with QC") AddOption(outputSharedClusterMap, bool, false, "", 0, "Ship optional shared cluster map as output for further use") AddOption(disableTPCNoisyPadFilter, bool, false, "", 0, "Disables all TPC noisy pad filters (Not the normal noise filter!)") -AddOption(createO2Output, char, 2, "", 0, "Create Track output in O2 format (2 = skip non-O2 output in GPU track format (reverts to =1 if QA is requested))") +AddOption(createO2Output, signed char, 2, "", 0, "Create Track output in O2 format (2 = skip non-O2 output in GPU track format (reverts to =1 if QA is requested))") AddOption(clearO2OutputFromGPU, bool, false, "", 0, "Free the GPU memory used for O2 output after copying to host, prevents further O2 processing on the GPU") AddOption(ignoreNonFatalGPUErrors, bool, false, "", 0, "Continue running after having received non fatal GPU errors, e.g. abort due to overflow") AddOption(tpcIncreasedMinClustersPerRow, unsigned int, 0, "", 0, "Impose a minimum buffer size for the clustersPerRow during TPC clusterization") @@ -559,13 +559,13 @@ EndConfig() // Derrived parameters used in GPUParam BeginHiddenConfig(GPUSettingsParam, param) AddVariableRTC(dAlpha, float, 0.f) // angular size -AddVariableRTC(assumeConstantBz, char, 0) // Assume a constant magnetic field -AddVariableRTC(toyMCEventsFlag, char, 0) // events were build with home-made event generator -AddVariableRTC(continuousTracking, char, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding -AddVariableRTC(resetTimers, char, 0) // Reset benchmark timers before event processing -AddVariableRTC(dodEdx, char, 0) // Do dEdx computation -AddVariableRTC(earlyTpcTransform, char, 0) // do Early TPC transformation -AddVariableRTC(debugLevel, char, 0) // Debug level +AddVariableRTC(assumeConstantBz, signed char, 0) // Assume a constant magnetic field +AddVariableRTC(toyMCEventsFlag, signed char, 0) // events were build with home-made event generator +AddVariableRTC(continuousTracking, signed char, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding +AddVariableRTC(resetTimers, signed char, 0) // Reset benchmark timers before event processing +AddVariableRTC(dodEdx, signed char, 0) // Do dEdx computation +AddVariableRTC(earlyTpcTransform, signed char, 0) // do Early TPC transformation +AddVariableRTC(debugLevel, signed char, 0) // Debug level AddVariableRTC(continuousMaxTimeBin, int, 0) // Max time bin for continuous tracking EndConfig() diff --git a/GPU/GPUTracking/utils/qconfig.cxx b/GPU/GPUTracking/utils/qconfig.cxx index f8a869ddb5987..82cd8df3a5036 100644 --- a/GPU/GPUTracking/utils/qconfig.cxx +++ b/GPU/GPUTracking/utils/qconfig.cxx @@ -334,10 +334,10 @@ inline int qAddOptionType(qConfigSettings& settings, bool& ref, int& true); } template <> -inline int qAddOptionType(qConfigSettings& settings, char& ref, int& i, const char** argv, const int argc, char /*def*/) +inline int qAddOptionType(qConfigSettings& settings, signed char& ref, int& i, const char** argv, const int argc, signed char /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> char { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> signed char { return atoi(a); }, settings.doDefault); diff --git a/GPU/GPUTracking/utils/qconfig_helpers.h b/GPU/GPUTracking/utils/qconfig_helpers.h index 4c80963d949a5..a873e618b05c6 100644 --- a/GPU/GPUTracking/utils/qconfig_helpers.h +++ b/GPU/GPUTracking/utils/qconfig_helpers.h @@ -42,6 +42,11 @@ inline std::string print_type(char val) return std::to_string(val); }; template <> +inline std::string print_type(signed char val) +{ + return std::to_string(val); +}; +template <> inline std::string print_type(unsigned char val) { return std::to_string(val); From 84ee8e1d67625323b4409a8d3cf62a23f9609177 Mon Sep 17 00:00:00 2001 From: nicolovalle <35177278+nicolovalle@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:08:32 +0200 Subject: [PATCH 0086/2205] ITS - (and MFT), better TF sampling in the deadmap builder (#13349) * ITS - (and MFT), better TF sampling in the deadmap builder * improved sampling algorithm --------- Co-authored-by: nvalle --- .../ITSMFTWorkflow/DeadMapBuilderSpec.h | 8 ++- .../workflow/src/DeadMapBuilderSpec.cxx | 58 +++++++++++++++---- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index 14f4575ee972c..00f9fc931e679 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -108,7 +108,12 @@ class ITSMFTDeadMapBuilder : public Task std::string mDataSource = "chipsstatus"; int mTFSampling = 350; - std::string mSamplingMode = "first-orbit-run"; // Use this default to ensure process of first TF. At the moment, use any other option to sample on absolute orbit value. + + // utils for an improved sampling algorithm + std::unordered_set mSampledTFs{}; + std::deque mSampledHistory{}; + int mTFSamplingTolerance = 20; + int mSampledSlidingWindowSize = 1000; // units: mTFSampling o2::itsmft::TimeDeadMap mMapObject; @@ -118,6 +123,7 @@ class ITSMFTDeadMapBuilder : public Task // Utils std::vector getChipIDsOnSameCable(uint16_t); + bool acceptTF(long); o2::framework::DataTakingContext mDataTakingContext{}; o2::framework::TimingInfo mTimingInfo{}; diff --git a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx index 8bb86a547fb25..39d1bb7df7728 100644 --- a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx @@ -47,7 +47,12 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) LOG(info) << "ITSMFTDeadMapBuilder init... " << mSelfName; mTFSampling = ic.options().get("tf-sampling"); - mSamplingMode = ic.options().get("sampling-mode"); + mTFSamplingTolerance = ic.options().get("tf-sampling-tolerance"); + if (mTFSamplingTolerance > mTFSampling) { + LOG(warning) << "Invalid request tf-sampling-tolerance larger or equal than tf-sampling. Setting tolerance to " << mTFSampling - 1; + mTFSamplingTolerance = mTFSampling - 1; + } + mSampledSlidingWindowSize = ic.options().get("tf-sampling-history-size"); mTFLength = ic.options().get("tf-length"); mDoLocalOutput = ic.options().get("local-output"); mObjectName = ic.options().get("outfile"); @@ -67,6 +72,8 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) N_CHIPS = o2::itsmft::ChipMappingITS::getNChips(); } + mSampledTFs.clear(); + mSampledHistory.clear(); mDeadMapTF.clear(); mStaticChipStatus.clear(); mMapObject.clear(); @@ -76,7 +83,7 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) mStaticChipStatus.resize(N_CHIPS, false); } - LOG(info) << "Sampling one TF every " << mTFSampling; + LOG(info) << "Sampling one TF every " << mTFSampling << " with " << mTFSamplingTolerance << " TF tolerance"; return; } @@ -95,6 +102,39 @@ std::vector ITSMFTDeadMapBuilder::getChipIDsOnSameCable(uint16_t chip) } } +bool ITSMFTDeadMapBuilder::acceptTF(long orbit) +{ + + // Description of the algorithm: + // Return true if the TF index (calculated as orbit/TF_length) falls within any interval [k * tf_sampling, k * tf_sampling + tolerance) for some integer k, provided no other TFs have been found in the same interval. + + if (mTFSamplingTolerance < 1) { + return ((orbit / mTFLength) % mTFSampling == 0); + } + + if ((orbit / mTFLength) % mTFSampling > mTFSamplingTolerance) { + return false; + } + + long sampling_index = orbit / mTFLength / mTFSampling; + + if (mSampledTFs.find(sampling_index) == mSampledTFs.end()) { + + mSampledTFs.insert(sampling_index); + mSampledHistory.push_back(sampling_index); + + if (mSampledHistory.size() > mSampledSlidingWindowSize) { + long oldIndex = mSampledHistory.front(); + mSampledHistory.pop_front(); + mSampledTFs.erase(oldIndex); + } + + return true; + } + + return false; +} + ////////////////////////////////////////////////////////////////////////////// void ITSMFTDeadMapBuilder::finalizeOutput() @@ -151,12 +191,9 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) mFirstOrbitRun = mFirstOrbitTF; } - long sampled_orbit = mFirstOrbitTF; - if (mSamplingMode == "first-orbit-run") { - sampled_orbit = sampled_orbit - mFirstOrbitRun; - } + long sampled_orbit = mFirstOrbitTF - mFirstOrbitRun; - if ((sampled_orbit / mTFLength) % mTFSampling != 0) { + if (!acceptTF(sampled_orbit)) { return; } @@ -270,7 +307,7 @@ void ITSMFTDeadMapBuilder::PrepareOutputCcdb(EndOfStreamContext* ec, std::string if (ec != nullptr) { LOG(important) << "Sending object " << info.getPath() << "/" << info.getFileName() - << "to ccdb-populator, of size " << image->size() << " bytes, valid for " + << " to ccdb-populator, of size " << image->size() << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp(); if (mRunMFT) { @@ -332,7 +369,7 @@ void ITSMFTDeadMapBuilder::stop() finalizeOutput(); if (!mCCDBUrl.empty()) { std::string detname = mRunMFT ? "MFT" : "ITS"; - LOG(warning) << "endOfStream not processed. Sending output to ccdb from the " << detname << "deadmap builder workflow."; + LOG(warning) << "endOfStream not processed. Sending output to ccdb from the " << detname << " deadmap builder workflow."; PrepareOutputCcdb(nullptr, mCCDBUrl); } else { LOG(alarm) << "endOfStream not processed. Nothing forwarded as output."; @@ -379,7 +416,8 @@ DataProcessorSpec getITSMFTDeadMapBuilderSpec(std::string datasource, bool doMFT outputs, AlgorithmSpec{adaptFromTask(datasource, doMFT)}, Options{{"tf-sampling", VariantType::Int, 350, {"Process every Nth TF. Selection according to first TF orbit."}}, - {"sampling-mode", VariantType::String, "first-orbit-run", {"Use absolute orbit value or offset from first processed orbit."}}, + {"tf-sampling-tolerance", VariantType::Int, 20, {"Tolerance on the tf-sampling value (sliding window size)."}}, + {"tf-sampling-history-size", VariantType::Int, 1000, {"Do not check if new TF is contained in a window that is older than N steps."}}, {"tf-length", VariantType::Int, 32, {"Orbits per TF."}}, {"skip-static-map", VariantType::Bool, false, {"Do not fill static part of the map."}}, {"ccdb-url", VariantType::String, "", {"CCDB url. Ignored if endOfStream is processed."}}, From d921a173346355f508270d8f186cd4d50dee71fb Mon Sep 17 00:00:00 2001 From: Joshua Koenig Date: Wed, 14 Aug 2024 13:34:17 +0200 Subject: [PATCH 0087/2205] [EMCAL-1135] Throw exception in case starttime is to large or small (#13369) - This commit is an extention for PR: https://github.com/AliceO2Group/AliceO2/pull/13326 - Move error class from base to reconstruction - added handling of error RawToCell converter: handleFastORStartTimeErrors - add error type to TRUDecodingError to indicate invalid starttime Co-authored-by: jokonig --- Detectors/EMCAL/reconstruction/CMakeLists.txt | 1 + .../EMCALReconstruction/RecoContainer.h | 5 ++++ .../ReconstructionErrors.h | 11 +++++---- .../EMCALReconstruction}/TRUDecodingErrors.h | 4 ++-- .../reconstruction/src/FastORTimeSeries.cxx | 5 +++- .../src/ReconstructionErrors.cxx | 8 +++++++ .../test/testFastORTimeSeries.cxx | 2 +- .../EMCALWorkflow/RawToCellConverterSpec.h | 13 ++++++++++ .../workflow/src/RawToCellConverterSpec.cxx | 24 ++++++++++++++++++- 9 files changed, 64 insertions(+), 9 deletions(-) rename Detectors/EMCAL/{base/include/EMCALBase => reconstruction/include/EMCALReconstruction}/TRUDecodingErrors.h (90%) diff --git a/Detectors/EMCAL/reconstruction/CMakeLists.txt b/Detectors/EMCAL/reconstruction/CMakeLists.txt index 62f66b7b613fe..32aa4ccca67a5 100644 --- a/Detectors/EMCAL/reconstruction/CMakeLists.txt +++ b/Detectors/EMCAL/reconstruction/CMakeLists.txt @@ -63,6 +63,7 @@ o2_target_root_dictionary( include/EMCALReconstruction/RecoParam.h include/EMCALReconstruction/StuDecoder.h include/EMCALReconstruction/TRUDataHandler.h + include/EMCALReconstruction/TRUDecodingErrors.h ) o2_add_executable(rawreader-file diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RecoContainer.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RecoContainer.h index 36ce04267a47f..dc3821810c4a5 100644 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RecoContainer.h +++ b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/RecoContainer.h @@ -30,6 +30,9 @@ #include #include +#ifndef ALICEO2_EMCAL_RECOCONTAINER_H +#define ALICEO2_EMCAL_RECOCONTAINER_H + namespace o2::emcal { /// \struct RecCellInfo @@ -372,3 +375,5 @@ class RecoContainerReader }; } // namespace o2::emcal + +#endif \ No newline at end of file diff --git a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/ReconstructionErrors.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/ReconstructionErrors.h index 2f09c83140ec0..c46ef63b6f3ac 100644 --- a/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/ReconstructionErrors.h +++ b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/ReconstructionErrors.h @@ -222,10 +222,11 @@ const char* getGainErrorDescription(unsigned int errorcode); /// FastOR index or TRU index is called, or by the TRU data handler if /// the patch index is outside range. enum class TRUDecodingError_t { - TRU_INDEX_INVALID, ///< TRU index invalid - PATCH_INDEX_INVALID, ///< Patch index outside range - FASTOR_INDEX_INVALID, ///< FastOR index unknown - UNKNOWN_ERROR ///< Unknown error type + TRU_INDEX_INVALID, ///< TRU index invalid + PATCH_INDEX_INVALID, ///< Patch index outside range + FASTOR_INDEX_INVALID, ///< FastOR index unknown + FASTOR_STARTTIME_INVALID, ///< FastOr stattime is larger than 14 + UNKNOWN_ERROR ///< Unknown error type }; /// \brief Get the number of TRU error codes @@ -253,6 +254,8 @@ constexpr int getErrorCodeFromTRUDecodingError(TRUDecodingError_t error) return 1; case TRUDecodingError_t::FASTOR_INDEX_INVALID: return 2; + case TRUDecodingError_t::FASTOR_STARTTIME_INVALID: + return 3; case TRUDecodingError_t::UNKNOWN_ERROR: return -1; } diff --git a/Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/TRUDecodingErrors.h similarity index 90% rename from Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h rename to Detectors/EMCAL/reconstruction/include/EMCALReconstruction/TRUDecodingErrors.h index a4a0d5d4d8584..084465f84944f 100644 --- a/Detectors/EMCAL/base/include/EMCALBase/TRUDecodingErrors.h +++ b/Detectors/EMCAL/reconstruction/include/EMCALReconstruction/TRUDecodingErrors.h @@ -29,7 +29,7 @@ class FastOrStartTimeInvalidException : public std::exception public: /// \brief Constructor /// \param l0size Size of the L0 patch - FastOrStartTimeInvalidException(unsigned int time) : std::exception(), mErrorMessage(), mStartTime(time) + FastOrStartTimeInvalidException(int time) : std::exception(), mErrorMessage(), mStartTime(time) { mErrorMessage = "FastOr starttime invalid: " + std::to_string(time); } @@ -46,7 +46,7 @@ class FastOrStartTimeInvalidException : public std::exception /// \brief Get the size of the L0 patch /// \return Size of the L0 patch - unsigned int getStartTime() const noexcept { return mStartTime; } + int getStartTime() const noexcept { return mStartTime; } private: std::string mErrorMessage; ///< Buffer for error message diff --git a/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx b/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx index 9146d9ed92b96..67ada70d6008c 100644 --- a/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx +++ b/Detectors/EMCAL/reconstruction/src/FastORTimeSeries.cxx @@ -12,7 +12,7 @@ #include #include #include "EMCALReconstruction/FastORTimeSeries.h" -#include "EMCALBase/TRUDecodingErrors.h" +#include "EMCALReconstruction/TRUDecodingErrors.h" using namespace o2::emcal; @@ -21,6 +21,9 @@ void FastORTimeSeries::fillReversed(const gsl::span samples, uin if (starttime >= 14) { throw FastOrStartTimeInvalidException(starttime); } + if (starttime + 1 < samples.size()) { + throw FastOrStartTimeInvalidException(static_cast(starttime) - static_cast(samples.size()) + 1); + } for (std::size_t isample = 0; isample < samples.size(); isample++) { mTimeSamples[starttime - isample] = samples[isample]; } diff --git a/Detectors/EMCAL/reconstruction/src/ReconstructionErrors.cxx b/Detectors/EMCAL/reconstruction/src/ReconstructionErrors.cxx index d2e5ea6d92a6f..6f1a5f5bd4f2d 100644 --- a/Detectors/EMCAL/reconstruction/src/ReconstructionErrors.cxx +++ b/Detectors/EMCAL/reconstruction/src/ReconstructionErrors.cxx @@ -156,6 +156,8 @@ TRUDecodingError_t getTRUDecodingErrorFromErrorCode(unsigned int errorcode) return TRUDecodingError_t::PATCH_INDEX_INVALID; case 2: return TRUDecodingError_t::FASTOR_INDEX_INVALID; + case 3: + return TRUDecodingError_t::FASTOR_STARTTIME_INVALID; default: return TRUDecodingError_t::UNKNOWN_ERROR; } @@ -170,6 +172,8 @@ const char* getTRUDecodingErrorName(TRUDecodingError_t errortype) return "PatchIndexInvalid"; case TRUDecodingError_t::FASTOR_INDEX_INVALID: return "FastORIndexInvalid"; + case TRUDecodingError_t::FASTOR_STARTTIME_INVALID: + return "FastORStartTimeInvalid"; default: return "UnknownError"; } @@ -189,6 +193,8 @@ const char* getTRUDecodingErrorTitle(TRUDecodingError_t errortype) return "Patch index invalid"; case TRUDecodingError_t::FASTOR_INDEX_INVALID: return "FastOR index invalid"; + case TRUDecodingError_t::FASTOR_STARTTIME_INVALID: + return "FastOR starttime invalid"; default: return "Unknown error"; } @@ -208,6 +214,8 @@ const char* getTRUDecodingErrorErrorDescription(TRUDecodingError_t errortype) return "Patch index is invalid"; case TRUDecodingError_t::FASTOR_INDEX_INVALID: return "FastOR index is invalid"; + case TRUDecodingError_t::FASTOR_STARTTIME_INVALID: + return "FastOR starttime is invalid"; default: return "Unknown error"; } diff --git a/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx b/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx index 5f512fc287967..4144273e1eb31 100644 --- a/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx +++ b/Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx @@ -16,7 +16,7 @@ #include #include #include -#include "EMCALBase/TRUDecodingErrors.h" +#include "EMCALReconstruction/TRUDecodingErrors.h" namespace o2 { diff --git a/Detectors/EMCAL/workflow/include/EMCALWorkflow/RawToCellConverterSpec.h b/Detectors/EMCAL/workflow/include/EMCALWorkflow/RawToCellConverterSpec.h index 78436eedfd522..00eb030e470d9 100644 --- a/Detectors/EMCAL/workflow/include/EMCALWorkflow/RawToCellConverterSpec.h +++ b/Detectors/EMCAL/workflow/include/EMCALWorkflow/RawToCellConverterSpec.h @@ -30,6 +30,7 @@ #include "EMCALReconstruction/RawReaderMemory.h" #include "EMCALReconstruction/RecoContainer.h" #include "EMCALReconstruction/ReconstructionErrors.h" +#include "EMCALReconstruction/TRUDecodingErrors.h" #include "EMCALWorkflow/CalibLoader.h" namespace o2 @@ -44,6 +45,7 @@ class MinorAltroDecodingError; class RawDecodingError; class FastORIndexException; class TRUIndexException; +class FastOrStartTimeInvalidException; namespace reco_workflow { @@ -466,6 +468,17 @@ class RawToCellConverterSpec : public framework::Task /// produced. void handleFastORErrors(const FastORIndexException& error, unsigned int linkID, unsigned int indexTRU); + /// \brief Handler function for FastOR start time errors + /// \param error FastOR index error + /// \param linkID DDL raising the exception + /// \param indexTRU TRU raising the exception + /// + /// Errors are printed to the infoLogger until a user-defiened + /// threshold is reached. In case the export of decoder errors + /// is activated an error object with additional information is + /// produced. + void handleFastORStartTimeErrors(const FastOrStartTimeInvalidException& e, unsigned int linkID, unsigned int indexTRU); + /// \brief Handler function patch index exception /// \param error Patch index error /// \param linkID DDL raising the exception diff --git a/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx b/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx index 55f464644ab73..f2acc370a1bdc 100644 --- a/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx +++ b/Detectors/EMCAL/workflow/src/RawToCellConverterSpec.cxx @@ -456,6 +456,7 @@ void RawToCellConverterSpec::addFEEChannelToEvent(o2::emcal::EventContainer& cur if (chantype == o2::emcal::ChannelType_t::HIGH_GAIN || chantype == o2::emcal::ChannelType_t::LOW_GAIN) { // high- / low-gain cell CellID = getCellAbsID(position.mSupermoduleID, position.mColumn, position.mRow); + isLowGain = chantype == o2::emcal::ChannelType_t::LOW_GAIN; } else { CellID = geLEDMONAbsID(position.mSupermoduleID, position.mColumn); // Module index encoded in colum for LEDMONs @@ -562,7 +563,12 @@ void RawToCellConverterSpec::addTRUChannelToEvent(o2::emcal::EventContainer& cur // std::cout << adc << ", "; //} // std::cout << std::endl; - currentEvent.setFastOR(absFastOR, bunch.getStartTime(), bunch.getADC()); + + try { + currentEvent.setFastOR(absFastOR, bunch.getStartTime(), bunch.getADC()); + } catch (FastOrStartTimeInvalidException& e) { + handleFastORStartTimeErrors(e, position.mFeeID, tru); + } } } catch (FastORIndexException& e) { handleFastORErrors(e, position.mFeeID, tru); @@ -941,6 +947,22 @@ void RawToCellConverterSpec::handleFastORErrors(const FastORIndexException& e, u } } +void RawToCellConverterSpec::handleFastORStartTimeErrors(const FastOrStartTimeInvalidException& e, unsigned int linkID, unsigned int indexTRU) +{ + if (mCreateRawDataErrors) { + mOutputDecoderErrors.emplace_back(linkID, ErrorTypeFEE::ErrorSource_t::TRU_ERROR, reconstructionerrors::getErrorCodeFromTRUDecodingError(reconstructionerrors::TRUDecodingError_t::FASTOR_STARTTIME_INVALID), indexTRU, -1); + } + if (mNumErrorMessages < mMaxErrorMessages) { + LOG(warning) << " TRU decoding: " << e.what() << " in FEE ID " << linkID << ", TRU " << indexTRU; + mNumErrorMessages++; + if (mNumErrorMessages == mMaxErrorMessages) { + LOG(warning) << "Max. amount of error messages (" << mMaxErrorMessages << " reached, further messages will be suppressed"; + } + } else { + mErrorMessagesSuppressed++; + } +} + void RawToCellConverterSpec::handlePatchError(const TRUDataHandler::PatchIndexException& e, unsigned int linkID, unsigned int indexTRU) { if (mCreateRawDataErrors) { From 6ff2d760380c9d09009c67ab921be96e625a2304 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 13 Aug 2024 14:20:41 +0200 Subject: [PATCH 0088/2205] TPC: Fix cluster sharing map allocating 4x too many bytes --- Detectors/TPC/workflow/src/ClusterSharingMapSpec.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/TPC/workflow/src/ClusterSharingMapSpec.cxx b/Detectors/TPC/workflow/src/ClusterSharingMapSpec.cxx index eef3061bc47c3..76d919470c79a 100644 --- a/Detectors/TPC/workflow/src/ClusterSharingMapSpec.cxx +++ b/Detectors/TPC/workflow/src/ClusterSharingMapSpec.cxx @@ -41,8 +41,8 @@ void ClusterSharingMapSpec::run(ProcessingContext& pc) std::shared_ptr param = o2::gpu::GPUO2InterfaceUtils::getFullParamShared(0.f, nHBPerTF); auto& bufVecSh = pc.outputs().make>(Output{o2::header::gDataOriginTPC, "CLSHAREDMAP", 0}, clustersTPC->clusterIndex.nClustersTotal); - size_t occupancyMapSize = o2::gpu::GPUO2InterfaceRefit::fillOccupancyMapGetSize(nHBPerTF, param.get()); - auto& bufVecOcc = pc.outputs().make>(Output{o2::header::gDataOriginTPC, "TPCOCCUPANCYMAP", 0}, occupancyMapSize); + size_t occupancyMapSizeBytes = o2::gpu::GPUO2InterfaceRefit::fillOccupancyMapGetSize(nHBPerTF, param.get()); + auto& bufVecOcc = pc.outputs().make>(Output{o2::header::gDataOriginTPC, "TPCOCCUPANCYMAP", 0}, occupancyMapSizeBytes / sizeof(int)); o2::gpu::GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(&clustersTPC->clusterIndex, tracksTPC, tracksTPCClRefs.data(), bufVecSh.data(), bufVecOcc.data(), nHBPerTF, param.get()); timer.Stop(); From 0cb639389013ff3d0b2c8d8658f75a6d5d10eb0f Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 13 Aug 2024 14:21:25 +0200 Subject: [PATCH 0089/2205] GPU/TPC: Some fixes for number of time bins not determined correctly for triggered data --- Detectors/TPC/qc/src/Tracking.cxx | 5 ++++- GPU/GPUTracking/DataTypes/GPUSettings.h | 4 ++-- .../Interface/GPUO2InterfaceConfigurableParam.cxx | 10 ++++++---- GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx | 2 ++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Detectors/TPC/qc/src/Tracking.cxx b/Detectors/TPC/qc/src/Tracking.cxx index e5773804105ce..a3ae6320fe9e0 100644 --- a/Detectors/TPC/qc/src/Tracking.cxx +++ b/Detectors/TPC/qc/src/Tracking.cxx @@ -55,7 +55,10 @@ void Tracking::initialize(outputModes outputMode, bool postprocessOnly) } else { throw std::runtime_error("Failed to initialize run parameters from GRP"); } - mQAConfig->ReadConfigurableParam(); + auto global = mQAConfig->ReadConfigurableParam(); + if (grp->isDetReadOut(o2::detectors::DetID::TPC) && global.tpcTriggeredMode ^ !grp->isDetContinuousReadOut(o2::detectors::DetID::TPC)) { + throw std::runtime_error("TPC triggered mode (GPU_global.tpcTriggeredMode) not set correctly"); + } mQAConfig->configQA.shipToQCAsCanvas = mOutputMode == outputLayout; mQA = std::make_unique(mQAConfig.get()); if (!postprocessOnly) { diff --git a/GPU/GPUTracking/DataTypes/GPUSettings.h b/GPU/GPUTracking/DataTypes/GPUSettings.h index 0d0f932c95e88..448646c22a2eb 100644 --- a/GPU/GPUTracking/DataTypes/GPUSettings.h +++ b/GPU/GPUTracking/DataTypes/GPUSettings.h @@ -53,11 +53,11 @@ class GPUSettings #ifdef GPUCA_NOCOMPAT // Settings describing the global run parameters struct GPUSettingsGRP { - // All new members must be sizeof(int) resp. sizeof(float) for alignment reasons! + // All new members must be sizeof(int) resp. sizeof(float) for alignment reasons!, default value for newly added members for old data will be 0. float solenoidBzNominalGPU = -5.00668f; // solenoid field strength int constBz = 0; // for test-MC events with constant Bz int homemadeEvents = 0; // Toy-MC events - int continuousMaxTimeBin = 0; // 0 for triggered events, -1 for default of 23ms + int continuousMaxTimeBin = 0; // 0 for triggered events, -1 for default TF length int needsClusterer = 0; // Set to true if the data requires the clusterizer int doCompClusterDecode = 0; // Set to true if the data contains compressed TPC clusters }; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx index 764424d50362c..b254c2fd5808f 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx @@ -103,10 +103,12 @@ GPUSettingsO2 GPUO2InterfaceConfiguration::ReadConfigurableParam(GPUO2InterfaceC obj.configReconstruction = rec; obj.configDisplay = display; obj.configQA = QA; - if (global.continuousMaxTimeBin) { - obj.configGRP.continuousMaxTimeBin = global.continuousMaxTimeBin; - } else { - obj.configGRP.continuousMaxTimeBin = global.tpcTriggeredMode ? 0 : -1; + if (obj.configGRP.continuousMaxTimeBin == 0 || obj.configGRP.continuousMaxTimeBin == -1) { + if (global.continuousMaxTimeBin) { + obj.configGRP.continuousMaxTimeBin = global.continuousMaxTimeBin; + } else { + obj.configGRP.continuousMaxTimeBin = global.tpcTriggeredMode ? 0 : -1; + } } if (global.solenoidBzNominalGPU > -1e6f) { obj.configGRP.solenoidBzNominalGPU = global.solenoidBzNominalGPU; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index cc4254f7156cf..f56e3dde1ea48 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -85,8 +85,10 @@ std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, un if (!pConfiguration) { tmpConfig = std::make_unique(); pConfiguration = &tmpConfig; + (*pConfiguration)->configGRP.continuousMaxTimeBin = -1; } else if (!*pConfiguration) { *pConfiguration = std::make_unique(); + (*pConfiguration)->configGRP.continuousMaxTimeBin = -1; } (*pConfiguration)->configGRP.solenoidBzNominalGPU = solenoidBz; if (pO2Settings && *pO2Settings) { From 6e8a0147d96775dfa5b92e9227657c74e3b0ed14 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 15 Aug 2024 11:50:49 +0200 Subject: [PATCH 0090/2205] FST: Fix running TPC at P2 online without GPUs --- prodtests/full-system-test/dpl-workflow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prodtests/full-system-test/dpl-workflow.sh b/prodtests/full-system-test/dpl-workflow.sh index e94f1e070631c..fa075b5b88ce9 100755 --- a/prodtests/full-system-test/dpl-workflow.sh +++ b/prodtests/full-system-test/dpl-workflow.sh @@ -320,7 +320,7 @@ if has_detector_calib PHS && workflow_has_parameter CALIB; then PHS_CONFIG+=" --fullclu-output" fi -[[ ${O2_GPU_DOUBLE_PIPELINE:-$EPNSYNCMODE} == 1 ]] && GPU_CONFIG+=" --enableDoublePipeline" +[[ ${O2_GPU_DOUBLE_PIPELINE:-$EPNSYNCMODE} == 1 && $GPUTYPE != "CPU" ]] && GPU_CONFIG+=" --enableDoublePipeline" [[ ${O2_GPU_RTC:-0} == 1 ]] && GPU_CONFIG_KEY+="GPU_proc_rtc.enable=1;GPU_proc_rtc.cacheOutput=1;GPU_proc.RTCcacheFolder=/var/tmp/o2_gpu_rtc_cache;" ( workflow_has_parameter AOD || [[ -z "$DISABLE_ROOT_OUTPUT" ]] || needs_root_output o2-emcal-cell-writer-workflow ) && has_detector EMC && RAW_EMC_SUBSPEC=" --subspecification 1 " From 2e52880457dee655a99196a7d05faab3e1355bbf Mon Sep 17 00:00:00 2001 From: iravasen Date: Thu, 15 Aug 2024 14:01:46 +0200 Subject: [PATCH 0091/2205] ITS Calibration: always reset chipDone counter independently on hits (#13386) * fix for chipDone counter: reset always independently on hits * removed unused counter --- .../include/ITSWorkflow/ThresholdCalibratorSpec.h | 6 ++++-- .../ITS/workflow/src/ThresholdCalibratorSpec.cxx | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h index a5064db424e5e..6bbf6a910c1f4 100644 --- a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h +++ b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h @@ -131,7 +131,8 @@ class ITSThresholdCalibrator : public Task private: void updateTimeDependentParams(ProcessingContext& pc); // detector information - static constexpr short int N_COL = 1024; // column number in Alpide chip + static constexpr short int N_COL = 1024; // number of columns in Alpide chip + static constexpr short int N_ROW = 512; // number of rows in Alpide chip static const short int N_RU = o2::itsmft::ChipMappingITS::getNRUs(); @@ -231,7 +232,8 @@ class ITSThresholdCalibrator : public Task short int mRunType = -1; short int mRunTypeUp = -1; short int mRunTypeRU[N_RU] = {0}; - short int mCdwCntRU[N_RU] = {0}; + short int mRunTypeRUCopy[N_RU] = {0}; + short int mCdwCntRU[N_RU][N_ROW] = {{0}}; short int mRowRU[N_RU] = {0}; bool mActiveLinks[N_RU][3] = {{false}}; std::set mRuSet; diff --git a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx index 0b3d67e515360..64fa4247d8aad 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx @@ -1338,6 +1338,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) // count the zeros if (!mRunTypeUp) { mRunTypeRU[iRU]++; + mRunTypeRUCopy[iRU]++; } // Divide calibration word (24-bit) by 2^16 to get the first 8 bits if (this->mScanType == 'T') { @@ -1361,7 +1362,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) // count the last N injections short int checkVal = (mScanType == 'I') ? mMin : mMax; if (loopval == checkVal && realcharge == mMin2) { // the second condition is relevant only for mScanType=p - mCdwCntRU[iRU]++; + mCdwCntRU[iRU][row]++; mRowRU[iRU] = row; // keep the row } if (this->mVerboseOutput) { @@ -1476,16 +1477,17 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) } std::vector chipEnabled = getChipListFromRu(iRU, mActiveLinks[iRU]); // chip boundaries // Fill the chipDone info string - if (mRunTypeRU[iRU] == nInjScaled * nL) { + if (mRunTypeRUCopy[iRU] == nInjScaled * nL) { for (short int iChip = 0; iChip < chipEnabled.size(); iChip++) { if ((chipEnabled[iChip] % mChipModBase) != mChipModSel) { continue; } addDatabaseEntry(chipEnabled[iChip], "", std::vector(), true); } + mRunTypeRUCopy[iRU] = 0; // reset here is safer (the other counter is reset in finalize) } // Check if scan of a row is finished: only for specific scans! - bool passCondition = (mCdwCntRU[iRU] == nInjScaled * nL); + bool passCondition = (mCdwCntRU[iRU][mRowRU[iRU]] >= nInjScaled * nL); if (mScanType != 'D' && mScanType != 'A' && mScanType != 'P' && mScanType != 'p' && mScanType != 'R' && mScanType != 'r' && passCondition) { // extract data from the row for (short int iChip = 0; iChip < chipEnabled.size(); iChip++) { @@ -1503,7 +1505,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc) } } } - mCdwCntRU[iRU] = 0; // reset + mCdwCntRU[iRU][mRowRU[iRU]] = 0; // reset } } // end loop on RuSet From 476a75a5bd49fa501a9540e57b6da05cb721ae1c Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:18:36 +0200 Subject: [PATCH 0092/2205] Simplify builder holders (#13384) --- .../Core/include/Framework/TableBuilder.h | 75 ++++--------------- 1 file changed, 16 insertions(+), 59 deletions(-) diff --git a/Framework/Core/include/Framework/TableBuilder.h b/Framework/Core/include/Framework/TableBuilder.h index 7de45f58d2e62..0df83bdfb0f53 100644 --- a/Framework/Core/include/Framework/TableBuilder.h +++ b/Framework/Core/include/Framework/TableBuilder.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace arrow { @@ -462,10 +463,10 @@ struct CachedInsertion { int pos = 0; }; -template typename InsertionPolicy> -struct BuilderHolder : InsertionPolicy { +template +struct BuilderHolder : P { static constexpr size_t index = I; - using Policy = InsertionPolicy; + using Policy = P; using ArrowType = typename detail::ConversionTraits::ArrowType; using BuilderType = typename arrow::TypeTraits::BuilderType; @@ -562,60 +563,16 @@ template struct is_bounded_array> : std::true_type { }; -template -struct HolderTrait { - - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; - -template -struct HolderTrait { - using Holder = BuilderHolder; -}; +template +concept BulkInsertable = (std::integral> && !std::same_as>); -template -struct HolderTrait { - using Holder = BuilderHolder; +template +struct InsertionTrait { + static consteval DirectInsertion policy() + requires(!BulkInsertable); + static consteval CachedInsertion policy() + requires(BulkInsertable); + using Policy = decltype(policy()); }; /// Helper function to convert a brace-initialisable struct to @@ -645,7 +602,7 @@ template constexpr auto makeHolderTypes() { return [](std::index_sequence) { - return std::tuple(typename HolderTrait::Holder(arrow::default_memory_pool())...); + return std::tuple(BuilderHolder::Policy>(arrow::default_memory_pool())...); }(std::make_index_sequence{}); } @@ -653,7 +610,7 @@ template auto makeHolders(arrow::MemoryPool* pool, size_t nRows) { return [pool, nRows](std::index_sequence) { - return new std::tuple(typename HolderTrait::Holder(pool, nRows)...); + return new std::tuple(BuilderHolder::Policy>(pool, nRows)...); }(std::make_index_sequence{}); } @@ -668,7 +625,7 @@ class TableBuilder static void throwError(RuntimeErrorRef const& ref); template - using HoldersTuple = typename std::tuple::Holder...>; + using HoldersTuple = typename std::tuple::Policy>...>; template using HoldersTupleIndexed = decltype(makeHolderTypes()); From b8782ae86cf2c129f81e571d101d966dd6e9c2ad Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 15 Aug 2024 19:00:29 +0200 Subject: [PATCH 0093/2205] Add support for bitmap in ROFRecords (#13385) --- .../include/DataFormatsITSMFT/ROFRecord.h | 12 ++++- .../ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 2 +- .../ITS/tracking/src/TrackingInterface.cxx | 47 ++++++++++--------- .../ITS/tracking/src/VertexerTraits.cxx | 2 +- 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/ROFRecord.h b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/ROFRecord.h index f5af1deeedd85..b25086fe42f30 100644 --- a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/ROFRecord.h +++ b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/ROFRecord.h @@ -45,6 +45,14 @@ class ROFRecord void setFirstEntry(int idx) { mROFEntry.setFirstEntry(idx); } void setNEntries(int n) { mROFEntry.setEntries(n); } + uint32_t getFlags() const { return mBits; } + void setFlags(uint32_t flags) { mBits = flags; } + void setFlag(uint8_t flagIndex) { mBits |= (1 << flagIndex); } + void resetFlag(uint8_t flagIndex) { mBits &= ~(1 << flagIndex); } + bool getFlag(uint8_t flagIndex) const { return mBits & (1 << flagIndex); } + void clearAllFlags() { mBits = 0; } + void setAllFlags() { mBits = ~0; } + const BCData& getBCData() const { return mBCData; } BCData& getBCData() { return mBCData; } EvIdx getEntry() const { return mROFEntry; } @@ -91,8 +99,8 @@ class ROFRecord o2::InteractionRecord mBCData; // BC data for given trigger EvIdx mROFEntry; //< reference on the 1st object of the ROF in data ROFtype mROFrame = 0; //< frame ID - - ClassDefNV(ROFRecord, 2); + uint32_t mBits = 0; + ClassDefNV(ROFRecord, 3); }; /// this is a simple reference connecting (composed) MC event ID (from the EventRecord of the RunContext) diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index 1722c05ecb4f6..4ea39e29310bf 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -98,7 +98,7 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in for (int iV{startVtx}; iV < endVtx; ++iV) { auto& primaryVertex{primaryVertices[iV]}; - if (primaryVertex.isFlagSet(1) && iteration != 3) { + if (primaryVertex.isFlagSet(2) && iteration != 3) { continue; } const float resolution = o2::gpu::CAMath::Sqrt(Sq(mTrkParams[iteration].PVres) / primaryVertex.getNContributors() + Sq(tf->getPositionResolution(iLayer))); diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx index 6419f5072c480..0fdf77e9e29fa 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx @@ -118,15 +118,14 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) } auto rofsinput = pc.inputs().get>("ROframes"); - auto& rofs = pc.outputs().make>(Output{"ITS", "ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end()); + auto& trackROFvec = pc.outputs().make>(Output{"ITS", "ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end()); auto& irFrames = pc.outputs().make>(Output{"ITS", "IRFRAMES", 0}); const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); // RS: this should come from CCDB - irFrames.reserve(rofs.size()); + irFrames.reserve(trackROFvec.size()); int nBCPerTF = alpParams.roFrameLengthInBC; - LOGP(info, "ITSTracker pulled {} clusters, {} RO frames", compClusters.size(), rofs.size()); - + LOGP(info, "ITSTracker pulled {} clusters, {} RO frames", compClusters.size(), trackROFvec.size()); const dataformats::MCTruthContainer* labels = nullptr; gsl::span mc2rofs; if (mIsMC) { @@ -165,8 +164,8 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) gsl::span::iterator pattIt = patterns.begin(); - gsl::span rofspan(rofs); - mTimeFrame->loadROFrameData(rofspan, compClusters, pattIt, mDict, labels); + gsl::span trackROFspan(trackROFvec); + mTimeFrame->loadROFrameData(trackROFspan, compClusters, pattIt, mDict, labels); pattIt = patterns.begin(); std::vector savedROF; auto logger = [&](std::string s) { LOG(info) << s; }; @@ -175,12 +174,12 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) FastMultEst multEst; // mult estimator std::vector processingMask, processUPCMask; - int cutVertexMult{0}, cutUPCVertex{0}, cutRandomMult = int(rofs.size()) - multEst.selectROFs(rofs, compClusters, physTriggers, processingMask); + int cutVertexMult{0}, cutUPCVertex{0}, cutRandomMult = int(trackROFvec.size()) - multEst.selectROFs(trackROFvec, compClusters, physTriggers, processingMask); processUPCMask.resize(processingMask.size(), false); mTimeFrame->setMultiplicityCutMask(processingMask); float vertexerElapsedTime{0.f}; if (mRunVertexer) { - vertROFvec.reserve(rofs.size()); + vertROFvec.reserve(trackROFvec.size()); // Run seeding vertexer if constexpr (isGPU) { vertexerElapsedTime = mVertexer->clustersToVerticesHybrid(logger); @@ -192,9 +191,9 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) } const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts gsl::span> vMCRecInfo; - for (auto iRof{0}; iRof < rofspan.size(); ++iRof) { + for (auto iRof{0}; iRof < trackROFspan.size(); ++iRof) { std::vector vtxVecLoc; - auto& vtxROF = vertROFvec.emplace_back(rofspan[iRof]); + auto& vtxROF = vertROFvec.emplace_back(trackROFspan[iRof]); vtxROF.setFirstEntry(vertices.size()); if (mRunVertexer) { auto vtxSpan = mTimeFrame->getPrimaryVertices(iRof); @@ -219,6 +218,11 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) allVerticesLabels.push_back(vMCRecInfo[iV].first); allVerticesPurities.push_back(vMCRecInfo[iV].second); } + if (v.isFlagSet(2)) { // Vertex is reconstructed in a second iteration + vtxROF.setFlag(2); // flag that at least one vertex is from the second iteration + } else { + vtxROF.setFlag(1); // flag that at least one vertex is from the first iteration + } } if (processingMask[iRof] && !selROF) { // passed selection in clusters and not in vertex multiplicity LOGP(info, "ROF {} rejected by the vertex multiplicity selection [{},{}]", iRof, multEstConf.cutMultVtxLow, multEstConf.cutMultVtxHigh); @@ -236,14 +240,14 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) } } if (mRunVertexer) { - LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}, upc.sel:{}", cutRandomMult + cutVertexMult + cutUPCVertex, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult, cutUPCVertex); + LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}, upc.sel:{}", cutRandomMult + cutVertexMult + cutUPCVertex, trackROFspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult, cutUPCVertex); LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} ({} + {}) vertices found in {}/{} ROFs", vertexerElapsedTime, mTimeFrame->getPrimaryVerticesNum(), mTimeFrame->getTotVertIteration()[0], o2::its::VertexerParamConfig::Instance().nIterations > 1 ? mTimeFrame->getTotVertIteration()[1] : 0, - rofspan.size() - mTimeFrame->getNoVertexROF(), - rofspan.size()); + trackROFspan.size() - mTimeFrame->getNoVertexROF(), + trackROFspan.size()); } if (mOverrideBeamEstimation) { @@ -251,7 +255,7 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) } else { LOG(info) << fmt::format(" - Beam position computed for the TF: {}, {}", mTimeFrame->getBeamX(), mTimeFrame->getBeamY()); } - if (mCosmicsProcessing && compClusters.size() > 1500 * rofspan.size()) { + if (mCosmicsProcessing && compClusters.size() > 1500 * trackROFspan.size()) { LOG(error) << "Cosmics processing was requested with an average detector occupancy exceeding 1.e-7, skipping TF processing."; } else { @@ -279,17 +283,18 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", mTimeFrame->hasBogusClusters()); } - for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) { - auto& rof{rofs[iROF]}; + for (unsigned int iROF{0}; iROF < trackROFvec.size(); ++iROF) { + auto& tracksROF{trackROFvec[iROF]}; + auto& vtxROF = vertROFvec[iROF]; auto& tracks = mTimeFrame->getTracks(iROF); auto number{tracks.size()}; auto first{allTracks.size()}; - int offset = -rof.getFirstEntry(); // cluster entry!!! - rof.setFirstEntry(first); - rof.setNEntries(number); - + int offset = -tracksROF.getFirstEntry(); // cluster entry!!! + tracksROF.setFirstEntry(first); + tracksROF.setNEntries(number); + tracksROF.setFlags(number ? vtxROF.getFlags() : 0); // copies 0xffffffff if cosmics if (processingMask[iROF]) { - irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size(); + irFrames.emplace_back(tracksROF.getBCData(), tracksROF.getBCData() + nBCPerTF - 1).info = tracks.size(); } allTrackLabels.reserve(mTimeFrame->getTracksLabel(iROF).size()); // should be 0 if not MC std::copy(mTimeFrame->getTracksLabel(iROF).begin(), mTimeFrame->getTracksLabel(iROF).end(), std::back_inserter(allTrackLabels)); diff --git a/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx index 2196e04752484..1d210cbf6a9a6 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/VertexerTraits.cxx @@ -469,7 +469,7 @@ void VertexerTraits::computeVertices(const int iteration) mTimeFrame->getTrackletClusters(rofId)[iCluster].getAvgDistance2()); // In place of chi2 vertices.back().setTimeStamp(rofId); - vertices.back().setFlags(iteration); + vertices.back().setFlags(iteration + 1); // This can be interpreted as the UPC flag if it is > 0 if (mTimeFrame->hasMCinformation()) { std::vector labels; for (auto& index : mTimeFrame->getTrackletClusters(rofId)[iCluster].getLabels()) { From ed85b4ccecf9d56bd4bc2c5120a8cb13acbe9d19 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 15 Aug 2024 21:44:03 +0200 Subject: [PATCH 0094/2205] Avoid doing one iteration when the tree has no entries (#13388) --- Detectors/EMCAL/simulation/src/RawCreator.cxx | 2 +- Detectors/PHOS/simulation/src/RawCreator.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/EMCAL/simulation/src/RawCreator.cxx b/Detectors/EMCAL/simulation/src/RawCreator.cxx index 883d907b8858e..386602e32b91c 100644 --- a/Detectors/EMCAL/simulation/src/RawCreator.cxx +++ b/Detectors/EMCAL/simulation/src/RawCreator.cxx @@ -122,7 +122,7 @@ int main(int argc, const char** argv) rawwriter.init(); // Loop over all entries in the tree, where each tree entry corresponds to a time frame - for (auto en : *treereader) { + while (treereader->Next()) { rawwriter.digitsToRaw(*digitbranch, *triggerbranch); } rawwriter.getWriter().writeConfFile("EMC", "RAWDATA", o2::utils::Str::concat_string(outputdir, "/EMCraw.cfg")); diff --git a/Detectors/PHOS/simulation/src/RawCreator.cxx b/Detectors/PHOS/simulation/src/RawCreator.cxx index 620c9f4def2be..de8bd53741572 100644 --- a/Detectors/PHOS/simulation/src/RawCreator.cxx +++ b/Detectors/PHOS/simulation/src/RawCreator.cxx @@ -109,7 +109,7 @@ int main(int argc, const char** argv) rawwriter.init(); // Loop over all entries in the tree, where each tree entry corresponds to a time frame - for (auto en : *treereader) { + while (treereader->Next()) { rawwriter.digitsToRaw(*digitbranch, *triggerbranch); } rawwriter.getWriter().writeConfFile("PHS", "RAWDATA", o2::utils::Str::concat_string(outputdir, "/PHSraw.cfg")); From ed7a61b91ea12779674dd953fa7fea7c3047078a Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Fri, 16 Aug 2024 12:31:46 +0200 Subject: [PATCH 0095/2205] DPL Analysis: make table origin a dynamic property in preparation to handle multiple sources (#13358) --- .../AODProducerWorkflow/AODProducerHelpers.h | 2 +- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 4 +- Framework/Core/include/Framework/ASoA.h | 277 +++++++++++------- .../include/Framework/AnalysisDataModel.h | 2 +- .../Core/include/Framework/AnalysisHelpers.h | 18 +- .../Core/include/Framework/AnalysisManagers.h | 2 +- .../Core/include/Framework/TableBuilder.h | 4 +- Framework/Core/src/AODReaderHelpers.cxx | 2 +- Framework/Core/test/benchmark_ASoA.cxx | 8 +- Framework/Core/test/benchmark_ASoAHelpers.cxx | 20 +- .../Core/test/benchmark_TableBuilder.cxx | 2 +- Framework/Core/test/test_ASoA.cxx | 38 +-- Framework/Core/test/test_ASoAHelpers.cxx | 28 +- .../Core/test/test_AnalysisDataModel.cxx | 2 +- Framework/Core/test/test_AnalysisTask.cxx | 2 +- .../Core/test/test_HistogramRegistry.cxx | 2 +- Framework/Core/test/test_TableBuilder.cxx | 4 +- 17 files changed, 234 insertions(+), 183 deletions(-) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h index dc6f589977cda..9ef05096b2fd2 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h @@ -50,7 +50,7 @@ struct TripletEqualTo { typedef boost::unordered_map TripletsMap_t; template -framework::Produces createTableCursor(framework::ProcessingContext& pc) +auto createTableCursor(framework::ProcessingContext& pc) { framework::Produces c; c.resetCursor(pc.outputs() diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 5d821fa3a971c..07e54403af472 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -1814,7 +1814,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto tracksCursor = createTableCursor(pc); auto tracksCovCursor = createTableCursor(pc); auto tracksExtraCursor = createTableCursor(pc); - auto tracksQACursor = createTableCursor(pc); + auto tracksQACursor = createTableCursor(pc); auto ambigTracksCursor = createTableCursor(pc); auto ambigMFTTracksCursor = createTableCursor(pc); auto ambigFwdTracksCursor = createTableCursor(pc); @@ -2986,7 +2986,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), - OutputForTable::spec(), + OutputForTable::spec(), OutputSpec{"TFN", "TFNumber"}, OutputSpec{"TFF", "TFFilename"}, OutputSpec{"AMD", "AODMetadataKeys"}, diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 2e80dca06fa36..d51b0516f18e7 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -15,6 +15,7 @@ #include "Framework/Pack.h" #include "Framework/FunctionalHelpers.h" #include "Headers/DataHeader.h" +#include "Headers/DataHeaderHelpers.h" #include "Framework/CompilerBuiltins.h" #include "Framework/Traits.h" #include "Framework/Expressions.h" @@ -37,6 +38,12 @@ using metadata = std::void_t; \ }; +#define DECLARE_SOA_ITERATOR_METADATA() \ + template \ + requires(o2::soa::is_soa_iterator_v) struct MetadataTrait { \ + using metadata = typename MetadataTrait::metadata; \ + }; + namespace o2::aod { DECLARE_SOA_METADATA(); @@ -163,7 +170,7 @@ void call_if_has_not_originals(TLambda&& lambda) } template -constexpr auto make_originals_from_type() +consteval decltype(auto) make_originals_from_type() { using decayed = std::decay_t; if constexpr (sizeof...(T) == 0) { @@ -186,9 +193,15 @@ constexpr auto make_originals_from_type() } template -constexpr auto make_originals_from_type(framework::pack) +consteval decltype(auto) make_originals_from_type(framework::pack p) { - return make_originals_from_type(); + if constexpr (sizeof...(T) == 0) { + return framework::pack<>{}; + } else { + return [](framework::pack) { + return make_originals_from_type(); + }(p); + } } /// Policy class for columns which are chunked. This @@ -770,7 +783,7 @@ struct DefaultIndexPolicy : IndexPolicyBase { int64_t mMaxRow = 0; }; -template +template class Table; /// Similar to a pair but not a pair, to avoid @@ -786,11 +799,11 @@ concept CanBind = requires(T&& t) { { t.B::mColumnIterator }; }; -template +template struct RowViewCore : public IP, C... { public: using policy_t = IP; - using table_t = o2::soa::Table; + using table_t = o2::soa::Table; using all_columns = framework::pack; using persistent_columns_t = framework::selected_pack; using index_columns_t = framework::selected_pack; @@ -813,7 +826,7 @@ struct RowViewCore : public IP, C... { } RowViewCore() = default; - RowViewCore(RowViewCore const& other) + RowViewCore(RowViewCore const& other) : IP{static_cast(other)}, C(static_cast(other))... { @@ -828,7 +841,7 @@ struct RowViewCore : public IP, C... { return *this; } - RowViewCore(RowViewCore const& other) requires std::is_same_v + RowViewCore(RowViewCore const& other) requires std::is_same_v : IP{static_cast(other)}, C(static_cast(other))... { @@ -843,7 +856,7 @@ struct RowViewCore : public IP, C... { RowViewCore operator++(int) { - RowViewCore copy = *this; + RowViewCore copy = *this; this->operator++(); return copy; } @@ -856,7 +869,7 @@ struct RowViewCore : public IP, C... { RowViewCore operator--(int) { - RowViewCore copy = *this; + RowViewCore copy = *this; this->operator--(); return copy; } @@ -958,7 +971,7 @@ struct RowViewCore : public IP, C... { [this](T*) -> void requires is_persistent_v { T::mColumnIterator.mCurrentPos = &this->mRowIndex; }, [this](T*) -> void requires is_dynamic_v { bindDynamicColumn(typename T::bindings_t{});}, [this](T*) -> void {}, - }; +}; (f(static_cast(nullptr)), ...); if constexpr (has_index_v) { this->setIndices(this->getIndices()); @@ -1005,7 +1018,7 @@ struct ArrowHelpers { }; template -using originals_pack_t = decltype(make_originals_from_type()); +using originals_pack_t = decltype(make_originals_from_type(framework::pack{})); template constexpr bool are_bindings_compatible_v(framework::pack&&) @@ -1207,9 +1220,35 @@ using PresliceOptional = PresliceBase; namespace o2::soa { +/// special case for the template with origin +template class Ref> +struct is_specialization_origin : std::false_type { +}; + +template mOrigTrPtr; - std::array mTrAux; // Aux track info for each track at each cand. vertex - CrossInfo mCrossings; // info on track crossing - - std::array mTrcEInv; // errors for each track at each cand. vertex - std::array mCandTr; // tracks at each cond. vertex (Note: Errors are at seed XY point) - std::array mTrCFVT; // TrackCoefVtx for each track at each cand. vertex - std::array mTrDer; // Track derivativse - std::array mTrPos; // Track positions - std::array mTrRes; // Track residuals - std::array mPCA; // PCA for each vertex candidate - std::array mChi2 = {0}; // Chi2 at PCA candidate - std::array mNIters; // number of iterations for each seed - std::array mTrPropDone{}; // Flag that the tracks are fully propagated to PCA - std::array mPropFailed{}; // Flag that some propagation failed for this PCA candidate - MatSym3D mWeightInv; // inverse weight of single track, [sum{M^T E M}]^-1 in EQ.T - std::array mOrder{0}; + o2::gpu::gpustd::array mOrigTrPtr; + o2::gpu::gpustd::array mTrAux; // Aux track info for each track at each cand. vertex + CrossInfo mCrossings; // info on track crossing + + o2::gpu::gpustd::array mTrcEInv; // errors for each track at each cand. vertex + o2::gpu::gpustd::array mCandTr; // tracks at each cond. vertex (Note: Errors are at seed XY point) + o2::gpu::gpustd::array mTrCFVT; // TrackCoefVtx for each track at each cand. vertex + o2::gpu::gpustd::array mTrDer; // Track derivativse + o2::gpu::gpustd::array mTrPos; // Track positions + o2::gpu::gpustd::array mTrRes; // Track residuals + o2::gpu::gpustd::array mPCA; // PCA for each vertex candidate + o2::gpu::gpustd::array mChi2 = {0}; // Chi2 at PCA candidate + o2::gpu::gpustd::array mNIters; // number of iterations for each seed + o2::gpu::gpustd::array mTrPropDone{}; // Flag that the tracks are fully propagated to PCA + o2::gpu::gpustd::array mPropFailed{}; // Flag that some propagation failed for this PCA candidate + MatSym3D mWeightInv; // inverse weight of single track, [sum{M^T E M}]^-1 in EQ.T + o2::gpu::gpustd::array mOrder{0}; int mCurHyp = 0; int mCrossIDCur = 0; int mCrossIDAlt = -1; @@ -347,7 +355,7 @@ class DCAFitterN ///_________________________________________________________________________ template template -int DCAFitterN::process(const Tr&... args) +GPUd() int DCAFitterN::process(const Tr&... args) { // This is a main entry point: fit PCA of N tracks mCallID++; @@ -401,7 +409,7 @@ int DCAFitterN::process(const Tr&... args) for (int i = mCurHyp; i--;) { // order in quality for (int j = i; j--;) { if (mChi2[mOrder[i]] < mChi2[mOrder[j]]) { - std::swap(mOrder[i], mOrder[j]); + o2::gpu::GPUCommonMath::Swap(mOrder[i], mOrder[j]); } } } @@ -415,7 +423,7 @@ int DCAFitterN::process(const Tr&... args) //__________________________________________________________________________ template -bool DCAFitterN::calcPCACoefs() +GPUd() bool DCAFitterN::calcPCACoefs() { //< calculate Ti matrices for global vertex decomposition to V = sum_{0::calcPCACoefs() //__________________________________________________________________________ template -bool DCAFitterN::calcInverseWeight() +GPUd() bool DCAFitterN::calcInverseWeight() { //< calculate [sum_{0::calcInverseWeight() //__________________________________________________________________________ template -void DCAFitterN::calcResidDerivatives() +GPUd() void DCAFitterN::calcResidDerivatives() { //< calculate matrix of derivatives for weighted chi2: residual i vs parameter X of track j MatStd3D matMT; @@ -514,7 +522,7 @@ void DCAFitterN::calcResidDerivatives() //__________________________________________________________________________ template -void DCAFitterN::calcResidDerivativesNoErr() +GPUd() void DCAFitterN::calcResidDerivativesNoErr() { //< calculate matrix of derivatives for absolute distance chi2: residual i vs parameter X of track j constexpr double NInv1 = 1. - NInv; // profit from Rii = I/Ninv @@ -564,7 +572,7 @@ void DCAFitterN::calcResidDerivativesNoErr() //__________________________________________________________________________ template -void DCAFitterN::calcRMatrices() +GPUd() void DCAFitterN::calcRMatrices() { //< calculate Rij = 1/N M_i^T * M_j matrices (rotation from j-th track to i-th track frame) for (int i = N; i--;) { @@ -579,10 +587,10 @@ void DCAFitterN::calcRMatrices() //__________________________________________________________________________ template -void DCAFitterN::calcChi2Derivatives() +GPUd() void DCAFitterN::calcChi2Derivatives() { //< calculate 1st and 2nd derivatives of wighted DCA (chi2) over track parameters X, see EQ.Chi2 in the ref - std::array, N> covIDrDx; // tempory vectors of covI_j * dres_j/dx_i + o2::gpu::gpustd::array, N> covIDrDx; // tempory vectors of covI_j * dres_j/dx_i // chi2 1st derivative for (int i = N; i--;) { @@ -597,7 +605,7 @@ void DCAFitterN::calcChi2Derivatives() cidr[1] = covI.syy * dr1[1] + covI.syz * dr1[2]; cidr[2] = covI.syz * dr1[1] + covI.szz * dr1[2]; // calculate res_i * covI_j * dres_j/dx_i - dchi1 += ROOT::Math::Dot(res, cidr); + dchi1 += o2::math_utils::Dot(res, cidr); } } // chi2 2nd derivative @@ -608,7 +616,7 @@ void DCAFitterN::calcChi2Derivatives() for (int k = N; k--;) { const auto& dr1j = mDResidDx[k][j]; // vector of k-th residuals 1st derivative over X param of track j const auto& cidrkj = covIDrDx[i][k]; // vector covI_k * dres_k/dx_i - dchi2 += ROOT::Math::Dot(dr1j, cidrkj); + dchi2 += o2::math_utils::Dot(dr1j, cidrkj); if (k == j) { const auto& res = mTrRes[mCurHyp][k]; // vector of residuals of track k const auto& covI = mTrcEInv[mCurHyp][k]; // inverse cov matrix of track k @@ -622,7 +630,7 @@ void DCAFitterN::calcChi2Derivatives() //__________________________________________________________________________ template -void DCAFitterN::calcChi2DerivativesNoErr() +GPUd() void DCAFitterN::calcChi2DerivativesNoErr() { //< calculate 1st and 2nd derivatives of abs DCA (chi2) over track parameters X, see (6) in the ref for (int i = N; i--;) { @@ -631,13 +639,13 @@ void DCAFitterN::calcChi2DerivativesNoErr() for (int j = N; j--;) { const auto& res = mTrRes[mCurHyp][j]; // vector of residuals of track j const auto& dr1 = mDResidDx[j][i]; // vector of j-th residuals 1st derivative over X param of track i - dchi1 += ROOT::Math::Dot(res, dr1); + dchi1 += o2::math_utils::Dot(res, dr1); if (i >= j) { // symmetrix matrix // chi2 2nd derivative auto& dchi2 = mD2Chi2Dx2[i][j]; // D2Chi2/Dx_i/Dx_j = sum_k { Dres_k/Dx_j * covI_k * Dres_k/Dx_i + res_k * covI_k * D2res_k/Dx_i/Dx_j } - dchi2 = ROOT::Math::Dot(mTrRes[mCurHyp][i], mD2ResidDx2[i][j]); + dchi2 = o2::math_utils::Dot(mTrRes[mCurHyp][i], mD2ResidDx2[i][j]); for (int k = N; k--;) { - dchi2 += ROOT::Math::Dot(mDResidDx[k][i], mDResidDx[k][j]); + dchi2 += o2::math_utils::Dot(mDResidDx[k][i], mDResidDx[k][j]); } } } @@ -646,7 +654,7 @@ void DCAFitterN::calcChi2DerivativesNoErr() //___________________________________________________________________ template -void DCAFitterN::calcPCA() +GPUd() void DCAFitterN::calcPCA() { // calculate point of closest approach for N prongs mPCA[mCurHyp] = mTrCFVT[mCurHyp][N - 1] * mTrPos[mCurHyp][N - 1]; @@ -657,7 +665,7 @@ void DCAFitterN::calcPCA() //___________________________________________________________________ template -bool DCAFitterN::recalculatePCAWithErrors(int cand) +GPUd() bool DCAFitterN::recalculatePCAWithErrors(int cand) { // recalculate PCA as a cov-matrix weighted mean, even if absDCA method was used if (isPropagateTracksToVertexDone(cand) && !propagateTracksToVertex(cand)) { @@ -682,7 +690,7 @@ bool DCAFitterN::recalculatePCAWithErrors(int cand) //___________________________________________________________________ template -void DCAFitterN::calcPCANoErr() +GPUd() void DCAFitterN::calcPCANoErr() { // calculate point of closest approach for N prongs w/o errors auto& pca = mPCA[mCurHyp]; @@ -704,15 +712,15 @@ void DCAFitterN::calcPCANoErr() //___________________________________________________________________ template -ROOT::Math::SMatrix> DCAFitterN::calcPCACovMatrix(int cand) const +GPUd() o2::math_utils::SMatrix> DCAFitterN::calcPCACovMatrix(int cand) const { // calculate covariance matrix for the point of closest approach MatSym3D covm; int nAdded = 0; for (int i = N; i--;) { // calculate sum of inverses - // MatSym3D covTr = ROOT::Math::Similarity(mUseAbsDCA ? getTrackRotMatrix(i) : mTrCFVT[mOrder[cand]][i], getTrackCovMatrix(i, cand)); + // MatSym3D covTr = o2::math_utils::Similarity(mUseAbsDCA ? getTrackRotMatrix(i) : mTrCFVT[mOrder[cand]][i], getTrackCovMatrix(i, cand)); // RS by using Similarity(mTrCFVT[mOrder[cand]][i], getTrackCovMatrix(i, cand)) we underestimate the error, use simple rotation - MatSym3D covTr = ROOT::Math::Similarity(getTrackRotMatrix(i), getTrackCovMatrix(i, cand)); + MatSym3D covTr = o2::math_utils::Similarity(getTrackRotMatrix(i), getTrackCovMatrix(i, cand)); if (covTr.Invert()) { covm += covTr; nAdded++; @@ -724,14 +732,14 @@ ROOT::Math::SMatrix> DCAFitterN -void DCAFitterN::calcTrackResiduals() +GPUd() void DCAFitterN::calcTrackResiduals() { // calculate residuals Vec3D vtxLoc; @@ -745,7 +753,7 @@ void DCAFitterN::calcTrackResiduals() //___________________________________________________________________ template -inline void DCAFitterN::calcTrackDerivatives() +GPUd() inline void DCAFitterN::calcTrackDerivatives() { // calculate track derivatives over X param for (int i = N; i--;) { @@ -755,7 +763,7 @@ inline void DCAFitterN::calcTrackDerivatives() //___________________________________________________________________ template -inline double DCAFitterN::calcChi2() const +GPUd() inline double DCAFitterN::calcChi2() const { // calculate current chi2 double chi2 = 0; @@ -769,7 +777,7 @@ inline double DCAFitterN::calcChi2() const //___________________________________________________________________ template -inline double DCAFitterN::calcChi2NoErr() const +GPUd() inline double DCAFitterN::calcChi2NoErr() const { // calculate current chi2 of abs. distance minimization double chi2 = 0; @@ -782,7 +790,7 @@ inline double DCAFitterN::calcChi2NoErr() const //___________________________________________________________________ template -bool DCAFitterN::correctTracks(const VecND& corrX) +GPUd() bool DCAFitterN::correctTracks(const VecND& corrX) { // propagate tracks to updated X for (int i = N; i--;) { @@ -797,7 +805,7 @@ bool DCAFitterN::correctTracks(const VecND& corrX) //___________________________________________________________________ template -bool DCAFitterN::propagateTracksToVertex(int icand) +GPUd() bool DCAFitterN::propagateTracksToVertex(int icand) { // propagate tracks to current vertex int ord = mOrder[icand]; @@ -834,7 +842,7 @@ bool DCAFitterN::propagateTracksToVertex(int icand) //___________________________________________________________________ template -inline o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int i, int icand) +GPUd() inline o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int i, int icand) { // propagate tracks param only to current vertex (if not already done) int ord = mOrder[icand]; @@ -845,16 +853,16 @@ inline o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int i, int trc.invalidate(); } } - return std::move(trc); + return trc; } //___________________________________________________________________ template -inline double DCAFitterN::getAbsMax(const VecND& v) +GPUd() inline double DCAFitterN::getAbsMax(const VecND& v) { double mx = -1; for (int i = N; i--;) { - auto vai = std::abs(v[i]); + auto vai = o2::gpu::GPUCommonMath::Abs(v[i]); if (mx < vai) { mx = vai; } @@ -864,7 +872,7 @@ inline double DCAFitterN::getAbsMax(const VecND& v) //___________________________________________________________________ template -bool DCAFitterN::minimizeChi2() +GPUd() bool DCAFitterN::minimizeChi2() { // find best chi2 (weighted DCA) of N tracks in the vicinity of the seed PCA for (int i = N; i--;) { @@ -921,7 +929,7 @@ bool DCAFitterN::minimizeChi2() //___________________________________________________________________ template -bool DCAFitterN::minimizeChi2NoErr() +GPUd() bool DCAFitterN::minimizeChi2NoErr() { // find best chi2 (absolute DCA) of N tracks in the vicinity of the PCA seed @@ -974,13 +982,13 @@ bool DCAFitterN::minimizeChi2NoErr() //___________________________________________________________________ template -bool DCAFitterN::roughDZCut() const +GPUd() bool DCAFitterN::roughDZCut() const { // apply rough cut on DZ between the tracks in the seed point bool accept = true; for (int i = N; accept && i--;) { for (int j = i; j--;) { - if (std::abs(mCandTr[mCurHyp][i].getZ() - mCandTr[mCurHyp][j].getZ()) > mMaxDZIni) { + if (o2::gpu::GPUCommonMath::Abs(mCandTr[mCurHyp][i].getZ() - mCandTr[mCurHyp][j].getZ()) > mMaxDZIni) { accept = false; break; } @@ -991,7 +999,7 @@ bool DCAFitterN::roughDZCut() const //___________________________________________________________________ template -bool DCAFitterN::closerToAlternative() const +GPUd() bool DCAFitterN::closerToAlternative() const { // check if the point current PCA point is closer to the seeding XY point being tested or to alternative see (if any) auto dxCur = mPCA[mCurHyp][0] - mCrossings.xDCA[mCrossIDCur], dyCur = mPCA[mCurHyp][1] - mCrossings.yDCA[mCrossIDCur]; @@ -1001,7 +1009,7 @@ bool DCAFitterN::closerToAlternative() const //___________________________________________________________________ template -void DCAFitterN::print() const +GPUd() void DCAFitterN::print() const { LOG(info) << N << "-prong vertex fitter in " << (mUseAbsDCA ? "abs." : "weighted") << " distance minimization mode"; LOG(info) << "Bz: " << mBz << " MaxIter: " << mMaxIter << " MaxChi2: " << mMaxChi2; @@ -1011,17 +1019,17 @@ void DCAFitterN::print() const //___________________________________________________________________ template -o2::track::TrackParCov DCAFitterN::createParentTrackParCov(int cand, bool sectorAlpha) const +GPUd() o2::track::TrackParCov DCAFitterN::createParentTrackParCov(int cand, bool sectorAlpha) const { const auto& trP = getTrack(0, cand); const auto& trN = getTrack(1, cand); - std::array covV = {0.}; - std::array pvecV = {0.}; + o2::gpu::gpustd::array covV = {0.}; + o2::gpu::gpustd::array pvecV = {0.}; int q = 0; for (int it = 0; it < N; it++) { const auto& trc = getTrack(it, cand); - std::array pvecT = {0.}; - std::array covT = {0.}; + o2::gpu::gpustd::array pvecT = {0.}; + o2::gpu::gpustd::array covT = {0.}; trc.getPxPyPzGlo(pvecT); trc.getCovXYZPxPyPzGlo(covT); constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component @@ -1040,34 +1048,34 @@ o2::track::TrackParCov DCAFitterN::createParentTrackParCov(int cand, covV[3] = covVtxV(2, 0); covV[4] = covVtxV(2, 1); covV[5] = covVtxV(2, 2); - return std::move(o2::track::TrackParCov(getPCACandidatePos(cand), pvecV, covV, q, sectorAlpha)); + return o2::track::TrackParCov(getPCACandidatePos(cand), pvecV, covV, q, sectorAlpha); } //___________________________________________________________________ template -o2::track::TrackPar DCAFitterN::createParentTrackPar(int cand, bool sectorAlpha) const +GPUd() o2::track::TrackPar DCAFitterN::createParentTrackPar(int cand, bool sectorAlpha) const { const auto& trP = getTrack(0, cand); const auto& trN = getTrack(1, cand); const auto& wvtx = getPCACandidate(cand); - std::array pvecV = {0.}; + o2::gpu::gpustd::array pvecV = {0.}; int q = 0; for (int it = 0; it < N; it++) { const auto& trc = getTrack(it, cand); - std::array pvecT = {0.}; + o2::gpu::gpustd::array pvecT = {0.}; trc.getPxPyPzGlo(pvecT); for (int i = 0; i < 3; i++) { pvecV[i] += pvecT[i]; } q += trc.getCharge(); } - const std::array vertex = {(float)wvtx[0], (float)wvtx[1], (float)wvtx[2]}; - return std::move(o2::track::TrackPar(vertex, pvecV, q, sectorAlpha)); + const o2::gpu::gpustd::array vertex = {(float)wvtx[0], (float)wvtx[1], (float)wvtx[2]}; + return o2::track::TrackPar(vertex, pvecV, q, sectorAlpha); } //___________________________________________________________________ template -inline bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, float x) +GPUd() inline bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, float x) { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { @@ -1083,7 +1091,7 @@ inline bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, fl //___________________________________________________________________ template -inline bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, float x) +GPUd() inline bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, float x) { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { diff --git a/Common/MathUtils/include/MathUtils/Cartesian.h b/Common/MathUtils/include/MathUtils/Cartesian.h index 9ca6d0def4682..67e17ae6bd47d 100644 --- a/Common/MathUtils/include/MathUtils/Cartesian.h +++ b/Common/MathUtils/include/MathUtils/Cartesian.h @@ -34,8 +34,8 @@ #include "GPUCommonMath.h" #include "CartesianGPU.h" #include "SMatrixGPU.h" - #endif + #include "GPUROOTCartesianFwd.h" #include "GPUROOTSMatrixFwd.h" @@ -250,6 +250,22 @@ class Transform3D : public ROOT::Math::Transform3D ClassDefNV(Transform3D, 1); }; #endif // Disable for GPU + +// Aliasing of the Dot(SVector a, SVector b) operation between SVectors +#if (!defined(GPUCA_STANDALONE) || !defined(DGPUCA_NO_ROOT)) && !defined(GPUCA_GPUCODE) && !defined(GPUCOMMONRTYPES_H_ACTIVE) +template +inline T Dot(const SVector& lhs, const SVector& rhs) +{ + return ROOT::Math::Dot(lhs, rhs); +} + +template +inline SMatrix> Similarity(const SMatrix& lhs, const SMatrix>& rhs) +{ + return ROOT::Math::Similarity(lhs, rhs); +} +#endif // Disable for GPU + } // namespace math_utils } // namespace o2 diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index 7175339db8592..6f0301390d54e 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -1468,5 +1468,5 @@ GPUdi() SMatrixGPU> Similarity(const SMatrixGPU using array = std::array; #endif } // namespace o2::gpu::gpustd - -#endif +#endif \ No newline at end of file diff --git a/GPU/Common/GPUCommonMath.h b/GPU/Common/GPUCommonMath.h index cf15d9ee0409b..abb35e1af1655 100644 --- a/GPU/Common/GPUCommonMath.h +++ b/GPU/Common/GPUCommonMath.h @@ -87,6 +87,9 @@ class GPUCommonMath GPUhdni() static float Hypot(float x, float y, float z); GPUhdni() static float Hypot(float x, float y, float z, float w); + template + GPUhd() static void Swap(T& a, T& b); + template GPUdi() static T AtomicExch(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val) { @@ -173,7 +176,7 @@ class GPUCommonMath typedef GPUCommonMath CAMath; -// CHOICE Syntax: CHOISE(Host, CUDA&HIP, OpenCL) +// CHOICE Syntax: CHOICE(Host, CUDA&HIP, OpenCL) #if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__)) // clang-format off #define CHOICE(c1, c2, c3) (c2) // Select second option for CUDA and HIP #elif defined(GPUCA_GPUCODE_DEVICE) && defined (__OPENCL__) @@ -321,6 +324,20 @@ GPUhdi() float GPUCommonMath::Hypot(float x, float y, float z, float w) return Sqrt(x * x + y * y + z * z + w * w); } +template +void _swap(T& a, T& b) +{ + T tmp = a; + a = b; + b = tmp; +} + +template +GPUhdi() void GPUCommonMath::Swap(T& a, T& b) +{ + CHOICE(std::swap(a, b), _swap(a, b), _swap(a, b)); +} + template GPUhdi() T GPUCommonMath::Min(const T x, const T y) { diff --git a/GPU/Common/GPUROOTSMatrixFwd.h b/GPU/Common/GPUROOTSMatrixFwd.h index 84047538cb912..b1dd9bd0bbb0d 100644 --- a/GPU/Common/GPUROOTSMatrixFwd.h +++ b/GPU/Common/GPUROOTSMatrixFwd.h @@ -44,12 +44,12 @@ namespace detail { template class SVectorGPU; +template +class SMatrixGPU; template class MatRepSymGPU; template class MatRepStdGPU; -template -class SMatrixGPU; } // namespace detail #if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE) @@ -59,17 +59,18 @@ template using SMatrix = ROOT::Math::SMatrix; template using MatRepSym = ROOT::Math::MatRepSym; -template +template using MatRepStd = ROOT::Math::MatRepStd; #else template using SVector = detail::SVectorGPU; +template > +using SMatrix = detail::SMatrixGPU; template using MatRepSym = detail::MatRepSymGPU; template using MatRepStd = detail::MatRepStdGPU; -template > -using SMatrix = detail::SMatrixGPU; + #endif } // namespace math_utils From a7150e2714f1bb782bd0d8fcb74b795890f1f02c Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 26 Aug 2024 13:06:04 +0200 Subject: [PATCH 0139/2205] o2-sim: Ability to adjust default option values depending on Run5 or not --- Common/SimConfig/include/SimConfig/SimConfig.h | 2 +- Common/SimConfig/src/SimConfig.cxx | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Common/SimConfig/include/SimConfig/SimConfig.h b/Common/SimConfig/include/SimConfig/SimConfig.h index b215f22546c8e..da2f978ddf319 100644 --- a/Common/SimConfig/include/SimConfig/SimConfig.h +++ b/Common/SimConfig/include/SimConfig/SimConfig.h @@ -118,7 +118,7 @@ class SimConfig return SimConfig(); } - static void initOptions(boost::program_options::options_description&); + static void initOptions(boost::program_options::options_description&, bool isUpgrade = false); // initializes the configuration from command line arguments // returns true of correctly initialized and not --help called diff --git a/Common/SimConfig/src/SimConfig.cxx b/Common/SimConfig/src/SimConfig.cxx index 0f798247d55c5..9a10b26547ce6 100644 --- a/Common/SimConfig/src/SimConfig.cxx +++ b/Common/SimConfig/src/SimConfig.cxx @@ -24,8 +24,15 @@ using namespace o2::conf; namespace bpo = boost::program_options; -void SimConfig::initOptions(boost::program_options::options_description& options) +void SimConfig::initOptions(boost::program_options::options_description& options, bool isUpgrade) { + // some default args might depend on whether Run3 or Run5 + // can be updated here: + std::string defaultGeomList{"ALICE2"}; + if (isUpgrade == true) { + defaultGeomList = "ALICE3"; + } + int nsimworkersdefault = std::max(1u, std::thread::hardware_concurrency() / 2); options.add_options()( "mcEngine,e", bpo::value()->default_value("TGeant4"), "VMC backend to be used.")( @@ -35,7 +42,7 @@ void SimConfig::initOptions(boost::program_options::options_description& options "skipModules", bpo::value>()->multitoken()->default_value(std::vector({""}), ""), "list of modules excluded in geometry (precendence over -m")( "readoutDetectors", bpo::value>()->multitoken()->default_value(std::vector(), ""), "list of detectors creating hits, all if not given; added to to active modules")( "skipReadoutDetectors", bpo::value>()->multitoken()->default_value(std::vector(), ""), "list of detectors to skip hit creation (precendence over --readoutDetectors")( - "detectorList", bpo::value()->default_value("ALICE2"), + "detectorList", bpo::value()->default_value(defaultGeomList), "Use a specific version of ALICE, e.g., a predefined list." "There is an 'official' list provided with:" "\nALICE2 : The default configuration for Run 3" @@ -490,7 +497,7 @@ bool SimConfig::resetFromArguments(int argc, char* argv[]) bpo::variables_map vm; bpo::options_description desc("Allowed options"); desc.add_options()("help,h", "Produce help message."); - initOptions(desc); + initOptions(desc, mConfigData.mIsUpgrade); try { bpo::store(parse_command_line(argc, argv, desc), vm); From f10d2e54cdb2305fad61853f3ce0fc91aa0eb100 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 20 Aug 2024 10:54:22 +0200 Subject: [PATCH 0140/2205] ITSMFT: Add setter for Start Position of hit Signed-off-by: Felix Schlepper --- .../ITSMFT/common/simulation/include/ITSMFTSimulation/Hit.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Hit.h b/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Hit.h index 012849d131aa4..537569757effd 100644 --- a/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Hit.h +++ b/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Hit.h @@ -94,6 +94,9 @@ class Hit : public o2::BasicXYZEHit Bool_t IsStoppedStart() const { return mTrackStatusStart & kTrackStopped; } Bool_t IsAliveStart() const { return mTrackStatusStart & kTrackAlive; } + // Entrance position setter + void SetPosStart(const math_utils::Point3D& p) { mPosStart = p; } + /// Output to screen void Print(const Option_t* opt) const; friend std::ostream& operator<<(std::ostream& of, const Hit& point) From e300277cfc065f5b82a772bb6bea4440a66a51f2 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 20 Aug 2024 10:57:06 +0200 Subject: [PATCH 0141/2205] IT3: Initial Hit misalignment, disabling tiles, LegendrePolynominals Signed-off-by: Felix Schlepper --- Common/MathUtils/CMakeLists.txt | 6 +- .../include/MathUtils/LegendrePols.h | 213 ++++++++++ Common/MathUtils/src/MathUtilsLinkDef.h | 3 + Detectors/Upgrades/ITS3/CMakeLists.txt | 1 + Detectors/Upgrades/ITS3/README.md | 19 + .../Upgrades/ITS3/alignment/CMakeLists.txt | 26 ++ .../include/ITS3Align/Deformations.h | 84 ++++ .../include/ITS3Align/MisalignmentHits.h | 216 ++++++++++ .../include/ITS3Align/MisalignmentManager.h | 53 +++ .../ITS3Align/MisalignmentParameters.h | 93 +++++ .../ITS3/alignment/src/Deformations.cxx | 41 ++ .../ITS3/alignment/src/ITS3AlignLinkDef.h | 20 + .../ITS3/alignment/src/MisalignmentHits.cxx | 369 +++++++++++++++++ .../alignment/src/MisalignmentManager.cxx | 195 +++++++++ .../alignment/src/MisalignmentParameters.cxx | 80 ++++ Detectors/Upgrades/ITS3/base/CMakeLists.txt | 8 +- .../ITS3/base/include/ITS3Base/ITS3Params.h | 35 ++ .../include/ITS3Base/MisalignmentParameter.h | 71 ---- .../ITS3Base/SegmentationSuperAlpide.h | 3 - .../ITS3/base/include/ITS3Base/SpecsV2.h | 30 +- .../Upgrades/ITS3/base/src/ITS3BaseLinkDef.h | 3 +- .../Upgrades/ITS3/base/src/ITS3Params.cxx | 13 + .../ITS3/base/src/MisalignmentParameter.cxx | 93 ----- Detectors/Upgrades/ITS3/macros/CMakeLists.txt | 23 +- .../Upgrades/ITS3/macros/align/CMakeLists.txt | 17 + .../ITS3/macros/align/CheckResidualsITS3.C | 372 ++++++++++++++++++ .../macros/align/CreateMisalignmentITS3.C | 94 +++++ .../ITS3/macros/align/MisAlignGeoITS3.notest | 129 ++++++ .../ITS3/macros/align/ShowCoefficients.C | 333 ++++++++++++++++ .../ITS3/macros/align/TestLegendrePol.C | 257 ++++++++++++ .../Upgrades/ITS3/macros/test/CMakeLists.txt | 184 +-------- .../ITS3/macros/test/CheckClustersITS3.C | 18 +- .../ITS3/macros/test/CheckDigitsITS3.C | 2 +- .../ITS3/macros/test/CheckTileNumbering.C | 183 +++++++++ .../ITS3/macros/test/CheckTracksITS3.C | 9 +- .../macros/test/CreateITS3StaticDeadMap.C | 79 ++++ .../ITS3/macros/test/TestSensorGeometry.C | 56 +++ .../ITS3/reconstruction/CMakeLists.txt | 2 +- .../include/ITS3Reconstruction/IOUtils.h | 16 + .../src/BuildTopologyDictionary.cxx | 2 + .../ITS3/reconstruction/src/Clusterer.cxx | 1 - .../ITS3/reconstruction/src/IOUtils.cxx | 26 +- .../DescriptorInnerBarrelITS3.h | 4 +- .../include/ITS3Simulation/Digitizer.h | 6 +- .../include/ITS3Simulation/ITS3Layer.h | 48 ++- .../ITS3/simulation/src/Digitizer.cxx | 13 +- .../ITS3/simulation/src/ITS3Layer.cxx | 120 ++++-- .../Upgrades/ITS3/workflow/CMakeLists.txt | 7 +- .../include/ITS3Workflow/TrackerSpec.h | 4 +- .../ITS3/workflow/src/TrackWriterSpec.cxx | 5 +- .../ITS3/workflow/src/TrackerSpec.cxx | 25 +- Steer/DigitizerWorkflow/CMakeLists.txt | 8 +- .../src/ITS3DigitizerSpec.cxx | 31 +- 53 files changed, 3290 insertions(+), 459 deletions(-) create mode 100644 Common/MathUtils/include/MathUtils/LegendrePols.h create mode 100644 Detectors/Upgrades/ITS3/alignment/CMakeLists.txt create mode 100644 Detectors/Upgrades/ITS3/alignment/include/ITS3Align/Deformations.h create mode 100644 Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentHits.h create mode 100644 Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentManager.h create mode 100644 Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentParameters.h create mode 100644 Detectors/Upgrades/ITS3/alignment/src/Deformations.cxx create mode 100644 Detectors/Upgrades/ITS3/alignment/src/ITS3AlignLinkDef.h create mode 100644 Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx create mode 100644 Detectors/Upgrades/ITS3/alignment/src/MisalignmentManager.cxx create mode 100644 Detectors/Upgrades/ITS3/alignment/src/MisalignmentParameters.cxx create mode 100644 Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h delete mode 100644 Detectors/Upgrades/ITS3/base/include/ITS3Base/MisalignmentParameter.h create mode 100644 Detectors/Upgrades/ITS3/base/src/ITS3Params.cxx delete mode 100644 Detectors/Upgrades/ITS3/base/src/MisalignmentParameter.cxx create mode 100644 Detectors/Upgrades/ITS3/macros/align/CMakeLists.txt create mode 100644 Detectors/Upgrades/ITS3/macros/align/CheckResidualsITS3.C create mode 100644 Detectors/Upgrades/ITS3/macros/align/CreateMisalignmentITS3.C create mode 100644 Detectors/Upgrades/ITS3/macros/align/MisAlignGeoITS3.notest create mode 100644 Detectors/Upgrades/ITS3/macros/align/ShowCoefficients.C create mode 100644 Detectors/Upgrades/ITS3/macros/align/TestLegendrePol.C create mode 100644 Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C create mode 100644 Detectors/Upgrades/ITS3/macros/test/CreateITS3StaticDeadMap.C create mode 100644 Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C diff --git a/Common/MathUtils/CMakeLists.txt b/Common/MathUtils/CMakeLists.txt index dc1d6966fbdba..d618bb8549175 100644 --- a/Common/MathUtils/CMakeLists.txt +++ b/Common/MathUtils/CMakeLists.txt @@ -24,7 +24,8 @@ o2_add_library( O2::GPUCommon ROOT::GenVector ROOT::Geom - Vc::Vc) + Vc::Vc + Boost::boost) o2_target_root_dictionary( MathUtils @@ -39,7 +40,8 @@ o2_target_root_dictionary( include/MathUtils/Primitive2D.h include/MathUtils/SMatrixGPU.h include/MathUtils/SymMatrixSolver.h - include/MathUtils/Tsallis.h) + include/MathUtils/Tsallis.h + include/MathUtils/LegendrePols.h) o2_add_test( CachingTF1 diff --git a/Common/MathUtils/include/MathUtils/LegendrePols.h b/Common/MathUtils/include/MathUtils/LegendrePols.h new file mode 100644 index 0000000000000..dca71c1275962 --- /dev/null +++ b/Common/MathUtils/include/MathUtils/LegendrePols.h @@ -0,0 +1,213 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file LegendrePols.h +/// \brief Definition of the NDim Legendre Polynominals +/// \author felix.schlepper@cern.ch + +#ifndef LEGENDRE_NDIM_POLYNOMINAL_H_ +#define LEGENDRE_NDIM_POLYNOMINAL_H_ + +#include "TNamed.h" +#include "Math/IParamFunction.h" +#include "TMatrixD.h" + +#include + +#include + +namespace o2::math_utils +{ + +// Defines the 1D Legendre Polynominals with coefficients: +// w(u) = c_0 + c_1 * u + c_2 * 0.5 * (3 * u * u - 1) + ... +// for u in [-1.0, 1.0] +class Legendre1DPolynominal final : public TNamed, + public ROOT::Math::IParametricFunctionOneDim +{ + public: + Legendre1DPolynominal() = default; + Legendre1DPolynominal(const Legendre1DPolynominal&) = default; + Legendre1DPolynominal(Legendre1DPolynominal&&) = delete; + Legendre1DPolynominal& operator=(const Legendre1DPolynominal&) = default; + Legendre1DPolynominal& operator=(Legendre1DPolynominal&&) = delete; + Legendre1DPolynominal(unsigned int order) : fOrder(order) {} + Legendre1DPolynominal(const std::vector p) + : fOrder(p.size() - 1), fParams(p) {} + + double operator()(double x) const { return DoEvalPar(x, Parameters()); } + double operator()(int i, double x) const + { + return DoEvalParSingle(i, x, Parameters()); + } + + ~Legendre1DPolynominal() final = default; + + const double* Parameters() const final { return &fParams.front(); } + + virtual void SetParameters(const double* p) final + { + fParams = std::vector(p, p + NPar()); + } + + unsigned int NPar() const final { return fParams.size(); } + unsigned int NOrder() const { return fOrder; } + + ROOT::Math::IBaseFunctionOneDim* Clone() const final { return new Legendre1DPolynominal(fParams); } + TObject* Clone(const char* name) const final + { + auto n = new Legendre1DPolynominal(fParams); + n->SetName(name); + return n; + } + + private: + double DoEvalPar(double x, const double* p) const final + { + double sum{0.0}; + for (unsigned int iOrder{0}; iOrder <= fOrder; ++iOrder) { + sum += p[iOrder] * boost::math::legendre_p(iOrder, x); + } + return sum; + } + + double DoEvalParSingle(int i, double x, const double* p) const + { + return p[i] * boost::math::legendre_p(i, x); + } + + unsigned int fOrder{0}; + std::vector fParams; + + ClassDefOverride(o2::math_utils::Legendre1DPolynominal, 1); +}; + +// Defines the 2D Legendre Polynominals with coefficients: +// w(u, v) = c_00 + +// c_10 * u + c_11 * v + +// c_20 * 0.5 * (3 * u * u - 1) + c_21 * u * v + c_22 * (3 * v * v - 1) + +/// .... +// for u&v in [-1.0, 1.0] +class Legendre2DPolynominal final : public TNamed, + public ROOT::Math::IParametricFunctionMultiDim +{ + public: + Legendre2DPolynominal() = default; + Legendre2DPolynominal(unsigned int order) : fOrder(order) {} + Legendre2DPolynominal(const std::vector& p) + : fOrder(p.size() - 1), fParams(p) {} + Legendre2DPolynominal(const TMatrixD& p) : fOrder(p.GetNrows() - 1) + { + fParams = std::vector(NPar()); + for (unsigned int iOrder{0}; iOrder <= fOrder; ++iOrder) { + for (unsigned int jOrder{0}; jOrder <= iOrder; ++jOrder) { + fParams[getFlatIdx(iOrder, jOrder)] = p(iOrder, jOrder); + } + } + } + ~Legendre2DPolynominal() final = default; + + double operator()(const double* x) const + { + return DoEvalPar(x, Parameters()); + } + double operator()(double x, double y) const { return DoEvalPar(x, y); } + double operator()(int i, int j, const double* x) const + { + return DoEvalParSingle(i, j, x, Parameters()); + } + double operator()(int i, int j, double x, double y) const + { + return DoEvalParSingle(i, j, x, y, Parameters()); + } + + const double* Parameters() const final { return &fParams.front(); } + + void SetParameters(const double* p) final + { + fParams = std::vector(p, p + NPar()); + } + + unsigned int NPar() const final + { + return fOrder * (fOrder + 1) / 2 + fOrder + 1; + } + unsigned int NDim() const final { return 2; } + unsigned int NOrder() const { return fOrder; } + + TMatrixD getCoefficients() const + { + TMatrixD m(fOrder + 1, fOrder + 1); + for (unsigned int iOrder{0}; iOrder <= fOrder; ++iOrder) { + for (unsigned int jOrder{0}; jOrder <= iOrder; ++jOrder) { + m(iOrder, jOrder) = fParams[getFlatIdx(iOrder, jOrder)]; + } + } + return m; + } + + void printCoefficients() const { getCoefficients().Print(); } + + // Unimplemented + ROOT::Math::IBaseFunctionMultiDim* Clone() const final { return new Legendre2DPolynominal(fParams); } + TObject* Clone(const char* name) const final + { + auto n = new Legendre2DPolynominal(fParams); + n->SetName(name); + return n; + } + + private: + double DoEvalPar(const double* x, const double* p) const final + { + double sum{0.0}; + for (unsigned int iOrder{0}; iOrder <= fOrder; ++iOrder) { + for (unsigned int jOrder{0}; jOrder <= iOrder; ++jOrder) { + sum += DoEvalParSingle(iOrder, jOrder, x, p); + } + } + return sum; + } + + double DoEvalPar(double x, double y) const + { + double sum{0.0}; + for (unsigned int iOrder{0}; iOrder <= fOrder; ++iOrder) { + for (unsigned int jOrder{0}; jOrder <= iOrder; ++jOrder) { + sum += DoEvalParSingle(iOrder, jOrder, x, y, Parameters()); + } + } + return sum; + } + + double DoEvalParSingle(int i, int j, const double* x, const double* p) const + { + return DoEvalParSingle(i, j, x[0], x[1], p); + } + + double DoEvalParSingle(int i, int j, double x, double y, + const double* p) const + { + return p[getFlatIdx(i, j)] * boost::math::legendre_p(j, x) * + boost::math::legendre_p(i - j, y); + } + + inline int getFlatIdx(int i, int j) const { return i * (i - 1) / 2 + j; } + + unsigned int fOrder{0}; + std::vector fParams; + + ClassDefOverride(o2::math_utils::Legendre2DPolynominal, 1); +}; + +} // namespace o2::math_utils + +#endif diff --git a/Common/MathUtils/src/MathUtilsLinkDef.h b/Common/MathUtils/src/MathUtilsLinkDef.h index b56ea7456aa0c..6067dd540110c 100644 --- a/Common/MathUtils/src/MathUtilsLinkDef.h +++ b/Common/MathUtils/src/MathUtilsLinkDef.h @@ -43,4 +43,7 @@ #pragma link C++ class o2::math_utils::Bracketd_t + ; #pragma link C++ class o2::math_utils::Tsallis + ; +#pragma link C++ class o2::math_utils::Legendre1DPolynominal + ; +#pragma link C++ class o2::math_utils::Legendre2DPolynominal + ; + #endif diff --git a/Detectors/Upgrades/ITS3/CMakeLists.txt b/Detectors/Upgrades/ITS3/CMakeLists.txt index 95c5e85f616a0..6965061571da6 100644 --- a/Detectors/Upgrades/ITS3/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory(macros) add_subdirectory(simulation) +add_subdirectory(alignment) add_subdirectory(base) add_subdirectory(workflow) add_subdirectory(reconstruction) diff --git a/Detectors/Upgrades/ITS3/README.md b/Detectors/Upgrades/ITS3/README.md index f5323e0e7e7ba..145fb0712e039 100644 --- a/Detectors/Upgrades/ITS3/README.md +++ b/Detectors/Upgrades/ITS3/README.md @@ -148,3 +148,22 @@ o2-sim -j 1 \ ``` The file `hijing.C` can be found [here](https://alice.its.cern.ch/jira/browse/AOGM-246). + +### Disabling individual tiles +1. Create a file `input.txt` with a comma separated list of disabled tiles. +2. (optional) Run the macro `CreateITS3StaticDeadMap.C` and/or visualize with `CheckTileNumbering.C` +3. Move the ccdb object into `${ALICEO2_CCDB_LOCALCACHE}/IT3/Calib/DeadMap`, this is not optional since there is no default object uploaded +4. Run digitizer with `ITS3Params.useDeadChannelMap=true;`, e.g.: +``` bash +o2-sim-digitizer-workflow --configKeyValues="ITS3Params.useDeadChannelMap=true;" +``` + + +### Alignment studies +#### Deform hits +1. Create misalignment parameters with `CreateMisalignmentITS3.C` +2. Visualize with `ShowCoefficients.C` +3. Run digitizer +``` bash +o2-sim-digitizer-workflow -b --configKeyValues="ITS3Params.applyMisalignmentHits=true;ITS3Params.misalignmentHitsParams=misparams.root" +``` diff --git a/Detectors/Upgrades/ITS3/alignment/CMakeLists.txt b/Detectors/Upgrades/ITS3/alignment/CMakeLists.txt new file mode 100644 index 0000000000000..f89ad821c65e7 --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(ITS3Align + SOURCES src/MisalignmentParameters.cxx + src/MisalignmentHits.cxx + src/MisalignmentManager.cxx + src/Deformations.cxx + PUBLIC_LINK_LIBRARIES O2::MathUtils + O2::Steer + O2::ITSBase + O2::ITSMFTSimulation) + +o2_target_root_dictionary(ITS3Align + HEADERS include/ITS3Align/MisalignmentParameters.h + include/ITS3Align/MisalignmentHits.h + include/ITS3Align/MisalignmentHits.h + include/ITS3Align/Deformations.h) diff --git a/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/Deformations.h b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/Deformations.h new file mode 100644 index 0000000000000..dfaade51e82ff --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/Deformations.h @@ -0,0 +1,84 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ITS3_DEFORMATIONS_H_ +#define ITS3_DEFORMATIONS_H_ + +#include "ITS3Align/MisalignmentParameters.h" +#include "MathUtils/LegendrePols.h" + +#include + +namespace o2::its3::align +{ + +class Deformations +{ + public: + // init deformations from the parameter file + void init(const std::filesystem::path&); + + double getDeformationX(unsigned int id, double u, double v) const { return getDeformation<0>(id, u, v); } + double getDeformationY(unsigned int id, double u, double v) const { return getDeformation<1>(id, u, v); } + double getDeformationZ(unsigned int id, double u, double v) const { return getDeformation<2>(id, u, v); } + double getDeformation(unsigned int id, unsigned int axis, double u, double v) const + { + if (axis == 0) { + return mLegX[id](u, v); + } else if (axis == 1) { + return mLegY[id](u, v); + } else { + return mLegZ[id](u, v); + } + } + std::array getDeformation(unsigned int id, double u, double v) const + { + return {getDeformation<0>(id, u, v), + getDeformation<1>(id, u, v), + getDeformation<2>(id, u, v)}; + } + std::array getOrders(unsigned int id) const + { + return {mLegX[id].NOrder(), mLegY[id].NOrder(), mLegZ[id].NOrder()}; + } + const o2::math_utils::Legendre2DPolynominal& getLegendre(unsigned int id, unsigned int axis) const + { + if (axis == 0) { + return mLegX[id]; + } else if (axis == 1) { + return mLegY[id]; + } else { + return mLegZ[id]; + } + } + + private: + template + double getDeformation(unsigned int id, double u, double v) const + { + if constexpr (axis == 0) { + return mLegX[id](u, v); + } else if constexpr (axis == 1) { + return mLegY[id](u, v); + } else { + return mLegZ[id](u, v); + } + } + + // 3 Legendre polynominals to model deformations in x,y,z; parameterized by normalized phi (u) and z (v) coordinates + std::array mLegX; + std::array mLegY; + std::array mLegZ; +}; + +} // namespace o2::its3::align + +#endif diff --git a/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentHits.h b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentHits.h new file mode 100644 index 0000000000000..37f5c9fdf701d --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentHits.h @@ -0,0 +1,216 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ITS3_MISALIGNMENTHITS_H_ +#define ITS3_MISALIGNMENTHITS_H_ + +#include "Math/IFunction.h" +#include "Math/Minimizer.h" + +#include "ReconstructionDataFormats/Track.h" +#include "ITS3Align/Deformations.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITSMFTSimulation/Hit.h" +#include "MathUtils/Cartesian.h" +#include "MathUtils/Utils.h" +#include "Steer/MCKinematicsReader.h" + +#include +#include +#include +#include +#include + +namespace o2::its3::align +{ + +class MisAlignmentHits +{ + public: + enum class PropMethod { + Propagator, + Line, + }; + + void init(); + + std::optional processHit(int iEvent, const o2::itsmft::Hit& hit); + + void resetStats() { mStats.fill(0ull); } + void printStats() const; + + private: + Deformations mDeformations; + std::unique_ptr mMinimizer; + PropMethod mMethod{PropMethod::Line}; + o2::its::GeometryTGeo* mGeo{nullptr}; + std::unique_ptr mMCReader; + + short getDetID(const o2::math_utils::Point3D& point); + short getDetIDFromCords(const o2::math_utils::Point3D& point); + short getDetIDFromPath(const std::string& path) const; + + // We treat each hit as two separate hits', one for the entering and one for the exiting hit + struct WorkingHit { + enum HitType : uint8_t { + kEntering = 0, + kExiting, + kTypes, + }; + + WorkingHit() = default; + + WorkingHit(int eventID, HitType t, const o2::itsmft::Hit& hit) : mEvent(eventID), + mTrackID(hit.GetTrackID()), + mType(t), + mDetID(hit.GetDetectorID()), + mLayerID(constants::detID::getDetID2Layer(mDetID)), + mSensorID(constants::detID::getSensorID(mDetID)) + { + if (mType == kEntering) { + mRadius = constants::radiiInner[mLayerID]; + mPoint = hit.GetPosStart(); + } else { + mRadius = constants::radiiOuter[mLayerID]; + mPoint = hit.GetPos(); + } + + // Pre-calculate the normalized u,v coordinates as starting parameters + const bool isTop = mSensorID % 2 == 0; + mPhi = o2::math_utils::to02Pi(std::atan2(mPoint.Y(), mPoint.X())); + mPhiBorder1 = o2::math_utils::to02Pi(((isTop) ? 0.f : 1.f) * TMath::Pi() + std::asin(constants::equatorialGap / 2.f / mRadius)); + mPhiBorder2 = o2::math_utils::to02Pi(((isTop) ? 1.f : 2.f) * TMath::Pi() - std::asin(constants::equatorialGap / 2.f / mRadius)); + mU = ((mPhi - mPhiBorder1) * 2.f) / (mPhiBorder2 - mPhiBorder1) - 1.f; + mV = (2.f * mPoint.Z() + constants::segment::lengthSensitive) / constants::segment::lengthSensitive - 1.f; + } + + void recalculateIdeal(float phi, float z) + { + mPointDef.SetX(mRadius * std::cos(phi)); + mPointDef.SetY(mRadius * std::sin(phi)); + mPointDef.SetZ(z); + } + + int mEvent; + int mTrackID; + HitType mType; + short mDetID; + int mLayerID; + int mSensorID; + float mRadius; + float mPhi; + o2::math_utils::Point3D mPoint; + o2::math_utils::Point3D mPointDef; + float mU; // u is normalized phi + float mV; // u is normalized z + + float mPhiBorder1; + float mPhiBorder2; + }; + std::array mCurWorkingHits; + o2::itsmft::Hit mCurHit; + + bool deformHit(WorkingHit::HitType t); + + auto getDeformation(unsigned int id, double u, double v) const + { + return mDeformations.getDeformation(id, u, v); + } + + // Mimize function assuming a straight line + // given in the parametric representation by y_v = t * d_x + x_s + // assuming no offset is needed + class StraightLine : public ROOT::Math::IBaseFunctionMultiDim + { + public: + StraightLine(const MisAlignmentHits* m) : mMis(m) {} + + std::array mD; + o2::math_utils::Point3D mStart; + unsigned int mSensorID; + double mRadius; + const MisAlignmentHits* mMis; + + double mPhiTot; + double mPhi1; + + unsigned int NDim() const override { return 3; } + ROOT::Math::IBaseFunctionMultiDim* Clone() const override { return nullptr; } + + private: + double DoEval(const double* x) const override; + }; + StraightLine mLine{this}; + void prepareLineMethod(WorkingHit::HitType from); + + // Mimize function using the MCTrack + class Propagator : public ROOT::Math::IBaseFunctionMultiDim + { + public: + Propagator(const MisAlignmentHits* m) : mMis(m) {} + + o2::track::TrackPar mTrack; + float mBz; + unsigned int mSensorID; + double mRadius; + const MisAlignmentHits* mMis; + + double mPhiTot; + double mPhi1; + + unsigned int NDim() const override { return 3; } + ROOT::Math::IBaseFunctionMultiDim* Clone() const override { return nullptr; } + + private: + double DoEval(const double* x) const override; + }; + Propagator mPropagator{this}; + bool preparePropagatorMethod(WorkingHit::HitType from); + + enum Stats : uint8_t { + kHitTotal = 0, + kHitIsOB, + kHitIsIB, + kHitDead, + kHitAlive, + kHitSuccess, + kHitMigrated, + kHitNotMigrated, + kHitEntBoundary, + kHitExtBoundary, + kHitNoBoundary, + kHitSameBoundary, + kFindNodeFailed, + kFindNodeSuccess, + kProjSensitive, + kProjNonSensitive, + kDetIDOk, + kDetIDBad, + kMinimizerStatusOk, + kMinimizerStatusBad, + kMinimizerValueOk, + kMinimizerValueBad, + kMinimizerConverged, + kMinimizerCovPos, + kMinimizerHesse, + kMinimizerEDM, + kMinimizerLimit, + kMinimizerOther, + kPropTrackNull, + kPropPDGNull, + kALL, + }; + std::array mStats; +}; + +} // namespace o2::its3::align + +#endif diff --git a/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentManager.h b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentManager.h new file mode 100644 index 0000000000000..0fe972442809d --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentManager.h @@ -0,0 +1,53 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ITS3_MISALIGNMENTMANAGER_H_ +#define ITS3_MISALIGNMENTMANAGER_H_ + +#include "Math/Transform3D.h" +#include "Math/Translation3D.h" +#include "Math/Rotation3D.h" +#include "Math/EulerAngles.h" +#include "Math/PositionVector3D.h" +#include "TGeoMatrix.h" + +#include + +namespace o2::its3::align +{ + +/// Collection of static functions and types to perform misalignment studies +struct MisalignmentManager { + using Vector3D = ROOT::Math::DisplacementVector3D, ROOT::Math::DefaultCoordinateSystemTag>; + using Point3D = ROOT::Math::PositionVector3D, ROOT::Math::DefaultCoordinateSystemTag>; + using Trans3D = ROOT::Math::Translation3DF; + using Rot3D = ROOT::Math::Rotation3D; + using Euler3D = ROOT::Math::EulerAngles; + using Trafo3D = ROOT::Math::Transform3DF; + + static void misalignHits(); + + static void createBackup(const std::filesystem::path& src, const std::filesystem::path& dest); + + static std::string appendStem(const std::string& filename, const std::string& add); + + static std::vector split(const std::string& s, char delimiter = '/'); + + static void navigate(const std::string& path); + + static std::string composePathSensor(int sensor); + + static void applyGlobalMatrixVolume(const std::string& path, const TGeoHMatrix& globalMatrix); +}; + +} // namespace o2::its3::align + +#endif diff --git a/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentParameters.h b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentParameters.h new file mode 100644 index 0000000000000..243623cc650e1 --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/include/ITS3Align/MisalignmentParameters.h @@ -0,0 +1,93 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file MisalignmentParameters.h +/// \brief Definition of the MisalignmentParameters class + +#ifndef ITS3_MISALIGNMENTPARAMETERS_H_ +#define ITS3_MISALIGNMENTPARAMETERS_H_ + +#include "ITS3Base/SpecsV2.h" + +#include "TNamed.h" +#include "TFile.h" +#include "TMatrixD.h" + +#include +#include + +namespace o2::its3::align +{ + +class MisalignmentParameters : public TNamed +{ + public: + MisalignmentParameters(); + + // IO + bool store(const std::string& file) const; + static MisalignmentParameters* load(const std::string& file); + + /// Global getters + double getGloTransX(unsigned int detID) const { return mGloTransX[detID]; } + double getGloTransY(unsigned int detID) const { return mGloTransY[detID]; } + double getGloTransZ(unsigned int detID) const { return mGloTransZ[detID]; } + double getGloRotX(unsigned int detID) const { return mGloRotX[detID]; } + double getGloRotY(unsigned int detID) const { return mGloRotY[detID]; } + double getGloRotZ(unsigned int detID) const { return mGloRotZ[detID]; } + /// Global setters + void setGloTransX(unsigned int detID, double v) { mGloTransX[detID] = v; } + void setGloTransY(unsigned int detID, double v) { mGloTransY[detID] = v; } + void setGloTransZ(unsigned int detID, double v) { mGloTransZ[detID] = v; } + void setGloRotX(unsigned int detID, double v) { mGloRotX[detID] = v; } + void setGloRotY(unsigned int detID, double v) { mGloRotY[detID] = v; } + void setGloRotZ(unsigned int detID, double v) { mGloRotZ[detID] = v; } + + /// Legendre Coeff. getters + const TMatrixD& getLegendreCoeffX(unsigned int sensorID) const { return mLegCoeffX[sensorID]; } + const TMatrixD& getLegendreCoeffY(unsigned int sensorID) const { return mLegCoeffY[sensorID]; } + const TMatrixD& getLegendreCoeffZ(unsigned int sensorID) const { return mLegCoeffZ[sensorID]; } + /// Legendre Coeff. setters + void setLegendreCoeffX(unsigned int sensorID, const TMatrixD& m) { setMatrix(mLegCoeffX[sensorID], m); } + void setLegendreCoeffY(unsigned int sensorID, const TMatrixD& m) { setMatrix(mLegCoeffY[sensorID], m); } + void setLegendreCoeffZ(unsigned int sensorID, const TMatrixD& m) { setMatrix(mLegCoeffZ[sensorID], m); } + + void printParams(unsigned int detID) const; + void printLegendreParams(unsigned int sensorID) const; + + private: + inline void setMatrix(TMatrixD& o, const TMatrixD& n) + { + o.ResizeTo(n.GetNrows(), n.GetNcols()); + o = n; + } + + static constexpr unsigned int nDetectors{constants::detID::nChips}; ///! for now just the IB + + // Global parameters + std::array mGloTransX; ///< Array to hold the global misalignment in x-direction + std::array mGloTransY; ///< Array to hold the global misalignment in y-direction + std::array mGloTransZ; ///< Array to hold the global misalignment in z-direction + std::array mGloRotX; ///< Array to hold the global misalignment in x-direction + std::array mGloRotY; ///< Array to hold the global misalignment in y-direction + std::array mGloRotZ; ///< Array to hold the global misalignment in z-direction + + // Legendre Polynominals coefficients + std::array mLegCoeffX; + std::array mLegCoeffY; + std::array mLegCoeffZ; + + ClassDefOverride(MisalignmentParameters, 1); +}; + +} // namespace o2::its3::align + +#endif diff --git a/Detectors/Upgrades/ITS3/alignment/src/Deformations.cxx b/Detectors/Upgrades/ITS3/alignment/src/Deformations.cxx new file mode 100644 index 0000000000000..38a959cf7030f --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/src/Deformations.cxx @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITS3Align/Deformations.h" +#include "ITS3Align/MisalignmentParameters.h" + +#include "Framework/Logger.h" + +#include + +namespace fs = std::filesystem; + +namespace o2::its3::align +{ + +void Deformations::init(const fs::path& path) +{ + if (!fs::exists(path)) { + LOGP(fatal, "File {} does not exists!", path.c_str()); + } + + auto params = MisalignmentParameters::load(path.string()); + LOGP(info, "Loaded Parameters"); + + // Set the legendre pols + for (int iSensor{0}; iSensor < 6; ++iSensor) { + mLegX[iSensor] = o2::math_utils::Legendre2DPolynominal(params->getLegendreCoeffX(iSensor)); + mLegY[iSensor] = o2::math_utils::Legendre2DPolynominal(params->getLegendreCoeffY(iSensor)); + mLegZ[iSensor] = o2::math_utils::Legendre2DPolynominal(params->getLegendreCoeffZ(iSensor)); + } +} + +} // namespace o2::its3::align diff --git a/Detectors/Upgrades/ITS3/alignment/src/ITS3AlignLinkDef.h b/Detectors/Upgrades/ITS3/alignment/src/ITS3AlignLinkDef.h new file mode 100644 index 0000000000000..ef526284f3a58 --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/src/ITS3AlignLinkDef.h @@ -0,0 +1,20 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::its3::align::MisalignmentParameters + ; + +#endif diff --git a/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx new file mode 100644 index 0000000000000..fbc0b5d623dca --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentHits.cxx @@ -0,0 +1,369 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITS3Align/MisalignmentHits.h" +#include "ITS3Base/SegmentationSuperAlpide.h" +#include "ITS3Base/ITS3Params.h" +#include "SimConfig/DigiParams.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/Logger.h" + +#include "Math/Factory.h" +#include "Math/UnaryOperators.h" +#include "TGeoNode.h" +#include "TGeoBBox.h" +#include "TString.h" + +#include +#include +#include +#include + +namespace o2::its3::align +{ + +void MisAlignmentHits::init() +{ + if (o2::its3::ITS3Params::Instance().misalignmentHitsUseProp) { + mMethod = PropMethod::Propagator; + } else { + mMethod = PropMethod::Line; + } + + mGeo = o2::its::GeometryTGeo::Instance(); + + mMinimizer.reset(ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad")); + if (mMinimizer == nullptr) { + LOGP(fatal, "Cannot create minimizer"); + } + mMinimizer->SetMaxFunctionCalls(1'000'000'000); + mMinimizer->SetStrategy(0); + mMinimizer->SetPrintLevel(0); + + if (mMethod == PropMethod::Propagator) { + LOGP(info, "Using propagator to find intersection"); + const auto& prefix = o2::conf::DigiParams::Instance().digitizationgeometry_prefix; + mMCReader = std::make_unique(prefix, o2::steer::MCKinematicsReader::Mode::kMCKine); + mMinimizer->SetFunction(mPropagator); + } else { + LOGP(info, "Using local straight-line to find intersection"); + mMinimizer->SetFunction(mLine); + } + + resetStats(); + + if (auto file = o2::its3::ITS3Params::Instance().misalignmentHitsParams; file.empty()) { + LOGP(fatal, "No parameter file specified"); + } else { + mDeformations.init(file); + } +} + +std::optional MisAlignmentHits::processHit(int iEvent, const o2::itsmft::Hit& hit) +{ + ++mStats[Stats::kHitTotal]; + + if (!constants::detID::isDetITS3(hit.GetDetectorID())) { + ++mStats[Stats::kHitIsOB]; + return hit; + } + ++mStats[Stats::kHitIsIB]; + + // Set the working hits + mCurHit = hit; + mCurWorkingHits[WorkingHit::kEntering] = WorkingHit(iEvent, WorkingHit::kEntering, hit); + mCurWorkingHits[WorkingHit::kExiting] = WorkingHit(iEvent, WorkingHit::kExiting, hit); + + // Do work + if (!deformHit(WorkingHit::kEntering) || !deformHit(WorkingHit::kExiting)) { + ++mStats[Stats::kHitDead]; + return std::nullopt; + } + ++mStats[Stats::kHitAlive]; + + // Set the possibly new detectorIDs with mid point approximation + auto midPointOrig = mCurWorkingHits[WorkingHit::kEntering].mPoint + (mCurWorkingHits[WorkingHit::kExiting].mPoint - mCurWorkingHits[WorkingHit::kEntering].mPoint) * 0.5; + auto midPointDef = mCurWorkingHits[WorkingHit::kEntering].mPointDef + (mCurWorkingHits[WorkingHit::kExiting].mPointDef - mCurWorkingHits[WorkingHit::kEntering].mPointDef) * 0.5; + const short idDef = getDetID(midPointDef), idOrig = getDetID(midPointOrig); + if (idDef == -1) { + return std::nullopt; + } + + if (idDef != idOrig) { + ++mStats[Stats::kHitMigrated]; + } else { + ++mStats[Stats::kHitNotMigrated]; + } + + if constexpr (false) { + /// TODO Does not yet work correctly + /// Check if we crossed a boundary within the entering and exiting hit from the midpoint + bool crossesBoundary{false}; + TGeoNode *nEnt{nullptr}, *nExt{nullptr}; + { + auto dirEnt = mCurWorkingHits[WorkingHit::kEntering].mPointDef - midPointDef; + auto stepEnt = std::min(static_cast(dirEnt.R()), std::abs(dirEnt.R() - 5.e-4)); + auto dirEntU = dirEnt.Unit(); + gGeoManager->SetCurrentPoint(midPointDef.X(), midPointDef.Y(), midPointDef.Z()); + gGeoManager->SetCurrentDirection(dirEntU.X(), dirEntU.Y(), dirEntU.Z()); + nEnt = gGeoManager->FindNextBoundaryAndStep(stepEnt, false); + if (gGeoManager->IsOnBoundary()) { + ++mStats[Stats::kHitEntBoundary]; + crossesBoundary = true; + } + } + { + auto dirExt = midPointDef - mCurWorkingHits[WorkingHit::kEntering].mPointDef; + auto stepExt = std::min(static_cast(dirExt.R()), std::abs(dirExt.R() - 5.e-4)); + auto dirExtU = dirExt.Unit(); + gGeoManager->SetCurrentPoint(midPointDef.X(), midPointDef.Y(), midPointDef.Z()); + gGeoManager->SetCurrentDirection(dirExtU.X(), dirExtU.Y(), dirExtU.Z()); + nExt = gGeoManager->FindNextBoundaryAndStep(stepExt, false); + if (gGeoManager->IsOnBoundary()) { + ++mStats[Stats::kHitExtBoundary]; + crossesBoundary = true; + } + } + + if (crossesBoundary && nEnt != nullptr && nExt != nullptr) { + if (nEnt != nExt) { + return std::nullopt; + } else { + ++mStats[Stats::kHitSameBoundary]; // indicates that the step size is too large and we end up in the mother volume; just pretend that his fine for now + } + } + ++mStats[Stats::kHitNoBoundary]; + } + + // Get new postion + mCurHit.SetPosStart(mCurWorkingHits[WorkingHit::kEntering].mPointDef); + mCurHit.SetPos(mCurWorkingHits[WorkingHit::kExiting].mPointDef); + mCurHit.SetDetectorID(idDef); + + ++mStats[Stats::kHitSuccess]; + return mCurHit; +} + +bool MisAlignmentHits::deformHit(WorkingHit::HitType t) +{ + auto& wHit = mCurWorkingHits[t]; + + mMinimizer->Clear(); // clear for next iteration + constexpr double minStep{1e-5}; + constexpr double zMargin{4.0}; + constexpr double phiMargin{0.4}; + if (mMethod == PropMethod::Line) { + prepareLineMethod(t); + mMinimizer->SetVariable(0, "t", 0.0, minStep); // this is left as a free parameter on since t is very small since start and end of hit are close + } else { + if (!preparePropagatorMethod(t)) { + return false; + } + mMinimizer->SetVariable(0, "r", mPropagator.mTrack.getX(), minStep); // this is left as a free parameter on since t is very small since start and end of hit are close + } + mMinimizer->SetLimitedVariable(1, "phiStar", wHit.mPhi, minStep, + std::max(static_cast(wHit.mPhiBorder1), static_cast(wHit.mPhi) - phiMargin), + std::min(static_cast(wHit.mPhiBorder2), static_cast(wHit.mPhi) + phiMargin)); + mMinimizer->SetLimitedVariable(2, "zStar", wHit.mPoint.Z(), minStep, + std::max(static_cast(-constants::segment::lengthSensitive / 2.f), static_cast(wHit.mPoint.Z()) - zMargin), + std::min(static_cast(constants::segment::lengthSensitive / 2.f), static_cast(wHit.mPoint.Z()) + zMargin)); + + mMinimizer->Minimize(); // perform the actual minimization + + auto ss = mMinimizer->Status(); + if (ss == 1) { + ++mStats[Stats::kMinimizerCovPos]; + } else if (ss == 2) { + ++mStats[Stats::kMinimizerHesse]; + } else if (ss == 3) { + ++mStats[Stats::kMinimizerEDM]; + } else if (ss == 4) { + ++mStats[Stats::kMinimizerLimit]; + } else if (ss == 5) { + ++mStats[Stats::kMinimizerOther]; + } else { + ++mStats[Stats::kMinimizerConverged]; + } + + if (ss == 0 || ss == 1) { // for Minuit2 0=ok, 1=ok with pos. forced hesse + ++mStats[Stats::kMinimizerStatusOk]; + if (mMinimizer->MinValue() < 2e-4) { // within 2 um considering the pixel pitch this good enough + ++mStats[Stats::kMinimizerValueOk]; + } else { + ++mStats[Stats::kMinimizerValueBad]; + return false; + } + } else { + ++mStats[Stats::kMinimizerStatusBad]; + return false; + } + + // Valid solution found; calculate new position on ideal geo + wHit.recalculateIdeal(static_cast(mMinimizer->X()[1]), static_cast(mMinimizer->X()[2])); + + return true; +} + +short MisAlignmentHits::getDetID(const o2::math_utils::Point3D& point) +{ + // Do not modify the path, I do not know if this is needed but lets be safe + gGeoManager->PushPath(); + auto id = getDetIDFromCords(point); + gGeoManager->PopPath(); + return id; +} + +short MisAlignmentHits::getDetIDFromCords(const o2::math_utils::Point3D& point) +{ + // retrive if any the node which constains the point + const auto node = gGeoManager->FindNode(point.X(), point.Y(), point.Z()); + if (node == nullptr) { + ++mStats[Stats::kFindNodeFailed]; + return -1; + } + ++mStats[Stats::kFindNodeSuccess]; + + // check if this node is a sensitive volume + const std::string path = gGeoManager->GetPath(); + if (path.find(o2::its::GeometryTGeo::getITS3SensorPattern()) == std::string::npos) { + ++mStats[Stats::kProjNonSensitive]; + return -1; + } + ++mStats[Stats::kProjSensitive]; + + return getDetIDFromPath(path); +} + +short MisAlignmentHits::getDetIDFromPath(const std::string& path) const +{ + static const std::regex pattern{R"(/cave_1/barrel_1/ITSV_2/ITSUWrapVol0_1/ITS3Layer(\d+)_(\d+)/ITS3CarbonForm(\d+)_(\d+)/ITS3Chip(\d+)_(\d+)/ITS3Segment(\d+)_(\d+)/ITS3RSU(\d+)_(\d+)/ITS3Tile(\d+)_(\d+)/ITS3PixelArray(\d+)_(\d+))"}; + if (std::smatch matches; std::regex_search(path, matches, pattern)) { + if (matches.size() == 15) { + int iLayer = std::stoi(matches[1]); + int iCarbonForm = std::stoi(matches[4]); + int iSegment = std::stoi(matches[8]); + int iRSU = std::stoi(matches[10]); + int iTile = std::stoi(matches[12]); + return mGeo->getChipIndex(iLayer, iCarbonForm, 0, iSegment, iRSU, iTile); + } else { + LOGP(fatal, "Path did not contain expected number of matches ({})!", matches.size()); + } + } else { + LOGP(fatal, "Path was not matched ({})!", path); + } + __builtin_unreachable(); +} + +void MisAlignmentHits::printStats() const +{ + auto makeFraction = [&](Stats n, Stats d) -> float { return static_cast(mStats[n]) / static_cast(mStats[d] + mStats[n]); }; + LOGP(info, "Processed {} Hits (IB:{}; OB:{}) ({:.2f}%):", mStats[Stats::kHitTotal], mStats[Stats::kHitIsIB], mStats[Stats::kHitIsOB], makeFraction(Stats::kHitIsIB, Stats::kHitIsOB)); + LOGP(info, " - Minimizer Status: {} ok {} bad ({:.2f}%)", mStats[Stats::kMinimizerStatusOk], mStats[Stats::kMinimizerStatusBad], makeFraction(Stats::kMinimizerStatusOk, Stats::kMinimizerStatusBad)); + LOGP(info, " - Minimizer Value: {} ok {} bad ({:.2f}%)", mStats[Stats::kMinimizerValueOk], mStats[Stats::kMinimizerValueBad], makeFraction(Stats::kMinimizerValueOk, Stats::kMinimizerValueBad)); + LOGP(info, " - Minimizer Detailed: {} Converged {} pos. forced Hesse ({:.2f}%)", mStats[Stats::kMinimizerConverged], mStats[Stats::kMinimizerHesse], makeFraction(Stats::kMinimizerConverged, Stats::kMinimizerHesse)); + LOGP(info, " - Minimizer Detailed: {} EDM {} call limit {} other ({:.2f}%)", mStats[Stats::kMinimizerEDM], mStats[Stats::kMinimizerLimit], mStats[Stats::kMinimizerOther], makeFraction(Stats::kMinimizerEDM, Stats::kMinimizerLimit)); + LOGP(info, " - FindNode: {} ok {} failed", mStats[Stats::kFindNodeSuccess], mStats[Stats::kFindNodeFailed]); + LOGP(info, " - IsSensitve: {} yes {} no ({:.2f}%)", mStats[Stats::kProjSensitive], mStats[Stats::kProjNonSensitive], makeFraction(Stats::kProjSensitive, Stats::kProjNonSensitive)); + LOGP(info, " - IsAlive: {} yes {} no ({:.2f}%)", mStats[Stats::kHitAlive], mStats[Stats::kHitDead], makeFraction(Stats::kHitAlive, Stats::kHitDead)); + LOGP(info, " - HasMigrated: {} yes {} no ({:.2f}%)", mStats[Stats::kHitMigrated], mStats[Stats::kHitNotMigrated], makeFraction(Stats::kHitMigrated, Stats::kHitNotMigrated)); + // LOGP(info, " - Crosses Boundary: {} entering {} exiting {} same {} no", mStats[Stats::kHitEntBoundary], mStats[Stats::kHitExtBoundary], mStats[Stats::kHitSameBoundary], mStats[Stats::kHitNoBoundary]); + if (mMethod == PropMethod::Propagator) { + LOGP(info, " - Propagator: {} null track {} null pdg", mStats[Stats::kPropTrackNull], mStats[Stats::kPropPDGNull]); + } + LOGP(info, " --> Good Hits {} ({:.2f}%)", mStats[Stats::kHitSuccess], makeFraction(Stats::kHitSuccess, Stats::kHitIsIB)); +} + +void MisAlignmentHits::prepareLineMethod(WorkingHit::HitType from) +{ + // Set the starint point and radius + // always start from the entering hit that way t is always pos. defined + mLine.mStart = mCurWorkingHits[WorkingHit::kEntering].mPoint; + mLine.mRadius = mCurWorkingHits[from].mRadius; + mLine.mSensorID = mCurWorkingHits[from].mSensorID; + mLine.mPhiTot = mCurWorkingHits[from].mPhiBorder2 - mCurWorkingHits[from].mPhiBorder1; + mLine.mPhi1 = mCurWorkingHits[from].mPhiBorder1; + // Calculate the direction vector + mLine.mD[0] = mCurWorkingHits[WorkingHit::kExiting].mPoint.X() - mCurWorkingHits[WorkingHit::kEntering].mPoint.X(); + mLine.mD[1] = mCurWorkingHits[WorkingHit::kExiting].mPoint.Y() - mCurWorkingHits[WorkingHit::kEntering].mPoint.Y(); + mLine.mD[2] = mCurWorkingHits[WorkingHit::kExiting].mPoint.Z() - mCurWorkingHits[WorkingHit::kEntering].mPoint.Z(); +} + +double MisAlignmentHits::StraightLine::DoEval(const double* x) const +{ + const double t = x[0]; + const double phi = x[1]; + const double z = x[2]; + const double nphi = std::clamp((phi - mPhi1) * 2.0 / mPhiTot - 1.0, -1.0, 1.0); + const double nz = std::clamp((z - (-constants::segment::lengthSensitive / 2.0)) * 2.0 / constants::segment::lengthSensitive - 1.0, -1.0, 1.0); + + /// Find the point along the line given current t + double xline = mStart.X() + t * mD[0], + yline = mStart.Y() + t * mD[1], + zline = mStart.Z() + t * mD[2]; + + // Find the point of the deformed geometry given a certain phi' and z' + double xideal = mRadius * std::cos(phi), yideal = mRadius * std::sin(phi), + zideal = z; + const auto [dx, dy, dz] = mMis->getDeformation(mSensorID, nphi, nz); + double xdef = xideal + dx, ydef = yideal + dy, zdef = zideal + dz; + + // Minimize the euclidean distance of the line point and the deformed point + return std::hypot(xline - xdef, yline - ydef, zline - zdef); +} + +bool MisAlignmentHits::preparePropagatorMethod(WorkingHit::HitType from) +{ + mPropagator.mRadius = mCurWorkingHits[from].mRadius; + mPropagator.mSensorID = mCurWorkingHits[from].mSensorID; + mPropagator.mPhiTot = mCurWorkingHits[from].mPhiBorder2 - mCurWorkingHits[from].mPhiBorder1; + mPropagator.mPhi1 = mCurWorkingHits[from].mPhiBorder1; + const auto mcTrack = mMCReader->getTrack(mCurWorkingHits[from].mEvent, mCurWorkingHits[from].mTrackID); + if (mcTrack == nullptr) { + ++mStats[Stats::kPropTrackNull]; + return false; + } + const std::array xyz{(float)mcTrack->GetStartVertexCoordinatesX(), (float)mcTrack->GetStartVertexCoordinatesY(), (float)mcTrack->GetStartVertexCoordinatesZ()}, + pxyz{(float)mcTrack->GetStartVertexMomentumX(), (float)mcTrack->GetStartVertexMomentumY(), (float)mcTrack->GetStartVertexMomentumZ()}; + const TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrack->GetPdgCode()); + if (pPDG == nullptr) { + ++mStats[Stats::kPropPDGNull]; + return false; + } + mPropagator.mTrack = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); + mPropagator.mBz = o2::base::Propagator::Instance()->getNominalBz(); + return true; +} + +double MisAlignmentHits::Propagator::DoEval(const double* x) const +{ + const double r = x[0]; + const double phi = x[1]; + const double z = x[2]; + const double nphi = (phi - mPhi1) * 2.0 / mPhiTot - 1.0; + const double nz = (z - (-constants::segment::lengthSensitive / 2.0)) * 2.0 / constants::segment::lengthSensitive - 1.0; + + auto trc = mTrack; + if (!trc.propagateTo(r, mBz)) { + return 999; + } + const auto glo = trc.getXYZGlo(); + + // Find the point of the deformed geometry given a certain phi' and z' + double xideal = mRadius * std::cos(phi), yideal = mRadius * std::sin(phi), + zideal = z; + const auto [dx, dy, dz] = mMis->getDeformation(mSensorID, nphi, nz); + double xdef = xideal + dx, ydef = yideal + dy, zdef = zideal + dz; + + // Minimize the euclidean distance of the propagator point and the deformed point + return std::hypot(glo.X() - xdef, glo.Y() - ydef, glo.Z() - zdef); +} + +} // namespace o2::its3::align diff --git a/Detectors/Upgrades/ITS3/alignment/src/MisalignmentManager.cxx b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentManager.cxx new file mode 100644 index 0000000000000..c9d71541bcd0e --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentManager.cxx @@ -0,0 +1,195 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/Logger.h" +#include "ITS3Align/MisalignmentManager.h" +#include "ITS3Align/MisalignmentHits.h" +#include "SimConfig/DigiParams.h" + +#include "TFile.h" +#include "TStopwatch.h" +#include "TGeoManager.h" + +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +namespace o2::its3::align +{ + +void MisalignmentManager::createBackup(const fs::path& src, const fs::path& dest) +{ + if (fs::exists(dest)) { + LOGP(info, "Previous orignal file found, using this as src"); + } else { + if (!fs::exists(src)) { + LOGP(fatal, "File {} does not exist", src.c_str()); + } + LOGP(info, "Trying to backup file to {}", dest.c_str()); + try { + fs::rename(src, dest); + } catch (const fs::filesystem_error& err) { + LOGP(fatal, "Cannot create backup file for Hit-File: {}", err.what()); + } + } +} + +void MisalignmentManager::misalignHits() +{ + LOGP(info, "{:*^90}", " ITS3 LOCAL MISALIGNMENT START "); + + TStopwatch timer; + timer.Start(); + + MisAlignmentHits MisAligner; + MisAligner.init(); + + const fs::path oldHitFileSrc{fs::current_path().string() + "/" + o2::conf::DigiParams::Instance().digitizationgeometry_prefix + "_HitsIT3.root"}; + const fs::path oldHitFileDest{fs::current_path().string() + "/" + o2::conf::DigiParams::Instance().digitizationgeometry_prefix + "_HitsIT3_Orig.root"}; + createBackup(oldHitFileSrc, oldHitFileDest); + + std::unique_ptr origFile{TFile::Open(oldHitFileDest.c_str(), "READ")}; + if (origFile == nullptr || origFile->IsZombie()) { + LOGP(fatal, "Original file {} cannot be opened", oldHitFileDest.c_str()); + } + + std::unique_ptr origTree{origFile->Get("o2sim")}; + if (origTree == nullptr) { + LOGP(fatal, "Cannot get hit-tree from orignal file"); + } + std::vector origHits, *origHitsPtr{&origHits}; + origTree->SetBranchAddress("IT3Hit", &origHitsPtr); + + std::unique_ptr newFile{TFile::Open(oldHitFileSrc.c_str(), "RECREATE")}; + if (newFile == nullptr || newFile->IsZombie()) { + LOGP(fatal, "New file {} cannot be opened", oldHitFileSrc.c_str()); + } + + auto newTree = std::make_unique("o2sim", "o2sim"); + std::vector newHits, *newHitsPtr{nullptr}; + newTree->Branch("IT3Hit", &newHitsPtr); + + LOGP(info, "Preparations done; starting hit loop"); + auto nEntries = origTree->GetEntries(); + ULong64_t totalOrigHits{0}, totalNewHits{0}; + for (Long64_t iEntry{0}; origTree->LoadTree(iEntry) >= 0; ++iEntry) { + if (origTree->GetEntry(iEntry) <= 0) { + continue; + } + + const auto progress = (iEntry * 100) / nEntries; + LOG_IF(info, progress % 10 == 0) << "Processing event " << iEntry << " / " << nEntries; + + newHits.clear(); + newHits.reserve(origHits.size()); + for (const auto& origHit : origHits) { + if (auto newHit = MisAligner.processHit(iEntry, origHit)) { + newHits.emplace_back(*newHit); + } + } + + newHitsPtr = &newHits; + newTree->Fill(); + + totalNewHits += newHits.size(); + totalOrigHits += origHits.size(); + } + + newFile->WriteTObject(newTree.get()); + + timer.Stop(); + + MisAligner.printStats(); + + auto totalDiscardedHits = totalOrigHits - totalNewHits; + LOGP(info, "Summary: Total orignal Hits {}", totalOrigHits); + LOGP(info, "Summary: Total misaligned Hits {} ({:.2f}%)", totalNewHits, static_cast(totalNewHits) / static_cast(totalOrigHits) * 100); + LOGP(info, "Summary: Total discarded Hits {} ({:.2f}%)", totalDiscardedHits, static_cast(totalDiscardedHits) / static_cast(totalOrigHits) * 100); + LOGP(info, "Summary: Misalignment took {:.2f}s", timer.CpuTime()); + LOGP(info, "{:*^90}", " ITS3 LOCAL MISALIGNMENT END "); +} + +std::string MisalignmentManager::appendStem(const std::string& filename, const std::string& add) +{ + fs::path filepath{filename}; + auto stem = filepath.stem().string(); + auto extension = filepath.extension().string(); + return stem + add + extension; +} + +std::vector MisalignmentManager::split(const std::string& s, char delimiter) +{ + std::vector tokens; + std::string token; + std::istringstream tokenStream(s); + while (std::getline(tokenStream, token, delimiter)) { + if (!token.empty()) { + tokens.push_back(token); + } + } + return tokens; +} + +void MisalignmentManager::navigate(const std::string& path) +{ + if (!gGeoManager->cd(path.c_str())) { + LOGP(fatal, "Cannot navigate to {}", path); + } +} + +std::string MisalignmentManager::composePathSensor(int sensor) +{ + const int layerID{sensor / 2}; + const int sensorID{sensor % 2}; + return fmt::format("/cave/barrel_1/ITSV_2/ITSUWrapVol0_1/ITS3Layer{}_0/ITS3CarbonForm{}_{}", + layerID, layerID, sensorID); +} + +void MisalignmentManager::applyGlobalMatrixVolume(const std::string& path, const TGeoHMatrix& globalMatrix) +{ + gGeoManager->CdTop(); + TGeoHMatrix* pgMatrix{nullptr}; + TGeoHMatrix gAccMatrix; + std::string curPath{}; + for (const auto& comp : split(path)) { + curPath += "/" + comp; + navigate(curPath); + pgMatrix = gGeoManager->GetCurrentMatrix(); + gAccMatrix.Multiply(pgMatrix); + } + navigate(path); + auto node = gGeoManager->GetCurrentNode(); + if (node == nullptr) { + LOGP(fatal, "Nullptr for node at {}", path); + } + auto motherVol = node->GetMotherVolume(); + if (motherVol == nullptr) { + LOGP(fatal, "Nullptr for motherVol at {}", path); + } + // Compute the inverse of the accumulated global transformation matrix + auto gAccMatrix1 = gAccMatrix.Inverse(); + // Compute the relative transformation matrix for the volume + auto relativeMatrix = globalMatrix; + relativeMatrix.MultiplyLeft(gAccMatrix1); + + auto nodemat = dynamic_cast(node); + nodemat->SetMatrix(new TGeoHMatrix(globalMatrix)); + + // Force the container volume of the object to update itself + motherVol->Voxelize(""); +} + +} // namespace o2::its3::align diff --git a/Detectors/Upgrades/ITS3/alignment/src/MisalignmentParameters.cxx b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentParameters.cxx new file mode 100644 index 0000000000000..0842b7252486a --- /dev/null +++ b/Detectors/Upgrades/ITS3/alignment/src/MisalignmentParameters.cxx @@ -0,0 +1,80 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file MisalignmentParameter.cxx +/// \brief Implementation of the MisalignmentParameter class + +#include "ITS3Align/MisalignmentParameters.h" +#include "Framework/Logger.h" + +#include "TFile.h" + +#include + +ClassImp(o2::its3::align::MisalignmentParameters); + +namespace o2::its3::align +{ + +MisalignmentParameters::MisalignmentParameters() +{ + SetName("MisalignmentParameters"); + SetTitle("ITS3 MisalignmentParameters"); +} + +bool MisalignmentParameters::store(const std::string& file) const +{ + std::unique_ptr fOut(TFile::Open(file.c_str(), "RECREATE")); + if (fOut == nullptr || fOut->IsZombie()) { + LOGP(info, "Unable to save misalignment parameters"); + return false; + } + fOut->WriteObjectAny(this, "o2::its3::align::MisalignmentParameters", "ccdb_object"); + return true; +} + +MisalignmentParameters* MisalignmentParameters::load(const std::string& file) +{ + std::unique_ptr fIn(TFile::Open(file.c_str(), "READ")); + auto p = fIn->Get("ccdb_object"); + if (p == nullptr) { + LOGP(fatal, "Unable to load parameters from file!"); + } + return p; +} + +void MisalignmentParameters::printParams(unsigned int detID) const +{ + LOGP(info, "Parameters for ID={}:", detID); + LOGP(info, " - Global Trans: X={} Y={} Z={}", getGloTransX(detID), getGloTransY(detID), getGloTransZ(detID)); + LOGP(info, " - Global Rots: X={} Y={} Z={}", getGloRotX(detID), getGloRotY(detID), getGloRotZ(detID)); + if (constants::detID::isDetITS3(detID)) { + auto sensorID = constants::detID::getSensorID(detID); + LOGP(info, " - Legendre Pol X:"); + getLegendreCoeffX(sensorID).Print(); + LOGP(info, " - Legendre Pol Y:"); + getLegendreCoeffY(sensorID).Print(); + LOGP(info, " - Legendre Pol Z:"); + getLegendreCoeffZ(sensorID).Print(); + } +} + +void MisalignmentParameters::printLegendreParams(unsigned int sensorID) const +{ + LOGP(info, " - Legendre Pol X:"); + getLegendreCoeffX(sensorID).Print(); + LOGP(info, " - Legendre Pol Y:"); + getLegendreCoeffY(sensorID).Print(); + LOGP(info, " - Legendre Pol Z:"); + getLegendreCoeffZ(sensorID).Print(); +} + +} // namespace o2::its3::align diff --git a/Detectors/Upgrades/ITS3/base/CMakeLists.txt b/Detectors/Upgrades/ITS3/base/CMakeLists.txt index 9bd47d2b6fc16..8695e2323bbab 100644 --- a/Detectors/Upgrades/ITS3/base/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/base/CMakeLists.txt @@ -10,10 +10,10 @@ # or submit itself to any jurisdiction. o2_add_library(ITS3Base - SOURCES src/MisalignmentParameter.cxx - src/SegmentationSuperAlpide.cxx + SOURCES src/SegmentationSuperAlpide.cxx + src/ITS3Params.cxx PUBLIC_LINK_LIBRARIES O2::CommonConstants O2::MathUtils O2::DetectorsBase) o2_target_root_dictionary(ITS3Base - HEADERS include/ITS3Base/MisalignmentParameter.h - include/ITS3Base/SegmentationSuperAlpide.h) + HEADERS include/ITS3Base/SegmentationSuperAlpide.h + include/ITS3Base/ITS3Params.h) diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h new file mode 100644 index 0000000000000..c685bf0f085d6 --- /dev/null +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/ITS3Params.h @@ -0,0 +1,35 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ITS3PARAMS_H_ +#define ITS3PARAMS_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2::its3 +{ + +struct ITS3Params : public o2::conf::ConfigurableParamHelper { + // Alignment studies + bool applyMisalignmentHits{false}; // Apply detector misalignment on hit level + std::string misalignmentHitsParams{}; // Path to parameter file for mis-alignment + bool misalignmentHitsUseProp{false}; // Use propagtor for mis-alignment + std::string globalGeoMisAlignerMacro{"${O2_ROOT}/share/macro/MisAlignGeoITS3.C"}; // Path to macro for global geometry mis-alignment + // Chip studies + bool useDeadChannelMap{false}; // Query for a dead channel map to study disabling individual tiles + + O2ParamDef(ITS3Params, "ITS3Params"); +}; + +} // namespace o2::its3 + +#endif // ITS3PARAMS_H_ diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/MisalignmentParameter.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/MisalignmentParameter.h deleted file mode 100644 index b0f572ca5891a..0000000000000 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/MisalignmentParameter.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file MisalignmentParameter.h -/// \brief Definition of the MisalignmentParameter class - -#ifndef ALICEO2_ITS_MISALIGNMENTPARAMETER_H_ -#define ALICEO2_ITS_MISALIGNMENTPARAMETER_H_ - -#include "FairParGenericSet.h" // for FairParGenericSet - -#include "Rtypes.h" // for ClassDef - -#include "TArrayD.h" // for TArrayD - -class FairParamList; - -namespace o2 -{ -namespace its3 -{ -class MisalignmentParameter : public FairParGenericSet -{ - public: - MisalignmentParameter(const char* name = "MisalignmentParameter", - const char* title = "Misalignment parameter for AliceO2ITSHitProducerIdealMisallign Parameters", - const char* context = "TestDefaultContext"); - - ~MisalignmentParameter() override; - - void Clear(); - - void putParams(FairParamList*) override; - - Bool_t getParams(FairParamList*) override; - - TArrayD getShiftX() { return mShiftX; } - TArrayD getShiftY() { return mShiftY; } - TArrayD getShiftZ() { return mShiftZ; } - TArrayD getRotX() { return mRotX; } - TArrayD getRotY() { return mRotY; } - TArrayD getRotZ() { return mRotZ; } - Int_t getNumberOfDetectors() { return mNumberOfDetectors; } - - private: - TArrayD mShiftX; ///< Array to hold the misalignment in x-direction - TArrayD mShiftY; ///< Array to hold the misalignment in y-direction - TArrayD mShiftZ; ///< Array to hold the misalignment in z-direction - TArrayD mRotX; ///< Array to hold the rotation in x-direction - TArrayD mRotY; ///< Array to hold the rotation in y-direction - TArrayD mRotZ; ///< Array to hold the rotation in z-direction - Int_t mNumberOfDetectors; ///< Total number of detectors - - MisalignmentParameter(const MisalignmentParameter&); - - MisalignmentParameter& operator=(const MisalignmentParameter&); - - ClassDefOverride(MisalignmentParameter, 1); -}; -} // namespace its3 -} // namespace o2 - -#endif diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h index d8dec1807215d..dbdf90574ce5d 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationSuperAlpide.h @@ -70,9 +70,6 @@ class SegmentationSuperAlpide static constexpr float mSensorLayerThickness{constants::thickness}; static constexpr float mSensorLayerThicknessEff{constants::effThickness}; static constexpr std::array mRadii{constants::radii}; - static constexpr std::array mEffRadii{mRadii[0] + constants::thickness / 2., - mRadii[1] + constants::thickness / 2., - mRadii[2] + constants::thickness / 2.}; /// Transformation from the curved surface to a flat surface /// \param xCurved Detector local curved coordinate x in cm with respect to diff --git a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h index a7f2e982107eb..d3efde58d0e0d 100644 --- a/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h +++ b/Detectors/Upgrades/ITS3/base/include/ITS3Base/SpecsV2.h @@ -108,26 +108,30 @@ constexpr EColor color{kGray}; } // namespace carbonfoam constexpr unsigned int nLayers{3}; constexpr unsigned int nTotLayers{7}; -constexpr unsigned int nChipsIB{2 * nLayers}; -constexpr std::array isITS3Layer{true, true, true, false, false, false, false}; ///< mask indicating a new layer -constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. +constexpr unsigned int nSensorsIB{2 * nLayers}; constexpr float equatorialGap{1 * mm}; constexpr std::array nSegments{3, 4, 5}; -constexpr float thickness{50 * mu}; //< Physical Thickness of chip -constexpr float effThickness{66 * mu}; //< Physical thickness + metal substrate +constexpr float thickness{50 * mu}; //< Physical Thickness of chip +constexpr float effThickness{66 * mu}; //< Physical thickness + metal substrate +constexpr std::array radii{19.0006 * mm, 25.228 * mm, 31.4554 * mm}; // middle radius e.g. inner radius+thickness/2. +constexpr std::array radiiInner{radii[0] - thickness / 2.f, radii[1] - thickness / 2.f, radii[2] - thickness / 2.f}; // inner radius +constexpr std::array radiiOuter{radii[0] + thickness / 2.f, radii[1] + thickness / 2.f, radii[2] + thickness / 2.f}; // inner radius namespace detID { constexpr unsigned int mDetIDs{2 * 12 * 12 * 12}; //< 2 Hemispheres * (3,4,5=12 segments in a layer) * 12 RSUs in a segment * 12 Tiles in a RSU constexpr unsigned int l0IDStart{0}; //< Start DetID layer 0 constexpr unsigned int l0IDEnd{2 * 3 * 12 * 12 - 1}; //< End First DetID layer 0; inclusive range +constexpr unsigned int l0IDTot{2 * 3 * 12 * 12}; //< Total DetID in Layer 0 constexpr unsigned int l1IDStart{l0IDEnd + 1}; //< Start DetID layer 1 constexpr unsigned int l1IDEnd{l1IDStart + 2 * 4 * 12 * 12 - 1}; //< End First DetID layer 1; inclusive range +constexpr unsigned int l1IDTot{2 * 4 * 12 * 12}; //< Total DetID in Layer 1 constexpr unsigned int l2IDStart{l1IDEnd + 1}; //< Start DetID layer 2 constexpr unsigned int l2IDEnd{l2IDStart + 2 * 5 * 12 * 12 - 1}; //< End First DetID layer 2; inclusive range +constexpr unsigned int l2IDTot{2 * 5 * 12 * 12}; //< Total DetID in Layer 2 constexpr unsigned int nChips{l2IDEnd + 1}; //< number of Chips (PixelArrays) in IB template -inline int getDetID2Layer(T detID) +inline T getDetID2Layer(T detID) { if (static_cast(l0IDStart) <= detID && detID <= static_cast(l0IDEnd)) { return 0; @@ -139,6 +143,20 @@ inline int getDetID2Layer(T detID) return -1; } +template +inline T getSensorID(T detID) +{ + auto layer = getDetID2Layer(detID); + if (layer == 0) { + return ((detID - l0IDStart) < static_cast(l0IDTot) / 2) ? 0 : 1; + } else if (layer == 1) { + return ((detID - l1IDStart) < static_cast(l1IDTot) / 2) ? 2 : 3; + } else if (layer == 2) { + return ((detID - l2IDStart) < static_cast(l2IDTot) / 2) ? 4 : 5; + } + return -1; +} + template inline bool isDetITS3(T detID) { diff --git a/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h b/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h index 9aeaec7d3bb76..dc0557824e0f8 100644 --- a/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h +++ b/Detectors/Upgrades/ITS3/base/src/ITS3BaseLinkDef.h @@ -16,6 +16,7 @@ #pragma link off all functions; #pragma link C++ class o2::its3::SegmentationSuperAlpide + ; -#pragma link C++ class o2::its3::MisalignmentParameter + ; +#pragma link C++ class o2::its3::ITS3Params + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its3::ITS3Params> + ; #endif diff --git a/Detectors/Upgrades/ITS3/base/src/ITS3Params.cxx b/Detectors/Upgrades/ITS3/base/src/ITS3Params.cxx new file mode 100644 index 0000000000000..0a846e9d68dd0 --- /dev/null +++ b/Detectors/Upgrades/ITS3/base/src/ITS3Params.cxx @@ -0,0 +1,13 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITS3Base/ITS3Params.h" +O2ParamImpl(o2::its3::ITS3Params) diff --git a/Detectors/Upgrades/ITS3/base/src/MisalignmentParameter.cxx b/Detectors/Upgrades/ITS3/base/src/MisalignmentParameter.cxx deleted file mode 100644 index 8b86523a69fce..0000000000000 --- a/Detectors/Upgrades/ITS3/base/src/MisalignmentParameter.cxx +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file MisalignmentParameter.cxx -/// \brief Implementation of the MisalignmentParameter class - -#include "ITS3Base/MisalignmentParameter.h" - -#include "FairParamList.h" - -using namespace o2::its3; - -ClassImp(o2::its3::MisalignmentParameter); - -MisalignmentParameter::MisalignmentParameter(const char* name, const char* title, const char* context) - : FairParGenericSet(name, title, context), - mShiftX(), - mShiftY(), - mShiftZ(), - mRotX(), - mRotY(), - mRotZ(), - mNumberOfDetectors(0) -{ -} - -MisalignmentParameter::~MisalignmentParameter() = default; -void MisalignmentParameter::Clear() {} -void MisalignmentParameter::putParams(FairParamList* list) -{ - if (!list) { - return; - } - - list->add("NumberOfDetectors", mNumberOfDetectors); - list->add("ShiftX", mShiftX); - list->add("ShiftY", mShiftY); - list->add("ShiftZ", mShiftZ); - list->add("RotationX", mRotX); - list->add("RotationY", mRotY); - list->add("RotationZ", mRotZ); -} - -Bool_t MisalignmentParameter::getParams(FairParamList* list) -{ - if (!list) { - return kFALSE; - } - - if (!list->fill("NumberOfDetectors", &mNumberOfDetectors)) { - return kFALSE; - } - - mShiftX.Set(mNumberOfDetectors); - if (!list->fill("ShiftX", &mShiftX)) { - return kFALSE; - } - - mShiftY.Set(mNumberOfDetectors); - if (!list->fill("ShiftY", &mShiftY)) { - return kFALSE; - } - - mShiftZ.Set(mNumberOfDetectors); - if (!list->fill("ShiftZ", &mShiftZ)) { - return kFALSE; - } - - mRotX.Set(mNumberOfDetectors); - if (!list->fill("RotationX", &mRotX)) { - return kFALSE; - } - - mRotY.Set(mNumberOfDetectors); - if (!list->fill("RotationY", &mRotY)) { - return kFALSE; - } - - mRotZ.Set(mNumberOfDetectors); - if (!list->fill("RotationZ", &mRotZ)) { - return kFALSE; - } - - return kTRUE; -} diff --git a/Detectors/Upgrades/ITS3/macros/CMakeLists.txt b/Detectors/Upgrades/ITS3/macros/CMakeLists.txt index 9e3dabc947fca..0801c2cf9a099 100644 --- a/Detectors/Upgrades/ITS3/macros/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/macros/CMakeLists.txt @@ -9,5 +9,26 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +# Define custom ITS3 macro function for convenience +macro(its3_add_macro file) + o2_add_test_root_macro( + ${file} + PUBLIC_LINK_LIBRARIES + O2::ITSBase + O2::ITS3Base + O2::ITSMFTBase + O2::ITSMFTSimulation + O2::ITS3Reconstruction + O2::ITS3Simulation + O2::ITS3Align + O2::MathUtils + O2::SimulationDataFormat + O2::DetectorsBase + O2::Steer + LABELS its3 + COMPILE_ONLY) +endmacro() + add_subdirectory(test) -add_subdirectory(eve) \ No newline at end of file +add_subdirectory(eve) +add_subdirectory(align) diff --git a/Detectors/Upgrades/ITS3/macros/align/CMakeLists.txt b/Detectors/Upgrades/ITS3/macros/align/CMakeLists.txt new file mode 100644 index 0000000000000..86ebd989133e0 --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +# install(FILES MisAlignGeoITS3.C DESTINATION share/macro/) +# its3_add_macro(MisAlignGeoITS3.C) +its3_add_macro(TestLegendrePol.C) +its3_add_macro(CreateMisalignmentITS3.C) +its3_add_macro(ShowCoefficients.C) +its3_add_macro(CheckResidualsITS3.C) diff --git a/Detectors/Upgrades/ITS3/macros/align/CheckResidualsITS3.C b/Detectors/Upgrades/ITS3/macros/align/CheckResidualsITS3.C new file mode 100644 index 0000000000000..9d352393d6fd9 --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/CheckResidualsITS3.C @@ -0,0 +1,372 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Steer/MCKinematicsReader.h" +#include "DetectorsBase/Propagator.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DetectorsBase/GeometryManager.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITS3Reconstruction/TopologyDictionary.h" +#include "ITS3Reconstruction/IOUtils.h" +#include "ITS3Base/SpecsV2.h" +#include "ReconstructionDataFormats/BaseCluster.h" +#include "MathUtils/Utils.h" + +#include +#include +#endif + +// Refit ITS3 tracks by using the clusters from the OB only then propagate the +// tracks to the IB clusters and calculate their residuals. + +constexpr auto mMatCorr{o2::base::Propagator::MatCorrType::USEMatCorrNONE}; +constexpr float mMaxStep{2}; +constexpr float mMaxSnp{0.95}; +o2::its3::TopologyDictionary* mDict; + +using Vector3D = ROOT::Math::DisplacementVector3D, ROOT::Math::DefaultCoordinateSystemTag>; +using Point3D = ROOT::Math::PositionVector3D, ROOT::Math::DefaultCoordinateSystemTag>; + +struct Cluster { + Vector3D displacement; + Point3D position; + float deltaR; +}; + +static ULong64_t cProp{0}; +static ULong64_t cUpdate{0}; +static ULong64_t cTotal{0}; +static ULong64_t cGood{0}; + +template +std::optional propagateTo(Track& trk, const o2::itsmft::CompClusterExt& clus, std::vector::iterator pattIt, bool reset = false) +{ + ++cTotal; + auto chipID = clus.getSensorID(); + float sigmaY2{0}, sigmaZ2{0}, sigmaYZ{0}; + const float alpha = o2::its::GeometryTGeo::Instance()->getSensorRefAlpha(clus.getSensorID()); // alpha for the tracking frame + const auto locC = o2::its3::ioutils::extractClusterData(clus, pattIt, mDict, sigmaY2, sigmaZ2); // get cluster in sensor local frame with errors + Point3D trkC; + auto isITS3 = o2::its3::constants::detID::isDetITS3(chipID); + if (isITS3) { + trkC = o2::its::GeometryTGeo::Instance()->getT2LMatrixITS3(chipID, alpha) ^ (locC); // cluster position in the tracking frame + } else { + trkC = o2::its::GeometryTGeo::Instance()->getMatrixT2L(chipID) ^ (locC); // cluster position in the tracking frame + } + const auto gloC = o2::its::GeometryTGeo::Instance()->getMatrixL2G(chipID)(locC); // global cluster position + const auto bz = o2::base::Propagator::Instance()->getNominalBz(); + + // rotate the parameters to the tracking frame then propagate to the clusters'x + if (!trk.rotate(alpha) || + !o2::base::Propagator::Instance()->propagateToX(trk, trkC.x(), bz, mMaxSnp, mMaxStep, mMatCorr)) { + ++cProp; + return std::nullopt; + } + + const auto trkGlo = trk.getXYZGlo(); + Cluster cluster; + cluster.position = trkGlo; + cluster.deltaR = (gloC.Rho() - trkGlo.Rho()) * 1e4; + if constexpr (std::is_same_v) { + // update the track with the OB clusters only + if (!isITS3) { + // if this is the outermost cluster reset the covariance matrix thereby forgetting all previous knowledge + if (reset) { + trk.resetCovariance(); + } + o2::BaseCluster cC{chipID, trkC, sigmaY2, sigmaZ2, sigmaYZ}; + if (!trk.update(cC)) { + ++cUpdate; + return std::nullopt; + } + } + cluster.displacement = (gloC - trkGlo) * 1e4; // in um + ++cGood; + } else { + float ip[2]; + trk.getImpactParams(gloC.X(), gloC.Y(), gloC.Z(), bz, ip); + cluster.displacement.SetX(ip[0] * 1e4); + cluster.displacement.SetZ(ip[1] * 1e4); + } + + return cluster; +} + +void CheckResidualsITS3(bool plotOnly = false, + bool useITS = false, + const std::string& dictFileName = "../ccdb/IT3/Calib/ClusterDictionary/snapshot.root", + const std::string& collisioncontextFileName = "collisioncontext.root", + const std::string& itsTracksFileName = "o2trac_its.root", + const std::string& itsClustersFileName = "o2clus_its.root", + const std::string& magFileName = "o2sim_grp.root", + const std::string& geomFileName = "") +{ + std::array hOBDx, hOBDy, hOBDz, hOBDr; + std::array hIBDx, hIBDy, hIBDz, hIBDr; + + if (!plotOnly) { + mDict = new o2::its3::TopologyDictionary(dictFileName); + + o2::base::GeometryManager::loadGeometry(geomFileName); + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, + o2::math_utils::TransformType::L2G)); // request cached transforms + o2::base::Propagator::initFieldFromGRP(magFileName); + + o2::steer::MCKinematicsReader mcReader; + if (!mcReader.initFromDigitContext(collisioncontextFileName)) { + LOGP(fatal, "Cannot init MC reader"); + } + + auto fITSTracks = TFile::Open(itsTracksFileName.c_str(), "READ"); + auto tITSTracks = fITSTracks->Get("o2sim"); + std::vector tracksITS, *tracksITSPtr{&tracksITS}; + tITSTracks->SetBranchAddress("ITSTrack", &tracksITSPtr); + std::vector tracksLabITS, *tracksLabITSPtr{&tracksLabITS}; + tITSTracks->SetBranchAddress("ITSTrackMCTruth", &tracksLabITSPtr); + std::vector tracksITSClusIdx, *tracksITSClusIdxPtr{&tracksITSClusIdx}; + tITSTracks->SetBranchAddress("ITSTrackClusIdx", &tracksITSClusIdxPtr); + auto fITSClusters = TFile::Open(itsClustersFileName.c_str(), "READ"); + auto tITSClusters = fITSClusters->Get("o2sim"); + std::vector clusITSArr, *clusITSArrPtr{&clusITSArr}; + tITSClusters->SetBranchAddress("ITSClusterComp", &clusITSArrPtr); + std::vector clusPattITSArr, *clusPattITSArrPtr{&clusPattITSArr}; + tITSClusters->SetBranchAddress("ITSClusterPatt", &clusPattITSArrPtr); + + const std::array vOBLength{84.3 / 2.0, 84.3 / 2.0, 147.5 / 2.0, 147.5 / 2.0}; + for (int i{3}; i < 7; ++i) { + int nBins = (useITS) ? 200 : 200; + int resid = (useITS) ? 300 : 200; + hOBDx[i - 3] = new TH3F(Form("hOBDx_%d", i), Form("DCA_{x} Layer %d;#varphi (rad);z (cm);#Deltax (#mum)", i), nBins, -TMath::Pi(), TMath::Pi(), nBins, -vOBLength[i - 3], vOBLength[i - 3], nBins, -resid, resid); + hOBDy[i - 3] = new TH3F(Form("hOBDy_%d", i), Form("DCA_{y} Layer %d;#varphi (rad);z (cm);#Deltay (#mum)", i), nBins, -TMath::Pi(), TMath::Pi(), nBins, -vOBLength[i - 3], vOBLength[i - 3], nBins, -resid, resid); + hOBDz[i - 3] = new TH3F(Form("hOBDz_%d", i), Form("DCA_{z} Layer %d;#varphi (rad);z (cm);#Deltaz (#mum)", i), nBins, -TMath::Pi(), TMath::Pi(), nBins, -vOBLength[i - 3], vOBLength[i - 3], nBins, -resid, resid); + hOBDr[i - 3] = new TH3F(Form("hOBDr_%d", i), Form("DCA_{clus.r-trk.r} Layer %d;#varphi (rad);z (cm);#Delta(clus.r-trk.r) (#mum)", i), nBins, -TMath::Pi(), TMath::Pi(), nBins, -vOBLength[i - 3], vOBLength[i - 3], nBins, -resid, resid); + } + for (int i{0}; i < 6; ++i) { + constexpr int nBins{100}; + int resid = (useITS) ? 100 : 500; + hIBDx[i] = new TH3F(Form("hIBDx_%d", i), Form("DCA_{x} Sensor %d;normalized #varphi;normalized z;#Deltax (#mum)", i), nBins, -1.0, 1.0, nBins, -1.0, 1.0, nBins, -resid, resid); + hIBDy[i] = new TH3F(Form("hIBDy_%d", i), Form("DCA_{y} Sensor %d;normalized #varphi;normalized z;#Deltay (#mum)", i), nBins, -1.0, 1.0, nBins, -1.0, 1.0, nBins, -resid, resid); + hIBDz[i] = new TH3F(Form("hIBDz_%d", i), Form("DCA_{z} Sensor %d;normalized #varphi;normalized z;#Deltaz (#mum)", i), nBins, -1.0, 1.0, nBins, -1.0, 1.0, nBins, -resid * 4, resid * 4); + hIBDr[i] = new TH3F(Form("hIBDr_%d", i), Form("DCA_{clus.r-trk.r} Sensor %d;normalized #varphi;normalized z;#Delta(clus.r-trk.r) (#mum)", i), nBins, -1.0, 1.0, nBins, -1.0, 1.0, nBins, -resid, resid); + } + + ULong64_t cTot{0}, cSkipped{0}; + const Long64_t nEntries = tITSTracks->GetEntries(); + for (Long64_t iEntry{0}; iEntry < nEntries; ++iEntry) { + tITSTracks->GetEntry(iEntry); + tITSClusters->GetEntry(iEntry); + + for (unsigned int iTrack{0}; iTrack < tracksITS.size(); ++iTrack) { + const auto& trk = tracksITS[iTrack]; + + if (trk.getNClusters() < 7) { + continue; + } + + // are all clusters valid + const auto& lab = tracksLabITS[iTrack]; + if (!lab.isValid()) { + continue; + } + + auto trkOut = trk.getParamOut(); + auto trkC = trk; + const int clEntry = trk.getFirstClusterEntry(); + const int ncl = trk.getNumberOfClusters(); + for (int icl = 0; icl != ncl; icl += 1, ++cTot) { // Start from outermost cluster + const int idx = tracksITSClusIdx[clEntry + icl]; + const auto& clus = clusITSArr[idx]; + const int layer = gman->getLayer(clus.getSensorID()); + const bool needsUpdate = layer > 2; // refit only with IB clusters + std::optional res; + if (!useITS) { + res = propagateTo(trkOut, clus, clusPattITSArr.begin(), layer == (ncl - 1)); + } else { + res = propagateTo(trkC, clus, clusPattITSArr.begin(), layer == (ncl - 1)); + } + if (res.has_value()) { + const auto& cluster = *res; + if (o2::its3::constants::detID::isDetITS3(clus.getSensorID())) { + const auto sensorID = o2::its3::constants::detID::getSensorID(clus.getSensorID()); + const bool isTop = sensorID % 2 == 0; + const float phi = o2::math_utils::to02Pi(cluster.position.Phi()); + const float phi1 = o2::math_utils::to02Pi(((isTop) ? 0.f : 1.f) * TMath::Pi() + std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[layer])); + const float phi2 = o2::math_utils::to02Pi(((isTop) ? 1.f : 2.f) * TMath::Pi() - std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[layer])); + const float nphi = ((phi - phi1) * 2.f) / (phi2 - phi1) - 1.f; + const float nz = (2.f * cluster.position.Z()) / o2::its3::constants::segment::lengthSensitive; + hIBDx[sensorID]->Fill(nphi, nz, cluster.displacement.X()); + hIBDy[sensorID]->Fill(nphi, nz, cluster.displacement.Y()); + hIBDz[sensorID]->Fill(nphi, nz, cluster.displacement.Z()); + hIBDr[sensorID]->Fill(nphi, nz, cluster.deltaR); + } else { + hOBDx[layer - 3]->Fill(cluster.position.Phi(), cluster.position.Z(), cluster.displacement.X()); + hOBDy[layer - 3]->Fill(cluster.position.Phi(), cluster.position.Z(), cluster.displacement.Y()); + hOBDz[layer - 3]->Fill(cluster.position.Phi(), cluster.position.Z(), cluster.displacement.Z()); + hOBDr[layer - 3]->Fill(cluster.position.Phi(), cluster.position.Z(), cluster.deltaR); + } + } else { + ++cSkipped; + } + } + } + } + + LOGP(info, "Skipped {} of {} clusters", cSkipped, cTot); + LOGP(info, "Total {} Good {} Prop {} Update {}", cTotal, cGood, cProp, cUpdate); + } else { + LOGP(info, "Only plotting"); + auto fIn = TFile::Open("CheckResidualsITS3.root", "READ"); + for (int i{3}; i < 7; ++i) { + hOBDx[i - 3] = fIn->Get(Form("hOBDx_%d", i)); + hOBDy[i - 3] = fIn->Get(Form("hOBDy_%d", i)); + hOBDz[i - 3] = fIn->Get(Form("hOBDz_%d", i)); + hOBDr[i - 3] = fIn->Get(Form("hOBDr_%d", i)); + } + for (int i{0}; i < 6; ++i) { + hIBDx[i] = fIn->Get(Form("hIBDx_%d", i)); + hIBDy[i] = fIn->Get(Form("hIBDy_%d", i)); + hIBDz[i] = fIn->Get(Form("hIBDz_%d", i)); + hIBDr[i] = fIn->Get(Form("hIBDr_%d", i)); + } + } + + auto c = new TCanvas(); + c->Divide(4, 2); + for (int i{0}; i < 4; ++i) { + c->cd(i + 1); + hOBDx[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 5); + hOBDx[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ob_dx.pdf"); + + c = new TCanvas(); + c->Divide(4, 2); + for (int i{0}; i < 4; ++i) { + c->cd(i + 1); + hOBDy[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 5); + hOBDy[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ob_dy.pdf"); + + c = new TCanvas(); + c->Divide(4, 2); + for (int i{0}; i < 4; ++i) { + c->cd(i + 1); + hOBDz[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 5); + hOBDz[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ob_dz.pdf"); + + c = new TCanvas(); + c->Divide(4, 2); + for (int i{0}; i < 4; ++i) { + c->cd(i + 1); + hOBDr[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 5); + hOBDr[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ob_dr.pdf"); + + c = new TCanvas(); + c->Divide(6, 2); + for (int i{0}; i < 6; ++i) { + c->cd(i + 1); + hIBDx[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 7); + hIBDx[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ib_dx.pdf"); + + c = new TCanvas(); + c->Divide(6, 2); + for (int i{0}; i < 6; ++i) { + c->cd(i + 1); + hIBDy[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 7); + hIBDy[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ib_dy.pdf"); + + c = new TCanvas(); + c->Divide(6, 2); + for (int i{0}; i < 6; ++i) { + c->cd(i + 1); + hIBDz[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 7); + hIBDz[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ib_dz.pdf"); + + c = new TCanvas(); + c->Divide(6, 2); + for (int i{0}; i < 6; ++i) { + c->cd(i + 1); + hIBDr[i]->Project3D("zx")->Draw("colz"); + c->cd(i + 7); + hIBDr[i]->Project3D("zy")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ib_dr.pdf"); + + c = new TCanvas(); + c->Divide(6, 3); + for (int i{0}; i < 6; ++i) { + c->cd(i + 1); + hIBDx[i]->Project3DProfile("yx")->Draw("colz"); + c->cd(i + 7); + hIBDy[i]->Project3DProfile("yx")->Draw("colz"); + c->cd(i + 13); + hIBDz[i]->Project3DProfile("yx")->Draw("colz"); + } + c->Draw(); + c->SaveAs("its3_ib_displacement.pdf"); + + if (!plotOnly) { + auto fOut = std::unique_ptr(TFile::Open("CheckResidualsITS3.root", "RECREATE")); + for (int i{0}; i < 6; ++i) { + hIBDx[i]->Write(); + hIBDy[i]->Write(); + hIBDz[i]->Write(); + hIBDr[i]->Write(); + } + for (int i{0}; i < 4; ++i) { + hOBDx[i]->Write(); + hOBDy[i]->Write(); + hOBDz[i]->Write(); + hOBDr[i]->Write(); + } + } +} diff --git a/Detectors/Upgrades/ITS3/macros/align/CreateMisalignmentITS3.C b/Detectors/Upgrades/ITS3/macros/align/CreateMisalignmentITS3.C new file mode 100644 index 0000000000000..8df00ee25de00 --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/CreateMisalignmentITS3.C @@ -0,0 +1,94 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TRandom.h" +#include "TMatrixD.h" + +#include "ITS3Align/MisalignmentParameters.h" +#endif + +void CreateMisalignmentITS3(bool dummy = false, bool manual = false) +{ + gRandom->SetSeed(42); + + // Legendre coeff. + constexpr int nOrder{2}; + auto getRandom = []() { + constexpr double scale{50.e-4}; + return scale * gRandom->Uniform(-1.0, 1.0); + }; + + auto getSign = []() { return gRandom->Uniform() ? -1.0 : 1.0; }; + + o2::its3::align::MisalignmentParameters params; + + if (dummy) { + TMatrixD coeffNull(0 + 1, 0 + 1); + for (int sensorID{0}; sensorID < 6; ++sensorID) { + params.setLegendreCoeffX(sensorID, coeffNull); + params.setLegendreCoeffY(sensorID, coeffNull); + params.setLegendreCoeffZ(sensorID, coeffNull); + } + } else if (manual) { + // (0,0) -> shift + // (1,0) -> + for (int sensorID{0}; sensorID < 6; ++sensorID) { + constexpr double scale{20e-4}; + TMatrixD coeffNull(1, 1); + + TMatrixD coeffMinusX(1 + 1, 1 + 1); + TMatrixD coeffPlusX(1 + 1, 1 + 1); + coeffMinusX(1, 1) = -scale; + coeffPlusX(1, 1) = scale; + + TMatrixD coeffMinusY(4 + 1, 4 + 1); + TMatrixD coeffPlusY(4 + 1, 4 + 1); + coeffMinusY(0, 0) = scale; + coeffPlusY(0, 0) = -scale; + coeffMinusY(4, 4) = -scale; + coeffPlusY(4, 4) = scale; + if (sensorID % 2 == 0) { + params.setLegendreCoeffX(sensorID, coeffPlusX); + params.setLegendreCoeffY(sensorID, coeffPlusY); + params.setLegendreCoeffZ(sensorID, coeffNull); + } else { + params.setLegendreCoeffX(sensorID, coeffMinusX); + params.setLegendreCoeffY(sensorID, coeffMinusY); + params.setLegendreCoeffZ(sensorID, coeffNull); + } + } + } else { + for (int sensorID{0}; sensorID < 6; ++sensorID) { + TMatrixD coeffX(nOrder + 1, nOrder + 1); + TMatrixD coeffY(nOrder + 1, nOrder + 1); + TMatrixD coeffZ(nOrder + 1, nOrder + 1); + for (int i{0}; i <= nOrder; ++i) { + for (int j{0}; j <= i; ++j) { + // some random scaling as higher order parameters have higher influence + coeffX(i, j) = getRandom() / (1.0 + i * j * 2.0); + coeffZ(i, j) = getRandom() / (1.0 + i * j * 2.0); + coeffY(i, j) = getRandom() / (1.0 + i * j * 2.0); + } + } + + params.setLegendreCoeffX(sensorID, coeffX); + params.setLegendreCoeffY(sensorID, coeffY); + params.setLegendreCoeffZ(sensorID, coeffZ); + } + } + + for (int sensorID{0}; sensorID < 6; ++sensorID) { + params.printLegendreParams(sensorID); + } + + params.store("misparams.root"); +} diff --git a/Detectors/Upgrades/ITS3/macros/align/MisAlignGeoITS3.notest b/Detectors/Upgrades/ITS3/macros/align/MisAlignGeoITS3.notest new file mode 100644 index 0000000000000..2a4bef978d0da --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/MisAlignGeoITS3.notest @@ -0,0 +1,129 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file MisAlignGeoITS3.C +/// \brief Misalign the global geometry of ITS3 +/// \author felix.schlepper@cern.ch + +#include "ITS3Align/MisalignmentManager.h" + +#include "TGeoManager.h" +#include "TGeoMatrix.h" +#include "TMath.h" + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" +#include "Framework/Logger.h" +#include "ITS3Base/SpecsV2.h" + +#include + +#include "boost/property_tree/ptree.hpp" + +using MM = o2::its3::align::MisalignmentManager; +namespace fs = std::filesystem; +namespace pt = boost::property_tree; +namespace its3c = o2::its3::constants; + +#define DECLARE_SENSOR(id) \ + float Sensor##id##Dx = 0.f; \ + float Sensor##id##Dy = 0.f; \ + float Sensor##id##Dz = 0.f; \ + float Sensor##id##Phi = 0.f; \ + float Sensor##id##Theta = 0.f; \ + float Sensor##id##Psi = 0.f; + +struct MisAlignGlobalParams : public o2::conf::ConfigurableParamHelper { + DECLARE_SENSOR(0) + DECLARE_SENSOR(1) + DECLARE_SENSOR(2) + DECLARE_SENSOR(3) + DECLARE_SENSOR(4) + DECLARE_SENSOR(5) + + O2ParamDef(MisAlignGlobalParams, "MisAlignGlobalParams"); +}; +O2ParamImpl(MisAlignGlobalParams); + +void MisAlignGeoITS3(const std::string& configFilePath = "", bool _export = false, bool draw = false, bool check = false, const std::string& geomFile = "o2sim_geometry-aligned.root") +{ + LOGP(info, "{:*^90}", " ITS3 GLOBAL MISALIGNMENT START "); + auto& params = MisAlignGlobalParams::Instance(); + params.writeINI("default_parameters_global.ini", "MisAlignGlobalParams"); + if (configFilePath.empty()) { + LOGP(info, "No user config provided using defaults"); + } else { + LOGP(info, "User config at {}", configFilePath); + params.updateFromFile(configFilePath); + } + params.writeINI("used_parameters_global.ini", "MisAlignGlobalParams"); + params.printKeyValues(true, true); + + const fs::path srcFile{geomFile}; + const fs::path destFile{MM::appendStem(geomFile, "_Orig")}; + if (gGeoManager == nullptr) { + MM::createBackup(srcFile, destFile); + TGeoManager::Import(destFile.c_str()); + } + + LOGP(info, "Building matrices"); + std::array gRotoTranslations{}; + for (int iSensor{0}; iSensor < (int)its3c::nSensorsIB; ++iSensor) { + auto& mat = gRotoTranslations[iSensor]; + // Phi Z rotation angle (first) defined in [-PI,PI] + // Theta X rotation angle (second) defined only [0,PI] + // Psi Z rotation angle (third) defined in [-PI,PI] + MM::Euler3D euler{ + ((iSensor % 2 == 0) ? 0. : -TMath::Pi()) + + TMath::DegToRad() * params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Phi", iSensor)), + TMath::DegToRad() * params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Theta", iSensor)), + TMath::DegToRad() * params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Psi", iSensor)), + }; + MM::Rot3D rot(euler); + std::array rota; + rot.GetComponents(std::begin(rota)); + mat.SetRotation(rota.data()); + std::array trans{ + params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Dx", iSensor)), + params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Dy", iSensor)), + params.getValueAs(fmt::format("MisAlignGlobalParams.Sensor{}Dz", iSensor)), + }; + mat.SetTranslation(trans.data()); + } + + LOGP(info, "Appying Global RotoTranslations"); + for (int iSensor{0}; iSensor < (int)its3c::nSensorsIB; ++iSensor) { + auto path = MM::composePathSensor(iSensor); + auto& mat = gRotoTranslations[iSensor]; + MM::applyGlobalMatrixVolume(path, mat); + } + + if (_export) { + gGeoManager->Export(srcFile.c_str()); + } + if (draw) { + MM::navigate("cave/barrel_1/ITSV_2/ITSUWrapVol0_1"); + gGeoManager->GetCurrentVolume()->Draw(); + gGeoManager->SetTopVisible(); + gGeoManager->RestoreMasterVolume(); + } + if (check) { + gGeoManager->CdTop(); + gGeoManager->CloseGeometry(); + gGeoManager->CheckGeometryFull(); + gGeoManager->CheckOverlaps(0.1, "s"); + gGeoManager->PrintOverlaps(); + auto overlaps = gGeoManager->GetListOfOverlaps(); + overlaps->At(0)->Print(); + overlaps->At(0)->Draw("ogl"); + } + LOGP(info, "{:*^90}", " ITS3 GLOBAL MISALIGNMENT END "); +} diff --git a/Detectors/Upgrades/ITS3/macros/align/ShowCoefficients.C b/Detectors/Upgrades/ITS3/macros/align/ShowCoefficients.C new file mode 100644 index 0000000000000..42749b707e81d --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/ShowCoefficients.C @@ -0,0 +1,333 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Math/Factory.h" +#include "Math/Minimizer.h" +#include "TAxis.h" +#include "TCanvas.h" +#include "TGraph.h" +#include "TGraph2D.h" +#include "TLegend.h" +#include "TMarker.h" +#include "TMultiGraph.h" +#include "TRandom.h" +#include "TMath.h" + +#include "MathUtils/LegendrePols.h" +#include "ITS3Align/Deformations.h" +#include "MathUtils/Utils.h" +#endif + +static ROOT::Math::Minimizer* gMin; + +void ShowCoefficients(const std::string& fileName = "misparams.root", bool findMin = false) +{ + constexpr double factor{10}; + o2::its3::align::Deformations def; + def.init(fileName); + + if (findMin) { + gMin = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad"); + if (gMin == nullptr) { + Error("", "Cannot create minimizer !"); + return; + } + gMin->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 + gMin->SetTolerance(0.00001); + gMin->SetPrintLevel(1); + } + + if constexpr (1) { + constexpr int nPoints{1000}; + const std::array zFix{-12., -8.67, -4.33, 0., 4.33, 8.67, 12.}; + const std::array phiFix{1. / 4. * TMath::Pi(), 0.5 * TMath::Pi(), 3. / 4. * TMath::Pi(), TMath::Pi(), 5. / 4. * TMath::Pi(), 6. / 4. * TMath::Pi(), 7. / 4. * TMath::Pi()}; + const std::array phiFixName{"#frac{1}{4}", "#frac{1}{2}", "#frac{3}{4}", "1", "#frac{5}{4}", "#frac{6}{4}", "#frac{7}{4}"}; + const std::array phiFixTop{true, true, true, false, false, false, false}; + const std::array, 2> sensorN{{{0, 2, 4}, {1, 3, 5}}}; + constexpr double z1{-o2::its3::constants::segment::lengthSensitive / 2.0}, z2{o2::its3::constants::segment::lengthSensitive / 2.0}, zTot{z2 - z1}, zStep{zTot / (nPoints - 1)}; + auto canv = new TCanvas(); + canv->Divide(7, 2); + for (int i{0}; i < 7; ++i) { + std::array xi, yi, xd, yd; + for (int s{0}; s < 6; ++s) { + const bool isTop = s % 2 == 0; + const double radius = o2::its3::constants::radii[s / 2]; + const double nzFix = (zFix[i] - z1) * 2.0 / zTot - 1.0; + const double phi1 = o2::math_utils::to02Pi(((isTop) ? 0.f : 1.f) * TMath::Pi() + std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phi2 = o2::math_utils::to02Pi(((isTop) ? 1.f : 2.f) * TMath::Pi() - std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phiTot{phi2 - phi1}, phiStep{phiTot / (nPoints - 1)}; + const double nphiFix = ((phiFix[i]) - phi1) * 2.0 / phiTot - 1.0; + + for (int j{0}; j < nPoints; ++j) { + const int idx = s * nPoints + j; + const double phi = phi1 + j * phiStep; + const double nphi = (phi - phi1) * 2.0 / phiTot - 1.0; + + xi[idx] = radius * std::cos(phi); + yi[idx] = radius * std::sin(phi); + const auto [dxXY, dyXY, _] = def.getDeformation(s, nphi, nzFix); + xd[idx] = xi[idx] + dxXY * factor; + yd[idx] = yi[idx] + dyXY * factor; + } + } + canv->cd(i + 1); + auto gixy = new TGraph(nPoints * 6, xi.data(), yi.data()); + gixy->SetNameTitle(Form("g_i_xy_%d", i), Form("Ideal xy at z=%.2f; x (cm); y (cm)", zFix[i])); + gixy->SetMarkerColor(kBlue); + gixy->Draw("AP"); + auto gdxy = new TGraph(nPoints * 6, xd.data(), yd.data()); + gdxy->SetNameTitle(Form("g_d_xy_%d", i), Form("Deformed (x%.0f) xy at z=%.2f; x (cm); y (cm)", factor, zFix[i])); + gdxy->SetMarkerColor(kRed); + gdxy->Draw("P;same"); + + if (i == 3) { + continue; + } + + std::array zi, ri, zd, rd; + const bool isTop = phiFixTop[i]; + for (const int s : ((isTop) ? sensorN[0] : sensorN[1])) { + const double radius = o2::its3::constants::radii[s / 2]; + const double phi1 = o2::math_utils::to02Pi(((isTop) ? 0.f : 1.f) * TMath::Pi() + std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phi2 = o2::math_utils::to02Pi(((isTop) ? 1.f : 2.f) * TMath::Pi() - std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phiTot{phi2 - phi1}, phiStep{phiTot / (nPoints - 1)}; + const double nphiFix = ((phiFix[i]) - phi1) * 2.0 / phiTot - 1.0; + for (int j{0}; j < nPoints; ++j) { + const int idx = (s / 2) * nPoints + j; + const double z = z1 + j * zStep; + const double nz = (z - z1) * 2.0 / zTot - 1.0; + const double xi = radius * std::cos(phiFix[i]), yi = radius * std::sin(phiFix[i]); + ri[idx] = radius; + zi[idx] = z; + const auto [dxZR, dyZR, dzZR] = def.getDeformation(s, nphiFix, nz); + zd[idx] = z + dzZR * factor; + const double xxd = xi + dxZR * factor, yyd = yi + dyZR * factor; + rd[idx] = std::sqrt(xxd * xxd + yyd * yyd); + } + } + canv->cd(i + 8); + auto gizr = new TGraph(nPoints * 3, zi.data(), ri.data()); + gizr->SetNameTitle(Form("g_i_zr_%d", i), Form("Ideal zr at #varphi=%s #Pi; z (cm); r (cm)", phiFixName[i])); + gizr->SetMarkerColor(kBlue); + gizr->Draw("AP"); + auto gdzr = new TGraph(nPoints * 3, zd.data(), rd.data()); + gdzr->SetNameTitle(Form("g_d_zr_%d", i), Form("Deformed (x%0.f) zr at #varphi=%s #Pi; z (cm); r (cm)", factor, phiFixName[i])); + gdzr->SetMarkerColor(kRed); + gdzr->Draw("P;same"); + } + canv->Draw(); + canv->SaveAs("its3_deformation.pdf"); + } + + if constexpr (1) { + const std::array axisName{"x", "y", "z"}; + constexpr int nPoints{100}; + constexpr int nPoints2{nPoints * nPoints}; + constexpr double minX{-1.0}, maxX{1.0}, + stepX{(maxX - minX) / static_cast(nPoints)}; + + for (unsigned int iSensor{0}; iSensor < 6; ++iSensor) { + const auto nOrders = def.getOrders(iSensor); + for (unsigned int iAxis{0}; iAxis < 3; ++iAxis) { + std::array x, y, z; + auto canv = new TCanvas(Form("c_sensor%d_d%s", iSensor, axisName[iAxis]), Form("Legendre Coefficients Sensor %d - Axis %s", iSensor, axisName[iAxis])); + canv->Divide(nOrders[iAxis] + 1, nOrders[iAxis] + 1); + + { // Draw total polynominal + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + for (int jPoint{0}; jPoint < nPoints; ++jPoint) { + double ycur = minX + jPoint * stepX; + int i = iPoint * nPoints + jPoint; + x[i] = xcur; + y[i] = ycur; + z[i] = def.getDeformation(iSensor, iAxis, xcur, ycur); + } + } + canv->cd(nOrders[iAxis] + 1); + auto g = new TGraph2D(nPoints2, x.data(), y.data(), z.data()); + g->SetTitle(Form("Legendre Polynominal %d-deg Sensor %d #Delta%s;u;v;w", nOrders[iAxis], iSensor, axisName[iAxis])); + g->SetName(Form("g_%d_%s", iSensor, axisName[iAxis])); + g->Draw("surf1"); + g->GetXaxis()->SetRangeUser(minX, maxX); + g->GetYaxis()->SetRangeUser(minX, maxX); + gPad->Update(); + } + + { // Draw decomposition of contributions to polynominal + const auto& leg = def.getLegendre(iSensor, iAxis); + const auto coeff = leg.getCoefficients(); + for (unsigned int iOrder{0}; iOrder <= nOrders[iAxis]; ++iOrder) { + for (unsigned int jOrder{0}; jOrder <= iOrder; ++jOrder) { + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + for (int jPoint{0}; jPoint < nPoints; ++jPoint) { + double ycur = minX + jPoint * stepX; + int i = iPoint * nPoints + jPoint; + x[i] = xcur; + y[i] = ycur; + z[i] = leg(iOrder, jOrder, xcur, ycur); + } + } + canv->cd(1 + iOrder * (nOrders[iAxis] + 1) + jOrder); + auto g = new TGraph2D(nPoints2, x.data(), y.data(), z.data()); + g->SetTitle(Form("c_{%d,%d}=%.4f;u;v;w", iOrder, jOrder, coeff(iOrder, jOrder))); + g->SetName(Form("g_%d_%d_%d_%d", iSensor, iAxis, iOrder, jOrder)); + if (iOrder == 0 && jOrder == 0) { // Fix display of constant value + g->Draw("P0"); + } else { + g->Draw("surf1"); + } + g->GetXaxis()->SetRangeUser(minX, maxX); + g->GetYaxis()->SetRangeUser(minX, maxX); + gPad->Update(); + } + } + } + + canv->Draw(); + canv->SaveAs(Form("its3_sensor%d_%s.pdf", iSensor, axisName[iAxis])); + } + } + } + + if constexpr (1) { + constexpr int nPoints{50}; + constexpr int nPoints2{nPoints * nPoints}; + constexpr double radL = o2::its3::constants::radii[2] + 0.3, zL = o2::its3::constants::segment::lengthSensitive / 2.0 + 2.0; + + // Plot the whole geometry + std::array gIdeal; + std::array gDeformed; + constexpr double z1{-o2::its3::constants::segment::lengthSensitive / 2.0}, z2{o2::its3::constants::segment::lengthSensitive / 2.0}, zTot{z2 - z1}, zStep{zTot / (nPoints - 1)}; + auto canv = new TCanvas(); + canv->Divide(2, 1); + for (unsigned int iSensor{0}; iSensor < 6; ++iSensor) { + std::array xi, yi, zi, xd, yd, zd; + const double radius = o2::its3::constants::radii[iSensor / 2]; + const bool isTop = iSensor % 2 == 0; + const double phi1 = o2::math_utils::to02Pi(((isTop) ? 0.f : 1.f) * TMath::Pi() + std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phi2 = o2::math_utils::to02Pi(((isTop) ? 1.f : 2.f) * TMath::Pi() - std::asin(o2::its3::constants::equatorialGap / 2.f / radius)); + const double phiTot{phi2 - phi1}, phiStep{phiTot / (nPoints - 1)}; + for (int iZ{0}; iZ < nPoints; ++iZ) { + double z = z1 + iZ * zStep; + for (int iPhi{0}; iPhi < nPoints; ++iPhi) { + int i = iZ * nPoints + iPhi; + double phi = phi1 + iPhi * phiStep; + + xi[i] = radius * std::cos(phi); + yi[i] = radius * std::sin(phi); + zi[i] = z; + + const double u = ((phi - phi1) * 2.f) / phiTot - 1.f; + const double v = ((z - z1)) / zTot - 1.f; + const auto [dx, dy, dz] = def.getDeformation(iSensor, u, v); + xd[i] = xi[i] + dx * factor; + yd[i] = yi[i] + dy * factor; + zd[i] = zi[i] + dz * factor; + } + } + + canv->cd(1); + auto ideal = new TGraph2D(Form("g_ideal_%d", iSensor), "Ideal Geometry", nPoints2, xi.data(), zi.data(), yi.data()); + ideal->SetMarkerStyle(kFullCircle); + ideal->SetMarkerSize(1); + ideal->SetMarkerColor(kBlue); + ideal->SetLineColor(kBlue); + if (iSensor == 0) { + ideal->Draw("p0"); + } else { + ideal->Draw("p0;same"); + if (iSensor == 5) { + gPad->Update(); + ideal->GetXaxis()->SetTitle("X"); + ideal->GetYaxis()->SetTitle("Z"); + ideal->GetZaxis()->SetTitle("Y"); + ideal->GetXaxis()->SetRangeUser(-radL, radL); + ideal->GetZaxis()->SetRangeUser(-radL, radL); + ideal->GetYaxis()->SetRangeUser(-zL, zL); + } + } + + canv->cd(2); + auto deformed = new TGraph2D(Form("g_def_%d", iSensor), "Deformed Geometry", nPoints2, xd.data(), zd.data(), yd.data()); + deformed->SetMarkerStyle(kFullCircle); + deformed->SetMarkerSize(1); + deformed->SetMarkerColor(kRed); + deformed->SetLineColor(kRed); + if (iSensor == 0) { + deformed->Draw("p0"); + } else { + deformed->Draw("p0;same"); + if (iSensor == 5) { + gPad->Update(); + deformed->GetXaxis()->SetTitle("X"); + deformed->GetYaxis()->SetTitle("Z"); + deformed->GetZaxis()->SetTitle("Y"); + deformed->GetXaxis()->SetRangeUser(-radL, radL); + deformed->GetZaxis()->SetRangeUser(-radL, radL); + deformed->GetYaxis()->SetRangeUser(-zL, zL); + } + } + } + + // Optionally find a deformation + /* if (findMin2D) { */ + /* std::vector cccc(nOrder + 2, 0.0); */ + /* cccc[0] = nOrder; */ + /* for (int i{0}; i <= nOrder; ++i) { */ + /* for (int j{0}; j <= i; ++j) { */ + /* int k = i * (i + 1) / 2 + j; */ + /* cccc[1 + k] = coeff(i, j); */ + /* } */ + /* } */ + /* auto ig = legendre_poly2D_integral(cccc.data()); */ + + /* gMin->Clear(); */ + /* ROOT::Math::Functor fmin(&legendre_poly2D_integral, */ + /* 2 + nOrder * (nOrder + 1) / 2 + nOrder); */ + /* Info("", "ig=%f parameters=%d", ig, */ + /* 2 + nOrder * (nOrder + 1) / 2 + nOrder); */ + /* gMin->SetFunction(fmin); */ + /* constexpr double minStep{0.001}; */ + /* gMin->SetFixedVariable(0, "nOrder", nOrder); */ + /* gMin->SetFixedVariable(1, "c_00", coeff(0, 0)); */ + /* for (int iOrder{1}; iOrder <= nOrder; ++iOrder) { */ + /* for (int jOrder{0}; jOrder <= iOrder; ++jOrder) { */ + /* int k = iOrder * (iOrder + 1) / 2 + jOrder + 1; */ + /* Info("", "Setting parameter %d", k); */ + /* if (getRandom() < 0.0) { */ + /* gMin->SetFixedVariable(k, Form("c_%d_%d", iOrder, jOrder), */ + /* coeff(iOrder, jOrder)); */ + /* } else { */ + /* gMin->SetVariable(k, Form("c_%d_%d", iOrder, jOrder), */ + /* coeff(iOrder, jOrder), minStep); */ + /* } */ + /* } */ + /* } */ + /* gMin->Minimize(); */ + /* return; */ + /* auto stat = gMin->Status(); */ + /* auto min = gMin->MinValue(); */ + /* if ((stat == 0 || stat == 1) && min < 0.01) { */ + /* Info("", "Minimizer converged with %f; using new values!", min); */ + /* const double *cmins = gMin->X(); */ + /* for (int iOrder{1}; iOrder <= nOrder; ++iOrder) { */ + /* for (int jOrder{0}; jOrder <= iOrder; ++jOrder) { */ + /* int k = iOrder * (iOrder + 1) / 2 + jOrder; */ + /* coeff(iOrder, jOrder) = cmins[k + 1]; */ + /* } */ + /* } */ + /* } */ + /* } */ + } +} diff --git a/Detectors/Upgrades/ITS3/macros/align/TestLegendrePol.C b/Detectors/Upgrades/ITS3/macros/align/TestLegendrePol.C new file mode 100644 index 0000000000000..720ab80264838 --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/align/TestLegendrePol.C @@ -0,0 +1,257 @@ +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Math/Factory.h" +#include "Math/Minimizer.h" +#include "TAxis.h" +#include "TCanvas.h" +#include "TGraph.h" +#include "TGraph2D.h" +#include "TLegend.h" +#include "TMarker.h" +#include "TMultiGraph.h" +#include "TRandom.h" + +#include "MathUtils/LegendrePols.h" +#endif + +static ROOT::Math::Minimizer* gMin; + +void TestLegendrePol(bool findMin1D = false, bool findMin2D = false) +{ + constexpr int nMaxOrder{2}; + constexpr int nPoints{100}; + constexpr int nPoints2{nPoints * nPoints}; + constexpr double minX{-1.0}, maxX{1.0}, + stepX{(maxX - minX) / static_cast(nPoints)}; + + gRandom->SetSeed(0); + auto getRandom = []() { + constexpr double scale{80.e-4}; + return scale * gRandom->Uniform(-1.0, 1.0); + }; + + if (findMin1D || findMin2D) { + gMin = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad"); + if (gMin == nullptr) { + Error("", "Cannot create minimizer !"); + return; + } + gMin->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 + gMin->SetTolerance(0.00001); + gMin->SetPrintLevel(1); + } + + { // 1D + Info("", "---------------- 1D -------------"); + std::array x, y; + for (int nOrder{0}; nOrder <= nMaxOrder; ++nOrder) { + std::vector coeff(nOrder + 1, 0.0); + std::generate(std::begin(coeff), std::end(coeff), getRandom); + + o2::math_utils::Legendre1DPolynominal leg1D(coeff); + + // Optionally find a deformation + if (findMin1D) { + std::vector cccc(nOrder + 2, 0.0); + cccc[0] = nOrder; + for (int iOrder{0}; iOrder <= nOrder; ++iOrder) { + cccc[1 + iOrder] = coeff[iOrder]; + } + + gMin->Clear(); + /* gMin->SetFunction(&leg1D.DoIntegralPar); */ + constexpr double minStep{0.001}; + gMin->SetFixedVariable(0, "c_0", coeff[0]); + for (int iOrder{1}; iOrder <= nOrder; ++iOrder) { + gMin->SetVariable(iOrder, Form("c_%d", iOrder), coeff[iOrder], + minStep); + } + gMin->Minimize(); + auto stat = gMin->Status(); + auto min = gMin->MinValue(); + if ((stat == 0 || stat == 1) && min < 0.01) { + Info("", "Minimizer converged with %f; using new values!", min); + const double* cmins = gMin->X(); + for (int i{0}; i <= nOrder; ++i) { + Info("", "New values are c_%d=%.4f -> %.4f", i, coeff[i], + cmins[1 + i]); + coeff[i] = cmins[1 + i]; + } + } + } + + auto c1d = new TCanvas(Form("c1D_%d", nOrder), + Form("Legendre 1D Order %d", nOrder)); + c1d->Divide(2, 1); + + { // Draw total polynominal + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + x[iPoint] = xcur; + y[iPoint] = leg1D(xcur); + } + c1d->cd(2); + auto g = new TGraph(nPoints, x.data(), y.data()); + g->SetName(Form("g1d_%d", nOrder)); + g->SetTitle(Form("Legendre Polynominal %d-deg;u;w", nOrder)); + g->Draw(); + } + + { // Draw single contributions + auto mg = new TMultiGraph(); + auto leg = new TLegend(); + for (int iOrder{0}; iOrder <= nOrder; ++iOrder) { + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + x[iPoint] = xcur; + y[iPoint] = leg1D(iOrder, xcur); + } + auto g = new TGraph(nPoints, x.data(), y.data()); + g->SetName(Form("g1d_%d_%d", nOrder, iOrder)); + g->SetTitle(Form("c_{%d}=%.4f;u;w", iOrder, coeff[iOrder])); + mg->Add(g, "PL"); + leg->AddEntry(g, Form("c_{%d}=%.4f", iOrder, coeff[iOrder]), "lp"); + } + c1d->cd(1); + mg->SetTitle("Contribution decomposition;u;w"); + mg->Draw("A pmc plc"); + leg->Draw(); + gPad->Update(); + } + } + } + + { // 2D + Info("", "---------------- 2D -------------"); + std::array x, y, z; + for (int nOrder{0}; nOrder <= nMaxOrder; ++nOrder) { + auto c2d = new TCanvas(Form("c2D_%d", nOrder), + Form("Legendre 2D Order %d", nOrder)); + c2d->Divide(nOrder + 1, nOrder + 1); + + TMatrixD coeff(nOrder + 1, nOrder + 1); + // Random initialization + for (int i{0}; i <= nOrder; ++i) { + for (int j{0}; j <= i; ++j) { + coeff(i, j) = getRandom(); + } + } + + o2::math_utils::Legendre2DPolynominal leg2D(coeff); + + // Optionally find a deformation + /* if (findMin2D) { */ + /* std::vector cccc(nOrder + 2, 0.0); */ + /* cccc[0] = nOrder; */ + /* for (int i{0}; i <= nOrder; ++i) { */ + /* for (int j{0}; j <= i; ++j) { */ + /* int k = i * (i + 1) / 2 + j; */ + /* cccc[1 + k] = coeff(i, j); */ + /* } */ + /* } */ + /* auto ig = legendre_poly2D_integral(cccc.data()); */ + + /* gMin->Clear(); */ + /* ROOT::Math::Functor fmin(&legendre_poly2D_integral, */ + /* 2 + nOrder * (nOrder + 1) / 2 + nOrder); */ + /* Info("", "ig=%f parameters=%d", ig, */ + /* 2 + nOrder * (nOrder + 1) / 2 + nOrder); */ + /* gMin->SetFunction(fmin); */ + /* constexpr double minStep{0.001}; */ + /* gMin->SetFixedVariable(0, "nOrder", nOrder); */ + /* gMin->SetFixedVariable(1, "c_00", coeff(0, 0)); */ + /* for (int iOrder{1}; iOrder <= nOrder; ++iOrder) { */ + /* for (int jOrder{0}; jOrder <= iOrder; ++jOrder) { */ + /* int k = iOrder * (iOrder + 1) / 2 + jOrder + 1; */ + /* Info("", "Setting parameter %d", k); */ + /* if (getRandom() < 0.0) { */ + /* gMin->SetFixedVariable(k, Form("c_%d_%d", iOrder, jOrder), */ + /* coeff(iOrder, jOrder)); */ + /* } else { */ + /* gMin->SetVariable(k, Form("c_%d_%d", iOrder, jOrder), */ + /* coeff(iOrder, jOrder), minStep); */ + /* } */ + /* } */ + /* } */ + /* gMin->Minimize(); */ + /* return; */ + /* auto stat = gMin->Status(); */ + /* auto min = gMin->MinValue(); */ + /* if ((stat == 0 || stat == 1) && min < 0.01) { */ + /* Info("", "Minimizer converged with %f; using new values!", min); */ + /* const double *cmins = gMin->X(); */ + /* for (int iOrder{1}; iOrder <= nOrder; ++iOrder) { */ + /* for (int jOrder{0}; jOrder <= iOrder; ++jOrder) { */ + /* int k = iOrder * (iOrder + 1) / 2 + jOrder; */ + /* coeff(iOrder, jOrder) = cmins[k + 1]; */ + /* } */ + /* } */ + /* } */ + /* } */ + + leg2D.printCoefficients(); + + { // Draw total polynominal + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + for (int jPoint{0}; jPoint < nPoints; ++jPoint) { + double ycur = minX + jPoint * stepX; + int i = iPoint * nPoints + jPoint; + x[i] = xcur; + y[i] = ycur; + z[i] = leg2D(xcur, ycur); + } + } + c2d->cd(nOrder + 1); + auto g = new TGraph2D(nPoints2, x.data(), y.data(), z.data()); + g->SetTitle(Form("Legendre Polynominal %d-deg;u;v;w", nOrder)); + g->SetName(Form("g2d_%d", nOrder)); + g->Draw("surf1"); + g->GetXaxis()->SetRangeUser(minX, maxX); + g->GetYaxis()->SetRangeUser(minX, maxX); + gPad->Update(); + } + + { // Draw decomposition of contributions to polynominal + for (int iOrder{0}; iOrder <= nOrder; ++iOrder) { + for (int jOrder{0}; jOrder <= iOrder; ++jOrder) { + for (int iPoint{0}; iPoint < nPoints; ++iPoint) { + double xcur = minX + iPoint * stepX; + for (int jPoint{0}; jPoint < nPoints; ++jPoint) { + double ycur = minX + jPoint * stepX; + int i = iPoint * nPoints + jPoint; + x[i] = xcur; + y[i] = ycur; + z[i] = leg2D(iOrder, jOrder, xcur, ycur); + } + } + c2d->cd(1 + iOrder * (nOrder + 1) + jOrder); + auto g = new TGraph2D(nPoints2, x.data(), y.data(), z.data()); + g->SetTitle(Form("c_{%d,%d}=%.4f;u;v;w", iOrder, jOrder, + coeff(iOrder, jOrder))); + g->SetName(Form("g2d_%d_%d_%d", nOrder, iOrder, jOrder)); + if (iOrder == 0 && jOrder == 0) { // Fix display of constant value + g->Draw("P0"); + } else { + g->Draw("surf1"); + } + g->GetXaxis()->SetRangeUser(minX, maxX); + g->GetYaxis()->SetRangeUser(minX, maxX); + gPad->Update(); + } + } + } + c2d->Draw(); + } + } +} diff --git a/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt b/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt index 095baa0859a6a..bdd0329c55ecd 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt @@ -9,170 +9,20 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_test_root_macro(CheckDigitsITS3.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckClustersITS3.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckTracksITS3.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckDCA.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - O2::Steer - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CreateDictionariesITS3.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(buildMatBudLUT.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckHits.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckDigitsDensity.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckClusterSize.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CompareClusterSize.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckSuperAlpideSegment.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckSuperAlpideSegmentTrans.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CompareClustersAndDigits.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) - -o2_add_test_root_macro(CheckROFs.C - PUBLIC_LINK_LIBRARIES O2::ITSBase - O2::ITS3Base - O2::ITSMFTBase - O2::ITSMFTSimulation - O2::ITS3Simulation - O2::ITS3Reconstruction - O2::MathUtils - O2::SimulationDataFormat - O2::DetectorsBase - LABELS its3 COMPILE_ONLY) +its3_add_macro(CheckDigitsITS3.C) +its3_add_macro(CheckClustersITS3.C) +its3_add_macro(CheckTracksITS3.C) +its3_add_macro(CheckDCA.C) +its3_add_macro(CreateDictionariesITS3.C) +its3_add_macro(buildMatBudLUT.C) +its3_add_macro(CheckHits.C) +its3_add_macro(CheckDigitsDensity.C) +its3_add_macro(CheckClusterSize.C) +its3_add_macro(CompareClusterSize.C) +its3_add_macro(CheckSuperAlpideSegment.C) +its3_add_macro(CheckSuperAlpideSegmentTrans.C) +its3_add_macro(CompareClustersAndDigits.C) +its3_add_macro(CheckROFs.C) +its3_add_macro(CheckTileNumbering.C) +its3_add_macro(CreateITS3StaticDeadMap.C) +its3_add_macro(TestSensorGeometry.C) diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C index 760d21e053549..af03ed7a9877b 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckClustersITS3.C @@ -39,8 +39,11 @@ #include "DetectorsCommonDataFormats/DetectorNameConf.h" #endif -void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hitfile = "o2sim_HitsIT3.root", - std::string inputGeom = "o2sim_geometry.root", std::string dictfile = "ccdb/IT3/Calib/ClusterDictionary/snapshot.root", bool batch = false) +void CheckClustersITS3(const std::string& clusfile = "o2clus_its.root", + const std::string& hitfile = "o2sim_HitsIT3.root", + const std::string& inputGeom = "", + std::string dictfile = "./ccdb/IT3/Calib/ClusterDictionary/snapshot.root", + bool batch = false) { gROOT->SetBatch(batch); @@ -59,7 +62,7 @@ void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hit std::vector hitVecPool; std::vector mc2hitVec; - ULong_t cPattValid{0}, cPattInvalid{0}; + ULong_t cPattValid{0}, cPattInvalid{0}, cLabelInvalid{0}, cNoMC{0}; TFile fout("CheckClusters.root", "recreate"); TNtuple nt("ntc", "cluster ntuple", "ev:lab:hlx:hlz:hgx:hgz:tx:tz:cgx:cgy:cgz:clx:cly:clz:dx:dy:dz:ex:ez:patid:rof:npx:id"); @@ -192,6 +195,7 @@ void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hit const auto& lab = (clusLabArr->getLabels(clEntry))[0]; if (!lab.isValid()) { + ++cLabelInvalid; continue; } @@ -202,7 +206,8 @@ void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hit uint64_t key = (uint64_t(trID) << 32) + chipID; auto hitEntry = mc2hit.find(key); if (hitEntry == mc2hit.end()) { - LOG(error) << "Failed to find MC hit entry for Tr" << trID << " chipID" << chipID; + LOG(debug) << "Failed to find MC hit entry for Tr" << trID << " chipID" << chipID; + ++cNoMC; continue; } const auto& hit = (*hitArray)[hitEntry->second]; @@ -246,10 +251,6 @@ void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hit o2::its3::SuperSegmentations[layer].curvedToFlat(locC.X(), locC.Y(), xFlatSta, yFlatSta); locC.SetXYZ(xFlatSta, yFlatSta, locC.Z()); } - LOGP(debug, "{:*^30}", "START"); - LOGP(debug, "Cluster: X={:.5f} ; Z={:.5f} ; NPix={}", locC.X(), locC.Z(), npix); - LOGP(debug, "Hit : X={:.5f} ; Z={:.5f}", locH.X(), locH.Z()); - LOGP(debug, "{:*^30}", "END"); std::array data = {(float)lab.getEventID(), (float)trID, locH.X(), locH.Z(), @@ -265,6 +266,7 @@ void CheckClustersITS3(std::string clusfile = "o2clus_its.root", std::string hit } LOGP(info, "There were {} valid PatternIDs and {} ({:.1f}%) invalid ones", cPattValid, cPattInvalid, ((float)cPattInvalid / (float)(cPattInvalid + cPattValid)) * 100); + LOGP(info, "There were {} invalid Labels and {} with No MC Hit information ", cLabelInvalid, cNoMC); auto canvCgXCgY = new TCanvas("canvCgXCgY", "", 1600, 1600); canvCgXCgY->Divide(2, 2); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C index 33ac59d69267b..16aa3adc8101c 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C @@ -40,7 +40,7 @@ #include "fairlogger/Logger.h" #endif -void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfile = "o2sim_HitsIT3.root", std::string inputGeom = "o2sim_geometry.root", bool batch = false) +void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfile = "o2sim_HitsIT3.root", std::string inputGeom = "", bool batch = false) { gROOT->SetBatch(batch); gStyle->SetPalette(kRainBow); diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C new file mode 100644 index 0000000000000..3a01960b1859d --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/test/CheckTileNumbering.C @@ -0,0 +1,183 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file CheckTileNumberingITS3.C +/// \brief Macro to quickly check the tile numbering scheme +/// \autor Felix Schlepper felix.schlepper@cern.ch + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ITSBase/GeometryTGeo.h" +#include "ITS3Base/SpecsV2.h" +#include "ITS3Base/SegmentationSuperAlpide.h" +#include "MathUtils/Cartesian.h" +#include "MathUtils/Utils.h" +#include "DataFormatsITSMFT/NoiseMap.h" + +#include +#include +#include +#include +#include +#endif + +constexpr float halfTiles = o2::its3::constants::segment::nTilesPerSegment / 2; +constexpr float halfZ = o2::its3::constants::segment::lengthSensitive / 2.f; + +o2::itsmft::NoiseMap* mNoiseMap{nullptr}; + +void Draw(TH2* in, float phiOff1, float phiOff2, int n = 3) +{ + const int nBinsX = in->GetXaxis()->GetNbins(); + const int nBinsY = in->GetYaxis()->GetNbins(); + + // Create a 2D histogram + TH2F* hChess = new TH2F(Form("%s_chess", in->GetName()), in->GetTitle(), + nBinsX, in->GetXaxis()->GetXmin(), in->GetXaxis()->GetXmax(), + nBinsY, in->GetYaxis()->GetXmin(), in->GetYaxis()->GetXmax()); + + // Loop over all bins and set the content in a chess pattern + for (int i = 1; i <= nBinsX; ++i) { + for (int j = 1; j <= nBinsY; ++j) { + // Alternating pattern: (i+j) % 2 gives 0 or 1 + int content = (((i + j) % 2) == 1) ? 2 : 0; + if (mNoiseMap != nullptr) { + int id = in->GetBinContent(i, j); + if (mNoiseMap->isFullChipMasked(id)) { + content = 1; + } + } + hChess->SetBinContent(i, j, content); + } + } + hChess->GetXaxis()->SetTitle(in->GetXaxis()->GetTitle()); + hChess->GetYaxis()->SetTitle(in->GetYaxis()->GetTitle()); + hChess->GetXaxis()->SetTickLength(0.003); + hChess->GetYaxis()->SetTickLength(0.003); + hChess->GetYaxis()->SetTitleOffset(0.5); + hChess->SetFillColorAlpha(18, 0.6); + hChess->Draw("col"); + + // vertical lines + for (int i{1}; i <= 11; ++i) { + float z = -halfZ + i * o2::its3::constants::rsu::length; + auto l = new TLine(z, phiOff1, z, phiOff2); + l->SetLineStyle(kDashed); + l->Draw("same"); + } + // horizontal lines + float dPhi = (phiOff2 - phiOff1) / (float)n; + for (int i{1}; i < n; ++i) { + float phi = phiOff1 + i * dPhi; + auto l = new TLine(-halfZ, phi, halfZ, phi); + l->SetLineStyle(kDashed); + l->Draw("same"); + } + + in->Draw("TEXT;same"); + gPad->Update(); +} + +void CheckTileNumbering(const std::string& inputGeom = "", const std::string& deadmap = "", bool write = false) +{ + gStyle->SetOptStat(0); + gStyle->SetHistMinimumZero(); + const Int_t NRGBs = 3; + Int_t colors[NRGBs] = {kWhite, kRed, kGray}; + TColor::SetPalette(NRGBs, colors, 1.0); + + const float phiOffsetL0 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[0]); + const float phiOffsetL1 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[1]); + const float phiOffsetL2 = std::asin(o2::its3::constants::equatorialGap / 2.f / o2::its3::constants::radii[2]); + const float markerSize = 0.5; + auto hL0Up = new TH2F("hL0Up", "L0 Upper;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 3, phiOffsetL0, TMath::Pi() - phiOffsetL0); + hL0Up->SetMarkerSize(markerSize); + auto hL0Bot = new TH2F("hL0Bot", "L0 Bottom;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 3, TMath::Pi() + phiOffsetL0, 2 * TMath::Pi() - phiOffsetL0); + hL0Bot->SetMarkerSize(markerSize); + auto hL1Up = new TH2F("hL1Up", "L1 Upper;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 4, phiOffsetL1, TMath::Pi() - phiOffsetL1); + hL1Up->SetMarkerSize(markerSize); + auto hL1Bot = new TH2F("hL1Bot", "L1 Bottom;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 4, TMath::Pi() + phiOffsetL1, 2 * TMath::Pi() - phiOffsetL1); + hL1Bot->SetMarkerSize(markerSize); + auto hL2Up = new TH2F("hL2Up", "L2 Upper;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 5, phiOffsetL2, TMath::Pi() - phiOffsetL2); + hL2Up->SetMarkerSize(markerSize); + auto hL2Bot = new TH2F("hL2Bot", "L2 Bottom;z (cm); #varphi (rad)", halfTiles, -halfZ, halfZ, 2 * 5, TMath::Pi() + phiOffsetL2, 2 * TMath::Pi() - phiOffsetL2); + hL2Bot->SetMarkerSize(markerSize); + std::array hSensors{hL0Up, hL0Bot, hL1Up, hL1Bot, hL2Up, hL2Bot}; + + o2::base::GeometryManager::loadGeometry(inputGeom); + auto gman = o2::its::GeometryTGeo::Instance(); + gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); + + if (!deadmap.empty()) { + std::unique_ptr f{TFile::Open(deadmap.c_str(), "READ")}; + mNoiseMap = f->Get("ccdb_object"); + } + + std::ofstream fs; + if (write) { + fs.open("its3Numbering.txt", std::ios::out); + if (!fs.is_open()) { + Error("", "Cannot open file for writing!"); + write = false; + } + } + + float xFlat{0}, yFlat{0}, x{0}, y{0}, z{0}; + for (unsigned int iDet{0}; iDet <= o2::its3::constants::detID::l2IDEnd; ++iDet) { + int sensorID = o2::its3::constants::detID::getSensorID(iDet); + int layerID = o2::its3::constants::detID::getDetID2Layer(iDet); + o2::its3::SuperSegmentations[layerID].flatToCurved(xFlat, 0., x, y); + o2::math_utils::Point3D locC{x, y, z}; + auto gloC = gman->getMatrixL2G(iDet)(locC); + float phi = o2::math_utils::to02Pi(std::atan2(gloC.Y(), gloC.X())); + /* phi = (phi >= 0) ? phi : (2 * TMath::Pi() + phi); */ + float z = gloC.Z(); + auto xBin = hSensors[sensorID]->GetXaxis()->FindBin(z); + auto yBin = hSensors[sensorID]->GetYaxis()->FindBin(phi); + hSensors[sensorID]->SetBinContent(xBin, yBin, iDet); + if (write) { + fs << std::setfill('0') << std::setw(4) << iDet << " -> Layer " << layerID << " Sensor " << sensorID << " phi=" << phi << " z=" << z << " Path: " << gman->getMatrixPath(iDet) + << "\n"; + } + } + + auto c = new TCanvas("cL0", "Numbering Layer 0", 1000, 700); + c->Divide(1, 2); + c->cd(1); + Draw(hL0Up, phiOffsetL0, TMath::Pi() - phiOffsetL0, 3); + c->cd(2); + Draw(hL0Bot, TMath::Pi() + phiOffsetL0, 2 * TMath::Pi() - phiOffsetL0, 3); + c->SaveAs("its3_tile_layer0.pdf"); + + c = new TCanvas("cL1", "Numbering Layer 1", 1000, 700); + c->Divide(1, 2); + c->cd(1); + Draw(hL1Up, phiOffsetL1, TMath::Pi() - phiOffsetL1, 4); + c->cd(2); + Draw(hL1Bot, TMath::Pi() + phiOffsetL1, 2 * TMath::Pi() - phiOffsetL1, 4); + c->SaveAs("its3_tile_layer1.pdf"); + + c = new TCanvas("cL2", "Numbering Layer 2", 1000, 700); + c->Divide(1, 2); + c->cd(1); + Draw(hL2Up, phiOffsetL2, TMath::Pi() - phiOffsetL2, 5); + c->cd(2); + Draw(hL2Bot, TMath::Pi() + phiOffsetL2, 2 * TMath::Pi() - phiOffsetL2, 5); + c->SaveAs("its3_tile_layer2.pdf"); +} diff --git a/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C b/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C index 4b502a16b2305..5c084e443bd07 100644 --- a/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C +++ b/Detectors/Upgrades/ITS3/macros/test/CheckTracksITS3.C @@ -74,7 +74,7 @@ void CheckTracksITS3(const std::string& tracfile = "o2trac_its.root", const std::string& clusfile = "o2clus_its.root", const std::string& kinefile = "o2sim_Kine.root", const std::string& magfile = "o2sim_grp.root", - const std::string& inputGeom = "o2sim_geometry.root", + const std::string& inputGeom = "", bool batch = false) { gROOT->SetBatch(batch); @@ -154,8 +154,9 @@ void CheckTracksITS3(const std::string& tracfile = "o2trac_its.root", for (unsigned int iClus{0}; iClus < clssize; ++iClus) { auto lab = (clusLabArr->getLabels(iClus))[0]; - if (!lab.isValid() || lab.getSourceID() != 0 || !lab.isCorrect()) + if (!lab.isValid() || lab.getSourceID() != 0 || !lab.isCorrect()) { continue; + } int trackID, evID, srcID; bool fake; @@ -354,12 +355,12 @@ void CheckTracksITS3(const std::string& tracfile = "o2trac_its.root", h_phi_eff->SetTotalHistogram(*h_phi_den, ""); h_phi_eff->SetPassedHistogram(*h_phi_num, ""); - h_phi_eff->SetTitle("Tracking Efficiency;#it{#eta};Eff."); + h_phi_eff->SetTitle("Tracking Efficiency;#varphi;Eff."); h_phi_eff->Write(); h_eta_eff->SetTotalHistogram(*h_eta_den, ""); h_eta_eff->SetPassedHistogram(*h_eta_num, ""); - h_eta_eff->SetTitle("Tracking Efficiency;#varphi;Eff."); + h_eta_eff->SetTitle("Tracking Efficiency;#it{#eta};Eff."); h_eta_eff->Write(); file.Close(); diff --git a/Detectors/Upgrades/ITS3/macros/test/CreateITS3StaticDeadMap.C b/Detectors/Upgrades/ITS3/macros/test/CreateITS3StaticDeadMap.C new file mode 100644 index 0000000000000..b77ae100b4a6c --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/test/CreateITS3StaticDeadMap.C @@ -0,0 +1,79 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file CreateITS3StaticDeadMap.C +/// \brief Macro to create a static dead channel map for ITS3 from a file + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TFile.h" +#include "TError.h" + +#include "DataFormatsITSMFT/NoiseMap.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +// Read in a file called 'input.txt' output a corresponding static dead map. +// File - Layout example +// ```````````````````` input.txt start +// 0 +// 1,2,3 +// 5,5 +// 2, +// ```````````````````` input.txt end +void CreateITS3StaticDeadMap(const std::string& filename = "input.txt") +{ + constexpr int nChips{27144}; + o2::itsmft::NoiseMap map{nChips}; + + std::set intSet; + std::ifstream infile(filename); + + if (!infile) { + Error("", "Failed to open file %s", filename.c_str()); + return; + } + + using std::operator""sv; + constexpr auto delim{","sv}; + + std::string line; + while (std::getline(infile, line)) { + std::stringstream ss(line); + for (const auto& item : line | + std::views::split(delim) | + std::views::filter([](const auto& str) { + return !str.empty(); + }) | + std::views::transform([](const auto&& str) { + return std::string(str.begin(), str.end()); + })) { + auto tile = std::stoi(item); + Info("", "Disabling tile %d", tile); + intSet.insert(std::stoi(item)); + } + } + + for (const auto& iChip : intSet) { + map.maskFullChip(iChip); + } + + std::unique_ptr f{TFile::Open("snapshot.root", "RECREATE")}; + f->WriteObjectAny(&map, "o2::itsmft::NoiseMap", "ccdb_object"); +} diff --git a/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C new file mode 100644 index 0000000000000..1a0ec73e34f31 --- /dev/null +++ b/Detectors/Upgrades/ITS3/macros/test/TestSensorGeometry.C @@ -0,0 +1,56 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Framework/Logger.h" +#include "ITS3Base/SpecsV2.h" +#include "ITS3Simulation/ITS3Layer.h" + +#include "TFile.h" +#include "TGeoManager.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TList.h" +#endif + +void TestSensorGeometry(bool checkFull = false) +{ + gGeoManager = new TGeoManager("simple", "Simple geometry"); + TGeoMaterial* matVacuum = new TGeoMaterial("Vacuum", 0, 0, 0); + TGeoMedium* Vacuum = new TGeoMedium("Vacuum", 1, matVacuum); + + auto top = gGeoManager->MakeBox("TOP", Vacuum, 270., 270., 120.); + gGeoManager->SetTopVolume(top); + + o2::its3::ITS3Layer layer0{0, top, nullptr, + o2::its3::ITS3Layer::BuildLevel::kLayer, true}; + + // Print available medias + TIter next{gGeoManager->GetListOfMedia()}; + TObject* obj; + while ((obj = (TObject*)next())) { + LOGP(info, "Media {}", obj->GetName()); + } + + gGeoManager->CloseGeometry(); + gGeoManager->SetVisLevel(99); + if (checkFull) { + gGeoManager->CheckGeometryFull(); + } + gGeoManager->CheckOverlaps(0.0001); + TIter nextOverlap{gGeoManager->GetListOfOverlaps()}; + while ((obj = (TObject*)nextOverlap())) { + LOGP(info, "Overlap in {}", obj->GetName()); + } + + std::unique_ptr f{TFile::Open("geo.root", "RECREATE")}; + f->WriteTObject(gGeoManager, "geometry"); +} diff --git a/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt b/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt index 76752f95ec26d..128e145b31317 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt @@ -10,7 +10,7 @@ # or submit itself to any jurisdiction. # -#add_compile_options(-O0 -g -fPIC -fno-omit-frame-pointer) +# add_compile_options(-O0 -g -fPIC -fno-omit-frame-pointer) o2_add_library(ITS3Reconstruction TARGETVARNAME targetName diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h index 949cd89f4b52f..2407344aa0193 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/IOUtils.h @@ -49,6 +49,22 @@ o2::math_utils::Point3D extractClusterData(const itsmft::CompClusterExt& c, i } } +template +o2::math_utils::Point3D extractClusterData(const itsmft::CompClusterExt& c, iterator& iter, const its3::TopologyDictionary* dict, T& sig2y, T& sig2z, uint8_t& cls) +{ + auto pattID = c.getPatternID(); + auto iterC = iter; + unsigned int clusterSize{999}; + if (pattID == itsmft::CompCluster::InvalidPatternID || dict->isGroup(pattID)) { + o2::itsmft::ClusterPattern patt(iterC); + clusterSize = patt.getNPixels(); + } else { + clusterSize = dict->getNpixels(pattID); + } + cls = static_cast(std::clamp(clusterSize, static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max()))); + return extractClusterData(c, iter, dict, sig2y, sig2z); +} + void convertCompactClusters(gsl::span clusters, gsl::span::iterator& pattIt, std::vector>& output, diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx index 2f080d28a8600..87ad450eecd9e 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/BuildTopologyDictionary.cxx @@ -36,6 +36,8 @@ void BuildTopologyDictionary::accountTopology(const itsmft::ClusterTopology& clu //___________________DEFINING_TOPOLOGY_CHARACTERISTICS__________________ itsmft::TopologyInfo topInf; topInf.mPattern.setPattern(cluster.getPattern().data()); + topInf.mSizeX = cluster.getRowSpan(); + topInf.mSizeZ = cluster.getColumnSpan(); //__________________COG_Determination_____________ topInf.mNpixels = cluster.getClusterPattern().getCOG(topInf.mCOGx, topInf.mCOGz); if (useDf) { diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx index 5259570e0fe1d..90f5245bcef58 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/Clusterer.cxx @@ -177,7 +177,6 @@ void Clusterer::ClustererThread::process(uint16_t chip, uint16_t nChips, CompClu } auto validPixID = curChipData->getFirstUnmasked(); auto npix = curChipData->getData().size(); - LOGP(debug, "ClustererThread: Chip={} npix={} validPixID={} -> valid={} -> singleHit={}", chipID, npix, validPixID, validPixID < npix, validPixID + 1 == npix); if (validPixID < npix) { // chip data may have all of its pixels masked! auto valp = validPixID++; if (validPixID == npix) { // special case of a single pixel fired on the chip diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx index 12f28c8783d75..f4cf31deb1ef8 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx @@ -22,6 +22,8 @@ #include "ITStracking/TrackingConfigParam.h" #include "Framework/Logger.h" +#include + namespace o2::its3::ioutils { @@ -44,9 +46,11 @@ void convertCompactClusters(gsl::span clusters, for (auto& c : clusters) { float sigmaY2, sigmaZ2, sigmaYZ = 0; auto locXYZ = extractClusterData(c, pattIt, dict, sigmaY2, sigmaZ2); - auto& cl3d = output.emplace_back(c.getSensorID(), geom->getMatrixT2L(c.getSensorID()) ^ locXYZ); // local --> tracking + const auto detID = c.getSensorID(); + auto& cl3d = output.emplace_back(detID, + (its3::constants::detID::isDetITS3(detID) ? geom->getT2LMatrixITS3(detID, geom->getSensorRefAlpha(detID)) : geom->getMatrixT2L(detID)) ^ locXYZ); // local --> tracking if (applyMisalignment) { - auto lrID = geom->getLayer(c.getSensorID()); + auto lrID = geom->getLayer(detID); sigmaY2 += conf.sysErrY2[lrID]; sigmaZ2 += conf.sysErrZ2[lrID]; } @@ -61,7 +65,7 @@ int loadROFrameDataITS3(its::TimeFrame* tf, const its3::TopologyDictionary* dict, const dataformats::MCTruthContainer* mcLabels) { - its::GeometryTGeo* geom = its::GeometryTGeo::Instance(); + auto geom = its::GeometryTGeo::Instance(); geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); tf->mNrof = 0; @@ -78,19 +82,9 @@ int loadROFrameDataITS3(its::TimeFrame* tf, auto pattID = c.getPatternID(); float sigmaY2{0}, sigmaZ2{0}, sigmaYZ{0}; - auto locXYZ = extractClusterData(c, pattIt, dict, sigmaY2, sigmaZ2); - - unsigned int clusterSize{0}; - if (pattID == itsmft::CompCluster::InvalidPatternID || dict->isGroup(pattID)) { - // TODO FIX - // o2::itsmft::ClusterPattern patt; - // patt.acquirePattern(pattIt); - // clusterSize = patt.getNPixels(); - clusterSize = 0; - } else { - clusterSize = dict->getNpixels(pattID); - } - clusterSizeVec.push_back(std::clamp(clusterSize, 0u, 255u)); + uint8_t clusterSize{0}; + auto locXYZ = extractClusterData(c, pattIt, dict, sigmaY2, sigmaZ2, clusterSize); + clusterSizeVec.push_back(clusterSize); // Transformation to the local --> global auto gloXYZ = geom->getMatrixL2G(sensorID) * locXYZ; diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h index fdf10a69413dc..80536a14d99c2 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/DescriptorInnerBarrelITS3.h @@ -47,7 +47,7 @@ class DescriptorInnerBarrelITS3 : public o2::its::DescriptorInnerBarrel // wrapper volume properties double mWrapperMinRadiusITS3{1.8}; double mWrapperMaxRadiusITS3{4.}; - double mWrapperZSpanITS3{50}; + double mWrapperZSpanITS3{20.}; private: std::array, constants::nLayers> mIBLayers; @@ -58,4 +58,4 @@ class DescriptorInnerBarrelITS3 : public o2::its::DescriptorInnerBarrel } // namespace o2::its3 -#endif \ No newline at end of file +#endif diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h index 49afd1202088c..7ece842b6f61f 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/Digitizer.h @@ -76,6 +76,8 @@ class Digitizer : public TObject mEventROFrameMax = 0; } + void setDeadChannelsMap(const o2::itsmft::NoiseMap* mp) { mDeadChanMap = mp; } + private: void processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID, int srcID); void registerDigits(o2::itsmft::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF, @@ -108,7 +110,7 @@ class Digitizer : public TObject o2::itsmft::AlpideSimResponse* mAlpSimResp = nullptr; // simulated response - const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS OR MFT upgrade geometry + const o2::its::GeometryTGeo* mGeometry = nullptr; ///< ITS3 geometry std::vector mChips; ///< Array of chips digits containers std::deque> mExtraBuff; ///< burrer (per roFrame) for extra digits @@ -117,6 +119,8 @@ class Digitizer : public TObject std::vector* mROFRecords = nullptr; //! output ROF records o2::dataformats::MCTruthContainer* mMCLabels = nullptr; //! output labels + const o2::itsmft::NoiseMap* mDeadChanMap = nullptr; + ClassDef(Digitizer, 4); }; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h index 140417d396421..7543650e04a71 100644 --- a/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h +++ b/Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ITS3Layer.h @@ -20,7 +20,8 @@ #include #include -#include "fairlogger/Logger.h" +#include "Framework/Logger.h" +#include namespace o2::its3 { @@ -39,20 +40,7 @@ class ITS3Layer // HalfBarrel CarbonForm // Layer Layer public: - ITS3Layer(int layer = 0) : mNLayer(layer) - { - LOGP(info, "Called on {} layer {}", layer, mNLayer); - } - - ITS3Layer(TGeoVolume* motherVolume, int layer = 0) : ITS3Layer(layer) - { - createLayer(motherVolume); - } - - // Create one layer of ITS3 and attach it to the motherVolume. - void createLayer(TGeoVolume* motherVolume); - - enum BuildLevel : uint8_t { + enum class BuildLevel : uint8_t { kPixelArray = 0, kTile, kRSU, @@ -62,14 +50,40 @@ class ITS3Layer kLayer, kAll, }; + static constexpr std::array(BuildLevel::kAll)> mNames{"PixelArray", "Tile", "RSU", "Segment", "CarbonForm", "Chip", "Layer"}; + static std::string_view getName(BuildLevel b) + { + return mNames[static_cast((b == BuildLevel::kAll) ? BuildLevel::kLayer : b)]; + } + explicit ITS3Layer(int layer = 0) : mNLayer(layer) + { + LOGP(debug, "Called on {} layer {}", layer, mNLayer); + init(); + } + + explicit ITS3Layer(TGeoVolume* motherVolume, int layer = 0) : ITS3Layer(layer) + { + createLayer(motherVolume); + } + + explicit ITS3Layer(int layer, TGeoVolume* motherVolume, TGeoMatrix* mat = nullptr, BuildLevel level = BuildLevel::kAll, bool createMaterials = false) : ITS3Layer(layer) + { + buildPartial(motherVolume, mat, level, createMaterials); + } + + // Create one layer of ITS3 and attach it to the motherVolume. + void createLayer(TGeoVolume* motherVolume); // Build a partial Version of the detector. - void buildPartial(TGeoVolume* motherVolume, TGeoMatrix* mat = nullptr, BuildLevel level = kAll); + void buildPartial(TGeoVolume* motherVolume, TGeoMatrix* mat = nullptr, BuildLevel level = BuildLevel::kAll, bool createMaterials = false); private: + bool mBuilt{false}; TGeoMedium* mSilicon{nullptr}; TGeoMedium* mAir{nullptr}; TGeoMedium* mCarbon{nullptr}; + void getMaterials(bool create = false); + TGeoMedium* getMaterial(const char* matName, bool create = false); void init(); void createPixelArray(); @@ -95,7 +109,7 @@ class ITS3Layer TGeoVolumeAssembly* mCarbonForm{nullptr}; TGeoVolumeAssembly* mLayer{nullptr}; - ClassDef(ITS3Layer, 1); + ClassDef(ITS3Layer, 2); }; } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx index 758c023d26ee6..f1519c1d04063 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/Digitizer.cxx @@ -18,11 +18,11 @@ #include "SimulationDataFormat/MCTruthContainer.h" #include "DetectorsRaw/HBFUtils.h" #include "ITS3Base/SpecsV2.h" +#include "Framework/Logger.h" #include #include #include -#include // for LOG using o2::itsmft::Hit; using Segmentation = o2::itsmft::SegmentationAlpide; @@ -38,6 +38,10 @@ void Digitizer::init() mChips.resize(numOfChips); for (int i = numOfChips; i--;) { mChips[i].setChipIndex(i); + if (mDeadChanMap != nullptr) { + mChips[i].disable(mDeadChanMap->isFullChipMasked(i)); + mChips[i].setDeadChanMap(mDeadChanMap); + } } if (mParams.getAlpSimResponse() == nullptr) { @@ -190,10 +194,9 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID // convert single hit to digits int chipID = hit.GetDetectorID(); auto& chip = mChips[chipID]; - // if (chip.isDisabled()) { // right now we do not have 'dead' chips - // LOG(debug) << "skip disabled chip " << chipID; - // return; - // } + if (chip.isDisabled()) { + return; + } float timeInROF = hit.GetTime() * sec2ns; if (timeInROF > 20e3) { const int maxWarn = 10; diff --git a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx index c384d42c155fc..26e47e03057c2 100644 --- a/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx +++ b/Detectors/Upgrades/ITS3/simulation/src/ITS3Layer.cxx @@ -33,61 +33,69 @@ using its3TGeo = o2::its::GeometryTGeo; void ITS3Layer::init() { - // First we start by creating variables which we are reusing a couple of times. mR = its3c::radii[mNLayer]; - mRmin = mR - its3c::thickness / 2.; - mRmax = mR + its3c::thickness / 2.; + mRmin = its3c::radiiInner[mNLayer]; + mRmax = its3c::radiiOuter[mNLayer]; +} +void ITS3Layer::getMaterials(bool create) +{ if (gGeoManager == nullptr) { LOGP(fatal, "gGeoManager not initalized!"); } - mSilicon = gGeoManager->GetMedium("IT3_SI$"); - if (mSilicon == nullptr) { - LOGP(fatal, "IT3_SI$ == nullptr!"); - } - - mAir = gGeoManager->GetMedium("IT3_AIR$"); - if (mAir == nullptr) { - LOGP(fatal, "IT3_AIR$ == nullptr!"); - } + mSilicon = getMaterial("IT3_SI$", create); + mAir = getMaterial("IT3_AIR$", create); + mCarbon = getMaterial("IT3_CARBON$", create); +} - mCarbon = gGeoManager->GetMedium("IT3_CARBON$"); - if (mCarbon == nullptr) { - LOGP(fatal, "IT3_CARBON$ == nullptr!"); +TGeoMedium* ITS3Layer::getMaterial(const char* matName, bool create) +{ + auto mat = gGeoManager->GetMedium(matName); + if (mat == nullptr) { + if (!create) { + LOGP(fatal, "Cannot get medium {}", matName); + } else { // create dummy + auto matDummy = gGeoManager->GetMaterial("MAT_DUMMY$"); + if (matDummy == nullptr) { + LOGP(info, "Created Dummy material"); + matDummy = new TGeoMaterial("MAT_DUMMY$", 26.98, 13, 2.7); + } + mat = new TGeoMedium(matName, 1, matDummy); + LOGP(info, "Created medium {}", matName); + } } + return mat; } void ITS3Layer::createLayer(TGeoVolume* motherVolume) { // Create one layer of ITS3 and attach it to the motherVolume. - init(); - createPixelArray(); - createTile(); - createRSU(); - createSegment(); - createChip(); - createCarbonForm(); + getMaterials(); createLayerImpl(); + mBuilt = true; LOGP(info, "ITS3-Layer: Created Layer {} with mR={} (minR={}, maxR={})", mNLayer, mR, mRmin, mRmax); if (motherVolume == nullptr) { return; } // Add it to motherVolume - LOGP(info, " `-> Attaching to motherVolume '{}'", motherVolume->GetName()); + LOGP(debug, " `-> Attaching to motherVolume '{}'", motherVolume->GetName()); auto* trans = new TGeoTranslation(0, 0, -constants::segment::lengthSensitive / 2.); motherVolume->AddNode(mLayer, 0, trans); } void ITS3Layer::createPixelArray() { - using namespace its3c::pixelarray; + if (mPixelArray != nullptr) { + return; + } // A pixel array is pure silicon and the sensitive part of our detector. // It will be segmented into a 442x156 matrix by the // SuperSegmentationAlpide. // Pixel Array is just a longer version of the biasing but starts in phi at // biasPhi2. + using namespace its3c::pixelarray; double pixelArrayPhi1 = constants::tile::readout::width / mR * o2m::Rad2Deg; double pixelArrayPhi2 = width / mR * o2m::Rad2Deg + pixelArrayPhi1; auto pixelArray = new TGeoTubeSeg(mRmin, mRmax, length / 2., @@ -99,11 +107,16 @@ void ITS3Layer::createPixelArray() void ITS3Layer::createTile() { - using namespace constants::tile; + if (mTile != nullptr) { + return; + } else { + createPixelArray(); + } // This functions creates a single Tile, which is the basic building block // of the chip. It consists of a pixelArray (sensitive area), biasing, power // switches and readout periphery (latter three are insensitive). // We construct the Tile such that the PixelArray is in the z-middle + using namespace constants::tile; mTile = new TGeoVolumeAssembly(its3TGeo::getITS3TilePattern(mNLayer)); mTile->VisibleDaughters(); @@ -143,8 +156,13 @@ void ITS3Layer::createTile() void ITS3Layer::createRSU() { - using namespace constants::rsu; + if (mRSU != nullptr) { + return; + } else { + createTile(); + } // A Repeated Sensor Unit (RSU) is 12 Tiles + 4 Databackbones stichted together. + using namespace constants::rsu; mRSU = new TGeoVolumeAssembly(its3TGeo::getITS3RSUPattern(mNLayer)); mRSU->VisibleDaughters(); int nCopyRSU{0}, nCopyDB{0}; @@ -208,10 +226,15 @@ void ITS3Layer::createRSU() void ITS3Layer::createSegment() { - using namespace constants::segment; + if (mSegment != nullptr) { + return; + } else { + createRSU(); + } // A segment is 12 RSUs + left and right end cap. We place the first rsu // as z-coordinate center and attach to this. Hence, we will displace the // left end-cap to the left and the right to right. + using namespace constants::segment; mSegment = new TGeoVolumeAssembly(its3TGeo::getITS3SegmentPattern(mNLayer)); mSegment->VisibleDaughters(); @@ -243,7 +266,11 @@ void ITS3Layer::createSegment() void ITS3Layer::createChip() { - + if (mChip != nullptr) { + return; + } else { + createSegment(); + } // A HalfLayer is composed out of multiple segment stitched together along // rphi. mChip = new TGeoVolumeAssembly(its3TGeo::getITS3ChipPattern(mNLayer)); @@ -258,6 +285,11 @@ void ITS3Layer::createChip() void ITS3Layer::createCarbonForm() { + if (mCarbonForm != nullptr) { + return; + } else { + createChip(); + } // TODO : Waiting for the further information from WP5(Corrado) using namespace constants::carbonfoam; mCarbonForm = new TGeoVolumeAssembly(its3TGeo::getITS3CarbonFormPattern(mNLayer)); @@ -325,6 +357,11 @@ TGeoCompositeShape* ITS3Layer::getHringShape(TGeoTubeSeg* Hring) void ITS3Layer::createLayerImpl() { + if (mLayer != nullptr) { + return; + } else { + createCarbonForm(); + } // At long last a single layer... A layer is two HalfLayers (duuhhh) but // we have to take care of the equatorial gap. So both half layers will be // offset slightly by rotating in phi the upper HalfLayer and negative phi @@ -342,32 +379,43 @@ void ITS3Layer::createLayerImpl() mLayer->AddNode(mCarbonForm, 1, rotBot); } -void ITS3Layer::buildPartial(TGeoVolume* motherVolume, TGeoMatrix* mat, BuildLevel level) +void ITS3Layer::buildPartial(TGeoVolume* motherVolume, TGeoMatrix* mat, BuildLevel level, bool createMaterials) { + if (!mBuilt) { + getMaterials(createMaterials); + } switch (level) { - case kPixelArray: + case BuildLevel::kPixelArray: + createPixelArray(); motherVolume->AddNode(mPixelArray, 0, mat); break; - case kTile: + case BuildLevel::kTile: + createTile(); motherVolume->AddNode(mTile, 0, mat); break; - case kRSU: + case BuildLevel::kRSU: + createRSU(); motherVolume->AddNode(mRSU, 0, mat); break; - case kSegment: + case BuildLevel::kSegment: + createSegment(); motherVolume->AddNode(mSegment, 0, mat); break; - case kChip: + case BuildLevel::kChip: + createChip(); motherVolume->AddNode(mChip, 0, mat); break; - case kCarbonForm: + case BuildLevel::kCarbonForm: + createCarbonForm(); motherVolume->AddNode(mCarbonForm, 0, mat); break; - case kLayer: + case BuildLevel::kLayer: [[fallthrough]]; default: + createLayerImpl(); motherVolume->AddNode(mLayer, 0, mat); } + LOGP(info, "Partially built ITS3-{}-{}", mNLayer, getName(level)); } } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt b/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt index d08c83cc0d73b..c4867f0e94ec1 100644 --- a/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt @@ -9,6 +9,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +# add_compile_options(-O0 -g -fPIC -fno-omit-frame-pointer) + o2_add_library(ITS3Workflow SOURCES src/DigitReaderSpec.cxx src/DigitWriterSpec.cxx @@ -31,8 +33,7 @@ o2_add_library(ITS3Workflow O2::ITS3Reconstruction O2::ITSWorkflow O2::GPUTracking - O2::ITSBase -) + O2::ITSBase) # o2_add_executable(digit-writer-workflow # SOURCES src/digit-writer-workflow.cxx @@ -57,4 +58,4 @@ o2_add_executable(reco-workflow # o2_add_executable(cluster-reader-workflow # SOURCES src/its-cluster-reader-workflow.cxx # COMPONENT_NAME its -# PUBLIC_LINK_LIBRARIES O2::ITSWorkflow) \ No newline at end of file +# PUBLIC_LINK_LIBRARIES O2::ITSWorkflow) diff --git a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h index 525707b77a5f8..f350c09b0192c 100644 --- a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h +++ b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h @@ -44,7 +44,7 @@ class TrackerDPL : public framework::Task void run(framework::ProcessingContext& pc) final; void endOfStream(framework::EndOfStreamContext& ec) final; void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final; - void setClusterDictionary(o2::its3::TopologyDictionary* d) { mDict = d; } + void setClusterDictionary(const o2::its3::TopologyDictionary* d) { mDict = d; } private: void updateTimeDependentParams(framework::ProcessingContext& pc); @@ -56,7 +56,7 @@ class TrackerDPL : public framework::Task std::unique_ptr mRecChain{}; bool mRunVertexer{true}; bool mCosmicsProcessing{false}; - o2::its3::TopologyDictionary* mDict{}; + const o2::its3::TopologyDictionary* mDict{}; std::unique_ptr mChainITS{}; std::unique_ptr mTracker{}; std::unique_ptr mVertexer{}; diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx index 24400e26eb2e2..856c806e74247 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackWriterSpec.cxx @@ -46,9 +46,10 @@ DataProcessorSpec getTrackWriterSpec(bool useMC) auto logger = [tracksSize](std::vector const& rofs) { LOG(info) << "ITS3TrackWriter pulled " << *tracksSize << " tracks, in " << rofs.size() << " RO frames"; }; - return MakeRootTreeWriterSpec("its-track-writer", + // NOTE: We name the branches as ITS and not IT3 to ensure matching works. + return MakeRootTreeWriterSpec("its3-track-writer", "o2trac_its.root", - MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with IT3 tracks"}, + MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with ITS3 tracks"}, BranchDefinition>{InputSpec{"tracks", "ITS", "TRACKS", 0}, "ITSTrack", tracksSizeGetter}, diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx index 939925b26a687..cc0cbcf333dd3 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx @@ -73,8 +73,27 @@ void TrackerDPL::init(InitContext& /*ic*/) trackParams[2].TrackletMinPt = 0.1f; trackParams[2].CellDeltaTanLambdaSigma *= 4.; trackParams[2].MinTrackLength = 4; + LOG(info) << "Initializing tracker in async. phase reconstruction with " << trackParams.size() << " passes"; + } else if (mMode == "async_misaligned") { + + trackParams.resize(3); + trackParams[0].PhiBins = 32; + trackParams[0].ZBins = 64; + trackParams[0].CellDeltaTanLambdaSigma *= 3.; + trackParams[0].SystErrorZ2[0] = 1.e-4; + trackParams[0].SystErrorZ2[1] = 1.e-4; + trackParams[0].SystErrorZ2[2] = 1.e-4; + std::copy(trackParams[0].SystErrorZ2.begin(), trackParams[0].SystErrorZ2.end(), trackParams[0].SystErrorY2.begin()); + trackParams[0].MaxChi2ClusterAttachment = 60.; + trackParams[0].MaxChi2NDF = 40.; + trackParams[1] = trackParams[0]; + trackParams[2] = trackParams[0]; + trackParams[1].MinTrackLength = 6; + trackParams[2].MinTrackLength = 4; + LOG(info) << "Initializing tracker in misaligned async. phase reconstruction with " << trackParams.size() << " passes"; + } else if (mMode == "sync_misaligned") { trackParams.resize(3); @@ -193,11 +212,10 @@ void TrackerDPL::run(ProcessingContext& pc) mTracker->setBz(o2::base::Propagator::Instance()->getNominalBz()); mVertexer->adoptTimeFrame(*timeFrame); - gsl::span::iterator pattIt = patterns.begin(); + auto pattIt = patterns.begin(); - gsl::span rofspan(rofs); + const gsl::span rofspan(rofs); ioutils::loadROFrameDataITS3(timeFrame, rofspan, compClusters, pattIt, mDict, labels); - pattIt = patterns.begin(); std::vector savedROF; auto logger = [&](const std::string& s) { LOG(info) << s; }; auto errorLogger = [&](const std::string& s) { LOG(error) << s; }; @@ -405,6 +423,7 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, co inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "VERTICESMCTR", 0, Lifetime::Timeframe); + outputs.emplace_back("ITS", "VERTICESMCPUR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe); } diff --git a/Steer/DigitizerWorkflow/CMakeLists.txt b/Steer/DigitizerWorkflow/CMakeLists.txt index fce6103573609..00ed662a75d39 100644 --- a/Steer/DigitizerWorkflow/CMakeLists.txt +++ b/Steer/DigitizerWorkflow/CMakeLists.txt @@ -19,7 +19,6 @@ o2_add_executable(digitizer-workflow src/GRPUpdaterSpec.cxx src/HMPIDDigitizerSpec.cxx src/ITSMFTDigitizerSpec.cxx - src/ITS3DigitizerSpec.cxx src/MCHDigitizerSpec.cxx src/MIDDigitizerSpec.cxx src/PHOSDigitizerSpec.cxx @@ -30,6 +29,7 @@ o2_add_executable(digitizer-workflow src/TPCDigitizerSpec.cxx src/ZDCDigitizerSpec.cxx src/TOFDigitizerSpec.cxx + $<$:src/ITS3DigitizerSpec.cxx> PUBLIC_LINK_LIBRARIES O2::Framework O2::Steer O2::CommonConstants @@ -65,9 +65,9 @@ o2_add_executable(digitizer-workflow O2::ZDCSimulation O2::ZDCWorkflow O2::DetectorsRaw - O2::ITS3Simulation - O2::ITS3Workflow - ) + $<$:O2::ITS3Simulation> + $<$:O2::ITS3Workflow> + $<$:O2::ITS3Align>) else() o2_add_executable(digitizer-workflow COMPONENT_NAME sim diff --git a/Steer/DigitizerWorkflow/src/ITS3DigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/ITS3DigitizerSpec.cxx index 6a8bbab76de7b..27f876f7bc24b 100644 --- a/Steer/DigitizerWorkflow/src/ITS3DigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/ITS3DigitizerSpec.cxx @@ -17,7 +17,7 @@ #include "Framework/DataRefUtils.h" #include "Framework/Lifetime.h" #include "Framework/Task.h" -#include "Steer/HitProcessingManager.h" // for DigitizationContext +#include "Steer/HitProcessingManager.h" #include "DataFormatsITSMFT/Digit.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "DetectorsBase/BaseDPLDigitizer.h" @@ -29,8 +29,12 @@ #include "ITSMFTSimulation/DPLDigitizerParam.h" #include "ITSMFTBase/DPLAlpideParam.h" #include "ITSBase/GeometryTGeo.h" +#include "ITS3Base/ITS3Params.h" +#include "ITS3Align/MisalignmentManager.h" + #include #include + #include using namespace o2::framework; @@ -73,6 +77,12 @@ class ITS3DPLDigitizerTask : BaseDPLDigitizer return; } updateTimeDependentParams(pc); + + if (ITS3Params::Instance().applyMisalignmentHits) { + LOGP(info, "Applying misalignment to ITS3 Hits"); + o2::its3::align::MisalignmentManager::misalignHits(); + } + // read collision context from input auto context = pc.inputs().get("collisioncontext"); context->initSimChains(mID, mSimChains); @@ -233,6 +243,10 @@ class ITS3DPLDigitizerTask : BaseDPLDigitizer << ((mROMode == o2::parameters::GRPObject::CONTINUOUS) ? "CONTINUOUS" : "TRIGGERED") << " RO mode"; + if (o2::its3::ITS3Params::Instance().useDeadChannelMap) { + pc.inputs().get("IT3_dead"); // trigger final ccdb update + } + // init digitizer mDigitizer.init(); } @@ -247,6 +261,11 @@ class ITS3DPLDigitizerTask : BaseDPLDigitizer par.printKeyValues(); return; } + if (matcher == ConcreteDataMatcher(mOrigin, "DEADMAP", 0)) { + LOG(info) << mID.getName() << " static dead map updated"; + mDigitizer.setDeadChannelsMap((o2::itsmft::NoiseMap*)obj); + return; + } } private: @@ -254,13 +273,13 @@ class ITS3DPLDigitizerTask : BaseDPLDigitizer bool mFinished{false}; bool mDisableQED{false}; const o2::detectors::DetID mID{o2::detectors::DetID::IT3}; - o2::header::DataOrigin mOrigin{o2::header::gDataOriginIT3}; + const o2::header::DataOrigin mOrigin{o2::header::gDataOriginIT3}; o2::its3::Digitizer mDigitizer{}; std::vector mDigits{}; std::vector mROFRecords{}; std::vector mROFRecordsAccum{}; std::vector mHits{}; - std::vector* mHitsP = &mHits; + std::vector* mHitsP{&mHits}; o2::dataformats::MCTruthContainer mLabels{}; o2::dataformats::MCTruthContainer mLabelsAccum{}; std::vector mMC2ROFRecordsAccum{}; @@ -277,12 +296,14 @@ DataProcessorSpec getITS3DigitizerSpec(int channel, bool mctruth) std::vector inputs; inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe); inputs.emplace_back("ITS_alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")); + if (o2::its3::ITS3Params::Instance().useDeadChannelMap) { + inputs.emplace_back("IT3_dead", "IT3", "DEADMAP", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/DeadMap")); + } return DataProcessorSpec{detStr + "Digitizer", inputs, makeOutChannels(detOrig, mctruth), AlgorithmSpec{adaptFromTask(mctruth)}, - Options{ - {"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}}}}; + Options{{"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}}}}; } } // namespace o2::its3 From f416e4705bcc9b04c7a054a22e856b0e0bda0dd7 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 26 Aug 2024 10:41:31 +0200 Subject: [PATCH 0142/2205] SVectorGPU and SMatrixGPU implementation should be in detail namespace --- Common/MathUtils/include/MathUtils/SMatrixGPU.h | 4 ++-- GPU/Common/test/testSMatrixImp.cu | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index 6f0301390d54e..fdb5bb2a5da66 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -34,7 +34,7 @@ #include "GPUCommonAlgorithm.h" #include "GPUCommonLogger.h" -namespace o2::math_utils +namespace o2::math_utils::detail { template struct Check { @@ -1468,5 +1468,5 @@ GPUdi() SMatrixGPU> Similarity(const SMatrixGPU #include -using MatSym3DGPU = o2::math_utils::SMatrixGPU>; +using MatSym3DGPU = o2::math_utils::detail::SMatrixGPU>; using MatSym3D = ROOT::Math::SMatrix>; -using Mat3DGPU = o2::math_utils::SMatrixGPU>; +using Mat3DGPU = o2::math_utils::detail::SMatrixGPU>; using Mat3D = ROOT::Math::SMatrix>; static constexpr double tolerance = 1e-8; From 74b2f026118d07550f35d37d8f463aa612f5962a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 26 Aug 2024 13:31:36 +0200 Subject: [PATCH 0143/2205] GPU: GPUWorkflowSpec will provide the o2::Propagator later, disable check --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- GPU/Workflow/src/GPUWorkflowSpec.cxx | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index c1afb727b1729..0b1370a1b41d0 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -273,6 +273,7 @@ AddOption(ignoreNonFatalGPUErrors, bool, false, "", 0, "Continue running after h AddOption(tpcIncreasedMinClustersPerRow, unsigned int, 0, "", 0, "Impose a minimum buffer size for the clustersPerRow during TPC clusterization") AddOption(noGPUMemoryRegistration, bool, false, "", 0, "Do not register input / output memory for GPU dma transfer") AddOption(o2PropagatorUseGPUField, bool, true, "", 0, "Makes the internal O2 propagator use the fast GPU polynomial b field approximation") +AddOption(willProvideO2PropagatorLate, bool, false, "", 0, "Disable check for availability of o2 propagator at initialization") AddOption(calibObjectsExtraMemorySize, unsigned int, 10u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") AddOption(fastTransformObjectsMinMemorySize, unsigned int, 400u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") AddOption(lateO2MatLutProvisioningSize, unsigned int, 0u, "", 0, "Memory size to reserve for late provisioning of matlut table") diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index bd1cd9859cbd2..8188402902674 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -680,7 +680,7 @@ int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) int GPUChainTracking::RunChain() { - if ((((GetRecoSteps() & RecoStep::TRDTracking) && !GetProcessingSettings().trdTrackModelO2) || ((GetRecoSteps() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && processors()->calibObjects.o2Propagator == nullptr) { + if ((((GetRecoSteps() & RecoStep::TRDTracking) && !GetProcessingSettings().trdTrackModelO2 && !GetProcessingSettings().willProvideO2PropagatorLate) || ((GetRecoSteps() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && processors()->calibObjects.o2Propagator == nullptr) { GPUFatal("Cannot run TRD tracking or refit with o2 track model without o2 propagator"); // This check must happen during run, since o2::Propagator cannot be available during init } if (GetProcessingSettings().ompAutoNThreads && !mRec->IsGPU()) { diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index b77b12b079547..f2a9ec635443c 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -275,6 +275,7 @@ void GPURecoWorkflowSpec::init(InitContext& ic) mConfig->configCalib.trdGeometry = mTRDGeometry.get(); } + mConfig->configProcessing.willProvideO2PropagatorLate = true; mConfig->configProcessing.o2PropagatorUseGPUField = true; if (mConfParam->printSettings && (mConfParam->printSettings > 1 || ic.services().get().inputTimesliceId == 0)) { From 7da89553ca4ea2a600de473751e0570f86092965 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 26 Aug 2024 22:38:35 +0200 Subject: [PATCH 0144/2205] GPU QA: Remove unused code --- GPU/GPUTracking/qa/GPUQA.cxx | 2 -- GPU/GPUTracking/qa/GPUQA.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index f4978a80801ab..f6127c1f8da80 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -345,8 +345,6 @@ GPUQA::~GPUQA() clearGarbagageCollector(); // Needed to guarantee correct order for ROOT ownership } -inline bool GPUQA::MCComp(const mcLabel_t& a, const mcLabel_t& b) { return (GPUQA::GetMCLabelID(a) > GPUQA::GetMCLabelID(b)); } - bool GPUQA::clusterRemovable(int attach, bool prot) const { CHECK_CLUSTER_STATE_NOCOUNT(); diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index 79580a737cdf2..4ed2072756bba 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -218,8 +218,6 @@ class GPUQA const auto& GetClusterLabels(); bool mcPresent(); - static bool MCComp(const mcLabel_t& a, const mcLabel_t& b); - GPUChainTracking* mTracking; const GPUSettingsQA& mConfig; const GPUParam* mParam; From 70d99e403dbb53dd98e26f2b5182c29c6ebfd978 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 26 Aug 2024 22:38:57 +0200 Subject: [PATCH 0145/2205] GPUQA: Treat O2 unset and O2 noise labels in meaningful way --- GPU/GPUTracking/qa/GPUQA.cxx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index f6127c1f8da80..c6cc4efb2e023 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -209,10 +209,8 @@ static constexpr Color_t defaultColorNums[COLORCOUNT] = {kRed, kBlue, kGreen, kM #define TRACK_EXPECTED_REFERENCE_X_DEFAULT 81 #ifdef GPUCA_TPC_GEOMETRY_O2 -inline unsigned int GPUQA::GetNMCCollissions() const -{ - return mMCInfosCol.size(); -} +static inline int GPUQA_O2_ConvertFakeLabel(int label) { return label >= 0x7FFFFFFE ? -1 : label; } +inline unsigned int GPUQA::GetNMCCollissions() const { return mMCInfosCol.size(); } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mMCInfosCol[iCol].num; } inline unsigned int GPUQA::GetNMCLabels() const { return mClNative->clustersMCTruth ? mClNative->clustersMCTruth->getIndexedSize() : 0; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mMCInfos[mMCInfosCol[iCol].first + iTrk]; } @@ -221,9 +219,9 @@ inline GPUQA::mcLabels_t GPUQA::GetMCLabel(unsigned int i) { return mClNative->c inline int GPUQA::GetMCLabelNID(const mcLabels_t& label) { return label.size(); } inline int GPUQA::GetMCLabelNID(unsigned int i) { return mClNative->clustersMCTruth->getLabels(i).size(); } inline GPUQA::mcLabel_t GPUQA::GetMCLabel(unsigned int i, unsigned int j) { return mClNative->clustersMCTruth->getLabels(i)[j]; } -inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return mClNative->clustersMCTruth->getLabels(i)[j].getTrackID(); } -inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return label[j].getTrackID(); } -inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return label.getTrackID(); } +inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(mClNative->clustersMCTruth->getLabels(i)[j].getTrackID()); } +inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(label[j].getTrackID()); } +inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return GPUQA_O2_ConvertFakeLabel(label.getTrackID()); } inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } inline const auto& GPUQA::GetClusterLabels() { return mClNative->clustersMCTruth; } inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } @@ -232,9 +230,7 @@ inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return 1; } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && mClNative && mClNative->clustersMCTruth && mMCInfos.size(); } #define TRACK_EXPECTED_REFERENCE_X 78 #else -inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) -{ -} +inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) {} inline bool GPUQA::mcLabelI_t::operator==(const GPUQA::mcLabel_t& l) { return AbsLabelID(track) == l.fMCID; } inline unsigned int GPUQA::GetNMCCollissions() const { return 1; } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mTracking->mIOPtrs.nMCInfosTPC; } From c1211ff32b83df4e6ffead39ea342552f4547761 Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 27 Aug 2024 15:36:30 +0200 Subject: [PATCH 0146/2205] Fix for dummy ITS vetrex seeding in cosmice mode --- Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index 54650555857c0..6f960aa251432 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -143,6 +143,7 @@ class TimeFrame { deepVectorClear(mPrimaryVertices); mROFramesPV.resize(1, 0); + mTotVertPerIteration.resize(1); }; bool isClusterUsed(int layer, int clusterId) const; From 303affb12f913edb7f3deff29b76d43ca1dfc28a Mon Sep 17 00:00:00 2001 From: yuanzhe Date: Tue, 27 Aug 2024 17:13:12 +0200 Subject: [PATCH 0147/2205] Common/Constans: Add hyperhelium5 mass --- Common/Constants/include/CommonConstants/PhysicsConstants.h | 4 +++- Common/Constants/include/CommonConstants/make_pdg_header.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Common/Constants/include/CommonConstants/PhysicsConstants.h b/Common/Constants/include/CommonConstants/PhysicsConstants.h index 3d8266307ada1..64d0aaca5873f 100644 --- a/Common/Constants/include/CommonConstants/PhysicsConstants.h +++ b/Common/Constants/include/CommonConstants/PhysicsConstants.h @@ -73,7 +73,8 @@ enum Pdg { kAlpha = 1000020040, kHyperTriton = 1010010030, kHyperHydrogen4 = 1010010040, - kHyperHelium4 = 1010020040 + kHyperHelium4 = 1010020040, + kHyperHelium5 = 1010020050 }; /// \brief Declarations of masses for additional particles @@ -120,6 +121,7 @@ constexpr double MassAlpha = 3.7273794066; constexpr double MassHyperTriton = 2.99131; constexpr double MassHyperHydrogen4 = 3.9226; constexpr double MassHyperHelium4 = 3.9217; +constexpr double MassHyperHelium5 = 4.841; /// \brief Declarations of masses for particles in ROOT PDG_t constexpr double MassDown = 0.00467; diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index 81bba8ec5996b..fc62474eafa65 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -129,6 +129,7 @@ class Pdg(Enum): kHyperTriton = 1010010030 kHyperHydrogen4 = 1010010040 kHyperHelium4 = 1010020040 + kHyperHelium5 = 1010020050 dbPdg = ROOT.o2.O2DatabasePDG From 53fee617a15e2ec138ac6a6be1152355f7deaca3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 20 Aug 2024 16:54:56 +0200 Subject: [PATCH 0148/2205] ALIGN: request only selected alignment objects Signed-off-by: Felix Schlepper --- Detectors/GRP/workflows/src/create-aligned-geometry.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Detectors/GRP/workflows/src/create-aligned-geometry.cxx b/Detectors/GRP/workflows/src/create-aligned-geometry.cxx index 3f9b621f31abe..d738976ff4ffd 100644 --- a/Detectors/GRP/workflows/src/create-aligned-geometry.cxx +++ b/Detectors/GRP/workflows/src/create-aligned-geometry.cxx @@ -150,7 +150,10 @@ DataProcessorSpec getAlignerSpec(DetID::mask_t dets) false, // GRPMagField false, // askMatLUT o2::base::GRPGeomRequest::Alignments, // geometry - inputs); + inputs, // inputs + false, // ask-once + false, // dprop + DetID::getNames(dets)); // only selected detectors return DataProcessorSpec{ "geometry-aligned-producer", From 48d2ec88754ec2eb7c94075aa56ada1aba4f23bc Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 08:57:21 +0200 Subject: [PATCH 0149/2205] DPL: Fix endOfStream callback sending old / uninitialized timingInfo values (#13441) --- Framework/Core/src/DataProcessingDevice.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 7c45cd7e7a707..067406415f6de 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1732,6 +1732,12 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) // We should keep the data generated at end of stream only for those // which are not sources. timingInfo.keepAtEndOfStream = shouldProcess; + // Fill timinginfo with some reasonable values for data sent with endOfStream + timingInfo.timeslice = relayer.getOldestPossibleOutput().timeslice.value; + timingInfo.tfCounter = 0; + timingInfo.firstTForbit = 0; + // timingInfo.runNumber = ; // Not sure where to get this if not already set + timingInfo.creation = std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count(); O2_SIGNPOST_EVENT_EMIT(calibration, dpid, "calibration", "TimingInfo.keepAtEndOfStream %d", timingInfo.keepAtEndOfStream); EndOfStreamContext eosContext{*context.registry, ref.get()}; From f67766c4dd4852648d181bff147d0efba7803c71 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 27 Aug 2024 22:59:04 +0200 Subject: [PATCH 0150/2205] DPL: Add debug message --- Framework/Core/src/DataProcessingDevice.cxx | 1 + GPU/Common/GPUCommonDef.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 067406415f6de..04e83046c0c76 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1851,6 +1851,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& } auto dih = o2::header::get(headerData); if (dih) { + O2_SIGNPOST_EVENT_EMIT(device, cid, "handle_data", "Got DomainInfoHeader with oldestPossibleTimeslice %d", (int)dih->oldestPossibleTimeslice); insertInputInfo(pi, 2, InputType::DomainInfo, info.id); *context.wasActive = true; continue; diff --git a/GPU/Common/GPUCommonDef.h b/GPU/Common/GPUCommonDef.h index 6a699835affa5..a8bf772d7aacc 100644 --- a/GPU/Common/GPUCommonDef.h +++ b/GPU/Common/GPUCommonDef.h @@ -19,7 +19,7 @@ // The following checks are increasingly more strict hiding the code in more and more cases: // #ifndef __OPENCL__ : Hide from OpenCL kernel code. All system headers and usage thereof must be protected like this, or stronger. // #ifndef GPUCA_GPUCODE_DEVICE : Hide from kernel code on all GPU architectures. This includes the __OPENCL__ case and bodies of all GPU device functions (GPUd(), etc.) -// #ifndef GPUCA_GPUCODE : Hide from compilation with GPU compiler. This includes the case kernel case of GPUCA_GPUCODE_DEVICE but also all host code compiled by the GPU compiler, e.g. for management. +// #ifndef GPUCA_GPUCODE : Hide from compilation with GPU compiler. This includes the kernel case of GPUCA_GPUCODE_DEVICE but also all host code compiled by the GPU compiler, e.g. for management. // #ifndef GPUCA_ALIGPUCODE : Code is completely invisible to the GPUCATracking library, irrespective of GPU or CPU compilation or which compiler. #ifndef GPUCOMMONDEF_H From e39d12ea3c19fe40fc90f6d634d19ffe16b37025 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:42:59 +0200 Subject: [PATCH 0151/2205] DPL: initialize TimingInfo.timeslice Empty processing will otherwise have it set wrong on End Of Stream --- Framework/Core/include/Framework/TimingInfo.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/TimingInfo.h b/Framework/Core/include/Framework/TimingInfo.h index 6b61b8e4ef5b5..00933a03845eb 100644 --- a/Framework/Core/include/Framework/TimingInfo.h +++ b/Framework/Core/include/Framework/TimingInfo.h @@ -23,7 +23,11 @@ namespace o2::framework struct TimingInfo { constexpr static ServiceKind service_kind = ServiceKind::Stream; - size_t timeslice; /// the timeslice associated to current processing + size_t timeslice = 0; /// the timeslice associated to current processing. The default + /// is in general overridden unless the end of stream arrives + /// without any previous processing, so we need to 0 it, + /// and not use -1, which would break the oldest possible timeframe + /// in that case. uint32_t firstTForbit = -1; /// the orbit the TF begins uint32_t tfCounter = -1; // the counter associated to a TF uint32_t runNumber = -1; From 19f65a7c5d3b8b15ecc5027a65c187e7763b9028 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 28 Aug 2024 13:48:47 +0200 Subject: [PATCH 0152/2205] Fix [modernize-make-shared] in clang-tidy (#13443) --- Detectors/ITSMFT/ITS/simulation/src/Detector.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx b/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx index d005c9ea9858a..9a93c72ee0760 100644 --- a/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx +++ b/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx @@ -143,10 +143,10 @@ Detector::Detector(Bool_t active, TString name) mHits(o2::utils::createSimVector()) { if (name == "ITS") { - mDescriptorIB.reset(new DescriptorInnerBarrelITS2(3)); + mDescriptorIB = std::make_shared(3); } else if (name == "IT3") { #ifdef ENABLE_UPGRADES - mDescriptorIB.reset(new DescriptorInnerBarrelITS3()); + mDescriptorIB = std::make_shared(); #endif } else { LOG(fatal) << "Detector name not supported (options ITS and ITS3)"; From fc63a61414d290f8e81d2485ae6a4f3e2d18b1e9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 13:59:41 +0200 Subject: [PATCH 0153/2205] FST: Some cleanup for FST simulation with embedding --- GPU/Common/GPUROOTSMatrixFwd.h | 1 - prodtests/full-system-test/README.md | 2 +- prodtests/{ => full-system-test}/pythia8.cfg | 0 prodtests/full_system_test.sh | 4 ++-- 4 files changed, 3 insertions(+), 4 deletions(-) rename prodtests/{ => full-system-test}/pythia8.cfg (100%) diff --git a/GPU/Common/GPUROOTSMatrixFwd.h b/GPU/Common/GPUROOTSMatrixFwd.h index b1dd9bd0bbb0d..2c19f034dc216 100644 --- a/GPU/Common/GPUROOTSMatrixFwd.h +++ b/GPU/Common/GPUROOTSMatrixFwd.h @@ -70,7 +70,6 @@ template using MatRepSym = detail::MatRepSymGPU; template using MatRepStd = detail::MatRepStdGPU; - #endif } // namespace math_utils diff --git a/prodtests/full-system-test/README.md b/prodtests/full-system-test/README.md index bcfeba42e3851..a52dfbc5d1203 100644 --- a/prodtests/full-system-test/README.md +++ b/prodtests/full-system-test/README.md @@ -30,7 +30,7 @@ For a simulation of a full 128 orbit time frame, run ``` NEvents=650 NEventsQED=30000 SHMSIZE=128000000000 TPCTRACKERSCRATCHMEMORY=30000000000 $O2_ROOT/prodtests/full_system_test.sh ``` -To simulate collisions with an embedded signal one can set 'D0_EMBEDDING=1' while also supplying a config file with the desired settings using 'FST_EMBEDDING_CONFIG'. For an example configuration see '/prodtests/pythia8.cfg' and to generate a specific configuration one can use '${O2DPG_ROOT}/MC/config/common/pythia8/utils/mkpy8cfg.py'. Additional examples can be found in '/run/SimExamples/' +To simulate collisions with an embedded signal one can set 'D0_EMBEDDING=1' while also supplying a config file with the desired settings using 'FST_EMBEDDING_CONFIG'. For an example configuration see '/prodtests/full-system-test/pythia8.cfg' and to generate a specific configuration one can use '${O2DPG_ROOT}/MC/config/common/pythia8/utils/mkpy8cfg.py'. Additional examples can be found in '/run/SimExamples/' ``` DO_EMBEDDING=1 NEvents=5 NEventsQED=100 $O2_ROOT/prodtests/full_system_test.sh ``` diff --git a/prodtests/pythia8.cfg b/prodtests/full-system-test/pythia8.cfg similarity index 100% rename from prodtests/pythia8.cfg rename to prodtests/full-system-test/pythia8.cfg diff --git a/prodtests/full_system_test.sh b/prodtests/full_system_test.sh index e429ee7ad078b..f8b6d66ce87e4 100755 --- a/prodtests/full_system_test.sh +++ b/prodtests/full_system_test.sh @@ -69,7 +69,7 @@ else RUNNUMBER=303000 # a default un-anchored pp run number fi FST_MC_ENGINE=${FST_MC_ENGINE:-TGeant4} -FST_EMBEDDING_CONFIG=${FST_EMBEDDING_CONFIG:-GeneratorPythia8.config=pythia8.cfg} +FST_EMBEDDING_CONFIG=${FST_EMBEDDING_CONFIG:-GeneratorPythia8.config=$O2_ROOT/prodtests/full-system-test/pythia8.cfg} DO_EMBEDDING=${DO_EMBEDDING:-0} if [[ $DO_EMBEDDING == 0 ]]; then SIM_SOURCES="o2sim" @@ -141,7 +141,7 @@ if [[ $DO_EMBEDDING == 1 ]]; then taskwrapper embed.log o2-sim ${FST_BFIELD+--field=}${FST_BFIELD} -j $NJOBS --run ${RUNNUMBER} -n $NEvents -g pythia8pp -e ${FST_MC_ENGINE} -o sig --configKeyValues ${FST_EMBEDDING_CONFIG} --embedIntoFile o2sim_Kine.root fi taskwrapper digi.log o2-sim-digitizer-workflow -n $NEvents ${DIGIQED} ${NOMCLABELS} --sims ${SIM_SOURCES} --tpc-lanes $((NJOBS < 36 ? NJOBS : 36)) --shm-segment-size $SHMSIZE ${GLOBALDPLOPT} ${DIGITOPT} --configKeyValues "\"${DIGITOPTKEY}\"" --interactionRate $FST_COLRATE --early-forward-policy always -[[ $SPLITTRDDIGI == "1" ]] && taskwrapper digiTRD.log o2-sim-digitizer-workflow -n $NEvents ${NOMCLABELS} --onlyDet TRD --trd-digit-downscaling ${DIGITDOWNSCALINGTRD} --shm-segment-size $SHMSIZE ${GLOBALDPLOPT} --incontext collisioncontext.root --configKeyValues "\"${DIGITOPTKEYTRD}\"" --early-forward-policy always +[[ $SPLITTRDDIGI == "1" ]] && taskwrapper digiTRD.log o2-sim-digitizer-workflow -n $NEvents ${NOMCLABELS} --sims ${SIM_SOURCES} --onlyDet TRD --trd-digit-downscaling ${DIGITDOWNSCALINGTRD} --shm-segment-size $SHMSIZE ${GLOBALDPLOPT} --incontext collisioncontext.root --configKeyValues "\"${DIGITOPTKEYTRD}\"" --early-forward-policy always touch digiTRD.log_done if [[ "0$GENERATE_ITSMFT_DICTIONARIES" == "01" ]]; then From 9fc5d420ef4ddf34700634cbdbba813cc1afe21d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 15:46:10 +0200 Subject: [PATCH 0154/2205] TPC: Fix coding convention --- Detectors/TPC/calibration/src/IDCAverageGroup.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/TPC/calibration/src/IDCAverageGroup.cxx b/Detectors/TPC/calibration/src/IDCAverageGroup.cxx index 71e3e5f53ad55..f027a0a7d0056 100644 --- a/Detectors/TPC/calibration/src/IDCAverageGroup.cxx +++ b/Detectors/TPC/calibration/src/IDCAverageGroup.cxx @@ -160,7 +160,7 @@ void o2::tpc::IDCAverageGroup::drawGrouping(const std::string filename) can.SetLeftMargin(0.06f); can.SetTopMargin(0.04f); can.cd(); - poly->SetTitle(0); + poly->SetTitle(nullptr); poly->GetYaxis()->SetTickSize(0.002f); poly->GetYaxis()->SetTitleOffset(0.7f); poly->SetStats(0); From 0f5463a7c8faec582f89922efa3c91d5dd4d13ad Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 15:33:45 +0200 Subject: [PATCH 0155/2205] GPU QA: TPC Tracking QA should support multiple MC sources --- GPU/GPUTracking/qa/GPUQA.cxx | 174 ++++++++++++++++++++--------------- GPU/GPUTracking/qa/GPUQA.h | 6 +- 2 files changed, 104 insertions(+), 76 deletions(-) diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index c6cc4efb2e023..0852078c3f8cc 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -80,13 +80,14 @@ using namespace GPUCA_NAMESPACE::gpu; #ifdef GPUCA_MERGER_BY_MC_LABEL -#define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() \ - if (!unattached && mTrackMCLabels[id].isValid()) { \ - int mcLabel = mTrackMCLabels[id].getTrackID(); \ - int mcEvent = mTrackMCLabels[id].getEventID(); \ - if (mTrackMCLabelsReverse[mcEvent][mcLabel] != id) { \ - attach &= (~gputpcgmmergertypes::attachGoodLeg); \ - } \ +#define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() \ + if (!unattached && mTrackMCLabels[id].isValid()) { \ + int mcLabel = mTrackMCLabels[id].getTrackID(); \ + int mcEvent = mTrackMCLabels[id].getEventID(); \ + int mcSource = mTrackMCLabels[id].getSourceID(); \ + if (mTrackMCLabelsReverse[mMCEventOffset[mcSource] + mcEvent][mcLabel] != id) { \ + attach &= (~gputpcgmmergertypes::attachGoodLeg); \ + } \ } #else #define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() @@ -212,9 +213,10 @@ static constexpr Color_t defaultColorNums[COLORCOUNT] = {kRed, kBlue, kGreen, kM static inline int GPUQA_O2_ConvertFakeLabel(int label) { return label >= 0x7FFFFFFE ? -1 : label; } inline unsigned int GPUQA::GetNMCCollissions() const { return mMCInfosCol.size(); } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mMCInfosCol[iCol].num; } +inline unsigned int GPUQA::GetNMCTracks(const mcLabel_t& label) const { return mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].num; } inline unsigned int GPUQA::GetNMCLabels() const { return mClNative->clustersMCTruth ? mClNative->clustersMCTruth->getIndexedSize() : 0; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mMCInfos[mMCInfosCol[iCol].first + iTrk]; } -inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return mMCInfos[mMCInfosCol[label.getEventID()].first + label.getTrackID()]; } +inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return mMCInfos[mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].first + label.getTrackID()]; } inline GPUQA::mcLabels_t GPUQA::GetMCLabel(unsigned int i) { return mClNative->clustersMCTruth->getLabels(i); } inline int GPUQA::GetMCLabelNID(const mcLabels_t& label) { return label.size(); } inline int GPUQA::GetMCLabelNID(unsigned int i) { return mClNative->clustersMCTruth->getLabels(i).size(); } @@ -222,7 +224,7 @@ inline GPUQA::mcLabel_t GPUQA::GetMCLabel(unsigned int i, unsigned int j) { retu inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(mClNative->clustersMCTruth->getLabels(i)[j].getTrackID()); } inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(label[j].getTrackID()); } inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return GPUQA_O2_ConvertFakeLabel(label.getTrackID()); } -inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } +inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mMCEventOffset[mClNative->clustersMCTruth->getLabels(i)[j].getSourceID()] + mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } inline const auto& GPUQA::GetClusterLabels() { return mClNative->clustersMCTruth; } inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return 1; } @@ -234,6 +236,7 @@ inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) inline bool GPUQA::mcLabelI_t::operator==(const GPUQA::mcLabel_t& l) { return AbsLabelID(track) == l.fMCID; } inline unsigned int GPUQA::GetNMCCollissions() const { return 1; } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mTracking->mIOPtrs.nMCInfosTPC; } +inline unsigned int GPUQA::GetNMCTracks(const mcLabel_t& label) const { return mTracking->mIOPtrs.nMCInfosTPC; } inline unsigned int GPUQA::GetNMCLabels() const { return mTracking->mIOPtrs.nMCLabelsTPC; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mTracking->mIOPtrs.mcInfosTPC[AbsLabelID(iTrk)]; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return GetMCTrack(label.fMCID, 0); } @@ -258,7 +261,7 @@ inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && GetNMCLabe template inline auto& GPUQA::GetMCTrackObj(T& obj, const GPUQA::mcLabelI_t& l) { - return obj[l.getEventID()][l.getTrackID()]; + return obj[mMCEventOffset[l.getSourceID()] + l.getEventID()][l.getTrackID()]; } template <> @@ -587,6 +590,9 @@ void GPUQA::DumpO2MCData(const char* filename) const n = mMCInfosCol.size(); fwrite(&n, sizeof(n), 1, fp); fwrite(mMCInfosCol.data(), sizeof(mMCInfosCol[0]), n, fp); + n = mMCEventOffset.size(); + fwrite(&n, sizeof(n), 1, fp); + fwrite(mMCEventOffset.data(), sizeof(mMCEventOffset[0]), n, fp); fclose(fp); } @@ -616,6 +622,15 @@ int GPUQA::ReadO2MCData(const char* filename) fclose(fp); return 1; } + if ((x = fread(&n, sizeof(n), 1, fp)) != 1) { + fclose(fp); + return 1; + } + mMCEventOffset.resize(n); + if (fread(mMCEventOffset.data(), sizeof(mMCEventOffset[0]), n, fp) != n) { + fclose(fp); + return 1; + } if (mTracking && mTracking->GetProcessingSettings().debugLevel >= 2) { printf("Read %ld MC Infos\n", ftell(fp)); } @@ -646,81 +661,90 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) static constexpr float PRIM_MAX_T = 0.01f; o2::steer::MCKinematicsReader mcReader("collisioncontext.root"); - int nSimEvents = mcReader.getNEvents(0); - mMCInfos.resize(nSimEvents); std::vector refId; auto dc = o2::steer::DigitizationContext::loadFromFile("collisioncontext.root"); auto evrec = dc->getEventRecords(); - mMCInfosCol.resize(nSimEvents); - for (int i = 0; i < nSimEvents; i++) { - auto ir = evrec[i]; - auto ir0 = o2::raw::HBFUtils::Instance().getFirstIRofTF(ir); - float timebin = (float)ir.differenceInBC(ir0) / o2::tpc::constants::LHCBCPERTIMEBIN; - - const std::vector& tracks = mcReader.getTracks(0, i); - const std::vector& trackRefs = mcReader.getTrackRefsByEvent(0, i); + unsigned int nSimSources = mcReader.getNSources(); + mMCEventOffset.resize(nSimSources); + unsigned int nSimTotalEvents = 0; + unsigned int nSimTotalTracks = 0; + for (unsigned int i = 0; i < nSimSources; i++) { + mMCEventOffset[i] = nSimTotalEvents; + nSimTotalEvents += mcReader.getNEvents(i); + } - refId.resize(tracks.size()); - std::fill(refId.begin(), refId.end(), -1); - for (unsigned int j = 0; j < trackRefs.size(); j++) { - if (trackRefs[j].getDetectorId() == o2::detectors::DetID::TPC) { - int trkId = trackRefs[j].getTrackID(); - if (refId[trkId] == -1) { - refId[trkId] = j; + mMCInfosCol.resize(nSimTotalEvents); + for (int iSim = 0; iSim < mcReader.getNSources(); iSim++) { + for (int i = 0; i < mcReader.getNEvents(iSim); i++) { + auto ir = evrec[i]; + auto ir0 = o2::raw::HBFUtils::Instance().getFirstIRofTF(ir); + float timebin = (float)ir.differenceInBC(ir0) / o2::tpc::constants::LHCBCPERTIMEBIN; + + const std::vector& tracks = mcReader.getTracks(iSim, i); + const std::vector& trackRefs = mcReader.getTrackRefsByEvent(iSim, i); + + refId.resize(tracks.size()); + std::fill(refId.begin(), refId.end(), -1); + for (unsigned int j = 0; j < trackRefs.size(); j++) { + if (trackRefs[j].getDetectorId() == o2::detectors::DetID::TPC) { + int trkId = trackRefs[j].getTrackID(); + if (refId[trkId] == -1) { + refId[trkId] = j; + } } } - } - mMCInfosCol[i].first = mMCInfos.size(); - mMCInfosCol[i].num = tracks.size(); - mMCInfos.resize(mMCInfos.size() + tracks.size()); - for (unsigned int j = 0; j < tracks.size(); j++) { - auto& info = mMCInfos[mMCInfosCol[i].first + j]; - const auto& trk = tracks[j]; - TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(trk.GetPdgCode()); - Int_t pid = -1; - if (abs(trk.GetPdgCode()) == kElectron) { - pid = 0; - } - if (abs(trk.GetPdgCode()) == kMuonMinus) { - pid = 1; - } - if (abs(trk.GetPdgCode()) == kPiPlus) { - pid = 2; - } - if (abs(trk.GetPdgCode()) == kKPlus) { - pid = 3; - } - if (abs(trk.GetPdgCode()) == kProton) { - pid = 4; - } + mMCInfosCol[mMCEventOffset[iSim] + i].first = mMCInfos.size(); + mMCInfosCol[mMCEventOffset[iSim] + i].num = tracks.size(); + mMCInfos.resize(mMCInfos.size() + tracks.size()); + for (unsigned int j = 0; j < tracks.size(); j++) { + auto& info = mMCInfos[mMCInfosCol[mMCEventOffset[iSim] + i].first + j]; + const auto& trk = tracks[j]; + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(trk.GetPdgCode()); + Int_t pid = -1; + if (abs(trk.GetPdgCode()) == kElectron) { + pid = 0; + } + if (abs(trk.GetPdgCode()) == kMuonMinus) { + pid = 1; + } + if (abs(trk.GetPdgCode()) == kPiPlus) { + pid = 2; + } + if (abs(trk.GetPdgCode()) == kKPlus) { + pid = 3; + } + if (abs(trk.GetPdgCode()) == kProton) { + pid = 4; + } - info.charge = particle ? particle->Charge() : 0; - info.prim = trk.T() < PRIM_MAX_T; - info.primDaughters = 0; - if (trk.getFirstDaughterTrackId() != -1) { - for (int k = trk.getFirstDaughterTrackId(); k <= trk.getLastDaughterTrackId(); k++) { - if (tracks[k].T() < PRIM_MAX_T) { - info.primDaughters = 1; - break; + info.charge = particle ? particle->Charge() : 0; + info.prim = trk.T() < PRIM_MAX_T; + info.primDaughters = 0; + if (trk.getFirstDaughterTrackId() != -1) { + for (int k = trk.getFirstDaughterTrackId(); k <= trk.getLastDaughterTrackId(); k++) { + if (tracks[k].T() < PRIM_MAX_T) { + info.primDaughters = 1; + break; + } } } - } - info.pid = pid; - info.t0 = timebin; - if (refId[j] >= 0) { - const auto& trkRef = trackRefs[refId[j]]; - info.x = trkRef.X(); - info.y = trkRef.Y(); - info.z = trkRef.Z(); - info.pX = trkRef.Px(); - info.pY = trkRef.Py(); - info.pZ = trkRef.Pz(); - info.genRadius = std::sqrt(trk.GetStartVertexCoordinatesX() * trk.GetStartVertexCoordinatesX() + trk.GetStartVertexCoordinatesY() * trk.GetStartVertexCoordinatesY() + trk.GetStartVertexCoordinatesZ() * trk.GetStartVertexCoordinatesZ()); - } else { - info.x = info.y = info.z = info.pX = info.pY = info.pZ = 0; - info.genRadius = 0; + info.pid = pid; + info.t0 = timebin; + if (refId[j] >= 0) { + const auto& trkRef = trackRefs[refId[j]]; + info.x = trkRef.X(); + info.y = trkRef.Y(); + info.z = trkRef.Z(); + info.pX = trkRef.Px(); + info.pY = trkRef.Py(); + info.pZ = trkRef.Pz(); + info.genRadius = std::sqrt(trk.GetStartVertexCoordinatesX() * trk.GetStartVertexCoordinatesX() + trk.GetStartVertexCoordinatesY() * trk.GetStartVertexCoordinatesY() + trk.GetStartVertexCoordinatesZ() * trk.GetStartVertexCoordinatesZ()); + } else { + info.x = info.y = info.z = info.pX = info.pY = info.pZ = 0; + info.genRadius = 0; + } } } } @@ -934,7 +958,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx int maxcount; auto maxLabel = acc.computeLabel(&maxweight, &sumweight, &maxcount); mTrackMCLabels[i] = maxLabel; - if (QA_DEBUG && track.OK() && GetNMCTracks(maxLabel.getEventID()) > (unsigned int)maxLabel.getTrackID()) { + if (QA_DEBUG && track.OK() && GetNMCTracks(maxLabel) > (unsigned int)maxLabel.getTrackID()) { const mcInfo_t& mc = GetMCTrack(maxLabel); GPUInfo("Track %d label %d (fake %d) weight %f clusters %d (fitted %d) (%f%% %f%%) Pt %f", i, maxLabel.getTrackID(), (int)(maxLabel.isFake()), maxweight, nClusters, track.NClustersFitted(), 100.f * maxweight / sumweight, 100.f * (float)maxcount / (float)nClusters, std::sqrt(mc.pX * mc.pX + mc.pY * mc.pY)); diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index 4ed2072756bba..ff6b6ad7134f1 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -199,10 +199,11 @@ class GPUQA static int AbsLabelID(const int id); #endif template - static auto& GetMCTrackObj(T& obj, const mcLabelI_t& l); + auto& GetMCTrackObj(T& obj, const mcLabelI_t& l); unsigned int GetNMCCollissions() const; unsigned int GetNMCTracks(int iCol) const; + unsigned int GetNMCTracks(const mcLabel_t& label) const; unsigned int GetNMCLabels() const; const mcInfo_t& GetMCTrack(unsigned int iTrk, unsigned int iCol); const mcInfo_t& GetMCTrack(const mcLabel_t& label); @@ -241,6 +242,9 @@ class GPUQA #endif std::vector mMCInfos; std::vector mMCInfosCol; + std::vector mMCNEvents; + std::vector mMCEventOffset; + std::vector mClusterParam; int mNTotalFakes = 0; From 24023f6ceb90eae2d92bfa4541dfa2336864b7fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 29 Aug 2024 08:40:44 +0200 Subject: [PATCH 0156/2205] Add getter for Afterburner tracks (#13067) --- Framework/Core/include/Framework/AnalysisDataModel.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 6a0c632263c3d..a5ee512e80f15 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -309,6 +309,11 @@ DECLARE_SOA_DYNAMIC_COLUMN(ITSClsSizeInLayer, itsClsSizeInLayer, //! Size of the return (itsClusterSizes >> (layer * 4)) & 0xf; }); +DECLARE_SOA_DYNAMIC_COLUMN(IsITSAfterburner, isITSAfterburner, //! If the track used the afterburner in the ITS + [](uint8_t detectorMap, float itsChi2Ncl) -> bool { + return (detectorMap & o2::aod::track::ITS) && (itsChi2Ncl < 0.f); + }); + namespace extensions { using TPCTimeErrEncoding = o2::aod::track::extensions::TPCTimeErrEncoding; @@ -332,6 +337,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(TPCDeltaTBwd, tpcDeltaTBwd, //! Delta Backward of tra return p.getDeltaTBwd(); }); } // namespace extensions + } // namespace v001 DECLARE_SOA_DYNAMIC_COLUMN(HasITS, hasITS, //! Flag to check if track has a ITS match @@ -514,6 +520,7 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "T track::TPCNClsCrossedRows, track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::v001::ITSClsSizeInLayer, + track::v001::IsITSAfterburner, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, From 341fb7a12e5157fcdc65feb21e23aa4809f41a9b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 22:51:42 +0200 Subject: [PATCH 0157/2205] GPU Display: Can show TPC clusters and tracks of different collisions color-coded based on MC information --- .../Interface/GPUO2InterfaceDisplay.cxx | 2 +- GPU/GPUTracking/display/GPUDisplay.cxx | 33 ++++++++++++++----- GPU/GPUTracking/display/GPUDisplay.h | 2 +- GPU/GPUTracking/display/GPUDisplayKeys.cxx | 2 +- GPU/GPUTracking/qa/GPUQA.cxx | 11 ++++--- GPU/GPUTracking/qa/GPUQA.h | 25 ++++++++------ 6 files changed, 49 insertions(+), 26 deletions(-) diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx index 1c1595c974b3e..6e51bcddb863a 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx @@ -35,7 +35,7 @@ GPUO2InterfaceDisplay::GPUO2InterfaceDisplay(const GPUO2InterfaceConfiguration* mQA.reset(new GPUQA(nullptr, &config->configQA, mParam.get())); mQA->InitO2MCData(); } - mDisplay.reset(GPUDisplayInterface::getDisplay(mFrontend.get(), nullptr, nullptr, mParam.get(), &mConfig->configCalib, &mConfig->configDisplay)); + mDisplay.reset(GPUDisplayInterface::getDisplay(mFrontend.get(), nullptr, mQA.get(), mParam.get(), &mConfig->configCalib, &mConfig->configDisplay)); } GPUO2InterfaceDisplay::~GPUO2InterfaceDisplay() = default; diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index bae8da5a6bf01..bab0bab7c9bcb 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -62,6 +62,8 @@ #include "DataFormatsTOF/Cluster.h" #include "TOFBase/Geo.h" #include "ITSBase/GeometryTGeo.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/ConstMCTruthContainer.h" #endif #ifdef GPUCA_O2_LIB #include "ITSMFTBase/DPLAlpideParam.h" @@ -193,8 +195,8 @@ void GPUDisplay::calcXYZ(const float* matrix) void GPUDisplay::SetCollisionFirstCluster(unsigned int collision, int slice, int cluster) { mNCollissions = std::max(mNCollissions, collision + 1); - mCollisionClusters.resize(mNCollissions); - mCollisionClusters[collision][slice] = cluster; + mOverlayTFClusters.resize(mNCollissions); + mOverlayTFClusters[collision][slice] = cluster; } void GPUDisplay::mAnimationCloseAngle(float& newangle, float lastAngle) @@ -582,11 +584,20 @@ GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned in { size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); - if (mCollisionClusters.size() > 0 || iCol == 0) { - const int firstCluster = (mCollisionClusters.size() > 1 && iCol > 0) ? mCollisionClusters[iCol - 1][iSlice] : 0; - const int lastCluster = (mCollisionClusters.size() > 1 && iCol + 1 < mCollisionClusters.size()) ? mCollisionClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); + if (mOverlayTFClusters.size() > 0 || iCol == 0 || mNCollissions) { + const int firstCluster = (mOverlayTFClusters.size() > 1 && iCol > 0) ? mOverlayTFClusters[iCol - 1][iSlice] : 0; + const int lastCluster = (mOverlayTFClusters.size() > 1 && iCol + 1 < mOverlayTFClusters.size()) ? mOverlayTFClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); + const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth; for (int cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { const int cid = GET_CID(iSlice, cidInSlice); +#ifdef GPUCA_HAVE_O2HEADERS + if (checkClusterCollision) { + const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid); + if (labels.size() ? (iCol != mQA->GetMCLabelCol(labels[0])) : (iCol != 0)) { + continue; + } + } +#endif if (mCfgH.hideUnmatchedClusters && mQA && mQA->SuppressHit(cid)) { continue; } @@ -1208,7 +1219,7 @@ int GPUDisplay::DrawGLScene() } if (!mIOPtrs) { mNCollissions = 0; - } else if (!mCollisionClusters.size()) { + } else if (!mOverlayTFClusters.size()) { mNCollissions = std::max(1u, mIOPtrs->nMCInfosTPCCol); } try { @@ -1828,11 +1839,15 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() } int slice = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].slice; unsigned int col = 0; - if (mCollisionClusters.size() > 1) { - int label = mQA ? mQA->GetMCTrackLabel(i) : -1; - while (col < mCollisionClusters.size() && mCollisionClusters[col][NSLICES] < label) { + if (mQA) { + const auto& label = mQA->GetMCTrackLabel(i); +#ifdef GPUCA_TPC_GEOMETRY_O2 + col = mQA->GetMCLabelCol(label); +#else + while (col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSLICES] < label) { col++; } +#endif } mThreadTracks[numThread][col][slice][0].emplace_back(i); } diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index 591d215239842..8d9a41017627e 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -247,7 +247,7 @@ class GPUDisplay : public GPUDisplayInterface float mRPhiTheta[3]; float mQuat[4]; - vecpod> mCollisionClusters; + vecpod> mOverlayTFClusters; int mNCollissions = 1; vecpod mVertexBuffer[NSLICES]; diff --git a/GPU/GPUTracking/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/GPUDisplayKeys.cxx index 7b5ab3a060255..de6e4567b9337 100644 --- a/GPU/GPUTracking/display/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/GPUDisplayKeys.cxx @@ -148,7 +148,7 @@ void GPUDisplay::HandleKey(unsigned char key) if (mCfgL.showCollision == -1) { SetInfo("Showing all collisions", 1); } else { - SetInfo("Showing collision %d", mCfgL.showCollision); + SetInfo("Showing collision %d / %d", mCfgL.showCollision, mNCollissions); } } else if (key == 'F') { mCfgR.fullScreen ^= 1; diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 0852078c3f8cc..846ba315a07a5 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -224,12 +224,14 @@ inline GPUQA::mcLabel_t GPUQA::GetMCLabel(unsigned int i, unsigned int j) { retu inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(mClNative->clustersMCTruth->getLabels(i)[j].getTrackID()); } inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(label[j].getTrackID()); } inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return GPUQA_O2_ConvertFakeLabel(label.getTrackID()); } -inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mMCEventOffset[mClNative->clustersMCTruth->getLabels(i)[j].getSourceID()] + mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } +inline unsigned int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mMCEventOffset[mClNative->clustersMCTruth->getLabels(i)[j].getSourceID()] + mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } inline const auto& GPUQA::GetClusterLabels() { return mClNative->clustersMCTruth; } inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return 1; } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && mClNative && mClNative->clustersMCTruth && mMCInfos.size(); } +unsigned int GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return !label.isValid() ? 0 : (mMCEventOffset[label.getSourceID()] + label.getEventID()); } +GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? MCCompLabel() : mTrackMCLabels[trackId]; } #define TRACK_EXPECTED_REFERENCE_X 78 #else inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) {} @@ -248,7 +250,8 @@ inline int GPUQA::GetMCLabelNID(unsigned int i) { return 3; } inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fMCID; } inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return label.fClusterID[j].fMCID; } inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return label.fMCID; } -inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return 0; } +inline unsigned int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return 0; } + inline const auto& GPUQA::GetClusterLabels() { return mTracking->mIOPtrs.mcLabelsTPC; } inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fWeight; } inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return label.fClusterID[j].fWeight; } @@ -256,6 +259,8 @@ inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return label.fWei inline int GPUQA::FakeLabelID(int id) { return id < 0 ? id : (-2 - id); } inline int GPUQA::AbsLabelID(int id) { return id >= 0 ? id : (-id - 2); } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && GetNMCLabels() && GetNMCTracks(0); } +unsigned int GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return 0; } +GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? MC_LABEL_INVALID : mTrackMCLabels[trackId]; } #define TRACK_EXPECTED_REFERENCE_X TRACK_EXPECTED_REFERENCE_X_DEFAULT #endif template @@ -426,8 +431,6 @@ void GPUQA::SetMCTrackRange(int min, int max) mMCTrackMax = max; } -int GPUQA::GetMCTrackLabel(unsigned int trackId) const { return (trackId >= mTrackMCLabels.size() ? MC_LABEL_INVALID : mTrackMCLabels[trackId].getTrackID()); } - int GPUQA::InitQACreateHistograms() { char name[2048], fname[1024]; diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index ff6b6ad7134f1..622c7726dd268 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -42,7 +42,7 @@ class GPUQA public: GPUQA(void* chain) {} ~GPUQA() = default; - + typedef int mcLabelI_t; int InitQA(int tasks = 0) { return 1; } void RunQA(bool matchOnly = false) {} int DrawQAHistograms() { return 1; } @@ -50,7 +50,7 @@ class GPUQA bool SuppressTrack(int iTrack) const { return false; } bool SuppressHit(int iHit) const { return false; } int HitAttachStatus(int iHit) const { return false; } - int GetMCTrackLabel(unsigned int trackId) const { return -1; } + mcLabelI_t GetMCTrackLabel(unsigned int trackId) const { return -1; } bool clusterRemovable(int attach, bool prot) const { return false; } void DumpO2MCData(const char* filename) const {} int ReadO2MCData(const char* filename) { return 1; } @@ -98,6 +98,16 @@ class GPUQA GPUQA(GPUChainTracking* chain, const GPUSettingsQA* config = nullptr, const GPUParam* param = nullptr); ~GPUQA(); +#ifdef GPUCA_TPC_GEOMETRY_O2 + using mcLabels_t = gsl::span; + using mcLabel_t = o2::MCCompLabel; + using mcLabelI_t = mcLabel_t; +#else + using mcLabels_t = AliHLTTPCClusterMCLabel; + using mcLabel_t = AliHLTTPCClusterMCWeight; + struct mcLabelI_t; +#endif + void UpdateParam(const GPUParam* param) { mParam = param; } int InitQA(int tasks = -1); void RunQA(bool matchOnly = false, const std::vector* tracksExternal = nullptr, const std::vector* tracksExtMC = nullptr, const o2::tpc::ClusterNativeAccess* clNative = nullptr); @@ -107,7 +117,8 @@ class GPUQA bool SuppressTrack(int iTrack) const; bool SuppressHit(int iHit) const; int HitAttachStatus(int iHit) const; - int GetMCTrackLabel(unsigned int trackId) const; + mcLabelI_t GetMCTrackLabel(unsigned int trackId) const; + unsigned int GetMCLabelCol(const mcLabel_t& label) const; bool clusterRemovable(int attach, bool prot) const; void InitO2MCData(GPUTrackingInOutPointers* updateIOPtr = nullptr); void DumpO2MCData(const char* filename) const; @@ -168,15 +179,9 @@ class GPUQA using mcInfo_t = GPUTPCMCInfo; #ifdef GPUCA_TPC_GEOMETRY_O2 - using mcLabels_t = gsl::span; - using mcLabel_t = o2::MCCompLabel; - using mcLabelI_t = mcLabel_t; - mcLabels_t GetMCLabel(unsigned int i); mcLabel_t GetMCLabel(unsigned int i, unsigned int j); #else - using mcLabels_t = AliHLTTPCClusterMCLabel; - using mcLabel_t = AliHLTTPCClusterMCWeight; struct mcLabelI_t { int getTrackID() const { return AbsLabelID(track); } int getEventID() const { return 0; } @@ -210,7 +215,7 @@ class GPUQA int GetMCLabelNID(const mcLabels_t& label); int GetMCLabelNID(unsigned int i); int GetMCLabelID(unsigned int i, unsigned int j); - int GetMCLabelCol(unsigned int i, unsigned int j); + unsigned int GetMCLabelCol(unsigned int i, unsigned int j); static int GetMCLabelID(const mcLabels_t& label, unsigned int j); static int GetMCLabelID(const mcLabel_t& label); float GetMCLabelWeight(unsigned int i, unsigned int j); From 686b69807e754c9d5182e81d863629873cee7637 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 28 Aug 2024 13:01:18 +0200 Subject: [PATCH 0158/2205] Use -1 for tfCounter and firstTfOrbit during EndOfStream This is no real TF data, so be explicit that it is invalid. The users should handle this case. --- Framework/Core/src/DataProcessingDevice.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 04e83046c0c76..4e89dee5d5db5 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1734,8 +1734,8 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) timingInfo.keepAtEndOfStream = shouldProcess; // Fill timinginfo with some reasonable values for data sent with endOfStream timingInfo.timeslice = relayer.getOldestPossibleOutput().timeslice.value; - timingInfo.tfCounter = 0; - timingInfo.firstTForbit = 0; + timingInfo.tfCounter = -1; + timingInfo.firstTForbit = -1; // timingInfo.runNumber = ; // Not sure where to get this if not already set timingInfo.creation = std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count(); O2_SIGNPOST_EVENT_EMIT(calibration, dpid, "calibration", "TimingInfo.keepAtEndOfStream %d", timingInfo.keepAtEndOfStream); From ea0443fc74fa408ee2bf2cc2fb7b266901ada92a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 11:11:45 +0200 Subject: [PATCH 0159/2205] GPU TPC: Add cfQMaxCutoffSingleTime and cfQMaxCutoffSinglePad options --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 2 ++ GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 0b1370a1b41d0..d57351bc753f4 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -122,6 +122,8 @@ AddOptionRTC(globalTrackingMinHits, unsigned char, 8, "", 0, "Min num of hits fo AddOptionRTC(noisyPadsQuickCheck, unsigned char, 1, "", 0, "Only check first fragment for noisy pads instead of all fragments (when test is enabled).") AddOptionRTC(cfQMaxCutoff, unsigned char, 3, "", 0, "Cluster Finder rejects cluster with qmax below or equal to this threshold") AddOptionRTC(cfQTotCutoff, unsigned char, 5, "", 0, "Cluster Finder rejects cluster with qtot below or equal to this threshold") +AddOptionRTC(cfQMaxCutoffSingleTime, unsigned char, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single time bin clusters") +AddOptionRTC(cfQMaxCutoffSinglePad, unsigned char, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single pad bin clusters") AddOptionRTC(cfInnerThreshold, unsigned char, 0, "", 0, "Cluster Finder extends cluster if inner charge above this threshold") AddOptionRTC(cfMinSplitNum, unsigned char, 1, "", 0, "Minimum number of split charges in a cluster for the cluster to be marked as split") AddOptionRTC(cfNoiseSuppressionEpsilon, unsigned char, 10, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression") diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx index 4b700be7f5109..500b4814df73f 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx @@ -30,6 +30,12 @@ GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::Cl if (mTimeMean < param.rec.tpc.clustersShiftTimebinsClusterizer) { return false; } + if (q <= param.rec.tpc.cfQMaxCutoffSingleTime && mTimeSigma == 0) { + return false; + } + if (q <= param.rec.tpc.cfQMaxCutoffSinglePad && mPadSigma == 0) { + return false; + } bool isEdgeCluster = CfUtils::isAtEdge(pos, param.tpcGeometry.NPads(pos.row())); bool wasSplitInTime = mSplitInTime >= param.rec.tpc.cfMinSplitNum; From 8d89a843dce9be4d419dc03a1899ce8766d42cfa Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Thu, 29 Aug 2024 19:15:11 +0200 Subject: [PATCH 0160/2205] Utility to keep only some trees out of the AO2Ds (#13422) Conveniently called strainer, to avoid confusion with skimming, thinning, dicing, molding, and all the other manufacturing terms used for our data processing Implement a random downsampling feature to reduce the size of the output AO2D file. This allows users to control the output file size, which can be useful when working with large datasets. The downsampling factor is specified as a command-line argument and is used to randomly select a subset of the input data to include in the output file. --- Framework/AODMerger/CMakeLists.txt | 5 + Framework/AODMerger/src/aodStrainer.cxx | 201 ++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 Framework/AODMerger/src/aodStrainer.cxx diff --git a/Framework/AODMerger/CMakeLists.txt b/Framework/AODMerger/CMakeLists.txt index 6d344237928b3..da74261cf64c8 100644 --- a/Framework/AODMerger/CMakeLists.txt +++ b/Framework/AODMerger/CMakeLists.txt @@ -18,3 +18,8 @@ o2_add_executable(thinner COMPONENT_NAME aod SOURCES src/aodThinner.cxx PUBLIC_LINK_LIBRARIES ROOT::Core ROOT::Net) + +o2_add_executable(strainer + COMPONENT_NAME aod + SOURCES src/aodStrainer.cxx + PUBLIC_LINK_LIBRARIES ROOT::Core ROOT::Net) diff --git a/Framework/AODMerger/src/aodStrainer.cxx b/Framework/AODMerger/src/aodStrainer.cxx new file mode 100644 index 0000000000000..f3f78a616951c --- /dev/null +++ b/Framework/AODMerger/src/aodStrainer.cxx @@ -0,0 +1,201 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include + +#include "TSystem.h" +#include "TFile.h" +#include "TTree.h" +#include "TList.h" +#include "TKey.h" +#include "TDirectory.h" +#include "TObjString.h" +#include +#include +#include + +#include "aodMerger.h" +#include + +// AOD strainer with correct index rewriting: a strainer only for the table of interest +int main(int argc, char* argv[]) +{ + std::string inputAO2D("AO2D.root"); + std::string outputFileName{"AO2D_strained.root"}; + std::string tables{"O2bc,O2calotrigger,O2collision,O2fdd,O2ft0,O2fv0a"}; + double downsampling = 1.0; + int verbosity = 2; + int exitCode = 0; // 0: success, >0: failure + + std::random_device rd; // Seed generator + std::mt19937 gen(rd()); // Mersenne Twister generator + std::uniform_real_distribution<> dis(0.0, 1.0); + + int option_index = 0; + static struct option long_options[] = { + {"input", required_argument, nullptr, 0}, + {"output", required_argument, nullptr, 1}, + {"verbosity", required_argument, nullptr, 2}, + {"tables", required_argument, nullptr, 3}, + {"downsampling", required_argument, nullptr, 4}, + {"help", no_argument, nullptr, 5}, + {nullptr, 0, nullptr, 0}}; + + while (true) { + int c = getopt_long(argc, argv, "", long_options, &option_index); + if (c == -1) { + break; + } else if (c == 0) { + inputAO2D = optarg; + } else if (c == 1) { + outputFileName = optarg; + } else if (c == 2) { + verbosity = atoi(optarg); + } else if (c == 3) { + tables = optarg; + } else if (c == 4) { + downsampling = atof(optarg); + } else if (c == 5) { + printf("AO2D strainer tool. Options: \n"); + printf(" --input <%s> Contains path to files to be merged. Default: %s\n", inputAO2D.c_str(), inputAO2D.c_str()); + printf(" --output <%s> Target output ROOT file. Default: %s\n", outputFileName.c_str(), outputFileName.c_str()); + printf(" --verbosity Verbosity of output (default: %d).\n", verbosity); + printf(" --tables Comma separated list of tables (default: %s).\n", tables.c_str()); + printf(" --downsampling Fraction of DF to be kept (default: %f)\n", downsampling); + return -1; + } else { + return -2; + } + } + + printf("AOD strainer started with:\n"); + printf(" Input file: %s\n", inputAO2D.c_str()); + printf(" Output file name: %s\n", outputFileName.c_str()); + printf(" Tables to be kept: %s\n", tables.c_str()); + printf(" Downsampling: %f\n", downsampling); + + std::vector listOfTables; + std::stringstream ss(tables); + std::string token; + + while (std::getline(ss, token, ',')) { + listOfTables.push_back(token); + } + + auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", 505); + TDirectory* outputDir = nullptr; + TString line(inputAO2D.c_str()); + printf("Processing input file: %s\n", line.Data()); + auto inputFile = TFile::Open(line); + if (!inputFile) { + printf("Error: Could not open input file %s.\n", line.Data()); + return -1; + } + + TList* keyList = inputFile->GetListOfKeys(); + keyList->Sort(); + + for (auto key1 : *keyList) { + if (((TObjString*)key1)->GetString().EqualTo("metaData")) { + auto metaDataCurrentFile = (TMap*)inputFile->Get("metaData"); + outputFile->cd(); + metaDataCurrentFile->Write("metaData", TObject::kSingleKey); + } + + if (((TObjString*)key1)->GetString().EqualTo("parentFiles")) { + auto parentFilesCurrentFile = (TMap*)inputFile->Get("parentFiles"); + outputFile->cd(); + parentFilesCurrentFile->Write("parentFiles", TObject::kSingleKey); + } + + if (!((TObjString*)key1)->GetString().BeginsWith("DF_") || dis(gen) > downsampling) { + continue; + } + + auto dfName = ((TObjString*)key1)->GetString().Data(); + if (verbosity > 0) { + printf(" Processing folder %s\n", dfName); + } + outputDir = outputFile->mkdir(dfName); + auto folder = (TDirectoryFile*)inputFile->Get(dfName); + auto treeList = folder->GetListOfKeys(); + + treeList->Sort(); + + // purging keys from duplicates + for (auto i = 0; i < treeList->GetEntries(); ++i) { + TKey* ki = (TKey*)treeList->At(i); + for (int j = i + 1; j < treeList->GetEntries(); ++j) { + TKey* kj = (TKey*)treeList->At(j); + if (std::strcmp(ki->GetName(), kj->GetName()) == 0 && std::strcmp(ki->GetTitle(), kj->GetTitle()) == 0) { + if (ki->GetCycle() < kj->GetCycle()) { + printf(" *** FATAL *** we had ordered the keys, first cycle should be higher, please check"); + exitCode = 5; + } else { + // key is a duplicate, let's remove it + treeList->Remove(kj); + j--; + } + } else { + // we changed key, since they are sorted, we won't have the same anymore + break; + } + } + } + + std::list foundTrees; + + for (auto key2 : *treeList) { + auto treeName = ((TObjString*)key2)->GetString().Data(); + bool found = (std::find(foundTrees.begin(), foundTrees.end(), treeName) != foundTrees.end()); + if (found == true) { + printf(" ***WARNING*** Tree %s was already merged (even if we purged duplicated trees before, so this should not happen), skipping\n", treeName); + continue; + } + bool foundTable = false; + for (auto const& table : listOfTables) { + if (table == removeVersionSuffix(treeName)) { + foundTrees.push_back(treeName); + foundTable = true; + break; + } + } + if (!foundTable) { + if (verbosity > 2) { + printf(" Skipping tree %s\n", treeName); + } + continue; + } + + auto inputTree = (TTree*)inputFile->Get(Form("%s/%s", dfName, treeName)); + if (verbosity > 1) { + printf(" Processing tree %s with %lld entries with total size %lld\n", treeName, inputTree->GetEntries(), inputTree->GetTotBytes()); + } + + outputDir->cd(); + auto outputTree = inputTree->CloneTree(-1, "fast"); + outputTree->Write(); + } + } + // in case of failure, remove the incomplete file + if (exitCode != 0) { + printf("Removing incomplete output file %s.\n", outputFile->GetName()); + gSystem->Unlink(outputFile->GetName()); + } else { + outputFile->Close(); + } + return exitCode; +} From 02acec2c5cccee1494f9249a5dbef0fa60ea7b0e Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 11:11:25 +0200 Subject: [PATCH 0161/2205] GPU Display: add option to show help text always without timer --- GPU/GPUTracking/display/GPUDisplay.cxx | 2 +- GPU/GPUTracking/display/GPUDisplay.h | 1 + GPU/GPUTracking/display/GPUDisplayKeys.cxx | 13 +++++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index bab0bab7c9bcb..f380fe694b848 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -2318,7 +2318,7 @@ void GPUDisplay::showInfo(const char* info) OpenGLPrint(mInfoText2, 40.f, 20.f, colorValue, colorValue, colorValue, 6 - mInfoText2Timer.GetCurrentElapsedTime()); } } - if (mInfoHelpTimer.IsRunning()) { + if (mInfoHelpTimer.IsRunning() || mPrintInfoTextAlways) { if (mInfoHelpTimer.GetCurrentElapsedTime() >= 6) { mInfoHelpTimer.Reset(); } else { diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index 8d9a41017627e..f50034d608874 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -296,6 +296,7 @@ class GPUDisplay : public GPUDisplayInterface opengl_spline mAnimationSplines[8]; int mPrintInfoText = 1; + bool mPrintInfoTextAlways = 0; char mInfoText2[1024]; HighResTimer mInfoText2Timer, mInfoHelpTimer; diff --git a/GPU/GPUTracking/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/GPUDisplayKeys.cxx index de6e4567b9337..7dc95111e819b 100644 --- a/GPU/GPUTracking/display/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/GPUDisplayKeys.cxx @@ -458,8 +458,17 @@ void GPUDisplay::HandleKey(unsigned char key) } SetInfo("Animation path loaded from file %s", "glanimation.tmp"); } else if (key == 'h') { - PrintHelp(); - SetInfo("Showing help text", 1); + if (mPrintInfoTextAlways) { + mPrintInfoTextAlways = false; + SetInfo("Showing help text disabled", 1); + } else if (mInfoHelpTimer.IsRunning()) { + mPrintInfoTextAlways = true; + mInfoHelpTimer.Reset(); + SetInfo("Showing help text until disabled", 1); + } else { + PrintHelp(); + SetInfo("Showing help text", 1); + } } else if (key == 'q') { SetInfo("Starting GUI", 1); mFrontend->startGUI(); From 4bede96b4a96712192d5f6dec1b1d7100e532865 Mon Sep 17 00:00:00 2001 From: iravasen Date: Thu, 29 Aug 2024 20:04:57 +0200 Subject: [PATCH 0162/2205] ITS calib: update default VCASN and bug fix for ITHR scan (#13434) * [WIP] ITS calib: update default upper limit of VCASN * solved bug for ITHR with parallel processes + improved chip selection for bad chips --- .../ITSWorkflow/ThresholdCalibratorSpec.h | 3 ++ .../workflow/src/ThresholdCalibratorSpec.cxx | 31 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h index 6bbf6a910c1f4..d97e1b78982eb 100644 --- a/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h +++ b/Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h @@ -322,6 +322,9 @@ class ITSThresholdCalibrator : public Task // Variable to select from which MEB to consider the hits. int mMeb = -1; + + // Percentage cut for VCASN/ITHR scans + short int mPercentageCut = 25; // default, at least 1 good row equivalent }; // Create a processor spec diff --git a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx index 64fa4247d8aad..a93ef3c4f4242 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx @@ -67,6 +67,8 @@ void ITSThresholdCalibrator::init(InitContext& ic) { LOGF(info, "ITSThresholdCalibrator init...", mSelfName); + mPercentageCut = ic.options().get("percentage-cut"); + mColStep = ic.options().get("s-curve-col-step"); if (mColStep >= N_COL) { LOG(warning) << "mColStep = " << mColStep << ": saving s-curves of only 1 pixel (pix 0) per row"; @@ -1761,7 +1763,13 @@ void ITSThresholdCalibrator::finalize() if (mRunTypeRU[iRU] >= nInjScaled * getNumberOfActiveLinks(mActiveLinks[iRU]) || mRunStopRequested) { std::vector chipList = getChipListFromRu(iRU, mActiveLinks[iRU]); for (size_t i = 0; i < chipList.size(); i++) { + if ((chipList[i] % mChipModBase) != mChipModSel) { + continue; + } if (!mThresholds.count(chipList[i])) { + if (mVerboseOutput) { + LOG(info) << "Setting ITHR = 50 for chip " << chipList[i]; + } std::vector data = {50, 0, 0, 0, 0}; addDatabaseEntry(chipList[i], name, data, false); } @@ -1788,7 +1796,21 @@ void ITSThresholdCalibrator::finalize() if (mVerboseOutput) { LOG(info) << "Average or mpv " << name << " of chip " << it->first << " = " << outVal << " e-"; } - float status = ((float)it->second[5] / (float)(it->second[4] + it->second[5])) * 100.; // percentage of unsuccessful threshold extractions + float status = ((float)it->second[4] / (float)(it->second[4] + it->second[5])) * 100.; // percentage of successful threshold extractions + if (status < mPercentageCut && (mScanType == 'I' || mScanType == 'V')) { + if (mScanType == 'I') { // default ITHR if percentage of success < mPercentageCut + outVal = 50.; + if (mVerboseOutput) { + LOG(info) << "Chip " << it->first << " status is " << status << ". Setting ITHR = 50"; + } + } else { // better to not set any VCASN if the percentage of success < mPercentageCut + it = this->mThresholds.erase(it); + if (mVerboseOutput) { + LOG(info) << "Chip " << it->first << " status is " << status << ". Ignoring this chip."; + } + continue; + } + } std::vector data = {outVal, rmsT, avgN, rmsN, status}; this->addDatabaseEntry(it->first, name, data, false); it = this->mThresholds.erase(it); @@ -1950,8 +1972,8 @@ DataProcessorSpec getITSThresholdCalibratorSpec(const ITSCalibInpConf& inpConf) {"enable-single-pix-tag", VariantType::Bool, false, {"Use to enable tagging of single noisy pix in digital and analogue scan"}}, {"ccdb-mgr-url", VariantType::String, "", {"CCDB url to download confDBmap"}}, {"min-vcasn", VariantType::Int, 30, {"Min value of VCASN in vcasn scan, default is 30"}}, - {"max-vcasn", VariantType::Int, 100, {"Max value of VCASN in vcasn scan, default is 80"}}, - {"min-ithr", VariantType::Int, 25, {"Min value of ITHR in ithr scan, default is 30"}}, + {"max-vcasn", VariantType::Int, 70, {"Max value of VCASN in vcasn scan, default is 70"}}, + {"min-ithr", VariantType::Int, 25, {"Min value of ITHR in ithr scan, default is 25"}}, {"max-ithr", VariantType::Int, 100, {"Max value of ITHR in ithr scan, default is 100"}}, {"manual-mode", VariantType::Bool, false, {"Flag to activate the manual mode in case run type is not recognized"}}, {"manual-min", VariantType::Int, 0, {"Min value of the variable used for the scan: use only in manual mode"}}, @@ -1974,7 +1996,8 @@ DataProcessorSpec getITSThresholdCalibratorSpec(const ITSCalibInpConf& inpConf) {"charge-a", VariantType::Int, 0, {"To use with --calculate-slope, it defines the charge (in DAC) for the 1st point used for the slope calculation"}}, {"charge-b", VariantType::Int, 0, {"To use with --calculate-slope, it defines the charge (in DAC) for the 2nd point used for the slope calculation"}}, {"meb-select", VariantType::Int, -1, {"Select from which multi-event buffer consider the hits: 0,1 or 2"}}, - {"s-curve-col-step", VariantType::Int, 8, {"save s-curves points to tree every s-curve-col-step pixels on 1 row"}}}}; + {"s-curve-col-step", VariantType::Int, 8, {"save s-curves points to tree every s-curve-col-step pixels on 1 row"}}, + {"percentage-cut", VariantType::Int, 25, {"discard chip in ITHR/VCASN scan if the percentage of success is less than this cut"}}}}; } } // namespace its } // namespace o2 From 683ffe68d3192607d2cc45e0dca3a7a6695f3396 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 17:25:53 +0200 Subject: [PATCH 0163/2205] DPL: Demote Error to Warning as agreed with Run Coordination --- Framework/Core/src/DataProcessingDevice.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 4e89dee5d5db5..386d5fe4403e9 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -142,7 +142,7 @@ void on_transition_requested_expired(uv_timer_t* handle) if (hasOnlyGenerated(spec)) { O2_SIGNPOST_EVENT_EMIT_INFO(calibration, cid, "callback", "Grace period for source expired. Exiting."); } else { - O2_SIGNPOST_EVENT_EMIT_ERROR(calibration, cid, "callback", "Grace period for data / calibration expired. Exiting."); + O2_SIGNPOST_EVENT_EMIT_WARN(calibration, cid, "callback", "Grace period for data / calibration expired. Exiting."); } state.transitionHandling = TransitionHandlingState::Expired; } From 6e8fbd3f1b9debe83aa263e983ca3816700bf5c9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 17:13:56 +0200 Subject: [PATCH 0164/2205] CCDB: If we parse multiple HTTP headers, take the largest Content-Length --- CCDB/src/CcdbApi.cxx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CCDB/src/CcdbApi.cxx b/CCDB/src/CcdbApi.cxx index b103b4dc63383..ee68d964333bc 100644 --- a/CCDB/src/CcdbApi.cxx +++ b/CCDB/src/CcdbApi.cxx @@ -656,7 +656,20 @@ size_t header_map_callback(char* buffer, size_t size, size_t nitems, void* userd const auto key = boost::algorithm::trim_copy(header.substr(0, index)); const auto value = boost::algorithm::trim_copy(header.substr(index + 1)); LOGP(debug, "Adding #{} {} -> {}", headers->size(), key, value); - headers->insert(std::make_pair(key, value)); + bool insert = true; + if (key == "Content-Length") { + auto cl = headers->find("Content-Length"); + if (cl != headers->end()) { + if (std::stol(cl->second) < stol(value)) { + headers->erase(key); + } else { + insert = false; + } + } + } + if (insert) { + headers->insert(std::make_pair(key, value)); + } } return size * nitems; } From 1cfc5dcee4596d33a143947ae60595e6c9576d22 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 17:14:16 +0200 Subject: [PATCH 0165/2205] CCDB: If growing PMR vector to store CCDB object, use exponential strategy --- CCDB/src/CcdbApi.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CCDB/src/CcdbApi.cxx b/CCDB/src/CcdbApi.cxx index ee68d964333bc..a17458a33e5e6 100644 --- a/CCDB/src/CcdbApi.cxx +++ b/CCDB/src/CcdbApi.cxx @@ -1689,9 +1689,10 @@ void CcdbApi::scheduleDownload(RequestContext& requestContext, size_t* requestCo if (chunk.capacity() < chunk.size() + realsize) { auto cl = ho.header.find("Content-Length"); if (cl != ho.header.end()) { - sz = std::max(chunk.size() + realsize, (size_t)std::stol(cl->second)); + size_t sizeFromHeader = std::stol(cl->second); + sz = std::max(chunk.size() * (sizeFromHeader ? 1 : 2) + realsize, sizeFromHeader); } else { - sz = chunk.size() + realsize; + sz = std::max(chunk.size() * 2, chunk.size() + realsize); // LOGP(debug, "SIZE IS NOT IN HEADER, allocate {}", sz); } chunk.reserve(sz); From 4caf18944046fe62998294b9d7121d0eb1c8aab1 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 29 Aug 2024 19:29:16 +0200 Subject: [PATCH 0166/2205] Optionally always parse trigger word, extra dump options With --always-parse-trigger decoder will always parse the GBT trigger word, even if the 1st trigger of the TF has a continuation flag set (this is a corruption in the real data but can be benign in the threshold calibration data. Extra verbosity option (3) is added to dump annotated cached raw data for every link before actual decoding starts. --- .../include/ITSMFTReconstruction/GBTLink.h | 51 ++++++++++++++++--- .../include/ITSMFTReconstruction/GBTWord.h | 2 +- .../ITSMFTReconstruction/RawPixelDecoder.h | 4 ++ .../common/reconstruction/src/GBTWord.cxx | 10 ++-- .../reconstruction/src/RawPixelDecoder.cxx | 1 + .../common/workflow/src/STFDecoderSpec.cxx | 4 +- 6 files changed, 59 insertions(+), 13 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h index 32c5a9b28a70c..2569caa719e90 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h @@ -80,7 +80,8 @@ struct GBTLink { enum Verbosity : int8_t { Silent = -1, VerboseErrors, VerboseHeaders, - VerboseData }; + VerboseData, + VerboseRawDump }; using RDH = o2::header::RDHAny; using RDHUtils = o2::raw::RDHUtils; @@ -108,6 +109,7 @@ struct GBTLink { // transient data filled from current RDH int wordLength = o2::itsmft::GBTPaddedWordLength; // padded (16bytes) vs non-padded (10bytes) words + bool alwaysParseTrigger = false; bool expectPadding = true; bool rofJumpWasSeen = false; // this link had jump in ROF IR uint32_t lanesActive = 0; // lanes declared by the payload header @@ -141,6 +143,43 @@ struct GBTLink { void cacheData(const void* ptr, size_t sz) { rawData.add(reinterpret_cast(ptr), sz); + if (verbosity >= VerboseRawDump) { + + LOGP(info, "Caching new RDH block for {}", describe()); + const auto* rdh = reinterpret_cast(ptr); + if (!rdh) { + return; + } + RDHUtils::printRDH(rdh); + long szd = RDHUtils::getMemorySize(*rdh); + long offs = sizeof(RDH); + char* ptrR = ((char*)ptr) + sizeof(RDH); + while (offs + wordLength <= szd) { + const o2::itsmft::GBTWord* w = reinterpret_cast(ptrR); + std::string com = fmt::format(" | FeeID:{:#06x} offs: {:6} ", feeID, offs); + if (w->isData()) { + com += "data word"; + } else if (w->isDataHeader()) { + com += "data header"; + } else if (w->isDataTrailer()) { + com += "data trailer"; + } else if (w->isTriggerWord()) { + com += "trigger word"; + } else if (w->isDiagnosticWord()) { + com += "diag word"; + } else if (w->isCalibrationWord()) { + com += "calib word"; + com += fmt::format(" #{}", ((const GBTCalibration*)w)->calibCounter); + } else if (w->isCableDiagnostic()) { + com += "cable diag word"; + } else if (w->isStatus()) { + com += "status word"; + } + w->printX(expectPadding, com); + offs += wordLength; + ptrR += wordLength; + } + } } bool needToPrintError(uint32_t count) { return verbosity == Silent ? false : (verbosity > VerboseErrors || count == 1); } @@ -318,13 +357,13 @@ GBTLink::CollectedDataStatus GBTLink::collectROFCableData(const Mapping& chmap) break; } if (gbtTrg) { - if (!gbtTrg->continuation) { // this is a continuation from the previous CRU page - statistics.nTriggers++; - lanesStop = 0; - lanesWithData = 0; + if (!gbtTrg->continuation || alwaysParseTrigger) { // this is a continuation from the previous CRU page + statistics.nTriggers += gbtTrg->continuation == 0; ir.bc = gbtTrg->bc; ir.orbit = gbtTrg->orbit; trigger = gbtTrg->triggerType; + lanesStop = 0; + lanesWithData = 0; } if (gbtTrg->noData) { if (verbosity >= VerboseHeaders) { @@ -351,7 +390,7 @@ GBTLink::CollectedDataStatus GBTLink::collectROFCableData(const Mapping& chmap) expectPacketDone = true; while (!gbtD->isDataTrailer() && !(cruPageAlignmentPaddingSeen = isAlignmentPadding())) { // start reading real payload - if (verbosity >= VerboseData) { + if ((verbosity % VerboseData) == 0) { gbtD->printX(expectPadding); } GBTLINK_DECODE_ERRORCHECK(errRes, checkErrorsGBTDataID(gbtD)); diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h index 83748a2bf7cdc..a0f758e5a5833 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h @@ -165,7 +165,7 @@ struct GBTWord { uint8_t getHeader() const { return id; } - void printX(bool padded = true) const; + void printX(bool padded = true, std::string com = "") const; void printB(bool padded = true) const; ClassDefNV(GBTWord, 1); diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h index c30615d2fdf15..4846eab140773 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h @@ -91,6 +91,9 @@ class RawPixelDecoder final : public PixelReader void setVerbosity(int v); int getVerbosity() const { return mVerbosity; } + void setAlwaysParseTrigger(bool v) { mAlwaysParseTrigger = v; } + bool getAlwaysParseTrigger() const { return mAlwaysParseTrigger; } + void printReport(bool decstat = true, bool skipNoErr = true) const; void produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo); @@ -164,6 +167,7 @@ class RawPixelDecoder final : public PixelReader bool mROFRampUpStage = false; // are we still in the ROF ramp up stage? bool mSkipRampUpData = false; bool mVerifyDecoder = false; + bool mAlwaysParseTrigger = false; int mVerbosity = 0; int mNThreads = 1; // number of decoding threads // statistics diff --git a/Detectors/ITSMFT/common/reconstruction/src/GBTWord.cxx b/Detectors/ITSMFT/common/reconstruction/src/GBTWord.cxx index 0d635df6fb9c4..1249072333222 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/GBTWord.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/GBTWord.cxx @@ -18,16 +18,16 @@ using namespace o2::itsmft; -void GBTWord::printX(bool padded) const +void GBTWord::printX(bool padded, std::string com) const { /// print in right aligned hex format, optionally padding to 128 bits if (padded) { - LOGF(info, "0x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + LOGF(info, "0x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %s", data8[15], data8[14], data8[13], data8[12], data8[11], data8[10], - data8[9], data8[8], data8[7], data8[6], data8[5], data8[4], data8[3], data8[2], data8[1], data8[0]); + data8[9], data8[8], data8[7], data8[6], data8[5], data8[4], data8[3], data8[2], data8[1], data8[0], com.c_str()); } else { - LOGF(info, "0x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - data8[9], data8[8], data8[7], data8[6], data8[5], data8[4], data8[3], data8[2], data8[1], data8[0]); + LOGF(info, "0x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %s", + data8[9], data8[8], data8[7], data8[6], data8[5], data8[4], data8[3], data8[2], data8[1], data8[0], com.c_str()); } } diff --git a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx index e7db59c303108..47b089ddf6073 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx @@ -270,6 +270,7 @@ void RawPixelDecoder::setupLinks(InputRecord& inputs) lnk.wordLength = (lnk.expectPadding = (RDHUtils::getDataFormat(rdh) == 0)) ? o2::itsmft::GBTPaddedWordLength : o2::itsmft::GBTWordLength; getCreateRUDecode(mMAP.FEEId2RUSW(RDHUtils::getFEEID(rdh))); // make sure there is a RU for this link lnk.verbosity = GBTLink::Verbosity(mVerbosity); + lnk.alwaysParseTrigger = mAlwaysParseTrigger; if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) { LOG(info) << mSelfName << " registered new link " << lnk.describe() << " RUSW=" << int(mMAP.FEEId2RUSW(lnk.feeID)); } diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index 4858128d61369..bbd1a52a919e5 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -95,6 +95,7 @@ void STFDecoder::init(InitContext& ic) if (mDumpOnError != int(GBTLink::RawDataDumps::DUMP_NONE) && (!dumpDir.empty() && !o2::utils::Str::pathIsDirectory(dumpDir))) { throw std::runtime_error(fmt::format("directory {} for raw data dumps does not exist", dumpDir)); } + mDecoder->setAlwaysParseTrigger(ic.options().get("always-parse-trigger")); mDecoder->setAllowEmptyROFs(ic.options().get("allow-empty-rofs")); mDecoder->setRawDumpDirectory(dumpDir); mDecoder->setFillCalibData(mDoCalibData); @@ -414,7 +415,8 @@ DataProcessorSpec getSTFDecoderSpec(const STFDecoderInp& inp) inp.origin == o2::header::gDataOriginITS ? AlgorithmSpec{adaptFromTask>(inp, ggRequest)} : AlgorithmSpec{adaptFromTask>(inp, ggRequest)}, Options{ {"nthreads", VariantType::Int, 1, {"Number of decoding/clustering threads"}}, - {"decoder-verbosity", VariantType::Int, 0, {"Verbosity level (-1: silent, 0: errors, 1: headers, 2: data) of 1st lane"}}, + {"decoder-verbosity", VariantType::Int, 0, {"Verbosity level (-1: silent, 0: errors, 1: headers, 2: data, 3: raw data dump) of 1st lane"}}, + {"always-parse-trigger", VariantType::Bool, false, {"parse trigger word even if flags continuation of old trigger"}}, {"raw-data-dumps", VariantType::Int, int(GBTLink::RawDataDumps::DUMP_NONE), {"Raw data dumps on error (0: none, 1: HBF for link, 2: whole TF for all links"}}, {"raw-data-dumps-directory", VariantType::String, "", {"Destination directory for the raw data dumps"}}, {"unmute-extra-lanes", VariantType::Bool, false, {"allow extra lanes to be as verbose as 1st one"}}, From 889dd5bb21947c05f01049a270eec592326491d8 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 21:13:21 +0200 Subject: [PATCH 0167/2205] GPU Vulkan Display: Fix validation layer warnings --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx | 12 +++++++++--- GPU/GPUTracking/display/shaders/fragment.frag | 2 +- GPU/GPUTracking/display/shaders/vertexPoint.vert | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index d57351bc753f4..8ad487444d94d 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -379,6 +379,7 @@ EndConfig() BeginSubConfig(GPUSettingsDisplayVulkan, vulkan, configStandalone.display, "GLV", 0, "Vulkan display settings", display_vulkan) AddOption(nFramesInFlight, int, 0, "", 0, "Max number of render frames in flight (0 = as many as swapchain images)") AddOption(uniformBuffersInDeviceMemory, bool, 1, "", 0, "Have uniform buffers in host-accessible device memory") +AddOption(forceDevice, int, -1, "", 0, "Force Vulkan device number to use") AddHelp("help", 'h') EndConfig() diff --git a/GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx b/GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx index 2f8a0e6e7c305..4d256d69eb0da 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx +++ b/GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx @@ -354,7 +354,7 @@ void GPUDisplayBackendVulkan::createDevice() const std::vector reqValidationLayers = { "VK_LAYER_KHRONOS_validation"}; auto debugCallback = [](VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) -> VkBool32 { - static bool throwOnError = getenv("GPUCA_VULKAN_VALIDATION_THROW") && atoi(getenv("GPUCA_VULKAN_VALIDATION_THROW")); + static int throwOnError = getenv("GPUCA_VULKAN_VALIDATION_THROW") ? atoi(getenv("GPUCA_VULKAN_VALIDATION_THROW")) : 0; static bool showVulkanValidationInfo = getenv("GPUCA_VULKAN_VALIDATION_INFO") && atoi(getenv("GPUCA_VULKAN_VALIDATION_INFO")); switch (messageSeverity) { case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: @@ -364,7 +364,7 @@ void GPUDisplayBackendVulkan::createDevice() break; case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: GPUWarning("%s", pCallbackData->pMessage); - if (throwOnError) { + if (throwOnError > 1) { throw std::logic_error("break_on_validation_warning"); } break; @@ -440,7 +440,12 @@ void GPUDisplayBackendVulkan::createDevice() bestScore = score; } } - + if (mDisplay->cfg().vulkan.forceDevice != -1) { + if (mDisplay->cfg().vulkan.forceDevice < 0 || mDisplay->cfg().vulkan.forceDevice >= (int)devices.size()) { + throw std::runtime_error("Invalid Vulkan device selected"); + } + mPhysicalDevice = devices[mDisplay->cfg().vulkan.forceDevice]; + } if (!mPhysicalDevice) { throw std::runtime_error("All available Vulkan devices unsuited"); } @@ -1605,6 +1610,7 @@ void GPUDisplayBackendVulkan::finishFrame(bool doScreenshot, bool toMixBuffer, f CHKERR(mGraphicsQueue.submit(1, &submitInfo, mInFlightFence[mCurrentFrame])); } + CHKERR(mDevice.waitForFences(1, &mInFlightFence[mCurrentFrame], true, UINT64_MAX)); // TODO: I think we need to wait for the fence, so that the image was acquired before we present. Perhaps we can present later to avoid delays vk::PresentInfoKHR presentInfo{}; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = stageFinishedSemaphore; diff --git a/GPU/GPUTracking/display/shaders/fragment.frag b/GPU/GPUTracking/display/shaders/fragment.frag index b1dd5690a5429..e6fe7c28a54ba 100644 --- a/GPU/GPUTracking/display/shaders/fragment.frag +++ b/GPU/GPUTracking/display/shaders/fragment.frag @@ -1,6 +1,6 @@ #version 460 core layout (location = 0) out vec4 outColor; -layout (push_constant) uniform pushColor { vec4 color; float size; } pc; +layout (push_constant) uniform pushColor { vec4 color; } pc; void main() { diff --git a/GPU/GPUTracking/display/shaders/vertexPoint.vert b/GPU/GPUTracking/display/shaders/vertexPoint.vert index e91f0c3ac171e..8b87073407298 100644 --- a/GPU/GPUTracking/display/shaders/vertexPoint.vert +++ b/GPU/GPUTracking/display/shaders/vertexPoint.vert @@ -1,7 +1,7 @@ #version 460 core layout (location = 0) in vec3 pos; layout (binding = 0) uniform uniformMatrix { mat4 ModelViewProj; } um; -layout (push_constant) uniform pushSize { vec4 color; float size; } ps; +layout (push_constant) uniform pushSize { layout(offset = 16) float size; } ps; void main() { From b0510fb4093429522b42895c031e4329bad43799 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 29 Aug 2024 21:13:38 +0200 Subject: [PATCH 0168/2205] GPU Display: Some cleanup, fixes and improvements --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 4 +- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- .../Standalone/Benchmark/standalone.cxx | 3 ++ GPU/GPUTracking/display/GPUDisplay.cxx | 3 ++ GPU/GPUTracking/display/GPUDisplayBackend.h | 2 +- .../display/GPUDisplayBackendOpenGL.cxx | 6 +-- .../display/GPUDisplayBackendOpenGL.h | 4 +- .../GPUDisplayBackendOpenGLMagneticField.cxx | 42 +++++++++---------- GPU/GPUTracking/display/GPUDisplayKeys.cxx | 18 ++++---- GPU/GPUTracking/qa/GPUQA.cxx | 2 +- 10 files changed, 48 insertions(+), 38 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 8ad487444d94d..06bf4b5817f3e 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -275,7 +275,7 @@ AddOption(ignoreNonFatalGPUErrors, bool, false, "", 0, "Continue running after h AddOption(tpcIncreasedMinClustersPerRow, unsigned int, 0, "", 0, "Impose a minimum buffer size for the clustersPerRow during TPC clusterization") AddOption(noGPUMemoryRegistration, bool, false, "", 0, "Do not register input / output memory for GPU dma transfer") AddOption(o2PropagatorUseGPUField, bool, true, "", 0, "Makes the internal O2 propagator use the fast GPU polynomial b field approximation") -AddOption(willProvideO2PropagatorLate, bool, false, "", 0, "Disable check for availability of o2 propagator at initialization") +AddOption(willProvideO2PropagatorLate, bool, false, "", 0, "Disable check for availability of o2 propagator and MatLUT at initialization") AddOption(calibObjectsExtraMemorySize, unsigned int, 10u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") AddOption(fastTransformObjectsMinMemorySize, unsigned int, 400u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") AddOption(lateO2MatLutProvisioningSize, unsigned int, 0u, "", 0, "Memory size to reserve for late provisioning of matlut table") @@ -325,7 +325,7 @@ AddOption(drawTPC, bool, true, "", 0, "Enable drawing TPC data") AddOption(drawTRD, bool, true, "", 0, "Enabale drawing TRD data") AddOption(drawTOF, bool, true, "", 0, "Enabale drawing TOF data") AddOption(drawITS, bool, true, "", 0, "Enabale drawing ITS data") -AddOption(drawField, bool, true, "", 0, "Enable drawing magnetic field") +AddOption(drawField, bool, false, "", 0, "Enable drawing magnetic field") AddOption(bFieldStepSize, float, 5.0f, "", 0, "Set field line step size") AddOption(bFieldStepCount, int, 100, "", 0, "Set field line step count") AddOption(bFieldLinesCount, int, 2000, "", 0, "Set field lines count") diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 8188402902674..95575eb6b9c0e 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -323,7 +323,7 @@ bool GPUChainTracking::ValidateSettings() return false; } if (GetRecoSteps() & RecoStep::TRDTracking) { - if (GetProcessingSettings().trdTrackModelO2 && (GetProcessingSettings().createO2Output == 0 || param().rec.tpc.nWaysOuter == 0 || GetMatLUT() == nullptr)) { + if (GetProcessingSettings().trdTrackModelO2 && (GetProcessingSettings().createO2Output == 0 || param().rec.tpc.nWaysOuter == 0 || (GetMatLUT() == nullptr && !GetProcessingSettings().willProvideO2PropagatorLate))) { GPUError("TRD tracking can only run on O2 TPC tracks if createO2Output is enabled (%d), nWaysOuter is set (%d), and matBudLUT is available (0x%p)", (int)GetProcessingSettings().createO2Output, (int)param().rec.tpc.nWaysOuter, (void*)GetMatLUT()); return false; } diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index b5bd2db80aba5..a0cd415ba21e3 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -351,6 +351,9 @@ int SetupReconstruction() } printf("Enabling event display (%s backend)\n", eventDisplay->frontendName()); procSet.eventDisplay = eventDisplay.get(); + if (!configStandalone.QA.noMC) { + procSet.runMC = true; + } } if (procSet.runQA && !configStandalone.QA.noMC) { diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index f380fe694b848..d99333bf651c5 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -1824,6 +1824,9 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() } else { sector = 0; } + if (mQA && mIOPtrs->outputTracksTPCO2MC) { + col = mQA->GetMCLabelCol(mIOPtrs->outputTracksTPCO2MC[i]); + } mThreadTracks[numThread][col][sector][0].emplace_back(i); } #endif diff --git a/GPU/GPUTracking/display/GPUDisplayBackend.h b/GPU/GPUTracking/display/GPUDisplayBackend.h index 569bf1d866b58..978da7c805517 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackend.h +++ b/GPU/GPUTracking/display/GPUDisplayBackend.h @@ -129,7 +129,7 @@ class GPUDisplayBackend backendTypes mBackendType = TYPE_INVALID; const char* mBackendName = nullptr; - std::unique_ptr mMagneticField; + std::unique_ptr mMagneticFieldVisualization; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx b/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx index c26029c92593b..35ac7421520af 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx +++ b/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx @@ -432,8 +432,8 @@ void GPUDisplayBackendOpenGL::ExitBackendA() CHKERR(glDeleteBuffers(1, &mSPIRVModelViewBuffer)); CHKERR(glDeleteBuffers(1, &mSPIRVColorBuffer)); } - if (mMagneticField) { - ExitMagField(); + if (mMagneticFieldVisualization) { + ExitMagFieldVisualization(); } } @@ -532,7 +532,7 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4& } else { CHKERR(glUniformMatrix4fv(mModelViewProjId, 1, GL_FALSE, &modelViewProj.Elements[0][0])); } - if (mMagneticField) { + if (mMagneticFieldVisualization) { CHKERR(glNamedBufferSubData(mFieldModelViewBuffer, 0, sizeof(modelViewProj), &modelViewProj)); } } diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h b/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h index 62207a479bb40..f7e2d4ee44460 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h +++ b/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h @@ -48,9 +48,9 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend void setDepthBuffer() override; void setFrameBuffer(unsigned int newID = 0); int InitBackendA() override; - int InitMagField(); + int InitMagFieldVisualization(); void ExitBackendA() override; - void ExitMagField(); + void ExitMagFieldVisualization(); static int checkShaderStatus(unsigned int shader); static int checkProgramStatus(unsigned int program); void clearScreen(bool alphaOnly = false); diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx b/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx index bcdf282984478..6affd22b3573b 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx +++ b/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx @@ -59,11 +59,11 @@ using namespace GPUCA_NAMESPACE::gpu; } \ } while (false) -int GPUDisplayBackendOpenGL::InitMagField() +int GPUDisplayBackendOpenGL::InitMagFieldVisualization() { #ifndef GPUCA_NO_FMT - mMagneticField = std::make_unique(); - mMagneticField->generateSeedPoints(mDisplay->cfgL().bFieldLinesCount); + mMagneticFieldVisualization = std::make_unique(); + mMagneticFieldVisualization->generateSeedPoints(mDisplay->cfgL().bFieldLinesCount); CHKERR(mVertexShaderPassthrough = glCreateShader(GL_VERTEX_SHADER)); CHKERR(mGeometryShader = glCreateShader(GL_GEOMETRY_SHADER)); @@ -116,7 +116,7 @@ int GPUDisplayBackendOpenGL::InitMagField() CHKERR(glVertexArrayAttribFormat(VAO_field, ATTRIB_ZERO, 3, GL_FLOAT, GL_FALSE, 0)); CHKERR(glCreateBuffers(1, &VBO_field)); - CHKERR(glNamedBufferData(VBO_field, mMagneticField->mFieldLineSeedPoints.size() * sizeof(GPUDisplayMagneticField::vtx), mMagneticField->mFieldLineSeedPoints.data(), GL_STATIC_DRAW)); + CHKERR(glNamedBufferData(VBO_field, mMagneticFieldVisualization->mFieldLineSeedPoints.size() * sizeof(GPUDisplayMagneticField::vtx), mMagneticFieldVisualization->mFieldLineSeedPoints.data(), GL_STATIC_DRAW)); CHKERR(glVertexArrayVertexBuffer(VAO_field, BUFFER_IDX, VBO_field, 0, sizeof(GPUDisplayMagneticField::vtx))); @@ -126,17 +126,17 @@ int GPUDisplayBackendOpenGL::InitMagField() CHKERR(glNamedBufferData(mFieldModelViewBuffer, sizeof(hmm_mat4), nullptr, GL_STREAM_DRAW)); CHKERR(glCreateBuffers(1, &mFieldModelConstantsBuffer)); - CHKERR(glNamedBufferData(mFieldModelConstantsBuffer, sizeof(GPUDisplayMagneticField::RenderConstantsUniform), mMagneticField->mRenderConstantsUniform.get(), GL_STREAM_DRAW)); + CHKERR(glNamedBufferData(mFieldModelConstantsBuffer, sizeof(GPUDisplayMagneticField::RenderConstantsUniform), mMagneticFieldVisualization->mRenderConstantsUniform.get(), GL_STREAM_DRAW)); CHKERR(glCreateBuffers(1, &mSolenoidSegmentsBuffer)); - CHKERR(glNamedBufferData(mSolenoidSegmentsBuffer, sizeof(GPUDisplayMagneticField::SolenoidSegmentsUniform), mMagneticField->mSolenoidSegments.get(), GL_STREAM_DRAW)); + CHKERR(glNamedBufferData(mSolenoidSegmentsBuffer, sizeof(GPUDisplayMagneticField::SolenoidSegmentsUniform), mMagneticFieldVisualization->mSolenoidSegments.get(), GL_STREAM_DRAW)); CHKERR(glCreateBuffers(1, &mSolenoidParameterizationBuffer)); - CHKERR(glNamedBufferData(mSolenoidParameterizationBuffer, sizeof(GPUDisplayMagneticField::SolenoidParameterizationUniform), mMagneticField->mSolenoidParameterization.get(), GL_STREAM_DRAW)); + CHKERR(glNamedBufferData(mSolenoidParameterizationBuffer, sizeof(GPUDisplayMagneticField::SolenoidParameterizationUniform), mMagneticFieldVisualization->mSolenoidParameterization.get(), GL_STREAM_DRAW)); CHKERR(glCreateBuffers(1, &mDipoleSegmentsBuffer)); - CHKERR(glNamedBufferData(mDipoleSegmentsBuffer, sizeof(GPUDisplayMagneticField::DipoleSegmentsUniform), mMagneticField->mDipoleSegments.get(), GL_STREAM_DRAW)); + CHKERR(glNamedBufferData(mDipoleSegmentsBuffer, sizeof(GPUDisplayMagneticField::DipoleSegmentsUniform), mMagneticFieldVisualization->mDipoleSegments.get(), GL_STREAM_DRAW)); CHKERR(glCreateBuffers(1, &mDipoleParameterizationBuffer)); - CHKERR(glNamedBufferData(mDipoleParameterizationBuffer, sizeof(GPUDisplayMagneticField::DipoleParameterizationUniform), mMagneticField->mDipoleParameterization.get(), GL_STREAM_DRAW)); + CHKERR(glNamedBufferData(mDipoleParameterizationBuffer, sizeof(GPUDisplayMagneticField::DipoleParameterizationUniform), mMagneticFieldVisualization->mDipoleParameterization.get(), GL_STREAM_DRAW)); #else throw std::runtime_error("Magnetic field needs fmt"); #endif @@ -146,18 +146,18 @@ int GPUDisplayBackendOpenGL::InitMagField() unsigned int GPUDisplayBackendOpenGL::drawField() { - if (!mMagneticField) { - return InitMagField(); // next frame will fill MVP matrix + if (!mMagneticFieldVisualization) { + return InitMagFieldVisualization(); // next frame will fill MVP matrix } - if (mMagneticField->mFieldLineSeedPoints.size() != (unsigned int)mDisplay->cfgL().bFieldLinesCount) { - mMagneticField->generateSeedPoints(mDisplay->cfgL().bFieldLinesCount); - CHKERR(glNamedBufferData(VBO_field, mMagneticField->mFieldLineSeedPoints.size() * sizeof(GPUDisplayMagneticField::vtx), mMagneticField->mFieldLineSeedPoints.data(), GL_STATIC_DRAW)); + if (mMagneticFieldVisualization->mFieldLineSeedPoints.size() != (unsigned int)mDisplay->cfgL().bFieldLinesCount) { + mMagneticFieldVisualization->generateSeedPoints(mDisplay->cfgL().bFieldLinesCount); + CHKERR(glNamedBufferData(VBO_field, mMagneticFieldVisualization->mFieldLineSeedPoints.size() * sizeof(GPUDisplayMagneticField::vtx), mMagneticFieldVisualization->mFieldLineSeedPoints.data(), GL_STATIC_DRAW)); } - mMagneticField->mRenderConstantsUniform->StepSize = mDisplay->cfgL().bFieldStepSize; - mMagneticField->mRenderConstantsUniform->StepCount = mDisplay->cfgL().bFieldStepCount; - CHKERR(glNamedBufferSubData(mFieldModelConstantsBuffer, 0, sizeof(GPUDisplayMagneticField::RenderConstantsUniform), mMagneticField->mRenderConstantsUniform.get())); + mMagneticFieldVisualization->mRenderConstantsUniform->StepSize = mDisplay->cfgL().bFieldStepSize; + mMagneticFieldVisualization->mRenderConstantsUniform->StepCount = mDisplay->cfgL().bFieldStepCount; + CHKERR(glNamedBufferSubData(mFieldModelConstantsBuffer, 0, sizeof(GPUDisplayMagneticField::RenderConstantsUniform), mMagneticFieldVisualization->mRenderConstantsUniform.get())); CHKERR(glBindVertexArray(VAO_field)); CHKERR(glUseProgram(mShaderProgramField)); @@ -172,7 +172,7 @@ unsigned int GPUDisplayBackendOpenGL::drawField() CHKERR(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mSolenoidParameterizationBuffer)); CHKERR(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mDipoleParameterizationBuffer)); - CHKERR(glDrawArrays(GL_POINTS, 0, mMagneticField->mFieldLineSeedPoints.size())); + CHKERR(glDrawArrays(GL_POINTS, 0, mMagneticFieldVisualization->mFieldLineSeedPoints.size())); CHKERR(glUseProgram(0)); CHKERR(glBindVertexArray(0)); @@ -180,7 +180,7 @@ unsigned int GPUDisplayBackendOpenGL::drawField() return 0; } -void GPUDisplayBackendOpenGL::ExitMagField() +void GPUDisplayBackendOpenGL::ExitMagFieldVisualization() { CHKERR(glDeleteBuffers(1, &mFieldModelViewBuffer)); CHKERR(glDeleteBuffers(1, &mFieldModelConstantsBuffer)); @@ -196,10 +196,10 @@ void GPUDisplayBackendOpenGL::ExitMagField() } #else // GPUCA_BUILD_EVENT_DISPLAY_OPENGL -int GPUDisplayBackendOpenGL::InitMagField() +int GPUDisplayBackendOpenGL::InitMagFieldVisualization() { return 0; } unsigned int GPUDisplayBackendOpenGL::drawField() { return 0; } -void GPUDisplayBackendOpenGL::ExitMagField() {} +void GPUDisplayBackendOpenGL::ExitMagFieldVisualization() {} #endif // GPUCA_BUILD_EVENT_DISPLAY_OPENGL diff --git a/GPU/GPUTracking/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/GPUDisplayKeys.cxx index 7dc95111e819b..b0ae3f50aafeb 100644 --- a/GPU/GPUTracking/display/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/GPUDisplayKeys.cxx @@ -47,7 +47,7 @@ const char* HelpText[] = { "[o] / [p] / [O] / [P] Save / restore current camera position / Animation path", "[h] Print Help", "[H] Show info texts", - "[q] / [Q] Start / Stop Qt GUI", + "[q] Start / Stop Qt GUI", "[w] / [s] / [a] / [d] Zoom / Strafe Left and Right", "[pgup] / [pgdn] Strafe up / down", "[e] / [f] Rotate left / right", @@ -64,7 +64,7 @@ const char* HelpText[] = { "[F1] / [F2] / [F3] / [F4] Enable / disable drawing of TPC / TRD / TOF / ITS", "[SHIFT] + [F1] to [F4] Enable / disable track detector filter", "[SHIFT] + [F12] Switch track detector filter between AND and OR mode" - // FREE: [m] [SPACE] [q] [Q] + // FREE: [m] [SPACE] [Q] // Test setting: ^ }; @@ -470,11 +470,15 @@ void GPUDisplay::HandleKey(unsigned char key) SetInfo("Showing help text", 1); } } else if (key == 'q') { - SetInfo("Starting GUI", 1); - mFrontend->startGUI(); - } else if (key == 'Q') { - SetInfo("Stopping GUI", 1); - mFrontend->stopGUI(); + static bool GUIStarted = false; + if (GUIStarted) { + SetInfo("Stopping GUI", 1); + mFrontend->stopGUI(); + } else { + SetInfo("Starting GUI", 1); + mFrontend->startGUI(); + } + GUIStarted = !GUIStarted; } /* else if (key == '^') diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 846ba315a07a5..b0df26c0e80d8 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -635,7 +635,7 @@ int GPUQA::ReadO2MCData(const char* filename) return 1; } if (mTracking && mTracking->GetProcessingSettings().debugLevel >= 2) { - printf("Read %ld MC Infos\n", ftell(fp)); + printf("Read %ld bytes MC Infos\n", ftell(fp)); } fclose(fp); if (mTracking) { From cbcd7517b658f952aa10f24de8920bbcc412c3e3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 30 Aug 2024 10:04:14 +0200 Subject: [PATCH 0169/2205] ITS: Alllow ROF data loading to be overridden (#13449) Signed-off-by: Felix Schlepper --- .../include/ITStracking/TrackingInterface.h | 16 +++++++++--- .../ITS/tracking/src/TrackingInterface.cxx | 25 ++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingInterface.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingInterface.h index 1c4d4871ab574..717ee892816ee 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingInterface.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingInterface.h @@ -57,8 +57,8 @@ class ITSTrackingInterface template void run(framework::ProcessingContext& pc); - void updateTimeDependentParams(framework::ProcessingContext& pc); - void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj); + virtual void updateTimeDependentParams(framework::ProcessingContext& pc); + virtual void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj); // Custom void setTraitsFromProvider(VertexerTraits*, TrackerTraits*, TimeFrame*); @@ -70,6 +70,15 @@ class ITSTrackingInterface mMode = mode; } + TimeFrame* mTimeFrame = nullptr; + + protected: + virtual void loadROF(gsl::span& trackROFspan, + gsl::span clusters, + gsl::span::iterator& pattIt, + const dataformats::MCTruthContainer* mcLabels); + void getConfiguration(framework::ProcessingContext& pc); + private: bool mIsMC = false; bool mRunVertexer = true; @@ -80,9 +89,8 @@ class ITSTrackingInterface const o2::itsmft::TopologyDictionary* mDict = nullptr; std::unique_ptr mTracker = nullptr; std::unique_ptr mVertexer = nullptr; - TimeFrame* mTimeFrame = nullptr; const o2::dataformats::MeanVertexObject* mMeanVertex; }; } // namespace o2::its -#endif // O2_ITS_TRACKINGINTERFACE \ No newline at end of file +#endif // O2_ITS_TRACKINGINTERFACE diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx index 31aca536e532e..f00d87164d7d6 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx @@ -166,7 +166,7 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) gsl::span::iterator pattIt = patterns.begin(); gsl::span trackROFspan(trackROFvec); - mTimeFrame->loadROFrameData(trackROFspan, compClusters, pattIt, mDict, labels); + loadROF(trackROFspan, compClusters, pattIt, labels); pattIt = patterns.begin(); std::vector savedROF; auto logger = [&](std::string s) { LOG(info) << s; }; @@ -343,11 +343,16 @@ void ITSTrackingInterface::updateTimeDependentParams(framework::ProcessingContex } GeometryTGeo* geom = GeometryTGeo::Instance(); geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); - mVertexer->getGlobalConfiguration(); - mTracker->getGlobalConfiguration(); - if (mOverrideBeamEstimation) { - pc.inputs().get("meanvtx"); - } + getConfiguration(pc); + } +} + +void ITSTrackingInterface::getConfiguration(framework::ProcessingContext& pc) +{ + mVertexer->getGlobalConfiguration(); + mTracker->getGlobalConfiguration(); + if (mOverrideBeamEstimation) { + pc.inputs().get("meanvtx"); } } @@ -391,6 +396,14 @@ void ITSTrackingInterface::setTraitsFromProvider(VertexerTraits* vertexerTraits, mTracker->adoptTimeFrame(*mTimeFrame); } +void ITSTrackingInterface::loadROF(gsl::span& trackROFspan, + gsl::span clusters, + gsl::span::iterator& pattIt, + const dataformats::MCTruthContainer* mcLabels) +{ + mTimeFrame->loadROFrameData(trackROFspan, clusters, pattIt, mDict, mcLabels); +} + template void ITSTrackingInterface::run(framework::ProcessingContext& pc); template void ITSTrackingInterface::run(framework::ProcessingContext& pc); } // namespace its From 7ce6af55bedd8280f1e0d5ba57a42c20cf4e413c Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 30 Aug 2024 12:58:50 +0200 Subject: [PATCH 0170/2205] Fix verbosity parsing in ITS decoder --decoder-verbosity N with N>0 and N%2==0 will trigger logging of every raw data word being decoded, with N>2 the dumping of annotated raw data before decoding starts is activated. The difference is that during decoding some raw data might be suppressed in case of detected errors while the dump with N>2 is done on the imeddiate input. --- .../reconstruction/include/ITSMFTReconstruction/GBTLink.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h index 2569caa719e90..7354dc100ffee 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h @@ -266,6 +266,7 @@ GBTLink::CollectedDataStatus GBTLink::collectROFCableData(const Mapping& chmap) currRawPiece = rawData.currentPiece(); uint8_t errRes = uint8_t(GBTLink::NoError); bool expectPacketDone = false; + bool verboseRawData = verbosity > 0 && ((verbosity % VerboseData) == 0); ir.clear(); while (currRawPiece) { // we may loop over multiple CRU page if (dataOffset >= currRawPiece->size) { @@ -390,7 +391,7 @@ GBTLink::CollectedDataStatus GBTLink::collectROFCableData(const Mapping& chmap) expectPacketDone = true; while (!gbtD->isDataTrailer() && !(cruPageAlignmentPaddingSeen = isAlignmentPadding())) { // start reading real payload - if ((verbosity % VerboseData) == 0) { + if (verboseRawData) { gbtD->printX(expectPadding); } GBTLINK_DECODE_ERRORCHECK(errRes, checkErrorsGBTDataID(gbtD)); From b3d62bb18a32d31e1dc4af14fb1637d88aae064d Mon Sep 17 00:00:00 2001 From: Ruben Shahoyan Date: Sat, 31 Aug 2024 14:06:20 +0200 Subject: [PATCH 0171/2205] Fixes for calibration data decoding (#13467) * Clean cable pointers cache if links set is modified * Check for the end-of-page padding after seeing trailer --- .../reconstruction/include/ITSMFTReconstruction/GBTLink.h | 8 ++++++-- .../ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h index 7354dc100ffee..62e0f82299a1f 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h @@ -154,7 +154,7 @@ struct GBTLink { long szd = RDHUtils::getMemorySize(*rdh); long offs = sizeof(RDH); char* ptrR = ((char*)ptr) + sizeof(RDH); - while (offs + wordLength <= szd) { + while (offs < szd) { const o2::itsmft::GBTWord* w = reinterpret_cast(ptrR); std::string com = fmt::format(" | FeeID:{:#06x} offs: {:6} ", feeID, offs); if (w->isData()) { @@ -420,9 +420,13 @@ GBTLink::CollectedDataStatus GBTLink::collectROFCableData(const Mapping& chmap) dataOffset += wordLength; GBTLINK_DECODE_ERRORCHECK(errRes, checkErrorsTrailerWord(gbtT)); + // are we at the end of the page? + if ((cruPageAlignmentPaddingSeen = isAlignmentPadding())) { + dataOffset = lastPageSize; + } // we finished the GBT page, but there might be continuation on the next CRU page if (!gbtT->packetDone) { - GBTLINK_DECODE_ERRORCHECK(errRes, checkErrorsPacketDoneMissing(gbtT, (dataOffset < currRawPiece->size && !isAlignmentPadding()))); + GBTLINK_DECODE_ERRORCHECK(errRes, checkErrorsPacketDoneMissing(gbtT, (dataOffset < currRawPiece->size && !cruPageAlignmentPaddingSeen))); continue; // keep reading next CRU page } // accumulate packet states diff --git a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx index 47b089ddf6073..209a9fde82632 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx @@ -312,6 +312,7 @@ void RawPixelDecoder::setupLinks(InputRecord& inputs) } for (auto& ru : mRUDecodeVec) { // reset RU->link references since they may have been changed memset(&ru.links[0], -1, RUDecodeData::MaxLinksPerRU * sizeof(int)); + memset(&ru.cableLinkPtr[0], 0, RUDecodeData::MaxCablesPerRU * sizeof(GBTLink*)); } } // sort RUs in stave increasing order From a3e87d686b5d4630d718debf1e015fcbb6153da5 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Sun, 1 Sep 2024 16:33:50 +0200 Subject: [PATCH 0172/2205] Fix std::make_shared for codechecker (#13469) --- Generators/src/GeneratorHepMC.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Generators/src/GeneratorHepMC.cxx b/Generators/src/GeneratorHepMC.cxx index 0af9363665bb5..b0b31b7ce8e93 100644 --- a/Generators/src/GeneratorHepMC.cxx +++ b/Generators/src/GeneratorHepMC.cxx @@ -489,9 +489,9 @@ bool GeneratorHepMC::makeReader() // specifies that LOG(info) << "Creating ASCII reader of " << filename; if (mVersion == 2) { - mReader.reset(new HepMC3::ReaderAsciiHepMC2(filename)); + mReader = std::make_shared(filename); } else { - mReader.reset(new HepMC3::ReaderAscii(filename)); + mReader = std::make_shared(filename); } } else { LOG(info) << "Deduce a reader of " << filename; From ffb9881bb09a510b47efcc7008e350daca206028 Mon Sep 17 00:00:00 2001 From: Marek Mytkowski <101755133+mytkom@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:19:34 +0200 Subject: [PATCH 0173/2205] DPL Analysis: add generic getter to expression column creation macro (#13408) --- Framework/Core/include/Framework/ASoA.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 2b2fa72e78072..1b8406b9109e3 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2104,6 +2104,12 @@ DECLARE_SOA_ITERATOR_METADATA(); { \ return *mColumnIterator; \ } \ + \ + decltype(auto) get() const \ + { \ + return _Getter_(); \ + } \ + \ static o2::framework::expressions::Projector Projector() \ { \ return _Expression_; \ From 9469a3c60353f11b758c28b608dafe6747f36d8f Mon Sep 17 00:00:00 2001 From: nivram-phy Date: Mon, 2 Sep 2024 12:31:15 +0200 Subject: [PATCH 0174/2205] Merged Noise Map branch (#13356) * Adding functionalities to produced merged noise map objects * Adding functionalities to produced merged noise map objects * Clang format * Fixing typo * fixing typos * Please consider the following formatting changes * fixing typos * Please consider the following formatting changes * fixing typos in copyright issue notice * making small changes to make code more stable * fixing typos * Please consider the following formatting changes * modifying checks on validtime * modifying checks on validtime --------- Co-authored-by: Niveditha Ramasubramanian Co-authored-by: ALICE Action Bot --- .../include/DataFormatsITSMFT/NoiseMap.h | 15 +++- .../MFTCalibration/NoiseCalibratorSpec.h | 6 ++ .../calibration/src/NoiseCalibratorSpec.cxx | 81 ++++++++++++++++++- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/NoiseMap.h b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/NoiseMap.h index ba98bf2e1e101..49e6f531eeb76 100644 --- a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/NoiseMap.h +++ b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/NoiseMap.h @@ -169,7 +169,6 @@ class NoiseMap // Methods required by the calibration framework void print(); void fill(const gsl::span data); - void merge(const NoiseMap* prev) {} const std::map* getChipMap(int chip) const { return chip < (int)mNoisyPixels.size() ? &mNoisyPixels[chip] : nullptr; } @@ -203,6 +202,20 @@ class NoiseMap return std::ceil((1. + 1. / t) / (relErr * relErr)); } + NoiseMap merge(const NoiseMap* prev) + { + int incre = 0; + for (size_t i = 0; i < (int)mNoisyPixels.size(); ++i) { + for (const auto& prev_np : prev->mNoisyPixels[i]) { // only enters this for loop if the "i" chip exists. + if (mNoisyPixels[i].find(prev_np.first) == mNoisyPixels[i].end()) { + mNoisyPixels[i][prev_np.first] = prev_np.second; + incre++; + } + } // end of for loop on elements of previous noise map + } // end of for loop on i (chip ID) + return (mNoisyPixels); + } // end of void merge + size_t size() const { return mNoisyPixels.size(); } void setNumOfStrobes(long n) { mNumOfStrobes = n; } void addStrobes(long n) { mNumOfStrobes += n; } diff --git a/Detectors/ITSMFT/MFT/calibration/include/MFTCalibration/NoiseCalibratorSpec.h b/Detectors/ITSMFT/MFT/calibration/include/MFTCalibration/NoiseCalibratorSpec.h index 2a5b2d6025e37..c28e5d82ca46f 100644 --- a/Detectors/ITSMFT/MFT/calibration/include/MFTCalibration/NoiseCalibratorSpec.h +++ b/Detectors/ITSMFT/MFT/calibration/include/MFTCalibration/NoiseCalibratorSpec.h @@ -16,6 +16,8 @@ #include +#include "CCDB/CcdbApi.h" + #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" @@ -48,8 +50,10 @@ class NoiseCalibratorSpec : public Task void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final; private: + o2::ccdb::CcdbApi api; void updateTimeDependentParams(ProcessingContext& pc); void sendOutputCcdb(DataAllocator& output); + void sendOutputCcdbMerge(DataAllocator& output); void sendOutputCcdbDcs(DataAllocator& output); void sendOutputDcs(DataAllocator& output); void setOutputDcs(const o2::itsmft::NoiseMap& payload); @@ -57,10 +61,12 @@ class NoiseCalibratorSpec : public Task std::unique_ptr mCalibrator = nullptr; std::shared_ptr mCCDBRequest; std::string mPath; + std::string mPathMerge; std::string mMeta; std::vector> mNoiseMapForDcs; std::string mPathDcs; + std::string mPathDcsMerge; std::string mOutputType; double mThresh; diff --git a/Detectors/ITSMFT/MFT/calibration/src/NoiseCalibratorSpec.cxx b/Detectors/ITSMFT/MFT/calibration/src/NoiseCalibratorSpec.cxx index d299bb82a51d7..8c79dcfebd8db 100644 --- a/Detectors/ITSMFT/MFT/calibration/src/NoiseCalibratorSpec.cxx +++ b/Detectors/ITSMFT/MFT/calibration/src/NoiseCalibratorSpec.cxx @@ -48,6 +48,8 @@ void NoiseCalibratorSpec::init(InitContext& ic) LOGP(info, "Setting the probability threshold to {} with relative error {}", probT, probTRelErr); mStopMeOnly = ic.options().get("stop-me-only"); mPath = ic.options().get("path-CCDB"); + mPathMerge = ic.options().get("path-CCDB-merge"); + mMeta = ic.options().get("meta"); mStart = ic.options().get("tstart"); mEnd = ic.options().get("tend"); @@ -57,6 +59,7 @@ void NoiseCalibratorSpec::init(InitContext& ic) mPathDcs = ic.options().get("path-DCS"); mOutputType = ic.options().get("send-to-server"); mNoiseMapForDcs.clear(); + api.init("http://alice-ccdb.cern.ch"); } void NoiseCalibratorSpec::run(ProcessingContext& pc) @@ -72,6 +75,8 @@ void NoiseCalibratorSpec::run(ProcessingContext& pc) if (mOutputType.compare("CCDB") == 0) { LOG(info) << "Sending an object to Production-CCDB"; sendOutputCcdb(pc.outputs()); + LOG(info) << "Sending an object to Production-CCDBMerge"; + sendOutputCcdbMerge(pc.outputs()); } else if (mOutputType.compare("DCS") == 0) { LOG(info) << "Sending an object to DCS-CCDB"; sendOutputDcs(pc.outputs()); @@ -92,6 +97,8 @@ void NoiseCalibratorSpec::run(ProcessingContext& pc) if (mOutputType.compare("CCDB") == 0) { LOG(info) << "Sending an object to Production-CCDB"; sendOutputCcdb(pc.outputs()); + LOG(info) << "Sending an object to Production-CCDBMerge"; + sendOutputCcdbMerge(pc.outputs()); } else if (mOutputType.compare("DCS") == 0) { LOG(info) << "Sending an object to DCS-CCDB"; sendOutputDcs(pc.outputs()); @@ -237,7 +244,73 @@ void NoiseCalibratorSpec::sendOutputCcdb(DataAllocator& output) auto flName = o2::ccdb::CcdbApi::generateFileName("noise"); auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info); info.setFileName(flName); - LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() + LOG(info) << "Sending object CCDB " << info.getPath() << "/" << info.getFileName() + << " of size " << image->size() + << " bytes, valid for " << info.getStartValidityTimestamp() + << " : " << info.getEndValidityTimestamp(); + + using clbUtils = o2::calibration::Utils; + output.snapshot(Output{clbUtils::gDataOriginCDBPayload, "MFT_NoiseMap", 0}, *image.get()); + output.snapshot(Output{clbUtils::gDataOriginCDBWrapper, "MFT_NoiseMap", 0}, info); +} + +void NoiseCalibratorSpec::sendOutputCcdbMerge(DataAllocator& output) +{ + + LOG(info) << "CCDB-Merge mode"; + + static bool done = false; + if (done) { + return; + } + done = true; + + mCalibrator->finalize(); + + long tstart = mStart; + if (tstart == -1) { + tstart = o2::ccdb::getCurrentTimestamp(); + } + long tend = mEnd; + if (tend == -1) { + constexpr long SECONDSPERYEAR = 365 * 24 * 60 * 60; + tend = o2::ccdb::getFutureTimestamp(SECONDSPERYEAR); + } + + std::map meta; + auto toKeyValPairs = [&meta](std::vector const& tokens) { + for (auto& token : tokens) { + auto keyval = Str::tokenize(token, '=', false); + if (keyval.size() != 2) { + LOG(error) << "Illegal command-line key/value string: " << token; + continue; + } + Str::trim(keyval[1]); + meta[keyval[0]] = keyval[1]; + } + }; + toKeyValPairs(Str::tokenize(mMeta, ';', true)); + + long startTF, endTF; + + auto payload = mCalibrator->getNoiseMap(); + // const auto& payload = mCalibrator->getNoiseMap(starTF, endTF); //For TimeSlot calibration + map headers; + map filter; + auto* payloadPrev1 = api.retrieveFromTFileAny(mPath, filter, -1, &headers); + long validtime = std::stol(headers["Valid-From"]); + auto mergedPL = payload; + if (validtime > 0) { + validtime = validtime - 1; + auto* payloadPrev2 = api.retrieveFromTFileAny(mPath, filter, validtime, &headers); + auto bufferPL = payloadPrev2->merge(payloadPrev1); + mergedPL = payload.merge(&bufferPL); + } + o2::ccdb::CcdbObjectInfo info(mPathMerge, "NoiseMap", "noise.root", meta, tstart, tend); + auto flName = o2::ccdb::CcdbApi::generateFileName("noise"); + auto image = o2::ccdb::CcdbApi::createObjectImage(&mergedPL, &info); + info.setFileName(flName); + LOG(info) << "Sending object ccdb-merge " << info.getPath() << "/" << info.getFileName() << " of size " << image->size() << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp(); @@ -310,12 +383,15 @@ void NoiseCalibratorSpec::endOfStream(o2::framework::EndOfStreamContext& ec) if (mOutputType.compare("CCDB") == 0) { LOG(info) << "Sending an object to Production-CCDB"; sendOutputCcdb(ec.outputs()); + LOG(info) << "Sending an object to Production-CCDB-Merge"; + sendOutputCcdbMerge(ec.outputs()); } else if (mOutputType.compare("DCS") == 0) { LOG(info) << "Sending an object to DCS-CCDB"; sendOutputDcs(ec.outputs()); } else { LOG(info) << "Sending an object to Production-CCDB and DCS-CCDB"; sendOutputCcdbDcs(ec.outputs()); + sendOutputCcdbMerge(ec.outputs()); } } @@ -374,7 +450,8 @@ DataProcessorSpec getNoiseCalibratorSpec(bool useDigits) {"tstart", VariantType::Int64, -1ll, {"Start of validity timestamp"}}, {"tend", VariantType::Int64, -1ll, {"End of validity timestamp"}}, {"path-CCDB", VariantType::String, "/MFT/Calib/NoiseMap", {"Path to write to in CCDB"}}, - {"path-DCS", VariantType::String, "/MFT/Config/NoiseMap", {"Path to write to in CCDB"}}, + {"path-CCDB-merge", VariantType::String, "/MFT/Calib/NoiseMapMerged", {"Path to write merged file to in CCDB"}}, + {"path-DCS", VariantType::String, "/MFT/Config/NoiseMap", {"Path to write to in DCS"}}, {"meta", VariantType::String, "", {"meta data to write in CCDB"}}, {"send-to-server", VariantType::String, "CCDB-DCS", {"meta data to write in DCS-CCDB"}}, {"stop-me-only", VariantType::Bool, false, {"At sufficient statistics stop only this device, otherwise whole workflow"}}}}; From 61bdfb11b1440be85a0daa59bc97991d78d11673 Mon Sep 17 00:00:00 2001 From: jmyrcha Date: Mon, 2 Sep 2024 16:44:49 +0200 Subject: [PATCH 0175/2205] o2-eve-workflow: fix number of files problem (urgent) (#13468) --- EventVisualisation/Workflow/src/FileProducer.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/EventVisualisation/Workflow/src/FileProducer.cxx b/EventVisualisation/Workflow/src/FileProducer.cxx index 818ab546f3047..c50dcb8fad135 100644 --- a/EventVisualisation/Workflow/src/FileProducer.cxx +++ b/EventVisualisation/Workflow/src/FileProducer.cxx @@ -41,18 +41,18 @@ FileProducer::FileProducer(const std::string& path, const std::string& ext, int std::string FileProducer::newFileName() const { - auto millisec_since_epoch = duration_cast(system_clock::now().time_since_epoch()).count(); + const auto millisec_since_epoch = duration_cast(system_clock::now().time_since_epoch()).count(); char hostname[_POSIX_HOST_NAME_MAX]; gethostname(hostname, _POSIX_HOST_NAME_MAX); - auto pid = getpid(); - auto result = fmt::format(fmt::runtime(this->mName), - fmt::arg("hostname", hostname), - fmt::arg("pid", pid), - fmt::arg("timestamp", millisec_since_epoch), - fmt::arg("ext", this->mExt)); - std::vector ext = {".json", ".root"}; + const auto pid = getpid(); + const auto result = fmt::format(fmt::runtime(this->mName), + fmt::arg("hostname", hostname), + fmt::arg("pid", pid), + fmt::arg("timestamp", millisec_since_epoch), + fmt::arg("ext", this->mExt)); + const std::vector ext = {".json", ".root", ".eve"}; DirectoryLoader::reduceNumberOfFiles(this->mPath, DirectoryLoader::load(this->mPath, "_", ext), this->mFilesInFolder); return this->mPath + "/" + result; From 0129685d3d65d0fc9d2a3c5799ff5932f76d53a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Mon, 2 Sep 2024 17:06:02 +0200 Subject: [PATCH 0176/2205] [Data model] add expected times (#13454) --- .../CommonConstants/PhysicsConstants.h | 10 ++++- .../include/Framework/AnalysisDataModel.h | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Common/Constants/include/CommonConstants/PhysicsConstants.h b/Common/Constants/include/CommonConstants/PhysicsConstants.h index 64d0aaca5873f..64c4ac9c6635e 100644 --- a/Common/Constants/include/CommonConstants/PhysicsConstants.h +++ b/Common/Constants/include/CommonConstants/PhysicsConstants.h @@ -193,8 +193,14 @@ constexpr double MassLambda = MassLambda0; constexpr double MassHyperhydrog4 = MassHyperHydrogen4; constexpr double MassHyperhelium4 = MassHyperHelium4; -constexpr float LightSpeedCm2S = 299792458.e2; // C in cm/s -constexpr float LightSpeedCm2NS = LightSpeedCm2S * 1e-9; // C in cm/ns +// Light speed +constexpr float LightSpeedCm2S = 299792458.e2; // C in cm/s +constexpr float LightSpeedCm2NS = LightSpeedCm2S * 1e-9; // C in cm/ns +constexpr float LightSpeedCm2PS = LightSpeedCm2S * 1e-12; // C in cm/ps + +// Light speed inverse +constexpr float invLightSpeedCm2PS = 1. / LightSpeedCm2PS; // 1/C in ps/cm + } // namespace o2::constants::physics #endif diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index a5ee512e80f15..0833c6e4aae65 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -266,6 +266,41 @@ DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector ma ifnode(aod::track::trdPattern > (uint8_t)0, static_cast(o2::aod::track::TRD), (uint8_t)0x0) | ifnode((aod::track::tofChi2 >= 0.f) && (aod::track::tofExpMom > 0.f), static_cast(o2::aod::track::TOF), (uint8_t)0x0)); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTime, tofExpTime, //! Expected time for the track to reach the TOF + [](float length, float tofExpMom, float mMassZSqared) -> float { + if (tofExpMom <= 0.f) { + return -999.f; + } + return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimePi, tofExpTimePi, //! Expected time for the track to reach the TOF under the pion hypothesis + [](float length, float tofExpMom) -> float { + if (tofExpMom <= 0.f) { + return -999.f; + } + constexpr float mMassZSqared = o2::constants::physics::MassPionCharged * o2::constants::physics::MassPionCharged; + return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeKa, tofExpTimeKa, //! Expected time for the track to reach the TOF under the kaon hypothesis + [](float length, float tofExpMom) -> float { + if (tofExpMom <= 0.f) { + return -999.f; + } + constexpr float mMassZSqared = o2::constants::physics::MassKaonCharged * o2::constants::physics::MassKaonCharged; + return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimePr, tofExpTimePr, //! Expected time for the track to reach the TOF under the proton hypothesis + [](float length, float tofExpMom) -> float { + if (tofExpMom <= 0.f) { + return -999.f; + } + constexpr float mMassZSqared = o2::constants::physics::MassProton * o2::constants::physics::MassProton; + return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + }); + namespace v001 { DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector map version 1, see enum DetectorMapEnum @@ -500,6 +535,10 @@ DECLARE_SOA_TABLE_FULL(StoredTracksExtra_000, "TracksExtra", "AOD", "TRACKEXTRA" track::HasTRD, track::HasTOF, track::TPCNClsFound, track::TPCNClsCrossedRows, + track::TOFExpTime, + track::TOFExpTimePi, + track::TOFExpTimeKa, + track::TOFExpTimePr, track::ITSNCls, track::ITSNClsInnerBarrel, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, @@ -521,6 +560,10 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "T track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::v001::ITSClsSizeInLayer, track::v001::IsITSAfterburner, + track::TOFExpTime, + track::TOFExpTimePi, + track::TOFExpTimeKa, + track::TOFExpTimePr, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, From e9e20e842e46f56538f0d858e427cfe7c7322479 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:13:00 +0200 Subject: [PATCH 0177/2205] DPL: introduce workflow_helpers signpost --- Framework/Core/src/WorkflowHelpers.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index da60bdbc6961e..567dcd8cc03a7 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -24,6 +24,7 @@ #include "Framework/PluginManager.h" #include "Framework/DataTakingContext.h" #include "Framework/DefaultsHelpers.h" +#include "Framework/Signpost.h" #include "Headers/DataHeader.h" #include @@ -34,8 +35,7 @@ #include #include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" +O2_DECLARE_DYNAMIC_LOG(workflow_helpers); namespace o2::framework { From eb192774ce6c1f09e734be38b23219d4e7420334 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:05:17 +0200 Subject: [PATCH 0178/2205] DPL: internal-dpl-injected-dummy sink should never depend on anything --- Framework/Core/src/TopologyPolicy.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/TopologyPolicy.cxx b/Framework/Core/src/TopologyPolicy.cxx index 9389534861f7e..e209c2702031e 100644 --- a/Framework/Core/src/TopologyPolicy.cxx +++ b/Framework/Core/src/TopologyPolicy.cxx @@ -162,10 +162,15 @@ TopologyPolicy::DependencyChecker TopologyPolicyHelpers::alwaysDependent() O2_SIGNPOST_END(topology, sid, "alwaysDependent", "false. %s and %s are the same.", dependent.name.c_str(), ancestor.name.c_str()); return false; } - if (ancestor.name == "internal-dpl-injected-dummy-sink") { - O2_SIGNPOST_END(topology, sid, "alwaysDependent", "false. %s is a dummy sink.", ancestor.name.c_str()); + if (ancestor.name.find("internal-dpl-injected-dummy-sink") != std::string::npos) { + O2_SIGNPOST_END(topology, sid, "alwaysDependent", "false. Nothing can depend on %s by policy.", ancestor.name.c_str()); return false; } + // We never put anything behind the dummy sink. + if (dependent.name.find("internal-dpl-injected-dummy-sink") != std::string::npos) { + O2_SIGNPOST_END(topology, sid, "alwaysDependent", "true. %s is always last.", ancestor.name.c_str()); + return true; + } const std::regex matcher(".*output-proxy.*"); // Check if regex applies std::cmatch m; From 42a2a8fee045c3cb2bb3c23ab294cdd28168db84 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:06:51 +0200 Subject: [PATCH 0179/2205] DPL: enable DPL_SIGNPOSTS early This will make sure that we can enable signposts in the driver --- Framework/Core/src/runDataProcessing.cxx | 74 ++++++++++++++---------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 2c5ef88fb767c..933eb1dda52cf 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -2725,6 +2725,41 @@ std::string debugTopoInfo(std::vector const& specs, return out.str(); } +void enableSignposts(std::string const& signpostsToEnable) +{ + static pid_t pid = getpid(); + if (signpostsToEnable.empty() == true) { + auto printAllSignposts = [](char const* name, void* l, void* context) { + auto* log = (_o2_log_t*)l; + LOGP(detail, "Signpost stream {} disabled. Enable it with o2-log -p {} -a {}", name, pid, (void*)&log->stacktrace); + return true; + }; + o2_walk_logs(printAllSignposts, nullptr); + return; + } + auto matchingLogEnabler = [](char const* name, void* l, void* context) { + auto* log = (_o2_log_t*)l; + auto* selectedName = (char const*)context; + std::string prefix = "ch.cern.aliceo2."; + if (strcmp(name, (prefix + selectedName).data()) == 0) { + LOGP(info, "Enabling signposts for stream \"ch.cern.aliceo2.{}\"", selectedName); + _o2_log_set_stacktrace(log, 1); + return false; + } else { + LOGP(info, "Signpost stream \"{}\" disabled. Enable it with o2-log -p {} -a {}", name, pid, (void*)&log->stacktrace); + } + return true; + }; + // Split signpostsToEnable by comma using strtok_r + char* saveptr; + char* src = const_cast(signpostsToEnable.data()); + auto* token = strtok_r(src, ",", &saveptr); + while (token) { + o2_walk_logs(matchingLogEnabler, token); + token = strtok_r(nullptr, ",", &saveptr); + } +} + // This is a toy executor for the workflow spec // What it needs to do is: // @@ -2745,6 +2780,12 @@ int doMain(int argc, char** argv, o2::framework::WorkflowSpec const& workflow, std::vector const& detectedParams, o2::framework::ConfigContext& configContext) { + // Peek very early in the driver options and look for + // signposts, so the we can enable it without going through the whole dance + if (getenv("DPL_DRIVER_SIGNPOSTS")) { + enableSignposts(getenv("DPL_DRIVER_SIGNPOSTS")); + } + std::vector currentArgs; std::vector plugins; std::vector forwardingPolicies = ForwardingPolicy::createDefaultPolicies(); @@ -3055,38 +3096,7 @@ int doMain(int argc, char** argv, o2::framework::WorkflowSpec const& workflow, } } - static pid_t pid = getpid(); - if (varmap.count("signposts")) { - auto signpostsToEnable = varmap["signposts"].as(); - auto matchingLogEnabler = [](char const* name, void* l, void* context) { - auto* log = (_o2_log_t*)l; - auto* selectedName = (char const*)context; - std::string prefix = "ch.cern.aliceo2."; - if (strcmp(name, (prefix + selectedName).data()) == 0) { - LOGP(info, "Enabling signposts for stream \"ch.cern.aliceo2.{}\"", selectedName); - _o2_log_set_stacktrace(log, 1); - return false; - } else { - LOGP(info, "Signpost stream \"{}\" disabled. Enable it with o2-log -p {} -a {}", name, pid, (void*)&log->stacktrace); - } - return true; - }; - // Split signpostsToEnable by comma using strtok_r - char* saveptr; - char* src = const_cast(signpostsToEnable.data()); - auto* token = strtok_r(src, ",", &saveptr); - while (token) { - o2_walk_logs(matchingLogEnabler, token); - token = strtok_r(nullptr, ",", &saveptr); - } - } else { - auto printAllSignposts = [](char const* name, void* l, void* context) { - auto* log = (_o2_log_t*)l; - LOGP(detail, "Signpost stream {} disabled. Enable it with o2-log -p {} -a {}", name, pid, (void*)&log->stacktrace); - return true; - }; - o2_walk_logs(printAllSignposts, nullptr); - } + enableSignposts(varmap["signposts"].as()); auto evaluateBatchOption = [&varmap]() -> bool { if (varmap.count("no-batch") > 0) { From 363bfa20b5837378fc478b977aefe5f96f29e948 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:08:26 +0200 Subject: [PATCH 0180/2205] DPL: Debug channel creation --- Framework/Core/src/DeviceSpecHelpers.cxx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Framework/Core/src/DeviceSpecHelpers.cxx b/Framework/Core/src/DeviceSpecHelpers.cxx index b9552dc093115..8076242bd274e 100644 --- a/Framework/Core/src/DeviceSpecHelpers.cxx +++ b/Framework/Core/src/DeviceSpecHelpers.cxx @@ -631,6 +631,28 @@ void DeviceSpecHelpers::processOutEdgeActions(ConfigContext const& configContext } DeviceConnectionId id{edge.producer, edge.consumer, edge.timeIndex, edge.producerTimeIndex, channel.port}; connections.push_back(id); + + auto& source = workflow[edge.producer]; + + O2_SIGNPOST_ID_GENERATE(sid, device_spec_helpers); + O2_SIGNPOST_START(device_spec_helpers, sid, "new channels", "Channel %{public}s has been created.", channel.name.c_str()); + O2_SIGNPOST_ID_GENERATE(iid, device_spec_helpers); + O2_SIGNPOST_START(device_spec_helpers, iid, "producer outputs", "Producer %{public}s has the following outputs:", source.name.c_str()); + for (auto& output : source.outputs) { + O2_SIGNPOST_EVENT_EMIT(device_spec_helpers, iid, "producer outputs", "%{public}s", DataSpecUtils::describe(output).c_str()); + } + O2_SIGNPOST_END(device_spec_helpers, iid, "producer outputs", ""); + O2_SIGNPOST_START(device_spec_helpers, iid, "producer forwards", "Producer %{public}s has the following forwards:", source.name.c_str()); + for (auto& forwards : device.forwards) { + O2_SIGNPOST_EVENT_EMIT(device_spec_helpers, iid, "producer forwards", "%{public}s", DataSpecUtils::describe(forwards.matcher).c_str()); + } + O2_SIGNPOST_END(device_spec_helpers, iid, "producer forwards", ""); + O2_SIGNPOST_START(device_spec_helpers, iid, "consumer inputs", "Consumer %{public}s has the following inputs:", consumer.name.c_str()); + for (auto& input : consumer.inputs) { + O2_SIGNPOST_EVENT_EMIT(device_spec_helpers, iid, "consumer inputs", "%{public}s", DataSpecUtils::describe(input).c_str()); + } + O2_SIGNPOST_END(device_spec_helpers, iid, "consumer inputs", ""); + O2_SIGNPOST_END(device_spec_helpers, sid, "new channels", ""); return channel; }; From 1e87f940fbeaa775361ae83f954ccd731a463dea Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:12:55 +0200 Subject: [PATCH 0181/2205] DPL: make sure the suffix does not play a role sorting the dummy sink --- Framework/Core/src/CompletionPolicy.cxx | 2 +- Framework/Core/src/DataProcessingDevice.cxx | 2 +- Framework/Core/src/WorkflowHelpers.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/Core/src/CompletionPolicy.cxx b/Framework/Core/src/CompletionPolicy.cxx index 726148e0a2ae9..9d92fd07e6f5a 100644 --- a/Framework/Core/src/CompletionPolicy.cxx +++ b/Framework/Core/src/CompletionPolicy.cxx @@ -26,7 +26,7 @@ std::vector { return { CompletionPolicyHelpers::consumeWhenAllOrdered("internal-dpl-aod-writer"), - CompletionPolicyHelpers::consumeWhenAny("internal-dpl-injected-dummy-sink", [](DeviceSpec const& s) { return s.name == "internal-dpl-injected-dummy-sink"; }), + CompletionPolicyHelpers::consumeWhenAny("internal-dpl-injected-dummy-sink", [](DeviceSpec const& s) { return s.name.find("internal-dpl-injected-dummy-sink") != std::string::npos; }), CompletionPolicyHelpers::consumeWhenAll()}; } diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 386d5fe4403e9..1c46ee9ae0ac6 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1096,7 +1096,7 @@ void DataProcessingDevice::fillContext(DataProcessorContext& context, DeviceCont context.balancingInputs = spec.completionPolicy.balanceChannels; // This is needed because the internal injected dummy sink should not // try to balance inputs unless the rate limiting is requested. - if (enableRateLimiting == false && spec.name == "internal-dpl-injected-dummy-sink") { + if (enableRateLimiting == false && spec.name.find("internal-dpl-injected-dummy-sink") != std::string::npos) { context.balancingInputs = false; } if (enableRateLimiting) { diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 567dcd8cc03a7..cd0c20af502f4 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -367,7 +367,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // timeframe data. bool timeframeSink = hasTimeframeInputs && !hasTimeframeOutputs; if (std::stoi(ctx.options().get("timeframes-rate-limit-ipcid")) != -1) { - if (timeframeSink && processor.name != "internal-dpl-injected-dummy-sink") { + if (timeframeSink && processor.name.find("internal-dpl-injected-dummy-sink") == std::string::npos) { processor.outputs.push_back(OutputSpec{{"dpl-summary"}, ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(runtime_hash(processor.name.c_str()))}}); } } From fa6d575505888b7adf2112fed1d277f27c294ae2 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:10:44 +0200 Subject: [PATCH 0182/2205] DPL: Debug the available outputs --- Framework/Core/src/WorkflowHelpers.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index cd0c20af502f4..d393991cc61dc 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -838,15 +838,23 @@ void WorkflowHelpers::constructGraph(const WorkflowSpec& workflow, // Notice that availableOutputsInfo MUST be updated first, since it relies on // the size of outputs to be the one before the update. auto enumerateAvailableOutputs = [&workflow, &outputs, &availableOutputsInfo]() { + O2_SIGNPOST_ID_GENERATE(sid, workflow_helpers); for (size_t wi = 0; wi < workflow.size(); ++wi) { auto& producer = workflow[wi]; + if (producer.outputs.empty()) { + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output enumeration", "No outputs for [%zu] %{public}s", wi, producer.name.c_str()); + } + O2_SIGNPOST_START(workflow_helpers, sid, "output enumeration", "Enumerating outputs for producer [%zu] %{}s public", wi, producer.name.c_str()); for (size_t oi = 0; oi < producer.outputs.size(); ++oi) { auto& out = producer.outputs[oi]; auto uniqueOutputId = outputs.size(); availableOutputsInfo.emplace_back(LogicalOutputInfo{wi, uniqueOutputId, false}); + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output enumeration", "- [%zu, %zu] %{public}s", + oi, uniqueOutputId, DataSpecUtils::describe(out).c_str()); outputs.push_back(out); } + O2_SIGNPOST_END(workflow_helpers, sid, "output enumeration", ""); } }; From 8391e4d63f7fa723aac549b51453044d192761f3 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:40:57 +0200 Subject: [PATCH 0183/2205] DPL: debug topology building --- Framework/Core/src/WorkflowHelpers.cxx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index d393991cc61dc..5b1f5ef766981 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -886,10 +886,17 @@ void WorkflowHelpers::constructGraph(const WorkflowSpec& workflow, std::vector matches(constOutputs.size()); for (size_t consumer = 0; consumer < workflow.size(); ++consumer) { + O2_SIGNPOST_ID_GENERATE(sid, workflow_helpers); + O2_SIGNPOST_START(workflow_helpers, sid, "input matching", "Matching inputs of consumer [%zu] %{}s public", consumer, workflow[consumer].name.c_str()); for (size_t input = 0; input < workflow[consumer].inputs.size(); ++input) { forwards.clear(); for (size_t i = 0; i < constOutputs.size(); i++) { matches[i] = DataSpecUtils::match(workflow[consumer].inputs[input], constOutputs[i]); + if (matches[i]) { + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output", "Input %{public}s matches %{public}s", + DataSpecUtils::describe(workflow[consumer].inputs[input]).c_str(), + DataSpecUtils::describe(constOutputs[i]).c_str()); + } } for (size_t i = 0; i < availableOutputsInfo.size(); i++) { @@ -905,6 +912,8 @@ void WorkflowHelpers::constructGraph(const WorkflowSpec& workflow, auto uniqueOutputId = oif->outputGlobalIndex; for (size_t tpi = 0; tpi < workflow[consumer].maxInputTimeslices; ++tpi) { for (size_t ptpi = 0; ptpi < workflow[producer].maxInputTimeslices; ++ptpi) { + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output", "Adding edge between %{public}s and %{public}s", workflow[consumer].name.c_str(), + workflow[producer].name.c_str()); logicalEdges.emplace_back(DeviceConnectionEdge{producer, consumer, tpi, ptpi, uniqueOutputId, input, oif->forward}); } } @@ -920,6 +929,7 @@ void WorkflowHelpers::constructGraph(const WorkflowSpec& workflow, availableOutputsInfo.push_back(forward); } } + O2_SIGNPOST_END(workflow_helpers, sid, "input matching", ""); } } From 815676e3fa2349927ed29e03876e9ed21baa39a6 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:40:57 +0200 Subject: [PATCH 0184/2205] DPL: do not add summary outputs more than once This seem to be the cause for the spurious circular dependency for the internal-dpl-injected-dummy-sink. --- Framework/Core/src/WorkflowHelpers.cxx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 5b1f5ef766981..f9aa103300813 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -368,7 +368,22 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext bool timeframeSink = hasTimeframeInputs && !hasTimeframeOutputs; if (std::stoi(ctx.options().get("timeframes-rate-limit-ipcid")) != -1) { if (timeframeSink && processor.name.find("internal-dpl-injected-dummy-sink") == std::string::npos) { - processor.outputs.push_back(OutputSpec{{"dpl-summary"}, ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(runtime_hash(processor.name.c_str()))}}); + O2_SIGNPOST_ID_GENERATE(sid, workflow_helpers); + uint32_t hash = runtime_hash(processor.name.c_str()); + bool hasMatch = false; + ConcreteDataMatcher summaryMatcher = ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(hash)}; + for (auto& output : processor.outputs) { + if (DataSpecUtils::match(output, summaryMatcher)) { + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output enumeration", "%{public}s already there in %{public}s", + DataSpecUtils::describe(output).c_str(), processor.name.c_str()); + hasMatch = true; + break; + } + } + if (!hasMatch) { + O2_SIGNPOST_EVENT_EMIT(workflow_helpers, sid, "output enumeration", "Adding DPL/SUMMARY/%d to %{public}s", hash, processor.name.c_str()); + processor.outputs.push_back(OutputSpec{{"dpl-summary"}, ConcreteDataMatcher{"DPL", "SUMMARY", static_cast(hash)}}); + } } } bool hasConditionOption = false; From a985fe95b8c6505f087381a55c4e4b8f36d22265 Mon Sep 17 00:00:00 2001 From: mkor <37400009+makor@users.noreply.github.com> Date: Tue, 3 Sep 2024 09:34:03 +0200 Subject: [PATCH 0185/2205] [QC-TPC] Remove non-mergable canvas objects from PID task. Add switch for hypothesis histos. (#13437) Co-authored-by: Maximilian Korwieser --- Detectors/TPC/qc/include/TPCQC/PID.h | 19 +++++++++++---- Detectors/TPC/qc/src/PID.cxx | 36 ++++------------------------ 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/Detectors/TPC/qc/include/TPCQC/PID.h b/Detectors/TPC/qc/include/TPCQC/PID.h index f07e795afe6a0..c847f3f7fdb5f 100644 --- a/Detectors/TPC/qc/include/TPCQC/PID.h +++ b/Detectors/TPC/qc/include/TPCQC/PID.h @@ -24,6 +24,7 @@ // root includes #include "TH1.h" +// Decapricated to be removed in next PR #include "TCanvas.h" // o2 includes @@ -70,7 +71,7 @@ class PID // To set the elementary track cuts void setPIDCuts(int minnCls = 60, float absTgl = 1., float mindEdxTot = 10.0, - float maxdEdxTot = 70., float minpTPC = 0.05, float maxpTPC = 20., float minpTPCMIPs = 0.45, float maxpTPCMIPs = 0.55, bool turnOffHistosForAsync = false) + float maxdEdxTot = 70., float minpTPC = 0.05, float maxpTPC = 20., float minpTPCMIPs = 0.45, float maxpTPCMIPs = 0.55, bool turnOffHistosForAsync = false, bool getdEdxVspHypoHist = false) { mCutMinnCls = minnCls; mCutAbsTgl = absTgl; @@ -81,15 +82,21 @@ class PID mCutMinpTPCMIPs = minpTPCMIPs; mCutMaxpTPCMIPs = maxpTPCMIPs; mTurnOffHistosForAsync = turnOffHistosForAsync; + mGetdEdxVspHypoHist = getdEdxVspHypoHist; } + + // Decapricated to be removed in next PR void setCreateCanvas(int createCanvas = 1) { mCreateCanvas = createCanvas; } + std::unordered_map>>& getMapOfHisto() { return mMapHist; } + const std::unordered_map>>& getMapOfHisto() const { return mMapHist; } + + // Decapricated to be removed in next PR std::unordered_map>>& getMapOfCanvas() { return mMapCanvas; } TCanvas* getSeparationPowerCanvas() { return mSeparationPowerCanvas.get(); } - const std::unordered_map>>& getMapOfHisto() const { return mMapHist; } const std::unordered_map>>& getMapOfCanvas() const { return mMapCanvas; } private: @@ -101,15 +108,19 @@ class PID float mCutMaxpTPC = 20.f; // pTPC max value float mCutMinpTPCMIPs = 0.45f; // pTPC min value for MIPs float mCutMaxpTPCMIPs = 0.55f; // pTPC max value for MIPs - bool mCreateCanvas = true; // Decide whether to create the TCanvas Object as it cannot be merged bool mTurnOffHistosForAsync = false; // Decide whether to turn off some histograms for async to reduce memory + bool mGetdEdxVspHypoHist = false; // Decide whether to generate the EdxVspHypo histograms + // Decapricated to be removed in next PR + bool mCreateCanvas = true; // Decide whether to create the TCanvas Object as it cannot be merged + std::unordered_map>> mMapHist; + // Decapricated to be removed in next PR // Map for Canvases to be published std::unordered_map>> mMapCanvas; // Map for Histograms which will be put onto the canvases, and not published separately std::unordered_map>> mMapHistCanvas; - // Canvas for Trending Separation Power std::unique_ptr mSeparationPowerCanvas; + ClassDefNV(PID, 1) }; } // namespace qc diff --git a/Detectors/TPC/qc/src/PID.cxx b/Detectors/TPC/qc/src/PID.cxx index 76d747165ea32..9b94e15cd4416 100644 --- a/Detectors/TPC/qc/src/PID.cxx +++ b/Detectors/TPC/qc/src/PID.cxx @@ -18,7 +18,6 @@ // root includes #include "TStyle.h" #include "TFile.h" -#include "TCanvas.h" #include "TMathBase.h" #include "TObjArray.h" @@ -93,16 +92,11 @@ void PID::initializeHistograms() mMapHist["hdEdxMaxMIPVsSec"].emplace_back(std::make_unique(fmt::format("hdEdxMaxMIPVsSec_{}", name).data(), (fmt::format("MIP Q_{{Max}} {}", name) + ";sector;d#it{E}/d#it{x}_{Max} (arb. unit)").data(), binsSec.bins, binsSec.min, binsSec.max, binsdEdxMIPMax.bins, binsdEdxMIPMax.min, binsdEdxMIPMax.max)); mMapHist["hMIPNclVsTgl"].emplace_back(std::make_unique(fmt::format("hMIPNclVsTgl_{}", name).data(), (fmt::format("rec. clusters {}", name) + ";#tan(#lambda); rec clusters").data(), 50, -2, 2, nclMax[idEdxType] - nclCuts[idEdxType], nclCuts[idEdxType], nclMax[idEdxType])); mMapHist["hMIPNclVsTglSub"].emplace_back(std::make_unique(fmt::format("hMIPNclVsTglSub_{}", name).data(), (fmt::format("sub-thrs. clusters {}", name) + ";#tan(#lambda);sub-thrs. clusters").data(), 50, -2, 2, 20, 0, 20)); - if (mCreateCanvas) { - mMapHistCanvas["hdEdxVspHypoPos"].emplace_back(std::make_unique(fmt::format("hdEdxVspHypoPos_{}", name).data(), (fmt::format("Q_{{Tot}} Pos {}", name) + ";#it{p} (GeV/#it{c});d#it{E}/d#it{x}_{Tot} (arb. unit)").data(), 200, bins.data(), binNumber, binsdEdxTot_Log.data())); - mMapHistCanvas["hdEdxVspHypoNeg"].emplace_back(std::make_unique(fmt::format("hdEdxVspHypoNeg_{}", name).data(), (fmt::format("Q_{{Tot}} Neg {}", name) + ";#it{p} (GeV/#it{c});d#it{E}/d#it{x}_{Tot} (arb. unit)").data(), 200, bins.data(), binNumber, binsdEdxTot_Log.data())); + if (mGetdEdxVspHypoHist) { + mMapHist["hdEdxVspHypoPos"].emplace_back(std::make_unique(fmt::format("hdEdxVspHypoPos_{}", name).data(), (fmt::format("Q_{{Tot}} Pos {}", name) + ";#it{p} (GeV/#it{c});d#it{E}/d#it{x}_{Tot} (arb. unit)").data(), 200, bins.data(), binNumber, binsdEdxTot_Log.data())); + mMapHist["hdEdxVspHypoNeg"].emplace_back(std::make_unique(fmt::format("hdEdxVspHypoNeg_{}", name).data(), (fmt::format("Q_{{Tot}} Neg {}", name) + ";#it{p} (GeV/#it{c});d#it{E}/d#it{x}_{Tot} (arb. unit)").data(), 200, bins.data(), binNumber, binsdEdxTot_Log.data())); } } - if (mCreateCanvas) { - mMapCanvas["CdEdxPIDHypothesisVsp"].emplace_back(std::make_unique("CdEdxPIDHypothesisVsp", "PID Hypothesis Ratio")); - mMapCanvas["CdEdxPIDHypothesisVsp"].at(0)->Divide(5, 2); - } - mSeparationPowerCanvas.reset(new TCanvas("CSeparationPower", "Separation Power")); } //______________________________________________________________________________ @@ -113,11 +107,6 @@ void PID::resetHistograms() hist->Reset(); } } - for (const auto& pair : mMapHistCanvas) { - for (auto& hist : pair.second) { - hist->Reset(); - } - } } //______________________________________________________________________________ @@ -185,10 +174,10 @@ bool PID::processTrack(const o2::tpc::TrackTPC& track, size_t nTracks) if (std::abs(tgl) < mCutAbsTgl) { mMapHist["hdEdxTotVsp"][idEdxType]->Fill(pTPC, dEdxTot[idEdxType]); mMapHist["hdEdxMaxVsp"][idEdxType]->Fill(pTPC, dEdxMax[idEdxType]); - if (mCreateCanvas) { + if (mGetdEdxVspHypoHist) { const auto pidHypothesis = track.getPID().getID(); if (pidHypothesis <= o2::track::PID::NIDs) { - auto pidHist = mMapHistCanvas[(track.getCharge() > 0) ? "hdEdxVspHypoPos" : "hdEdxVspHypoNeg"][idEdxType].get(); + auto pidHist = mMapHist[(track.getCharge() > 0) ? "hdEdxVspHypoPos" : "hdEdxVspHypoNeg"][idEdxType].get(); pidHist->SetBinContent(pidHist->GetXaxis()->FindBin(pTPC), pidHist->GetYaxis()->FindBin(dEdxTot[idEdxType]), pidHypothesis + 1); } } @@ -227,21 +216,6 @@ bool PID::processTrack(const o2::tpc::TrackTPC& track, size_t nTracks) } } } - - if (mCreateCanvas) { - for (auto const& pairC : mMapCanvas) { - for (auto& canv : pairC.second) { - int h = 1; - for (auto const& pairH : mMapHistCanvas) { - for (auto& hist : pairH.second) { - canv->cd(h); - hist->Draw(); - h++; - } - } - } - } - } return true; } From 8f828e2a7ce74ea93e457a1d481bc18b493fba15 Mon Sep 17 00:00:00 2001 From: Michal Date: Fri, 30 Aug 2024 09:16:30 +0200 Subject: [PATCH 0186/2205] Signaling `content not retreived` on any `transfer finished` error --- CCDB/src/CCDBDownloader.cxx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CCDB/src/CCDBDownloader.cxx b/CCDB/src/CCDBDownloader.cxx index 0dfb793363be4..3fca3c8cc2ae6 100644 --- a/CCDB/src/CCDBDownloader.cxx +++ b/CCDB/src/CCDBDownloader.cxx @@ -485,7 +485,7 @@ void CCDBDownloader::transferFinished(CURL* easy_handle, CURLcode curlCode) bool contentRetrieved = false; if (curlCode != 0) { - LOG(error) << "CCDBDownloader: " << curl_easy_strerror(curlCode) << "\n"; + LOG(error) << "CCDBDownloader CURL transfer error - " << curl_easy_strerror(curlCode) << "\n"; } switch (performData->type) { @@ -520,15 +520,14 @@ void CCDBDownloader::transferFinished(CURL* easy_handle, CURLcode curlCode) } else if (300 <= httpCode && httpCode < 400 && performData->locInd < locations.size()) { followRedirect(performData, easy_handle, locations, rescheduled, contentRetrieved); } else if (200 <= httpCode && httpCode < 300) { - contentRetrieved = true; // Can be overruled by following timeout check + contentRetrieved = true; // Can be overruled by following error check } } else { LOG(error) << loggingMessage; } - // Check for timeout - if (curlCode == CURLE_OPERATION_TIMEDOUT) { - LOG(error) << "Connection timed out.\n"; + // Check for errors + if (curlCode != 0) { contentRetrieved = false; } From fb3ebd8b9ad62c5cb7f8adb503c1228ace49836e Mon Sep 17 00:00:00 2001 From: Andreas Molander Date: Wed, 21 Aug 2024 12:47:53 +0300 Subject: [PATCH 0187/2205] FIT: Install macro for reading dead channel map --- Detectors/FIT/macros/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Detectors/FIT/macros/CMakeLists.txt b/Detectors/FIT/macros/CMakeLists.txt index 9d366cf04e297..320cc19b00b8c 100644 --- a/Detectors/FIT/macros/CMakeLists.txt +++ b/Detectors/FIT/macros/CMakeLists.txt @@ -40,4 +40,5 @@ o2_add_test_root_macro(readFITDCSdata.C O2::CCDB LABELS fit) -o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/readFITDCSdata.C) \ No newline at end of file +o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/readFITDCSdata.C) +o2_data_file(COPY readFITDeadChannelMap.C DESTINATION Detectors/FIT/macros/readFITDeadChannelMap.C) \ No newline at end of file From cbe36d6ee101ccba72170eac610719745c2b813c Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:32:16 +0200 Subject: [PATCH 0188/2205] DPL GUI: remove protection for spurious formatting DebugGUI is now able to detect "%s" and shortcuts the formatting in that case. This allows us to print colored text without risks. --- Framework/GUISupport/src/FrameworkGUIDebugger.cxx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Framework/GUISupport/src/FrameworkGUIDebugger.cxx b/Framework/GUISupport/src/FrameworkGUIDebugger.cxx index 2fc8c7623c857..a025822a2abcb 100644 --- a/Framework/GUISupport/src/FrameworkGUIDebugger.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDebugger.cxx @@ -145,18 +145,12 @@ void displayHistory(const DeviceInfo& info, DeviceControl& control) ji = (ji + 1) % historySize; continue; } - // Print matching lines + // Print matching lines. Notice we filter twice, once on input, to reduce the + // stream, a second time at display time, to avoid showing unrelevant + // messages from past. if (strstr(line.c_str(), control.logFilter) != nullptr) { - auto color = colorForLogLevel(logLevel); - // We filter twice, once on input, to reduce the - // stream, a second time at display time, to avoid - // showing unrelevant messages from past. if (logLevel >= control.logLevel) { - if (line.find('%', 0) != std::string::npos) { - ImGui::TextUnformatted(line.c_str(), line.c_str() + line.size()); - } else { - ImGui::TextColored(color, line.c_str(), line.c_str() + line.size()); - } + ImGui::TextColored(colorForLogLevel(logLevel), "%s", line.c_str()); } } ji = (ji + 1) % historySize; From 5215528b0c57760a690efd39b11531f1f2f205e5 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:19:31 +0200 Subject: [PATCH 0189/2205] Avoid memory churn when looking up channel --- Framework/Core/include/Framework/ExternalFairMQDeviceProxy.h | 4 ++-- Framework/Core/src/ExternalFairMQDeviceProxy.cxx | 5 +++-- .../Core/test/benchmark_ExternalFairMQDeviceProxies.cxx | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Framework/Core/include/Framework/ExternalFairMQDeviceProxy.h b/Framework/Core/include/Framework/ExternalFairMQDeviceProxy.h index 3ff77ae703b9b..415c6c5f702d8 100644 --- a/Framework/Core/include/Framework/ExternalFairMQDeviceProxy.h +++ b/Framework/Core/include/Framework/ExternalFairMQDeviceProxy.h @@ -22,7 +22,7 @@ namespace o2::framework /// A callback function to retrieve the fair::mq::Channel name to be used for sending /// messages of the specified OutputSpec -using ChannelRetriever = std::function; +using ChannelRetriever = std::function; /// The callback which actually does the heavy lifting of converting the input data into /// DPL messages. The callback is invoked with the following parameters: /// @param timingInfo is the timing information of the current timeslice @@ -144,6 +144,6 @@ DataProcessorSpec specifyFairMQDeviceMultiOutputProxy(char const* label, const char* defaultChannelConfig, ChannelSelector channelSelector = defaultOutputProxyChannelSelector); -} // namespace o2 +} // namespace o2::framework #endif // FRAMEWORK_RAWDEVICESOURCE_H diff --git a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx index 820181ff353ed..239dd5f40e82f 100644 --- a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx +++ b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx @@ -752,14 +752,15 @@ DataProcessorSpec specifyExternalFairMQDeviceProxy(char const* name, outputChannels = std::move(outputChannels)](ServiceRegistryRef ref, TimingInfo& timingInfo, fair::mq::Parts& inputs, int, size_t ci, bool newRun) -> bool { auto* device = ref.get().device(); // pass a copy of the outputRoutes - auto channelRetriever = [&outputRoutes](OutputSpec const& query, DataProcessingHeader::StartTime timeslice) -> std::string { + auto channelRetriever = [&outputRoutes](OutputSpec const& query, DataProcessingHeader::StartTime timeslice) -> std::string const& { + static std::string emptyChannel = ""; for (auto& route : outputRoutes) { LOG(debug) << "matching: " << DataSpecUtils::describe(query) << " to route " << DataSpecUtils::describe(route.matcher); if (DataSpecUtils::match(route.matcher, query) && ((timeslice % route.maxTimeslices) == route.timeslice)) { return route.channel; } } - return {""}; + return emptyChannel; }; std::string const& channel = channels[ci]; diff --git a/Framework/Core/test/benchmark_ExternalFairMQDeviceProxies.cxx b/Framework/Core/test/benchmark_ExternalFairMQDeviceProxies.cxx index c116ed81537ce..de022030155f2 100644 --- a/Framework/Core/test/benchmark_ExternalFairMQDeviceProxies.cxx +++ b/Framework/Core/test/benchmark_ExternalFairMQDeviceProxies.cxx @@ -483,7 +483,7 @@ std::vector defineDataProcessing(ConfigContext const& config) // Note: we want to run both the output and input proxy in the same workflow and thus we need // different data identifiers and change the data origin in the forwarding OutputSpec query{"PRX", dh->dataDescription, dh->subSpecification}; - auto channelName = channelRetriever(query, dph->startTime); + auto const& channelName = channelRetriever(query, dph->startTime); bool isData = DataSpecUtils::match(OutputSpec{"TST", "DATA", 0}, dh->dataOrigin, dh->dataDescription, dh->subSpecification); // for the configured data channel we require the channel name, the EOS message containing // the forwarded SourceInfoHeader created by the output proxy will be skipped here since the From 64c47f67b223de7aebd35bd1dc40d1019ddc2476 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 4 Sep 2024 14:30:57 +0200 Subject: [PATCH 0190/2205] ITS-GPU: various fixes + separate vertexing kernels (#13473) * Staging * Move vertexer kernels away from the traits * Fix GPU APIs compatibility * Fix Hybrid interfaces for CPU * Checkpoint work * Unregister memory in sync and async when iteration == par.size()-1 * Fix USEMatCorrNONE case in gpu fit * Update usage * Make TrackingFrameInfo array const * Update methods --- .../GPU/ITStrackingGPU/TimeFrameGPU.h | 9 +- .../GPU/ITStrackingGPU/TrackingKernels.h | 15 +- .../GPU/ITStrackingGPU/VertexingKernels.h | 59 +++ .../ITS/tracking/GPU/cuda/CMakeLists.txt | 3 +- .../ITS/tracking/GPU/cuda/TimeFrameGPU.cu | 343 +++++++++--------- .../tracking/GPU/cuda/TrackerTraitsGPU.cxx | 13 +- .../ITS/tracking/GPU/cuda/TrackingKernels.cu | 33 +- .../tracking/GPU/cuda/VertexerTraitsGPU.cxx | 230 ++++++++++++ ...rtexerTraitsGPU.cu => VertexingKernels.cu} | 253 ++----------- .../ITS/tracking/GPU/hip/CMakeLists.txt | 3 +- .../ITSMFT/ITS/tracking/src/Vertexer.cxx | 2 +- .../ITSMFT/ITS/workflow/src/RecoWorkflow.cxx | 2 +- 12 files changed, 509 insertions(+), 456 deletions(-) create mode 100644 Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexingKernels.h create mode 100644 Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx rename Detectors/ITSMFT/ITS/tracking/GPU/cuda/{VertexerTraitsGPU.cu => VertexingKernels.cu} (63%) diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h index a67ef03e0ef22..12a5f877c0135 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h @@ -174,9 +174,9 @@ class GpuTimeFrameChunk template class TimeFrameGPU : public TimeFrame { - public: friend class GpuTimeFrameChunk; + public: TimeFrameGPU(); ~TimeFrameGPU(); @@ -185,7 +185,7 @@ class TimeFrameGPU : public TimeFrame void unregisterHostMemory(const int); void initialise(const int, const TrackingParameters&, const int, IndexTableUtils* utils = nullptr, const TimeFrameGPUParameters* pars = nullptr); void initialiseHybrid(const int, const TrackingParameters&, const int, IndexTableUtils* utils = nullptr, const TimeFrameGPUParameters* pars = nullptr); - void initDevice(const int, IndexTableUtils*, const TrackingParameters& trkParam, const TimeFrameGPUParameters&, const int, const int); + void initDevice(IndexTableUtils*, const TrackingParameters& trkParam, const TimeFrameGPUParameters&, const int, const int); void initDeviceSAFitting(); void loadTrackingFrameInfoDevice(const int); void loadUnsortedClustersDevice(); @@ -227,7 +227,8 @@ class TimeFrameGPU : public TimeFrame TrackITSExt* getDeviceTrackITSExt() { return mTrackITSExtDevice; } gpuPair* getDeviceNeighbours(const int layer) { return mNeighboursDevice[layer]; } TrackingFrameInfo* getDeviceTrackingFrameInfo(const int); - TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() { return mTrackingFrameInfoDeviceArray; } + // TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() { return mTrackingFrameInfoDeviceArray; } + const TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() const { return mTrackingFrameInfoDeviceArray; } Cluster** getDeviceArrayClusters() const { return mClustersDeviceArray; } Cluster** getDeviceArrayUnsortedClusters() const { return mUnsortedClustersDeviceArray; } Tracklet** getDeviceArrayTracklets() const { return mTrackletsDeviceArray; } @@ -275,7 +276,7 @@ class TimeFrameGPU : public TimeFrame TrackITSExt* mTrackITSExtDevice; std::array*, nLayers - 2> mNeighboursDevice; std::array mTrackingFrameInfoDevice; - TrackingFrameInfo** mTrackingFrameInfoDeviceArray; + const TrackingFrameInfo** mTrackingFrameInfoDeviceArray; // State std::vector mGpuStreams; diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h index 3fea14af708a8..e96125bdd3bc7 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h @@ -16,9 +16,7 @@ #include "DetectorsBase/Propagator.h" #include "GPUCommonDef.h" -namespace o2 -{ -namespace its +namespace o2::its { class CellSeed; namespace gpu @@ -40,9 +38,9 @@ GPUd() bool fitTrack(TrackITSExt& track, template GPUg() void fitTrackSeedsKernel( CellSeed* trackSeeds, - TrackingFrameInfo** foundTrackingFrameInfo, + const TrackingFrameInfo** foundTrackingFrameInfo, o2::its::TrackITSExt* tracks, - const size_t nSeeds, + const unsigned int nSeeds, const float Bz, const int startLevel, float maxChi2ClusterAttachment, @@ -53,15 +51,14 @@ GPUg() void fitTrackSeedsKernel( } // namespace gpu void trackSeedHandler(CellSeed* trackSeeds, - TrackingFrameInfo** foundTrackingFrameInfo, + const TrackingFrameInfo** foundTrackingFrameInfo, o2::its::TrackITSExt* tracks, - const size_t nSeeds, + const unsigned int nSeeds, const float Bz, const int startLevel, float maxChi2ClusterAttachment, float maxChi2NDF, const o2::base::Propagator* propagator, const o2::base::PropagatorF::MatCorrType matCorrType); -} // namespace its -} // namespace o2 +} // namespace o2::its #endif // ITSTRACKINGGPU_TRACKINGKERNELS_H_ diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexingKernels.h new file mode 100644 index 0000000000000..6ae042d081688 --- /dev/null +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/VertexingKernels.h @@ -0,0 +1,59 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// + +#ifndef ITSTRACKINGGPU_VERTEXINGKERNELS_H_ +#define ITSTRACKINGGPU_VERTEXINGKERNELS_H_ +#include "ITStracking/MathUtils.h" +#include "ITStracking/Configuration.h" +#include "ITStracking/ClusterLines.h" +#include "ITStracking/Tracklet.h" + +#include "ITStrackingGPU/Utils.h" +#include "ITStrackingGPU/ClusterLinesGPU.h" +#include "ITStrackingGPU/VertexerTraitsGPU.h" +#include "ITStrackingGPU/TracerGPU.h" + +#include "GPUCommonArray.h" + +namespace o2::its::gpu +{ +#ifdef GPUCA_GPUCODE // GPUg() global kernels must only when compiled by GPU compiler +template +GPUg() void trackleterKernelMultipleRof( + const Cluster* clustersNextLayer, // 0 2 + const Cluster* clustersCurrentLayer, // 1 1 + const int* sizeNextLClusters, + const int* sizeCurrentLClusters, + const int* nextIndexTables, + Tracklet* Tracklets, + int* foundTracklets, + const IndexTableUtils* utils, + const unsigned int startRofId, + const unsigned int rofSize, + const float phiCut, + const size_t maxTrackletsPerCluster); +#endif +template +void trackletFinderHandler(const Cluster* clustersNextLayer, // 0 2 + const Cluster* clustersCurrentLayer, // 1 1 + const int* sizeNextLClusters, + const int* sizeCurrentLClusters, + const int* nextIndexTables, + Tracklet* Tracklets, + int* foundTracklets, + const IndexTableUtils* utils, + const unsigned int startRofId, + const unsigned int rofSize, + const float phiCut, + const size_t maxTrackletsPerCluster = 1e2); +} // namespace o2::its::gpu +#endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt index cb37f7fb1966e..2f8422112dc58 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt @@ -22,7 +22,8 @@ o2_add_library(ITStrackingCUDA TimeFrameGPU.cu TracerGPU.cu TrackingKernels.cu - VertexerTraitsGPU.cu + VertexingKernels.cu + VertexerTraitsGPU.cxx Utils.cu PUBLIC_INCLUDE_DIRECTORIES ../ PUBLIC_LINK_LIBRARIES O2::ITStracking diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu index 1d0fca2585730..ff9ef6c80b9a3 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu @@ -90,47 +90,47 @@ void GpuTimeFrameChunk::allocate(const size_t nrof, Stream& stream) { RANGE("device_partition_allocation", 2); mNRof = nrof; - for (int i = 0; i < nLayers; ++i) { - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mClustersDevice[i])), sizeof(Cluster) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - // checkGPUError(cudaMallocAsync(reinterpret_cast(&(mTrackingFrameInfoDevice[i])), sizeof(TrackingFrameInfo) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mClusterExternalIndicesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mIndexTablesDevice[i])), sizeof(int) * (256 * 128 + 1) * nrof, stream.get())); - if (i < nLayers - 1) { - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mTrackletsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mTrackletsDevice[i])), sizeof(Tracklet) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - if (i < nLayers - 2) { - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mCellsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->validatedTrackletsCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mCellsDevice[i])), sizeof(CellSeed) * mTFGPUParams->maxNeighboursSize * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mRoadsLookupTablesDevice[i]), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, stream.get())); - if (i < nLayers - 3) { - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mNeighboursCellLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mNeighboursCellDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, stream.get())); - } - if (i < 2) { - checkGPUError(cudaMallocAsync(reinterpret_cast(&(mNTrackletsPerClusterDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - } - } - } - } - checkGPUError(cudaMallocAsync(reinterpret_cast(&mCUBTmpBufferDevice), mTFGPUParams->tmpCUBBufferSize * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mLinesDevice), sizeof(Line) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mNFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mNExclusiveFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof + 1, stream.get())); // + 1 for cub::DeviceScan::ExclusiveSum, to cover cases where we have maximum number of clusters per ROF - checkGPUError(cudaMallocAsync(reinterpret_cast(&mUsedTrackletsDevice), sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mClusteredLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * nrof, stream.get())); - // checkGPUError(cudaMallocAsync(reinterpret_cast(&mRoadsDevice), sizeof(Road) * mTFGPUParams->maxRoadPerRofSize * nrof, stream.get())); - - /// Invariant allocations - checkGPUError(cudaMallocAsync(reinterpret_cast(&mFoundTrackletsDevice), (nLayers - 1) * sizeof(int) * nrof, stream.get())); // No need to reset, we always read it after writing - checkGPUError(cudaMallocAsync(reinterpret_cast(&mNFoundCellsDevice), (nLayers - 2) * sizeof(int) * nrof, stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mNeighboursCellDeviceArray), (nLayers - 3) * sizeof(int*), stream.get())); - checkGPUError(cudaMallocAsync(reinterpret_cast(&mNeighboursCellLookupTablesDeviceArray), (nLayers - 3) * sizeof(int*), stream.get())); - - /// Copy pointers of allocated memory to regrouping arrays - checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, stream.get())); - checkGPUError(cudaMemcpyAsync(mNeighboursCellDeviceArray, mNeighboursCellDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); - checkGPUError(cudaMemcpyAsync(mNeighboursCellLookupTablesDeviceArray, mNeighboursCellLookupTablesDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); + // for (int i = 0; i < nLayers; ++i) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClustersDevice[i])), sizeof(Cluster) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackingFrameInfoDevice[i])), sizeof(TrackingFrameInfo) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClusterExternalIndicesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mIndexTablesDevice[i])), sizeof(int) * (256 * 128 + 1) * nrof, &stream, true); + // if (i < nLayers - 1) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsDevice[i])), sizeof(Tracklet) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // if (i < nLayers - 2) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->validatedTrackletsCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsDevice[i])), sizeof(CellSeed) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsLookupTablesDevice[i]), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // if (i < nLayers - 3) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // } + // if (i < 2) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNTrackletsPerClusterDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // } + // } + // } + // } + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCUBTmpBufferDevice), mTFGPUParams->tmpCUBBufferSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mLinesDevice), sizeof(Line) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNExclusiveFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof + 1, &stream, true); // + 1 for cub::DeviceScan::ExclusiveSum, to cover cases where we have maximum number of clusters per ROF + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mUsedTrackletsDevice), sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mClusteredLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * nrof, &stream, true); + // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsDevice), sizeof(Road) * mTFGPUParams->maxRoadPerRofSize * nrof, &stream, true); + + // /// Invariant allocations + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mFoundTrackletsDevice), (nLayers - 1) * sizeof(int) * nrof, &stream, true); // No need to reset, we always read it after writing + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundCellsDevice), (nLayers - 2) * sizeof(int) * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellLookupTablesDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); + + // /// Copy pointers of allocated memory to regrouping arrays + // checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, stream.get())); + // checkGPUError(cudaMemcpyAsync(mNeighboursCellDeviceArray, mNeighboursCellDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); + // checkGPUError(cudaMemcpyAsync(mNeighboursCellLookupTablesDeviceArray, mNeighboursCellLookupTablesDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); mAllocated = true; } @@ -139,61 +139,61 @@ template void GpuTimeFrameChunk::reset(const Task task, Stream& stream) { RANGE("buffer_reset", 0); - if ((bool)task) { // Vertexer-only initialisation (cannot be constexpr: due to the presence of gpu raw calls can't be put in header) - for (int i = 0; i < 2; i++) { - auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); - auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; - thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); - checkGPUError(cudaMemsetAsync(mNTrackletsPerClusterDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - } - checkGPUError(cudaMemsetAsync(mUsedTrackletsDevice, false, sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - checkGPUError(cudaMemsetAsync(mClusteredLinesDevice, -1, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * mNRof, stream.get())); - } else { - for (int i = 0; i < nLayers; ++i) { - if (i < nLayers - 1) { - checkGPUError(cudaMemsetAsync(mTrackletsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); - auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; - thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); - if (i < nLayers - 2) { - checkGPUError(cudaMemsetAsync(mCellsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->cellsLUTsize * mNRof, stream.get())); - checkGPUError(cudaMemsetAsync(mRoadsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - if (i < nLayers - 3) { - checkGPUError(cudaMemsetAsync(mNeighboursCellLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - checkGPUError(cudaMemsetAsync(mNeighboursCellDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - } - } - } - } - checkGPUError(cudaMemsetAsync(mNFoundCellsDevice, 0, (nLayers - 2) * sizeof(int), stream.get())); - } + // if ((bool)task) { // Vertexer-only initialisation (cannot be constexpr: due to the presence of gpu raw calls can't be put in header) + // for (int i = 0; i < 2; i++) { + // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); + // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; + // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); + // checkGPUError(cudaMemsetAsync(mNTrackletsPerClusterDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // } + // checkGPUError(cudaMemsetAsync(mUsedTrackletsDevice, false, sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mClusteredLinesDevice, -1, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * mNRof, stream.get())); + // } else { + // for (int i = 0; i < nLayers; ++i) { + // if (i < nLayers - 1) { + // checkGPUError(cudaMemsetAsync(mTrackletsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); + // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; + // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); + // if (i < nLayers - 2) { + // checkGPUError(cudaMemsetAsync(mCellsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->cellsLUTsize * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mRoadsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // if (i < nLayers - 3) { + // checkGPUError(cudaMemsetAsync(mNeighboursCellLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mNeighboursCellDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // } + // } + // } + // } + // checkGPUError(cudaMemsetAsync(mNFoundCellsDevice, 0, (nLayers - 2) * sizeof(int), stream.get())); + // } } template size_t GpuTimeFrameChunk::computeScalingSizeBytes(const int nrof, const TimeFrameGPUParameters& config) { - size_t rofsize = nLayers * sizeof(int); // number of clusters per ROF - rofsize += nLayers * sizeof(Cluster) * config.clustersPerROfCapacity; // clusters - rofsize += nLayers * sizeof(TrackingFrameInfo) * config.clustersPerROfCapacity; // tracking frame info - rofsize += nLayers * sizeof(int) * config.clustersPerROfCapacity; // external cluster indices - rofsize += nLayers * sizeof(int) * (256 * 128 + 1); // index tables - rofsize += (nLayers - 1) * sizeof(int) * config.clustersPerROfCapacity; // tracklets lookup tables - rofsize += (nLayers - 1) * sizeof(Tracklet) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // tracklets - rofsize += 2 * sizeof(int) * config.clustersPerROfCapacity; // tracklets found per cluster (vertexer) - rofsize += sizeof(unsigned char) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // used tracklets (vertexer) - rofsize += (nLayers - 2) * sizeof(int) * config.validatedTrackletsCapacity; // cells lookup tables - rofsize += (nLayers - 2) * sizeof(CellSeed) * config.maxNeighboursSize; // cells - rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours lookup tables - rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours - rofsize += sizeof(Road) * config.maxRoadPerRofSize; // roads - rofsize += (nLayers - 2) * sizeof(int) * config.maxNeighboursSize; // road LUT - rofsize += sizeof(Line) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // lines - rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines - rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines exclusive sum - rofsize += sizeof(int) * config.clustersPerROfCapacity * config.maxTrackletsPerCluster; // lines used in clusterlines - - rofsize += (nLayers - 1) * sizeof(int); // total found tracklets - rofsize += (nLayers - 2) * sizeof(int); // total found cells + size_t rofsize = nLayers * sizeof(int); // number of clusters per ROF + // rofsize += nLayers * sizeof(Cluster) * config.clustersPerROfCapacity; // clusters + // rofsize += nLayers * sizeof(TrackingFrameInfo) * config.clustersPerROfCapacity; // tracking frame info + // rofsize += nLayers * sizeof(int) * config.clustersPerROfCapacity; // external cluster indices + // rofsize += nLayers * sizeof(int) * (256 * 128 + 1); // index tables + // rofsize += (nLayers - 1) * sizeof(int) * config.clustersPerROfCapacity; // tracklets lookup tables + // rofsize += (nLayers - 1) * sizeof(Tracklet) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // tracklets + // rofsize += 2 * sizeof(int) * config.clustersPerROfCapacity; // tracklets found per cluster (vertexer) + // rofsize += sizeof(unsigned char) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // used tracklets (vertexer) + // rofsize += (nLayers - 2) * sizeof(int) * config.validatedTrackletsCapacity; // cells lookup tables + // rofsize += (nLayers - 2) * sizeof(CellSeed) * config.maxNeighboursSize; // cells + // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours lookup tables + // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours + // rofsize += sizeof(Road) * config.maxRoadPerRofSize; // roads + // rofsize += (nLayers - 2) * sizeof(int) * config.maxNeighboursSize; // road LUT + // rofsize += sizeof(Line) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // lines + // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines + // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines exclusive sum + // rofsize += sizeof(int) * config.clustersPerROfCapacity * config.maxTrackletsPerCluster; // lines used in clusterlines + + // rofsize += (nLayers - 1) * sizeof(int); // total found tracklets + // rofsize += (nLayers - 2) * sizeof(int); // total found cells return rofsize * nrof; } @@ -219,12 +219,6 @@ Cluster* GpuTimeFrameChunk::getDeviceClusters(const int layer) return mClustersDevice[layer]; } -// template -// TrackingFrameInfo* GpuTimeFrameChunk::getDeviceTrackingFrameInfo(const int layer) -// { -// return mTrackingFrameInfoDevice[layer]; -// } - template int* GpuTimeFrameChunk::getDeviceClusterExternalIndices(const int layer) { @@ -284,25 +278,25 @@ template size_t GpuTimeFrameChunk::loadDataOnDevice(const size_t startRof, const size_t maxRof, const int maxLayers, Stream& stream) { RANGE("load_clusters_data", 5); - auto nRofs = std::min(maxRof - startRof, mNRof); - mNPopulatedRof = mTimeFramePtr->getNClustersROFrange(startRof, nRofs, 0).size(); - for (int i = 0; i < maxLayers; ++i) { - mHostClusters[i] = mTimeFramePtr->getClustersPerROFrange(startRof, nRofs, i); - mHostIndexTables[i] = mTimeFramePtr->getIndexTablePerROFrange(startRof, nRofs, i); - if (mHostClusters[i].size() > mTFGPUParams->clustersPerROfCapacity * nRofs) { - LOGP(warning, "Clusters on layer {} exceed the expected value, resizing to config value: {}, will lose information!", i, mTFGPUParams->clustersPerROfCapacity * nRofs); - } - checkGPUError(cudaMemcpyAsync(mClustersDevice[i], - mHostClusters[i].data(), - (int)std::min(mHostClusters[i].size(), mTFGPUParams->clustersPerROfCapacity * nRofs) * sizeof(Cluster), - cudaMemcpyHostToDevice, stream.get())); - if (mHostIndexTables[i].data()) { - checkGPUError(cudaMemcpyAsync(mIndexTablesDevice[i], - mHostIndexTables[i].data(), - mHostIndexTables[i].size() * sizeof(int), - cudaMemcpyHostToDevice, stream.get())); - } - } + // auto nRofs = std::min(maxRof - startRof, mNRof); + // mNPopulatedRof = mTimeFramePtr->getNClustersROFrange(startRof, nRofs, 0).size(); + // for (int i = 0; i < maxLayers; ++i) { + // mHostClusters[i] = mTimeFramePtr->getClustersPerROFrange(startRof, nRofs, i); + // mHostIndexTables[i] = mTimeFramePtr->getIndexTablePerROFrange(startRof, nRofs, i); + // if (mHostClusters[i].size() > mTFGPUParams->clustersPerROfCapacity * nRofs) { + // LOGP(warning, "Clusters on layer {} exceed the expected value, resizing to config value: {}, will lose information!", i, mTFGPUParams->clustersPerROfCapacity * nRofs); + // } + // checkGPUError(cudaMemcpyAsync(mClustersDevice[i], + // mHostClusters[i].data(), + // (int)std::min(mHostClusters[i].size(), mTFGPUParams->clustersPerROfCapacity * nRofs) * sizeof(Cluster), + // cudaMemcpyHostToDevice, stream.get())); + // if (mHostIndexTables[i].data()) { + // checkGPUError(cudaMemcpyAsync(mIndexTablesDevice[i], + // mHostIndexTables[i].data(), + // mHostIndexTables[i].size() * sizeof(int), + // cudaMemcpyHostToDevice, stream.get())); + // } + // } return mNPopulatedRof; // return the number of ROFs we loaded the data for. } @@ -373,13 +367,13 @@ void TimeFrameGPU::initialise(const int iteration, mHostNTracklets.resize((nLayers - 1) * mGpuParams.nTimeFrameChunks, 0); mHostNCells.resize((nLayers - 2) * mGpuParams.nTimeFrameChunks, 0); - auto init = [&](int p) -> void { - this->initDevice(p, utils, trkParam, *gpuParam, maxLayers, iteration); + auto init = [&]() -> void { + this->initDevice(utils, trkParam, *gpuParam, maxLayers, iteration); }; - std::thread t1{init, mGpuParams.nTimeFrameChunks}; + std::thread t1{init}; RANGE("tf_cpu_initialisation", 1); o2::its::TimeFrame::initialise(iteration, trkParam, maxLayers); - registerHostMemory(maxLayers); + // registerHostMemory(maxLayers); t1.join(); } @@ -401,70 +395,59 @@ void TimeFrameGPU::wipe(const int maxLayers) } template -void TimeFrameGPU::initDevice(const int chunks, - IndexTableUtils* utils, +void TimeFrameGPU::initDevice(IndexTableUtils* utils, const TrackingParameters& trkParam, const TimeFrameGPUParameters& gpuParam, const int maxLayers, const int iteration) { - mStaticTrackingParams.ZBins = trkParam.ZBins; - mStaticTrackingParams.PhiBins = trkParam.PhiBins; - if (mFirstInit) { - mGpuParams = gpuParam; - if (mGpuParams.maxGPUMemoryGB < 0) { - // Adaptive to available memory, hungry mode - size_t free; - checkGPUError(cudaMemGetInfo(&free, nullptr)); - mAvailMemGB = (double)free / GB; - LOGP(info, "Hungry memory mode requested, found {} free GB, going to use all of them", mAvailMemGB); - } else { - mAvailMemGB = mGpuParams.maxGPUMemoryGB; - LOGP(info, "Fixed memory mode requested, will try to use {} GB", mAvailMemGB); - } - checkGPUError(cudaMalloc(reinterpret_cast(&mTrackingParamsDevice), sizeof(gpu::StaticTrackingParameters))); - checkGPUError(cudaMemcpy(mTrackingParamsDevice, &mStaticTrackingParams, sizeof(gpu::StaticTrackingParameters), cudaMemcpyHostToDevice)); - if (utils) { // If utils is not nullptr, then its gpu vertexing - mIndexTableUtils = *utils; - checkGPUError(cudaMalloc(reinterpret_cast(&mIndexTableUtilsDevice), sizeof(IndexTableUtils))); - } else { // GPU tracking otherwise - mIndexTableUtils.setTrackingParameters(trkParam); - } - - mMemChunks.resize(chunks, GpuTimeFrameChunk{static_cast(this), mGpuParams}); - mVerticesInChunks.resize(chunks); - mNVerticesInChunks.resize(chunks); - mLabelsInChunks.resize(chunks); - LOGP(debug, "Size of fixed part is: {} MB", GpuTimeFrameChunk::computeFixedSizeBytes(mGpuParams) / MB); - LOGP(debug, "Size of scaling part is: {} MB", GpuTimeFrameChunk::computeScalingSizeBytes(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mAvailMemGB), mGpuParams) / MB); - LOGP(info, "Allocating {} chunks of {} rofs capacity each.", chunks, GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mAvailMemGB)); - - for (int iChunk{0}; iChunk < mMemChunks.size(); ++iChunk) { - mMemChunks[iChunk].allocate(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mAvailMemGB), mGpuStreams[iChunk]); - } - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - checkGPUError(cudaMalloc(reinterpret_cast(&mROFramesClustersDevice[iLayer]), mROFramesClusters[iLayer].size() * sizeof(int))); - checkGPUError(cudaMalloc(reinterpret_cast(&(mUsedClustersDevice[iLayer])), sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof)); - } - checkGPUError(cudaMalloc(reinterpret_cast(&mVerticesDevice), sizeof(Vertex) * mGpuParams.maxVerticesCapacity)); - checkGPUError(cudaMalloc(reinterpret_cast(&mROFramesPVDevice), sizeof(int) * (mNrof + 1))); - - mFirstInit = false; - } - if (maxLayers < nLayers) { // Vertexer - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - checkGPUError(cudaMemcpy(mROFramesClustersDevice[iLayer], mROFramesClusters[iLayer].data(), mROFramesClusters[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); - } - } else { // Tracker - checkGPUError(cudaMemcpy(mVerticesDevice, mPrimaryVertices.data(), sizeof(Vertex) * mPrimaryVertices.size(), cudaMemcpyHostToDevice)); - checkGPUError(cudaMemcpy(mROFramesPVDevice, mROFramesPV.data(), sizeof(int) * mROFramesPV.size(), cudaMemcpyHostToDevice)); - if (!iteration) { - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - checkGPUError(cudaMemset(mUsedClustersDevice[iLayer], 0, sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof)); - } - } - } - checkGPUError(cudaMemcpy(mIndexTableUtilsDevice, &mIndexTableUtils, sizeof(IndexTableUtils), cudaMemcpyHostToDevice)); + // mStaticTrackingParams.ZBins = trkParam.ZBins; + // mStaticTrackingParams.PhiBins = trkParam.PhiBins; + // if (mFirstInit) { + // mGpuParams = gpuParam; + // allocMemAsync(reinterpret_cast(&mTrackingParamsDevice), sizeof(gpu::StaticTrackingParameters), nullptr, true); + // checkGPUError(cudaMemcpy(mTrackingParamsDevice, &mStaticTrackingParams, sizeof(gpu::StaticTrackingParameters), cudaMemcpyHostToDevice)); + // if (utils) { // If utils is not nullptr, then its gpu vertexing + // mIndexTableUtils = *utils; + // allocMemAsync(reinterpret_cast(&mIndexTableUtilsDevice), sizeof(IndexTableUtils), nullptr, true); + // } else { // GPU tracking otherwise + // mIndexTableUtils.setTrackingParameters(trkParam); + // } + + // mMemChunks.resize(mGpuParams.nTimeFrameChunks, GpuTimeFrameChunk{static_cast(this), mGpuParams}); + // mVerticesInChunks.resize(mGpuParams.nTimeFrameChunks); + // mNVerticesInChunks.resize(mGpuParams.nTimeFrameChunks); + // mLabelsInChunks.resize(mGpuParams.nTimeFrameChunks); + // LOGP(info, "Size of fixed part is: {} MB", GpuTimeFrameChunk::computeFixedSizeBytes(mGpuParams) / MB); + // LOGP(info, "Size of scaling part is: {} MB", GpuTimeFrameChunk::computeScalingSizeBytes(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mAvailMemGB), mGpuParams) / MB); + // LOGP(info, "Allocating {} chunks of {} rofs capacity each.", mGpuParams.nTimeFrameChunks, mGpuParams.nROFsPerChunk); + + // for (int iChunk{0}; iChunk < mMemChunks.size(); ++iChunk) { + // mMemChunks[iChunk].allocate(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mGpuParams.maxGPUMemoryGB), mGpuStreams[iChunk]); + // } + // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + // allocMemAsync(reinterpret_cast(&mROframesClustersDevice[iLayer]), mROframesClusters[iLayer].size() * sizeof(int), nullptr, true); + // allocMemAsync(reinterpret_cast(&(mUsedClustersDevice[iLayer])), sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof, nullptr, true); + // } + // allocMemAsync(reinterpret_cast(&mVerticesDevice), sizeof(Vertex) * mGpuParams.maxVerticesCapacity, nullptr, true); + // allocMemAsync(reinterpret_cast(&mROframesPVDevice), sizeof(int) * (mNrof + 1), nullptr, true); + + // mFirstInit = false; + // } + // if (maxLayers < nLayers) { // Vertexer + // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + // checkGPUError(cudaMemcpy(mROframesClustersDevice[iLayer], mROframesClusters[iLayer].data(), mROframesClusters[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); + // } + // } else { // Tracker + // checkGPUError(cudaMemcpy(mVerticesDevice, mPrimaryVertices.data(), sizeof(Vertex) * mPrimaryVertices.size(), cudaMemcpyHostToDevice)); + // checkGPUError(cudaMemcpy(mROframesPVDevice, mROframesPV.data(), sizeof(int) * mROframesPV.size(), cudaMemcpyHostToDevice)); + // if (!iteration) { + // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + // checkGPUError(cudaMemset(mUsedClustersDevice[iLayer], 0, sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof)); + // } + // } + // } + // checkGPUError(cudaMemcpy(mIndexTableUtilsDevice, &mIndexTableUtils, sizeof(IndexTableUtils), cudaMemcpyHostToDevice)); } template @@ -588,7 +571,7 @@ template void TimeFrameGPU::downloadTrackITSExtDevice(std::vector& seeds) { LOGP(debug, "gpu-transfer: downloading {} tracks, for {} MB.", mTrackITSExt.size(), mTrackITSExt.size() * sizeof(o2::its::TrackITSExt) / MB); - checkGPUError(cudaMemcpyAsync(mTrackITSExt.data(), mTrackITSExtDevice, mTrackITSExt.size() * sizeof(o2::its::TrackITSExt), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + checkGPUError(cudaMemcpyAsync(mTrackITSExt.data(), mTrackITSExtDevice, seeds.size() * sizeof(o2::its::TrackITSExt), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); checkGPUError(cudaHostUnregister(mTrackITSExt.data())); checkGPUError(cudaHostUnregister(seeds.data())); discardResult(cudaDeviceSynchronize()); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx index ef444cdc79b92..7f1d6812bc6cd 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx @@ -21,9 +21,7 @@ #include "ITStrackingGPU/TrackerTraitsGPU.h" #include "ITStrackingGPU/TrackingKernels.h" -namespace o2 -{ -namespace its +namespace o2::its { constexpr int UnusedIndex{-1}; @@ -382,7 +380,7 @@ void TrackerTraitsGPU::findRoads(const int iteration) for (int iLayer{startLayer - 1}; iLayer > 0 && level > 2; --iLayer) { lastCellSeed.swap(updatedCellSeed); lastCellId.swap(updatedCellId); - updatedCellSeed.clear(); + std::vector().swap(updatedCellSeed); /// tame the memory peaks updatedCellId.clear(); processNeighbours(iLayer, --level, lastCellSeed, lastCellId, updatedCellSeed, updatedCellId); } @@ -462,11 +460,10 @@ void TrackerTraitsGPU::findRoads(const int iteration) mTimeFrame->getTracks(std::min(rofs[0], rofs[1])).emplace_back(track); } } - if (iteration == 2) { - mTimeFrameGPU->unregisterHostMemory(0); // FIXME this needs to work also with sync + if (iteration == mTrkParams.size() - 1) { + mTimeFrameGPU->unregisterHostMemory(0); } }; template class TrackerTraitsGPU<7>; -} // namespace its -} // namespace o2 +} // namespace o2::its diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index 4eb99f812f4ea..2374e7b8d04a2 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -59,9 +59,8 @@ inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort = } } -namespace o2 -{ -namespace its +namespace o2::its + { using namespace constants::its2; @@ -76,7 +75,7 @@ GPUd() bool fitTrack(TrackITSExt& track, float maxQoverPt, int nCl, float Bz, - TrackingFrameInfo** tfInfos, + const TrackingFrameInfo** tfInfos, const o2::base::Propagator* prop, o2::base::PropagatorF::MatCorrType matCorrType) { @@ -99,10 +98,6 @@ GPUd() bool fitTrack(TrackITSExt& track, } if (matCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { - track.setChi2(track.getChi2() + track.getPredictedChi2(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)); - if (!track.TrackParCov::update(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)) { - return false; - } const float xx0 = (iLayer > 2) ? 1.e-2f : 5.e-3f; // Rough layer thickness constexpr float radiationLength = 9.36f; // Radiation length of Si [cm] constexpr float density = 2.33f; // Density of Si [g/cm^3] @@ -128,9 +123,9 @@ GPUd() bool fitTrack(TrackITSExt& track, template GPUg() void fitTrackSeedsKernel( CellSeed* trackSeeds, - TrackingFrameInfo** foundTrackingFrameInfo, + const TrackingFrameInfo** foundTrackingFrameInfo, o2::its::TrackITSExt* tracks, - const size_t nSeeds, + const unsigned int nSeeds, const float Bz, const int startLevel, float maxChi2ClusterAttachment, @@ -149,7 +144,6 @@ GPUg() void fitTrackSeedsKernel( for (int iL{0}; iL < 7; ++iL) { temporaryTrack.setExternalClusterIndex(iL, clusters[iL], clusters[iL] != constants::its::UnusedIndex); } - bool fitSuccess = fitTrack(temporaryTrack, // TrackITSExt& track, 0, // int lastLayer, nLayers, // int firstLayer, @@ -287,7 +281,7 @@ struct trackletSortIndexFunctor : public thrust::binary_function { }; // Print layer buffer -GPUg() void printBufferLayerOnThread(const int layer, const int* v, size_t size, const int len = 150, const unsigned int tId = 0) +GPUg() void printBufferLayerOnThread(const int layer, const int* v, unsigned int size, const int len = 150, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { for (int i{0}; i < size; ++i) { @@ -301,7 +295,7 @@ GPUg() void printBufferLayerOnThread(const int layer, const int* v, size_t size, } // Dump vertices -GPUg() void printVertices(const Vertex* v, size_t size, const unsigned int tId = 0) +GPUg() void printVertices(const Vertex* v, unsigned int size, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { printf("vertices: "); @@ -435,7 +429,7 @@ GPUg() void computeLayerTrackletsKernelSingleRof( trackletsLookUpTable[currentSortedIndex]++; // Race-condition safe const float phi{o2::gpu::GPUCommonMath::ATan2(currentCluster.yCoordinate - nextCluster.yCoordinate, currentCluster.xCoordinate - nextCluster.xCoordinate)}; const float tanL{(currentCluster.zCoordinate - nextCluster.zCoordinate) / (currentCluster.radius - nextCluster.radius)}; - const size_t stride{currentClusterIndex * maxTrackletsPerCluster}; + const unsigned int stride{currentClusterIndex * maxTrackletsPerCluster}; new (tracklets + stride + storedTracklets) Tracklet{currentSortedIndex, roFrameClustersNext[rof1] + iNextCluster, tanL, phi, rof0, rof1}; ++storedTracklets; } @@ -559,7 +553,7 @@ GPUg() void computeLayerTrackletsKernelMultipleRof( if ((deltaZ / sigmaZ < trkPars->NSigmaCut && (deltaPhi < phiCut || o2::gpu::GPUCommonMath::Abs(deltaPhi - constants::math::TwoPi) < phiCut))) { const float phi{o2::gpu::GPUCommonMath::ATan2(currentCluster.yCoordinate - nextCluster.yCoordinate, currentCluster.xCoordinate - nextCluster.xCoordinate)}; const float tanL{(currentCluster.zCoordinate - nextCluster.zCoordinate) / (currentCluster.radius - nextCluster.radius)}; - const size_t stride{currentClusterIndex * maxTrackletsPerCluster}; + const unsigned int stride{currentClusterIndex * maxTrackletsPerCluster}; if (storedTracklets < maxTrackletsPerCluster) { new (trackletsRof0 + stride + storedTracklets) Tracklet{currentSortedIndexChunk, nextClusterIndex, tanL, phi, static_cast(rof0), static_cast(rof1)}; } @@ -715,9 +709,9 @@ void cellNeighboursHandler(CellSeed* cellsCurrentLayer, } void trackSeedHandler(CellSeed* trackSeeds, - TrackingFrameInfo** foundTrackingFrameInfo, + const TrackingFrameInfo** foundTrackingFrameInfo, o2::its::TrackITSExt* tracks, - const size_t nSeeds, + const unsigned int nSeeds, const float Bz, const int startLevel, float maxChi2ClusterAttachment, @@ -729,7 +723,7 @@ void trackSeedHandler(CellSeed* trackSeeds, trackSeeds, // CellSeed* trackSeeds, foundTrackingFrameInfo, // TrackingFrameInfo** foundTrackingFrameInfo, tracks, // o2::its::TrackITSExt* tracks, - nSeeds, // const size_t nSeeds, + nSeeds, // const unsigned int nSeeds, Bz, // const float Bz, startLevel, // const int startLevel, maxChi2ClusterAttachment, // float maxChi2ClusterAttachment, @@ -740,5 +734,4 @@ void trackSeedHandler(CellSeed* trackSeeds, gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); } -} // namespace its -} // namespace o2 +} // namespace o2::its diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx new file mode 100644 index 0000000000000..0e03dd0f25ce4 --- /dev/null +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx @@ -0,0 +1,230 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \author matteo.concas@cern.ch + +#include +#include +#include +#include +#include +#include + +#ifdef VTX_DEBUG +#include "TTree.h" +#include "TFile.h" +#endif + +#include "ITStrackingGPU/VertexingKernels.h" +#include "ITStrackingGPU/VertexerTraitsGPU.h" + +namespace o2::its +{ +VertexerTraitsGPU::VertexerTraitsGPU() +{ + setIsGPU(true); +} + +void VertexerTraitsGPU::initialise(const TrackingParameters& trackingParams, const int iteration) +{ + mTimeFrameGPU->initialise(0, trackingParams, 3, &mIndexTableUtils, &mTfGPUParams); +} +void VertexerTraitsGPU::updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& tfPar) +{ + mVrtParams = vrtPar; + mTfGPUParams = tfPar; + mIndexTableUtils.setTrackingParameters(vrtPar[0]); + for (auto& par : mVrtParams) { + par.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * par.phiCut / constants::math::TwoPi)); + par.zSpan = static_cast(std::ceil(par.zCut * mIndexTableUtils.getInverseZCoordinate(0))); + } +} + +void VertexerTraitsGPU::computeTracklets(const int iteration) +{ + if (!mTimeFrameGPU->getClusters().size()) { + return; + } + std::vector threads(mTimeFrameGPU->getNChunks()); + for (int chunkId{0}; chunkId < mTimeFrameGPU->getNChunks(); ++chunkId) { + // int rofPerChunk{mTimeFrameGPU->mNrof / (int)mTimeFrameGPU->getNChunks()}; + // mTimeFrameGPU->getVerticesInChunks()[chunkId].clear(); + // mTimeFrameGPU->getNVerticesInChunks()[chunkId].clear(); + // mTimeFrameGPU->getLabelsInChunks()[chunkId].clear(); + // auto doVertexReconstruction = [&, chunkId, rofPerChunk]() -> void { + // auto offset = chunkId * rofPerChunk; + // auto maxROF = offset + rofPerChunk; + // while (offset < maxROF) { + // auto rofs = mTimeFrameGPU->loadChunkData(chunkId, offset, maxROF); + // RANGE("chunk_gpu_vertexing", 1); + // // gpu::GpuTimer timer{offset, mTimeFrameGPU->getStream(chunkId).get()}; + // // timer.Start("vtTrackletFinder"); + // gpu::trackleterKernelMultipleRof<<getStream(chunkId).get()>>>( + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clustersNextLayer, // 0 2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clustersCurrentLayer, // 1 1 + // mTimeFrameGPU->getDeviceROframesClusters(0), // const int* sizeNextLClusters, + // mTimeFrameGPU->getDeviceROframesClusters(1), // const int* sizeCurrentLClusters, + // mTimeFrameGPU->getChunk(chunkId).getDeviceIndexTables(0), // const int* nextIndexTables, + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* Tracklets, + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // int* foundTracklets, + // mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, + // offset, // const unsigned int startRofId, + // rofs, // const unsigned int rofSize, + // mVrtParams.phiCut, // const float phiCut, + // mVrtParams.maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 + + // gpu::trackleterKernelMultipleRof<<getStream(chunkId).get()>>>( + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(2), // const Cluster* clustersNextLayer, // 0 2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clustersCurrentLayer, // 1 1 + // mTimeFrameGPU->getDeviceROframesClusters(2), // const int* sizeNextLClusters, + // mTimeFrameGPU->getDeviceROframesClusters(1), // const int* sizeCurrentLClusters, + // mTimeFrameGPU->getChunk(chunkId).getDeviceIndexTables(2), // const int* nextIndexTables, + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* Tracklets, + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // int* foundTracklets, + // mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, + // offset, // const unsigned int startRofId, + // rofs, // const unsigned int rofSize, + // mVrtParams.phiCut, // const float phiCut, + // mVrtParams.maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 + + // gpu::trackletSelectionKernelMultipleRof<<getStream(chunkId).get()>>>( + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clusters0, // Clusters on layer 0 + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clusters1, // Clusters on layer 1 + // mTimeFrameGPU->getDeviceROframesClusters(0), // const int* sizeClustersL0, // Number of clusters on layer 0 per ROF + // mTimeFrameGPU->getDeviceROframesClusters(1), // const int* sizeClustersL1, // Number of clusters on layer 1 per ROF + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* tracklets01, // Tracklets on layer 0-1 + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* tracklets12, // Tracklets on layer 1-2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // const int* nFoundTracklets01, // Number of tracklets found on layers 0-1 + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // const int* nFoundTracklet12, // Number of tracklets found on layers 1-2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), // unsigned char* usedTracklets, // Used tracklets + // mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), // Line* lines, // Lines + // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), // int* nFoundLines, // Number of found lines + // mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan + // offset, // const unsigned int startRofId, // Starting ROF ID + // rofs, // const unsigned int rofSize, // Number of ROFs to consider + // mVrtParams.maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster + // mVrtParams.tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda + // mVrtParams.phiCut); // const float phiCut = 0.002f) // Cut on phi + + // discardResult(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), + // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, + // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), + // mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), + // mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), + // mTimeFrameGPU->getStream(chunkId).get())); + + // // Reset used tracklets + // checkGPUError(cudaMemsetAsync(mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), + // false, + // sizeof(unsigned char) * mVrtParams.maxTrackletsPerCluster * mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), + // mTimeFrameGPU->getStream(chunkId).get()), + // __FILE__, __LINE__); + + // gpu::trackletSelectionKernelMultipleRof<<getStream(chunkId).get()>>>( + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clusters0, // Clusters on layer 0 + // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clusters1, // Clusters on layer 1 + // mTimeFrameGPU->getDeviceROframesClusters(0), // const int* sizeClustersL0, // Number of clusters on layer 0 per ROF + // mTimeFrameGPU->getDeviceROframesClusters(1), // const int* sizeClustersL1, // Number of clusters on layer 1 per ROF + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* tracklets01, // Tracklets on layer 0-1 + // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* tracklets12, // Tracklets on layer 1-2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // const int* nFoundTracklets01, // Number of tracklets found on layers 0-1 + // mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // const int* nFoundTracklet12, // Number of tracklets found on layers 1-2 + // mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), // unsigned char* usedTracklets, // Used tracklets + // mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), // Line* lines, // Lines + // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), // int* nFoundLines, // Number of found lines + // mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan + // offset, // const unsigned int startRofId, // Starting ROF ID + // rofs, // const unsigned int rofSize, // Number of ROFs to consider + // mVrtParams.maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster + // mVrtParams.tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda + // mVrtParams.phiCut); // const float phiCut = 0.002f) // Cut on phi + + // int nClusters = mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1); + // int lastFoundLines; + // std::vector exclusiveFoundLinesHost(nClusters + 1); + + // // Obtain whole exclusive sum including nCluster+1 element (nCluster+1)th element is the total number of found lines. + // checkGPUError(cudaMemcpyAsync(exclusiveFoundLinesHost.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), (nClusters) * sizeof(int), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); + // checkGPUError(cudaMemcpyAsync(&lastFoundLines, mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines() + nClusters - 1, sizeof(int), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); + // exclusiveFoundLinesHost[nClusters] = exclusiveFoundLinesHost[nClusters - 1] + lastFoundLines; + + // std::vector lines(exclusiveFoundLinesHost[nClusters]); + + // checkGPUError(cudaMemcpyAsync(lines.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), sizeof(Line) * lines.size(), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); + // checkGPUError(cudaStreamSynchronize(mTimeFrameGPU->getStream(chunkId).get())); + + // // Compute vertices + // std::vector clusterLines; + // std::vector usedLines; + // for (int rofId{0}; rofId < rofs; ++rofId) { + // auto rof = offset + rofId; + // auto clustersL1offsetRof = mTimeFrameGPU->getROframeClusters(1)[rof] - mTimeFrameGPU->getROframeClusters(1)[offset]; // starting cluster offset for this ROF + // auto nClustersL1Rof = mTimeFrameGPU->getROframeClusters(1)[rof + 1] - mTimeFrameGPU->getROframeClusters(1)[rof]; // number of clusters for this ROF + // auto linesOffsetRof = exclusiveFoundLinesHost[clustersL1offsetRof]; // starting line offset for this ROF + // auto nLinesRof = exclusiveFoundLinesHost[clustersL1offsetRof + nClustersL1Rof] - linesOffsetRof; + // gsl::span linesInRof(lines.data() + linesOffsetRof, static_cast::size_type>(nLinesRof)); + + // usedLines.resize(linesInRof.size(), false); + // usedLines.assign(linesInRof.size(), false); + // clusterLines.clear(); + // clusterLines.reserve(nClustersL1Rof); + // computeVerticesInRof(rof, + // linesInRof, + // usedLines, + // clusterLines, + // mTimeFrameGPU->getBeamXY(), + // mTimeFrameGPU->getVerticesInChunks()[chunkId], + // mTimeFrameGPU->getNVerticesInChunks()[chunkId], + // mTimeFrameGPU, + // mTimeFrameGPU->hasMCinformation() ? &mTimeFrameGPU->getLabelsInChunks()[chunkId] : nullptr); + // } + // offset += rofs; + // } + // }; + // // Do work + // threads[chunkId] = std::thread(doVertexReconstruction); + // } + // for (auto& thread : threads) { + // thread.join(); + // } + // for (int chunkId{0}; chunkId < mTimeFrameGPU->getNChunks(); ++chunkId) { + // int start{0}; + // for (int rofId{0}; rofId < mTimeFrameGPU->getNVerticesInChunks()[chunkId].size(); ++rofId) { + // gsl::span rofVerts{mTimeFrameGPU->getVerticesInChunks()[chunkId].data() + start, static_cast::size_type>(mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId])}; + // mTimeFrameGPU->addPrimaryVertices(rofVerts); + // if (mTimeFrameGPU->hasMCinformation()) { + // mTimeFrameGPU->getVerticesLabels().emplace_back(); + // // TODO: add MC labels + // } + // start += mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId]; + // } + // } + // mTimeFrameGPU->wipe(3); + } +} + +void VertexerTraitsGPU::computeTrackletMatching(const int iteration) +{ +} + +void VertexerTraitsGPU::computeVertices(const int iteration) +{ +} + +void VertexerTraitsGPU::computeVerticesHist() +{ +} + +VertexerTraits* createVertexerTraitsGPU() +{ + return new VertexerTraitsGPU; +} +} // namespace o2::its diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu similarity index 63% rename from Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu rename to Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu index 156282d14538c..9e99687c3be6a 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu @@ -8,36 +8,12 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// -/// \author matteo.concas@cern.ch +/// #include -#include -#include -#include -#include -#include -#include - #include -#include "ITStracking/MathUtils.h" -#include "ITStracking/Configuration.h" -#include "ITStracking/ClusterLines.h" -#include "ITStracking/Tracklet.h" - -#include "ITStrackingGPU/Utils.h" -#include "ITStrackingGPU/ClusterLinesGPU.h" -#include "ITStrackingGPU/VertexerTraitsGPU.h" - -#include "GPUCommonArray.h" - -#ifdef VTX_DEBUG -#include "TTree.h" -#include "TFile.h" -#endif - -#include "ITStrackingGPU/TracerGPU.h" +#include "ITStrackingGPU/VertexingKernels.h" namespace o2 { @@ -49,6 +25,24 @@ using gpu::utils::checkGPUError; using math_utils::getNormalizedPhi; using namespace constants::its2; +namespace gpu +{ +template +void trackletFinderHandler(const Cluster* clustersNextLayer, // 0 2 + const Cluster* clustersCurrentLayer, // 1 1 + const int* sizeNextLClusters, + const int* sizeCurrentLClusters, + const int* nextIndexTables, + Tracklet* Tracklets, + int* foundTracklets, + const IndexTableUtils* utils, + const unsigned int startRofId, + const unsigned int rofSize, + const float phiCut, + const size_t maxTrackletsPerCluster) +{ +} +/* GPUd() float smallestAngleDifference(float a, float b) { float diff = fmod(b - a + constants::math::Pi, constants::math::TwoPi) - constants::math::Pi; @@ -86,19 +80,6 @@ GPUh() void gpuThrowOnError() } } -VertexerTraitsGPU::VertexerTraitsGPU() -{ - setIsGPU(true); -} - -void VertexerTraitsGPU::initialise(const TrackingParameters& trackingParams, const int iteration) -{ - mTimeFrameGPU->initialise(0, trackingParams, 3, &mIndexTableUtils, &mTfGPUParams); -} - -namespace gpu -{ - template GPUd() void printOnThread(const unsigned int tId, const char* str, Args... args) { @@ -589,197 +570,7 @@ GPUg() void computeVertexKernel( } } } +*/ } // namespace gpu - -void VertexerTraitsGPU::updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& tfPar) -{ - mVrtParams = vrtPar; - mTfGPUParams = tfPar; - mVrtParams = vrtPar; - mIndexTableUtils.setTrackingParameters(vrtPar[0]); - for (auto& par : mVrtParams) { - par.phiSpan = static_cast(std::ceil(mIndexTableUtils.getNphiBins() * par.phiCut / constants::math::TwoPi)); - par.zSpan = static_cast(std::ceil(par.zCut * mIndexTableUtils.getInverseZCoordinate(0))); - } -} - -void VertexerTraitsGPU::computeTracklets(const int iteration) -{ - if (!mTimeFrameGPU->getClusters().size()) { - return; - } - std::vector threads(mTimeFrameGPU->getNChunks()); - for (int chunkId{0}; chunkId < mTimeFrameGPU->getNChunks(); ++chunkId) { - int rofPerChunk{mTimeFrameGPU->mNrof / (int)mTimeFrameGPU->getNChunks()}; - mTimeFrameGPU->getVerticesInChunks()[chunkId].clear(); - mTimeFrameGPU->getNVerticesInChunks()[chunkId].clear(); - mTimeFrameGPU->getLabelsInChunks()[chunkId].clear(); - auto doVertexReconstruction = [&, chunkId, rofPerChunk]() -> void { - auto offset = chunkId * rofPerChunk; - auto maxROF = offset + rofPerChunk; - while (offset < maxROF) { - auto rofs = mTimeFrameGPU->loadChunkData(chunkId, offset, maxROF); - RANGE("chunk_gpu_vertexing", 1); - // gpu::GpuTimer timer{offset, mTimeFrameGPU->getStream(chunkId).get()}; - // timer.Start("vtTrackletFinder"); - gpu::trackleterKernelMultipleRof<<getStream(chunkId).get()>>>( - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clustersNextLayer, // 0 2 - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clustersCurrentLayer, // 1 1 - mTimeFrameGPU->getDeviceROFramesClusters(0), // const int* sizeNextLClusters, - mTimeFrameGPU->getDeviceROFramesClusters(1), // const int* sizeCurrentLClusters, - mTimeFrameGPU->getChunk(chunkId).getDeviceIndexTables(0), // const int* nextIndexTables, - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* Tracklets, - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // int* foundTracklets, - mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, - offset, // const unsigned int startRofId, - rofs, // const unsigned int rofSize, - mVrtParams[iteration].phiCut, // const float phiCut, - mVrtParams[iteration].maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 - - gpu::trackleterKernelMultipleRof<<getStream(chunkId).get()>>>( - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(2), // const Cluster* clustersNextLayer, // 0 2 - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clustersCurrentLayer, // 1 1 - mTimeFrameGPU->getDeviceROFramesClusters(2), // const int* sizeNextLClusters, - mTimeFrameGPU->getDeviceROFramesClusters(1), // const int* sizeCurrentLClusters, - mTimeFrameGPU->getChunk(chunkId).getDeviceIndexTables(2), // const int* nextIndexTables, - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* Tracklets, - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // int* foundTracklets, - mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils, - offset, // const unsigned int startRofId, - rofs, // const unsigned int rofSize, - mVrtParams[iteration].phiCut, // const float phiCut, - mVrtParams[iteration].maxTrackletsPerCluster); // const size_t maxTrackletsPerCluster = 1e2 - - gpu::trackletSelectionKernelMultipleRof<<getStream(chunkId).get()>>>( - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clusters0, // Clusters on layer 0 - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clusters1, // Clusters on layer 1 - mTimeFrameGPU->getDeviceROFramesClusters(0), // const int* sizeClustersL0, // Number of clusters on layer 0 per ROF - mTimeFrameGPU->getDeviceROFramesClusters(1), // const int* sizeClustersL1, // Number of clusters on layer 1 per ROF - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* tracklets01, // Tracklets on layer 0-1 - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* tracklets12, // Tracklets on layer 1-2 - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // const int* nFoundTracklets01, // Number of tracklets found on layers 0-1 - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // const int* nFoundTracklet12, // Number of tracklets found on layers 1-2 - mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), // unsigned char* usedTracklets, // Used tracklets - mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), // Line* lines, // Lines - mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), // int* nFoundLines, // Number of found lines - mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan - offset, // const unsigned int startRofId, // Starting ROF ID - rofs, // const unsigned int rofSize, // Number of ROFs to consider - mVrtParams[iteration].maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster - mVrtParams[iteration].tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda - mVrtParams[iteration].phiCut); // const float phiCut = 0.002f) // Cut on phi - - discardResult(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), - mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, - mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), - mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), - mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), - mTimeFrameGPU->getStream(chunkId).get())); - - // Reset used tracklets - checkGPUError(cudaMemsetAsync(mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), - false, - sizeof(unsigned char) * mVrtParams[iteration].maxTrackletsPerCluster * mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1), - mTimeFrameGPU->getStream(chunkId).get()), - __FILE__, __LINE__); - - gpu::trackletSelectionKernelMultipleRof<<getStream(chunkId).get()>>>( - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(0), // const Cluster* clusters0, // Clusters on layer 0 - mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(1), // const Cluster* clusters1, // Clusters on layer 1 - mTimeFrameGPU->getDeviceROFramesClusters(0), // const int* sizeClustersL0, // Number of clusters on layer 0 per ROF - mTimeFrameGPU->getDeviceROFramesClusters(1), // const int* sizeClustersL1, // Number of clusters on layer 1 per ROF - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(0), // Tracklet* tracklets01, // Tracklets on layer 0-1 - mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(1), // Tracklet* tracklets12, // Tracklets on layer 1-2 - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(0), // const int* nFoundTracklets01, // Number of tracklets found on layers 0-1 - mTimeFrameGPU->getChunk(chunkId).getDeviceNTrackletCluster(1), // const int* nFoundTracklet12, // Number of tracklets found on layers 1-2 - mTimeFrameGPU->getChunk(chunkId).getDeviceUsedTracklets(), // unsigned char* usedTracklets, // Used tracklets - mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), // Line* lines, // Lines - mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines(), // int* nFoundLines, // Number of found lines - mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), // int* nExclusiveFoundLines, // Number of found lines exclusive scan - offset, // const unsigned int startRofId, // Starting ROF ID - rofs, // const unsigned int rofSize, // Number of ROFs to consider - mVrtParams[iteration].maxTrackletsPerCluster, // const int maxTrackletsPerCluster = 1e2, // Maximum number of tracklets per cluster - mVrtParams[iteration].tanLambdaCut, // const float tanLambdaCut = 0.025f, // Cut on tan lambda - mVrtParams[iteration].phiCut); // const float phiCut = 0.002f) // Cut on phi - - int nClusters = mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, 1); - int lastFoundLines; - std::vector exclusiveFoundLinesHost(nClusters + 1); - - // Obtain whole exclusive sum including nCluster+1 element (nCluster+1)th element is the total number of found lines. - checkGPUError(cudaMemcpyAsync(exclusiveFoundLinesHost.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceNExclusiveFoundLines(), (nClusters) * sizeof(int), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); - checkGPUError(cudaMemcpyAsync(&lastFoundLines, mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundLines() + nClusters - 1, sizeof(int), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); - exclusiveFoundLinesHost[nClusters] = exclusiveFoundLinesHost[nClusters - 1] + lastFoundLines; - - std::vector lines(exclusiveFoundLinesHost[nClusters]); - - checkGPUError(cudaMemcpyAsync(lines.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceLines(), sizeof(Line) * lines.size(), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); - checkGPUError(cudaStreamSynchronize(mTimeFrameGPU->getStream(chunkId).get())); - - // Compute vertices - std::vector clusterLines; - std::vector usedLines; - for (int rofId{0}; rofId < rofs; ++rofId) { - auto rof = offset + rofId; - auto clustersL1offsetRof = mTimeFrameGPU->getROFrameClusters(1)[rof] - mTimeFrameGPU->getROFrameClusters(1)[offset]; // starting cluster offset for this ROF - auto nClustersL1Rof = mTimeFrameGPU->getROFrameClusters(1)[rof + 1] - mTimeFrameGPU->getROFrameClusters(1)[rof]; // number of clusters for this ROF - auto linesOffsetRof = exclusiveFoundLinesHost[clustersL1offsetRof]; // starting line offset for this ROF - auto nLinesRof = exclusiveFoundLinesHost[clustersL1offsetRof + nClustersL1Rof] - linesOffsetRof; - gsl::span linesInRof(lines.data() + linesOffsetRof, static_cast::size_type>(nLinesRof)); - - usedLines.resize(linesInRof.size(), false); - usedLines.assign(linesInRof.size(), false); - clusterLines.clear(); - clusterLines.reserve(nClustersL1Rof); - computeVerticesInRof(rof, - linesInRof, - usedLines, - clusterLines, - mTimeFrameGPU->getBeamXY(), - mTimeFrameGPU->getVerticesInChunks()[chunkId], - mTimeFrameGPU->getNVerticesInChunks()[chunkId], - mTimeFrameGPU, - mTimeFrameGPU->hasMCinformation() ? &mTimeFrameGPU->getLabelsInChunks()[chunkId] : nullptr); - } - offset += rofs; - } - }; - // Do work - threads[chunkId] = std::thread(doVertexReconstruction); - } - for (auto& thread : threads) { - thread.join(); - } - for (int chunkId{0}; chunkId < mTimeFrameGPU->getNChunks(); ++chunkId) { - int start{0}; - for (int rofId{0}; rofId < mTimeFrameGPU->getNVerticesInChunks()[chunkId].size(); ++rofId) { - gsl::span rofVerts{mTimeFrameGPU->getVerticesInChunks()[chunkId].data() + start, static_cast::size_type>(mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId])}; - mTimeFrameGPU->addPrimaryVertices(rofVerts, rofId, 0); - if (mTimeFrameGPU->hasMCinformation()) { - // mTimeFrameGPU->getVerticesLabels().emplace_back(); - // TODO: add MC labels - } - start += mTimeFrameGPU->getNVerticesInChunks()[chunkId][rofId]; - } - } - mTimeFrameGPU->wipe(3); -} - -void VertexerTraitsGPU::computeTrackletMatching(const int iteration) -{ -} - -void VertexerTraitsGPU::computeVertices(const int iteration) -{ -} - -void VertexerTraitsGPU::computeVerticesHist() -{ -} - -VertexerTraits* createVertexerTraitsGPU() -{ - return new VertexerTraitsGPU; -} } // namespace its -} // namespace o2 +} // namespace o2 \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt index 3c5614b172040..f51544eaa970c 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt @@ -20,7 +20,8 @@ if(HIP_ENABLED) ../cuda/TrackerTraitsGPU.cxx ../cuda/TracerGPU.cu ../cuda/TrackingKernels.cu - ../cuda/VertexerTraitsGPU.cu + ../cuda/VertexingKernels.cu + ../cuda/VertexerTraitsGPU.cxx ../cuda/Utils.cu PUBLIC_INCLUDE_DIRECTORIES ../ PUBLIC_LINK_LIBRARIES O2::ITStracking diff --git a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx index ff515c9f4b216..69d1ac9e7547c 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx @@ -90,7 +90,7 @@ float Vertexer::clustersToVerticesHybrid(std::function logg auto timeVertexingIteration = evaluateTask( &Vertexer::findVerticesHybrid, "Hybrid Vertexer vertex finding", [](std::string) {}, iteration); - printEpilog(logger, false, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), mTimeFrame->getTotVertIteration().size(), timeInit, timeTracklet, timeSelection, timeVertexing); + printEpilog(logger, true, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), mTimeFrame->getTotVertIteration().size(), timeInit, timeTracklet, timeSelection, timeVertexing); timeInit += timeInitIteration; timeTracklet += timeTrackletIteration; timeSelection += timeSelectionIteration; diff --git a/Detectors/ITSMFT/ITS/workflow/src/RecoWorkflow.cxx b/Detectors/ITSMFT/ITS/workflow/src/RecoWorkflow.cxx index dc75d90150eb8..b03d1dccfb8e7 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/RecoWorkflow.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/RecoWorkflow.cxx @@ -79,7 +79,7 @@ framework::WorkflowSpec getWorkflow(bool useMC, std::move(ggInputs.begin(), ggInputs.end(), std::back_inserter(taskInputs)); specs.emplace_back(DataProcessorSpec{ - "its-tracker", + "its-gpu-tracker", taskInputs, task->outputs(), AlgorithmSpec{adoptTask(task)}, From 8e63310973d9cb161bbf8652c55475bbcc99334f Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:46:01 +0200 Subject: [PATCH 0191/2205] DPL: allow printing stacktrace on signposts --- Framework/Core/src/runDataProcessing.cxx | 17 ++++++++++++++--- .../Foundation/include/Framework/Signpost.h | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 933eb1dda52cf..4cec8c63fe856 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -2741,9 +2741,20 @@ void enableSignposts(std::string const& signpostsToEnable) auto* log = (_o2_log_t*)l; auto* selectedName = (char const*)context; std::string prefix = "ch.cern.aliceo2."; - if (strcmp(name, (prefix + selectedName).data()) == 0) { - LOGP(info, "Enabling signposts for stream \"ch.cern.aliceo2.{}\"", selectedName); - _o2_log_set_stacktrace(log, 1); + auto* last = strchr(selectedName, ':'); + int maxDepth = 1; + if (last) { + char* err; + maxDepth = strtol(last + 1, &err, 10); + if (*(last + 1) == '\0' || *err != '\0') { + maxDepth = 1; + } + } + + auto fullName = prefix + std::string{selectedName, last ? last - selectedName : strlen(selectedName)}; + if (strncmp(name, fullName.data(), fullName.size()) == 0) { + LOGP(info, "Enabling signposts for stream \"{}\" with depth {}.", fullName, maxDepth); + _o2_log_set_stacktrace(log, maxDepth); return false; } else { LOGP(info, "Signpost stream \"{}\" disabled. Enable it with o2-log -p {} -a {}", name, pid, (void*)&log->stacktrace); diff --git a/Framework/Foundation/include/Framework/Signpost.h b/Framework/Foundation/include/Framework/Signpost.h index 5e844ce01b20c..74368f73c382e 100644 --- a/Framework/Foundation/include/Framework/Signpost.h +++ b/Framework/Foundation/include/Framework/Signpost.h @@ -381,7 +381,8 @@ void _o2_signpost_event_emit(_o2_log_t* log, _o2_signpost_id_t id, char const* n O2_LOG_MACRO("%s", prebuffer); if (log->stacktrace > 1) { void* traces[o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE]; - int maxBacktrace = backtrace(traces, o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE); + // We add one extra frame, because one is for the logging + int maxBacktrace = backtrace(traces, (log->stacktrace + 1) < o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE ? (log->stacktrace + 1) : o2::framework::BacktraceHelpers::MAX_BACKTRACE_SIZE); o2::framework::BacktraceHelpers::demangled_backtrace_symbols(traces, maxBacktrace, STDERR_FILENO); } } From 4720c16bf8ef1d087df824146b803b8b645b474d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 4 Sep 2024 13:09:06 +0200 Subject: [PATCH 0192/2205] ROOT Dictionary: Fix error handling in wrapper for dictionary generation --- cmake/rootcling_wrapper.sh.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/rootcling_wrapper.sh.in b/cmake/rootcling_wrapper.sh.in index 8d4e3514a6e81..76ce8c8115ca9 100755 --- a/cmake/rootcling_wrapper.sh.in +++ b/cmake/rootcling_wrapper.sh.in @@ -92,10 +92,12 @@ LOGFILE=${DICTIONARY_FILE}.log ${COMPILE_DEFINITIONS//;/ } \ ${PCMDEPS:+-m }${PCMDEPS//;/ -m } \ ${HEADERS//;/ } \ - > ${LOGFILE} 2>&1 || cat ${LOGFILE} >&2 + > ${LOGFILE} 2>&1 || ROOTCLINGRETVAL=$? -if [[ $? != "0" ]]; then - rm $DICTIONARY_FILE +if [[ ${ROOTCLINGRETVAL:-0} != "0" ]]; then + cat ${LOGFILE} >&2 + rm -f $DICTIONARY_FILE + echo "ROOT CLING Dictionary generation of $DICTIONARY_FILE failed with error code $ROOTCLINGRETVAL" exit 1 fi From a7c2323740b06335afae6665d0021ed869dd9c24 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 4 Sep 2024 15:23:02 +0200 Subject: [PATCH 0193/2205] Remove unused mLabels containers --- Steer/DigitizerWorkflow/src/MCTruthSourceSpec.cxx | 1 - Steer/DigitizerWorkflow/src/MCTruthWriterSpec.cxx | 1 - 2 files changed, 2 deletions(-) diff --git a/Steer/DigitizerWorkflow/src/MCTruthSourceSpec.cxx b/Steer/DigitizerWorkflow/src/MCTruthSourceSpec.cxx index 6888b118fb06c..cbc870129e9a8 100644 --- a/Steer/DigitizerWorkflow/src/MCTruthSourceSpec.cxx +++ b/Steer/DigitizerWorkflow/src/MCTruthSourceSpec.cxx @@ -72,7 +72,6 @@ class MCTruthSourceTask : public o2::framework::Task bool mFinished = false; int mSize = 0; bool mNew = false; - o2::dataformats::MCTruthContainer mLabels; // labels which get filled }; o2::framework::DataProcessorSpec getMCTruthSourceSpec(bool newmctruth) diff --git a/Steer/DigitizerWorkflow/src/MCTruthWriterSpec.cxx b/Steer/DigitizerWorkflow/src/MCTruthWriterSpec.cxx index 78fb8988a2419..efbd87742a578 100644 --- a/Steer/DigitizerWorkflow/src/MCTruthWriterSpec.cxx +++ b/Steer/DigitizerWorkflow/src/MCTruthWriterSpec.cxx @@ -97,7 +97,6 @@ class MCTruthWriterTask : public o2::framework::Task bool mNew = false; bool mIO = false; int mID = 0; - o2::dataformats::MCTruthContainer mLabels; // labels which get filled }; o2::framework::DataProcessorSpec getMCTruthWriterSpec(int id, bool doio, bool newmctruth) From c148c3978bc94507b8d81ebcb1018c00ae4a145f Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 5 Sep 2024 16:30:12 +0200 Subject: [PATCH 0194/2205] GPU HIP CMake: Improve CUDA similarity check, avoid unnecessary recheck --- GPU/GPUTracking/Base/hip/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Base/hip/CMakeLists.txt b/GPU/GPUTracking/Base/hip/CMakeLists.txt index 46b5edabdea58..f500220008536 100644 --- a/GPU/GPUTracking/Base/hip/CMakeLists.txt +++ b/GPU/GPUTracking/Base/hip/CMakeLists.txt @@ -52,7 +52,8 @@ if(NOT DEFINED GPUCA_HIP_HIPIFY_FROM_CUDA OR "${GPUCA_HIP_HIPIFY_FROM_CUDA}") list(APPEND HIP_SOURCES "${GPUCA_HIP_SOURCE_DIR}/${HIP_SOURCE}") endforeach() - add_custom_target(${MODULE}_HIPIFIED_CHK COMMAND diff -u ${GPUCA_HIP_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip ${CMAKE_CURRENT_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip DEPENDS ${GPUCA_HIP_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip ${CMAKE_CURRENT_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${MODULE}_HIPIFIED_CHK.done COMMAND diff -u ${GPUCA_HIP_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip ${CMAKE_CURRENT_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip && touch ${CMAKE_CURRENT_BINARY_DIR}/${MODULE}_HIPIFIED_CHK.done DEPENDS ${GPUCA_HIP_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip ${CMAKE_CURRENT_SOURCE_DIR}/GPUReconstructionHIPkernel.template.hip) + add_custom_target(${MODULE}_HIPIFIED_CHK DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${MODULE}_HIPIFIED_CHK.done) else() get_filename_component(GPUCA_HIP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ABSOLUTE) endif() From 86fca7ee996f8ebf63e5ce1c5c4e09dd5d8408de Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 5 Sep 2024 09:01:29 +0200 Subject: [PATCH 0195/2205] DPL: move analysis topology helper methods to a separate class On their way to a separate plugin --- Framework/Core/CMakeLists.txt | 1 + .../include/Framework/CommonDataProcessors.h | 27 +- Framework/Core/src/AnalysisSupportHelpers.cxx | 506 ++++++++++++++++++ Framework/Core/src/AnalysisSupportHelpers.h | 86 +++ Framework/Core/src/ArrowSupport.cxx | 7 +- Framework/Core/src/CommonDataProcessors.cxx | 413 -------------- Framework/Core/src/WorkflowHelpers.cxx | 142 +---- Framework/Core/src/WorkflowHelpers.h | 18 - 8 files changed, 624 insertions(+), 576 deletions(-) create mode 100644 Framework/Core/src/AnalysisSupportHelpers.cxx create mode 100644 Framework/Core/src/AnalysisSupportHelpers.h diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index 4381b6c4fa29d..7ddffda175a0a 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -16,6 +16,7 @@ o2_add_library(Framework src/ArrowSupport.cxx src/ArrowTableSlicingCache.cxx src/AnalysisDataModel.cxx + src/AnalysisSupportHelpers.cxx src/ASoA.cxx src/AsyncQueue.cxx src/AnalysisDataModelHelpers.cxx diff --git a/Framework/Core/include/Framework/CommonDataProcessors.h b/Framework/Core/include/Framework/CommonDataProcessors.h index bb97f29edfc42..824386c4d5921 100644 --- a/Framework/Core/include/Framework/CommonDataProcessors.h +++ b/Framework/Core/include/Framework/CommonDataProcessors.h @@ -17,31 +17,10 @@ #include #include -namespace o2::framework -{ - -class DataOutputDirector; - -struct OutputTaskInfo { - uint32_t id; - std::string name; -}; - -struct OutputObjectInfo { - uint32_t id; - std::vector bindings; -}; -} // namespace o2::framework -extern template class std::vector; -extern template class std::vector; namespace o2::framework { /// Helpers to create a few general data processors struct CommonDataProcessors { - /// Match all inputs of kind ATSK and write them to a ROOT file, - /// one root file per originating task. - static DataProcessorSpec getOutputObjHistSink(std::vector const& objmap, - std::vector const& tskmap); /// Given the list of @a danglingInputs @return a DataProcessor which does /// a binary dump for all the dangling inputs matching the Timeframe /// lifetime. @a unmatched will be filled with all the InputSpecs which are @@ -54,10 +33,6 @@ struct CommonDataProcessors { /// @fixme: for now only the dangling inputs are forwarded. static DataProcessorSpec getGlobalFairMQSink(std::vector const& danglingInputs); - /// writes inputs of kind AOD to file - static DataProcessorSpec getGlobalAODSink(std::shared_ptr dod, - std::vector const& outputInputs); - /// @return a dummy DataProcessorSpec which requires all the passed @a InputSpec /// and simply discards them. @a rateLimitingChannelConfig is the configuration /// for the rate limiting channel, if any required. @@ -67,4 +42,4 @@ struct CommonDataProcessors { } // namespace o2::framework -#endif // o2_framework_CommonDataProcessors_H_INCLUDED +#endif // O2_FRAMEWORK_COMMONDATAPROCESSORS_H_ diff --git a/Framework/Core/src/AnalysisSupportHelpers.cxx b/Framework/Core/src/AnalysisSupportHelpers.cxx new file mode 100644 index 0000000000000..3613bfedb887a --- /dev/null +++ b/Framework/Core/src/AnalysisSupportHelpers.cxx @@ -0,0 +1,506 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "AnalysisSupportHelpers.h" +#include "Framework/DataOutputDirector.h" +#include "Framework/OutputObjHeader.h" +#include "Framework/ControlService.h" +#include "Framework/EndOfStreamContext.h" +#include "Framework/DeviceSpec.h" +#include "Framework/TableTreeHelpers.h" + +#include "TFile.h" +#include "TTree.h" +#include "TMap.h" +#include "TObjString.h" + +template class std::vector; +template class std::vector; + +namespace o2::framework +{ + +struct InputObjectRoute { + std::string name; + uint32_t uniqueId; + std::string directory; + uint32_t taskHash; + OutputObjHandlingPolicy policy; + OutputObjSourceType sourceType; +}; + +struct InputObject { + TClass* kind = nullptr; + void* obj = nullptr; + std::string name; + int count = -1; +}; + +void AnalysisSupportHelpers::addMissingOutputsToReader(std::vector const& providedOutputs, + std::vector const& requestedInputs, + DataProcessorSpec& publisher) +{ + auto matchingOutputFor = [](InputSpec const& requested) { + return [&requested](OutputSpec const& provided) { + return DataSpecUtils::match(requested, provided); + }; + }; + for (InputSpec const& requested : requestedInputs) { + auto provided = std::find_if(providedOutputs.begin(), + providedOutputs.end(), + matchingOutputFor(requested)); + + if (provided != providedOutputs.end()) { + continue; + } + + auto inList = std::find_if(publisher.outputs.begin(), + publisher.outputs.end(), + matchingOutputFor(requested)); + if (inList != publisher.outputs.end()) { + continue; + } + + auto concrete = DataSpecUtils::asConcreteDataMatcher(requested); + publisher.outputs.emplace_back(concrete.origin, concrete.description, concrete.subSpec, requested.lifetime, requested.metadata); + } +} + +void AnalysisSupportHelpers::addMissingOutputsToSpawner(std::vector const& providedSpecials, + std::vector const& requestedSpecials, + std::vector& requestedAODs, + DataProcessorSpec& publisher) +{ + for (auto& input : requestedSpecials) { + if (std::any_of(providedSpecials.begin(), providedSpecials.end(), [&input](auto const& x) { + return DataSpecUtils::match(input, x); + })) { + continue; + } + auto concrete = DataSpecUtils::asConcreteDataMatcher(input); + publisher.outputs.emplace_back(concrete.origin, concrete.description, concrete.subSpec); + for (auto& i : input.metadata) { + if ((i.type == VariantType::String) && (i.name.find("input:") != std::string::npos)) { + auto spec = DataSpecUtils::fromMetadataString(i.defaultValue.get()); + auto j = std::find(publisher.inputs.begin(), publisher.inputs.end(), spec); + if (j == publisher.inputs.end()) { + publisher.inputs.push_back(spec); + } + DataSpecUtils::updateInputList(requestedAODs, std::move(spec)); + } + } + } +} + +void AnalysisSupportHelpers::addMissingOutputsToBuilder(std::vector const& requestedSpecials, + std::vector& requestedAODs, + std::vector& requestedDYNs, + DataProcessorSpec& publisher) +{ + for (auto& input : requestedSpecials) { + auto concrete = DataSpecUtils::asConcreteDataMatcher(input); + publisher.outputs.emplace_back(concrete.origin, concrete.description, concrete.subSpec); + for (auto& i : input.metadata) { + if ((i.type == VariantType::String) && (i.name.find("input:") != std::string::npos)) { + auto spec = DataSpecUtils::fromMetadataString(i.defaultValue.get()); + auto j = std::find_if(publisher.inputs.begin(), publisher.inputs.end(), [&](auto x) { return x.binding == spec.binding; }); + if (j == publisher.inputs.end()) { + publisher.inputs.push_back(spec); + } + if (DataSpecUtils::partialMatch(spec, AODOrigins)) { + DataSpecUtils::updateInputList(requestedAODs, std::move(spec)); + } else if (DataSpecUtils::partialMatch(spec, header::DataOrigin{"DYN"})) { + DataSpecUtils::updateInputList(requestedDYNs, std::move(spec)); + } + } + } + } +} + +const static std::unordered_map ROOTfileNames = {{OutputObjHandlingPolicy::AnalysisObject, "AnalysisResults.root"}, + {OutputObjHandlingPolicy::QAObject, "QAResults.root"}}; + +// ============================================================================= +DataProcessorSpec AnalysisSupportHelpers::getOutputObjHistSink(std::vector const& objmap, std::vector const& tskmap) +{ + auto writerFunction = [objmap, tskmap](InitContext& ic) -> std::function { + auto& callbacks = ic.services().get(); + auto inputObjects = std::make_shared>>(); + + static TFile* f[OutputObjHandlingPolicy::numPolicies]; + for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { + f[i] = nullptr; + } + + static std::string currentDirectory = ""; + static std::string currentFile = ""; + + auto endofdatacb = [inputObjects](EndOfStreamContext& context) { + LOG(debug) << "Writing merged objects and histograms to file"; + if (inputObjects->empty()) { + LOG(error) << "Output object map is empty!"; + context.services().get().readyToQuit(QuitRequest::Me); + return; + } + for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { + if (f[i] != nullptr) { + f[i]->Close(); + } + } + LOG(debug) << "All outputs merged in their respective target files"; + context.services().get().readyToQuit(QuitRequest::Me); + }; + + callbacks.set(endofdatacb); + return [inputObjects, objmap, tskmap](ProcessingContext& pc) mutable -> void { + auto const& ref = pc.inputs().get("x"); + if (!ref.header) { + LOG(error) << "Header not found"; + return; + } + if (!ref.payload) { + LOG(error) << "Payload not found"; + return; + } + auto datah = o2::header::get(ref.header); + if (!datah) { + LOG(error) << "No data header in stack"; + return; + } + + auto objh = o2::header::get(ref.header); + if (!objh) { + LOG(error) << "No output object header in stack"; + return; + } + + InputObject obj; + FairInputTBuffer tm(const_cast(ref.payload), static_cast(datah->payloadSize)); + tm.InitMap(); + obj.kind = tm.ReadClass(); + tm.SetBufferOffset(0); + tm.ResetMap(); + if (obj.kind == nullptr) { + LOG(error) << "Cannot read class info from buffer."; + return; + } + + auto policy = objh->mPolicy; + auto sourceType = objh->mSourceType; + auto hash = objh->mTaskHash; + + obj.obj = tm.ReadObjectAny(obj.kind); + auto* named = static_cast(obj.obj); + obj.name = named->GetName(); + auto hpos = std::find_if(tskmap.begin(), tskmap.end(), [&](auto&& x) { return x.id == hash; }); + if (hpos == tskmap.end()) { + LOG(error) << "No task found for hash " << hash; + return; + } + auto taskname = hpos->name; + auto opos = std::find_if(objmap.begin(), objmap.end(), [&](auto&& x) { return x.id == hash; }); + if (opos == objmap.end()) { + LOG(error) << "No object list found for task " << taskname << " (hash=" << hash << ")"; + return; + } + auto objects = opos->bindings; + if (std::find(objects.begin(), objects.end(), obj.name) == objects.end()) { + LOG(error) << "No object " << obj.name << " in map for task " << taskname; + return; + } + auto nameHash = runtime_hash(obj.name.c_str()); + InputObjectRoute key{obj.name, nameHash, taskname, hash, policy, sourceType}; + auto existing = std::find_if(inputObjects->begin(), inputObjects->end(), [&](auto&& x) { return (x.first.uniqueId == nameHash) && (x.first.taskHash == hash); }); + // If it's the first one, we just add it to the list. + if (existing == inputObjects->end()) { + obj.count = objh->mPipelineSize; + inputObjects->push_back(std::make_pair(key, obj)); + existing = inputObjects->end() - 1; + } else { + obj.count = existing->second.count; + // Otherwise, we merge it with the existing one. + auto merger = existing->second.kind->GetMerge(); + if (!merger) { + LOG(error) << "Already one unmergeable object found for " << obj.name; + return; + } + TList coll; + coll.Add(static_cast(obj.obj)); + merger(existing->second.obj, &coll, nullptr); + } + // We expect as many objects as the pipeline size, for + // a given object name and task hash. + existing->second.count -= 1; + + if (existing->second.count != 0) { + return; + } + // Write the object here. + auto route = existing->first; + auto entry = existing->second; + auto file = ROOTfileNames.find(route.policy); + if (file == ROOTfileNames.end()) { + return; + } + auto filename = file->second; + if (f[route.policy] == nullptr) { + f[route.policy] = TFile::Open(filename.c_str(), "RECREATE"); + } + auto nextDirectory = route.directory; + if ((nextDirectory != currentDirectory) || (filename != currentFile)) { + if (!f[route.policy]->FindKey(nextDirectory.c_str())) { + f[route.policy]->mkdir(nextDirectory.c_str()); + } + currentDirectory = nextDirectory; + currentFile = filename; + } + + // translate the list-structure created by the registry into a directory structure within the file + std::function writeListToFile; + writeListToFile = [&](TList* list, TDirectory* parentDir) { + TIter next(list); + TObject* object = nullptr; + while ((object = next())) { + if (object->InheritsFrom(TList::Class())) { + writeListToFile(static_cast(object), parentDir->mkdir(object->GetName(), object->GetName(), true)); + } else { + parentDir->WriteObjectAny(object, object->Class(), object->GetName()); + auto* written = list->Remove(object); + delete written; + } + } + }; + + TDirectory* currentDir = f[route.policy]->GetDirectory(currentDirectory.c_str()); + if (route.sourceType == OutputObjSourceType::HistogramRegistrySource) { + auto* outputList = static_cast(entry.obj); + outputList->SetOwner(false); + + // if registry should live in dedicated folder a TNamed object is appended to the list + if (outputList->Last() && outputList->Last()->IsA() == TNamed::Class()) { + delete outputList->Last(); + outputList->RemoveLast(); + currentDir = currentDir->mkdir(outputList->GetName(), outputList->GetName(), true); + } + + writeListToFile(outputList, currentDir); + outputList->SetOwner(); + delete outputList; + entry.obj = nullptr; + } else { + currentDir->WriteObjectAny(entry.obj, entry.kind, entry.name.c_str()); + delete (TObject*)entry.obj; + entry.obj = nullptr; + } + }; + }; + + char const* name = "internal-dpl-aod-global-analysis-file-sink"; + // Lifetime is sporadic because we do not ask each analysis task to send its + // results every timeframe. + DataProcessorSpec spec{ + .name = name, + .inputs = {InputSpec("x", DataSpecUtils::dataDescriptorMatcherFrom(header::DataOrigin{"ATSK"}), Lifetime::Sporadic)}, + .algorithm = {writerFunction}, + }; + + return spec; +} + +// add sink for the AODs +DataProcessorSpec + AnalysisSupportHelpers::getGlobalAODSink(std::shared_ptr dod, + std::vector const& outputInputs) +{ + + auto writerFunction = [dod, outputInputs](InitContext& ic) -> std::function { + LOGP(debug, "======== getGlobalAODSink::Init =========="); + + // find out if any table needs to be saved + bool hasOutputsToWrite = false; + for (auto& outobj : outputInputs) { + auto ds = dod->getDataOutputDescriptors(outobj); + if (ds.size() > 0) { + hasOutputsToWrite = true; + break; + } + } + + // if nothing needs to be saved then return a trivial functor + // this happens when nothing needs to be saved but there are dangling outputs + if (!hasOutputsToWrite) { + return [](ProcessingContext&) mutable -> void { + static bool once = false; + if (!once) { + LOG(info) << "No AODs to be saved."; + once = true; + } + }; + } + + // end of data functor is called at the end of the data stream + auto endofdatacb = [dod](EndOfStreamContext& context) { + dod->closeDataFiles(); + context.services().get().readyToQuit(QuitRequest::Me); + }; + + auto& callbacks = ic.services().get(); + callbacks.set(endofdatacb); + + // prepare map(startTime, tfNumber) + std::map tfNumbers; + std::map tfFilenames; + + std::vector aodMetaDataKeys; + std::vector aodMetaDataVals; + + // this functor is called once per time frame + return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals](ProcessingContext& pc) mutable -> void { + LOGP(debug, "======== getGlobalAODSink::processing =========="); + LOGP(debug, " processing data set with {} entries", pc.inputs().size()); + + // return immediately if pc.inputs() is empty. This should never happen! + if (pc.inputs().size() == 0) { + LOGP(info, "No inputs available!"); + return; + } + + // update tfNumbers + uint64_t startTime = 0; + uint64_t tfNumber = 0; + auto ref = pc.inputs().get("tfn"); + if (ref.spec && ref.payload) { + startTime = DataRefUtils::getHeader(ref)->startTime; + tfNumber = pc.inputs().get("tfn"); + tfNumbers.insert(std::pair(startTime, tfNumber)); + } + // update tfFilenames + std::string aodInputFile; + auto ref2 = pc.inputs().get("tff"); + if (ref2.spec && ref2.payload) { + startTime = DataRefUtils::getHeader(ref2)->startTime; + aodInputFile = pc.inputs().get("tff"); + tfFilenames.insert(std::pair(startTime, aodInputFile)); + } + + // close all output files if one has reached size limit + dod->checkFileSizes(); + + // loop over the DataRefs which are contained in pc.inputs() + for (const auto& ref : pc.inputs()) { + if (!ref.spec) { + LOGP(debug, "Invalid input will be skipped!"); + continue; + } + + // get metadata + if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataKeys"))) { + aodMetaDataKeys = pc.inputs().get>(ref.spec->binding); + } + if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataVals"))) { + aodMetaDataVals = pc.inputs().get>(ref.spec->binding); + } + + // skip non-AOD refs + if (!DataSpecUtils::partialMatch(*ref.spec, writableAODOrigins)) { + continue; + } + startTime = DataRefUtils::getHeader(ref)->startTime; + + // does this need to be saved? + auto dh = DataRefUtils::getHeader(ref); + auto tableName = dh->dataDescription.as(); + auto ds = dod->getDataOutputDescriptors(*dh); + if (ds.empty()) { + continue; + } + + // get TF number from startTime + auto it = tfNumbers.find(startTime); + if (it != tfNumbers.end()) { + tfNumber = (it->second / dod->getNumberTimeFramesToMerge()) * dod->getNumberTimeFramesToMerge(); + } else { + LOGP(fatal, "No time frame number found for output with start time {}", startTime); + throw std::runtime_error("Processing is stopped!"); + } + // get aod input file from startTime + auto it2 = tfFilenames.find(startTime); + if (it2 != tfFilenames.end()) { + aodInputFile = it2->second; + } + + // get the TableConsumer and corresponding arrow table + auto msg = pc.inputs().get(ref.spec->binding); + if (msg.header == nullptr) { + LOGP(error, "No header for message {}:{}", ref.spec->binding, DataSpecUtils::describe(*ref.spec)); + continue; + } + auto s = pc.inputs().get(ref.spec->binding); + auto table = s->asArrowTable(); + if (!table->Validate().ok()) { + LOGP(warning, "The table \"{}\" is not valid and will not be saved!", tableName); + continue; + } + if (table->schema()->fields().empty()) { + LOGP(debug, "The table \"{}\" is empty but will be saved anyway!", tableName); + } + + // loop over all DataOutputDescriptors + // a table can be saved in multiple ways + // e.g. different selections of columns to different files + for (auto d : ds) { + auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile); + auto treename = fileAndFolder.folderName + "/" + d->treename; + TableToTree ta2tr(table, + fileAndFolder.file, + treename.c_str()); + + // update metadata + if (fileAndFolder.file->FindObjectAny("metaData")) { + LOGF(debug, "Metadata: target file %s already has metadata, preserving it", fileAndFolder.file->GetName()); + } else if (!aodMetaDataKeys.empty() && !aodMetaDataVals.empty()) { + TMap aodMetaDataMap; + for (uint32_t imd = 0; imd < aodMetaDataKeys.size(); imd++) { + aodMetaDataMap.Add(new TObjString(aodMetaDataKeys[imd]), new TObjString(aodMetaDataVals[imd])); + } + fileAndFolder.file->WriteObject(&aodMetaDataMap, "metaData", "Overwrite"); + } + + if (!d->colnames.empty()) { + for (auto& cn : d->colnames) { + auto idx = table->schema()->GetFieldIndex(cn); + auto col = table->column(idx); + auto field = table->schema()->field(idx); + if (idx != -1) { + ta2tr.addBranch(col, field); + } + } + } else { + ta2tr.addAllBranches(); + } + ta2tr.process(); + } + } + }; + }; // end of writerFunction + + // the command line options relevant for the writer are global + // see runDataProcessing.h + DataProcessorSpec spec{ + "internal-dpl-aod-writer", + outputInputs, + Outputs{}, + AlgorithmSpec(writerFunction), + {}}; + + return spec; +} +} // namespace o2::framework diff --git a/Framework/Core/src/AnalysisSupportHelpers.h b/Framework/Core/src/AnalysisSupportHelpers.h new file mode 100644 index 0000000000000..43ce7ab85b96d --- /dev/null +++ b/Framework/Core/src/AnalysisSupportHelpers.h @@ -0,0 +1,86 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_ANALYSISSUPPORTHELPERS_H_ +#define O2_FRAMEWORK_ANALYSISSUPPORTHELPERS_H_ + +#include "Framework/OutputSpec.h" +#include "Framework/InputSpec.h" +#include "Framework/DataProcessorSpec.h" +#include "Headers/DataHeader.h" +#include + +namespace o2::framework +{ +static constexpr std::array AODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}}; +static constexpr std::array extendedAODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}, header::DataOrigin{"DYN"}, header::DataOrigin{"AMD"}}; +static constexpr std::array writableAODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}, header::DataOrigin{"DYN"}}; + +class DataOutputDirector; + +struct OutputTaskInfo { + uint32_t id; + std::string name; +}; + +struct OutputObjectInfo { + uint32_t id; + std::vector bindings; +}; +} // namespace o2::framework + +extern template class std::vector; +extern template class std::vector; + +namespace o2::framework +{ +// +struct AnalysisContext { + std::vector requestedAODs; + std::vector providedAODs; + std::vector requestedDYNs; + std::vector providedDYNs; + std::vector requestedIDXs; + std::vector providedOutputObjHist; + std::vector spawnerInputs; + + std::vector outTskMap; + std::vector outObjHistMap; +}; + +// Helper class to be moved in the AnalysisSupport plugin at some point +struct AnalysisSupportHelpers { + /// Helper functions to add AOD related internal devices. + /// FIXME: moved here until we have proper plugin based amendment + /// of device injection + static void addMissingOutputsToReader(std::vector const& providedOutputs, + std::vector const& requestedInputs, + DataProcessorSpec& publisher); + static void addMissingOutputsToSpawner(std::vector const& providedSpecials, + std::vector const& requestedSpecials, + std::vector& requestedAODs, + DataProcessorSpec& publisher); + static void addMissingOutputsToBuilder(std::vector const& requestedSpecials, + std::vector& requestedAODs, + std::vector& requestedDYNs, + DataProcessorSpec& publisher); + + /// Match all inputs of kind ATSK and write them to a ROOT file, + /// one root file per originating task. + static DataProcessorSpec getOutputObjHistSink(std::vector const& objmap, + std::vector const& tskmap); + /// writes inputs of kind AOD to file + static DataProcessorSpec getGlobalAODSink(std::shared_ptr dod, + std::vector const& outputInputs); +}; + +}; // namespace o2::framework + +#endif // O2_FRAMEWORK_ANALYSISSUPPORTHELPERS_H_ diff --git a/Framework/Core/src/ArrowSupport.cxx b/Framework/Core/src/ArrowSupport.cxx index 34916445a3912..5c1a9050c4e40 100644 --- a/Framework/Core/src/ArrowSupport.cxx +++ b/Framework/Core/src/ArrowSupport.cxx @@ -30,6 +30,7 @@ #include "Framework/ServiceMetricsInfo.h" #include "WorkflowHelpers.h" #include "Framework/WorkflowSpecNode.h" +#include "AnalysisSupportHelpers.h" #include "CommonMessageBackendsHelpers.h" #include @@ -445,7 +446,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // replace AlgorithmSpec // FIXME: it should be made more generic, so it does not need replacement... builder->algorithm = readers::AODReaderHelpers::indexBuilderCallback(requestedIDXs); - WorkflowHelpers::addMissingOutputsToBuilder(requestedIDXs, requestedAODs, requestedDYNs, *builder); + AnalysisSupportHelpers::addMissingOutputsToBuilder(requestedIDXs, requestedAODs, requestedDYNs, *builder); } if (spawner != workflow.end()) { @@ -480,7 +481,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // replace AlgorithmSpec // FIXME: it should be made more generic, so it does not need replacement... spawner->algorithm = readers::AODReaderHelpers::aodSpawnerCallback(spawnerInputs); - WorkflowHelpers::addMissingOutputsToSpawner({}, spawnerInputs, requestedAODs, *spawner); + AnalysisSupportHelpers::addMissingOutputsToSpawner({}, spawnerInputs, requestedAODs, *spawner); } if (writer != workflow.end()) { @@ -535,7 +536,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // add TFNumber and TFFilename as input to the writer outputsInputsAOD.emplace_back("tfn", "TFN", "TFNumber"); outputsInputsAOD.emplace_back("tff", "TFF", "TFFilename"); - workflow.push_back(CommonDataProcessors::getGlobalAODSink(dod, outputsInputsAOD)); + workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD)); } // Move the dummy sink at the end, if needed for (size_t i = 0; i < workflow.size(); ++i) { diff --git a/Framework/Core/src/CommonDataProcessors.cxx b/Framework/Core/src/CommonDataProcessors.cxx index 9817a57734c1d..d893e16513f40 100644 --- a/Framework/Core/src/CommonDataProcessors.cxx +++ b/Framework/Core/src/CommonDataProcessors.cxx @@ -32,7 +32,6 @@ #include "Framework/Variant.h" #include "../../../Algorithm/include/Algorithm/HeaderStack.h" #include "Framework/OutputObjHeader.h" -#include "Framework/TableTreeHelpers.h" #include "Framework/StringHelpers.h" #include "Framework/ChannelSpec.h" #include "Framework/ChannelSpecHelpers.h" @@ -44,11 +43,6 @@ #include "WorkflowHelpers.h" #include -#include "TFile.h" -#include "TTree.h" -#include "TMap.h" -#include "TObjString.h" - #include #include #include @@ -57,417 +51,11 @@ #include #include -template class std::vector; -template class std::vector; using namespace o2::framework::data_matcher; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" - namespace o2::framework { -struct InputObjectRoute { - std::string name; - uint32_t uniqueId; - std::string directory; - uint32_t taskHash; - OutputObjHandlingPolicy policy; - OutputObjSourceType sourceType; -}; - -struct InputObject { - TClass* kind = nullptr; - void* obj = nullptr; - std::string name; - int count = -1; -}; - -const static std::unordered_map ROOTfileNames = {{OutputObjHandlingPolicy::AnalysisObject, "AnalysisResults.root"}, - {OutputObjHandlingPolicy::QAObject, "QAResults.root"}}; - -// ============================================================================= -DataProcessorSpec CommonDataProcessors::getOutputObjHistSink(std::vector const& objmap, std::vector const& tskmap) -{ - auto writerFunction = [objmap, tskmap](InitContext& ic) -> std::function { - auto& deviceSpec = ic.services().get(); - auto& callbacks = ic.services().get(); - auto inputObjects = std::make_shared>>(); - - static TFile* f[OutputObjHandlingPolicy::numPolicies]; - for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { - f[i] = nullptr; - } - - static std::string currentDirectory = ""; - static std::string currentFile = ""; - - auto endofdatacb = [inputObjects](EndOfStreamContext& context) { - LOG(debug) << "Writing merged objects and histograms to file"; - if (inputObjects->empty()) { - LOG(error) << "Output object map is empty!"; - context.services().get().readyToQuit(QuitRequest::Me); - return; - } - for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { - if (f[i] != nullptr) { - f[i]->Close(); - } - } - LOG(debug) << "All outputs merged in their respective target files"; - context.services().get().readyToQuit(QuitRequest::Me); - }; - - callbacks.set(endofdatacb); - return [inputObjects, objmap, tskmap](ProcessingContext& pc) mutable -> void { - auto const& ref = pc.inputs().get("x"); - if (!ref.header) { - LOG(error) << "Header not found"; - return; - } - if (!ref.payload) { - LOG(error) << "Payload not found"; - return; - } - auto datah = o2::header::get(ref.header); - if (!datah) { - LOG(error) << "No data header in stack"; - return; - } - - auto objh = o2::header::get(ref.header); - if (!objh) { - LOG(error) << "No output object header in stack"; - return; - } - - InputObject obj; - FairInputTBuffer tm(const_cast(ref.payload), static_cast(datah->payloadSize)); - tm.InitMap(); - obj.kind = tm.ReadClass(); - tm.SetBufferOffset(0); - tm.ResetMap(); - if (obj.kind == nullptr) { - LOG(error) << "Cannot read class info from buffer."; - return; - } - - auto policy = objh->mPolicy; - auto sourceType = objh->mSourceType; - auto hash = objh->mTaskHash; - - obj.obj = tm.ReadObjectAny(obj.kind); - auto* named = static_cast(obj.obj); - obj.name = named->GetName(); - auto hpos = std::find_if(tskmap.begin(), tskmap.end(), [&](auto&& x) { return x.id == hash; }); - if (hpos == tskmap.end()) { - LOG(error) << "No task found for hash " << hash; - return; - } - auto taskname = hpos->name; - auto opos = std::find_if(objmap.begin(), objmap.end(), [&](auto&& x) { return x.id == hash; }); - if (opos == objmap.end()) { - LOG(error) << "No object list found for task " << taskname << " (hash=" << hash << ")"; - return; - } - auto objects = opos->bindings; - if (std::find(objects.begin(), objects.end(), obj.name) == objects.end()) { - LOG(error) << "No object " << obj.name << " in map for task " << taskname; - return; - } - auto nameHash = runtime_hash(obj.name.c_str()); - InputObjectRoute key{obj.name, nameHash, taskname, hash, policy, sourceType}; - auto existing = std::find_if(inputObjects->begin(), inputObjects->end(), [&](auto&& x) { return (x.first.uniqueId == nameHash) && (x.first.taskHash == hash); }); - // If it's the first one, we just add it to the list. - if (existing == inputObjects->end()) { - obj.count = objh->mPipelineSize; - inputObjects->push_back(std::make_pair(key, obj)); - existing = inputObjects->end() - 1; - } else { - obj.count = existing->second.count; - // Otherwise, we merge it with the existing one. - auto merger = existing->second.kind->GetMerge(); - if (!merger) { - LOG(error) << "Already one unmergeable object found for " << obj.name; - return; - } - TList coll; - coll.Add(static_cast(obj.obj)); - merger(existing->second.obj, &coll, nullptr); - } - // We expect as many objects as the pipeline size, for - // a given object name and task hash. - existing->second.count -= 1; - - if (existing->second.count != 0) { - return; - } - // Write the object here. - auto route = existing->first; - auto entry = existing->second; - auto file = ROOTfileNames.find(route.policy); - if (file == ROOTfileNames.end()) { - return; - } - auto filename = file->second; - if (f[route.policy] == nullptr) { - f[route.policy] = TFile::Open(filename.c_str(), "RECREATE"); - } - auto nextDirectory = route.directory; - if ((nextDirectory != currentDirectory) || (filename != currentFile)) { - if (!f[route.policy]->FindKey(nextDirectory.c_str())) { - f[route.policy]->mkdir(nextDirectory.c_str()); - } - currentDirectory = nextDirectory; - currentFile = filename; - } - - // translate the list-structure created by the registry into a directory structure within the file - std::function writeListToFile; - writeListToFile = [&](TList* list, TDirectory* parentDir) { - TIter next(list); - TObject* object = nullptr; - while ((object = next())) { - if (object->InheritsFrom(TList::Class())) { - writeListToFile(static_cast(object), parentDir->mkdir(object->GetName(), object->GetName(), true)); - } else { - parentDir->WriteObjectAny(object, object->Class(), object->GetName()); - auto* written = list->Remove(object); - delete written; - } - } - }; - - TDirectory* currentDir = f[route.policy]->GetDirectory(currentDirectory.c_str()); - if (route.sourceType == OutputObjSourceType::HistogramRegistrySource) { - auto* outputList = static_cast(entry.obj); - outputList->SetOwner(false); - - // if registry should live in dedicated folder a TNamed object is appended to the list - if (outputList->Last() && outputList->Last()->IsA() == TNamed::Class()) { - delete outputList->Last(); - outputList->RemoveLast(); - currentDir = currentDir->mkdir(outputList->GetName(), outputList->GetName(), true); - } - - writeListToFile(outputList, currentDir); - outputList->SetOwner(); - delete outputList; - entry.obj = nullptr; - } else { - currentDir->WriteObjectAny(entry.obj, entry.kind, entry.name.c_str()); - delete (TObject*)entry.obj; - entry.obj = nullptr; - } - }; - }; - - char const* name = "internal-dpl-aod-global-analysis-file-sink"; - // Lifetime is sporadic because we do not ask each analysis task to send its - // results every timeframe. - DataProcessorSpec spec{ - .name = name, - .inputs = {InputSpec("x", DataSpecUtils::dataDescriptorMatcherFrom(header::DataOrigin{"ATSK"}), Lifetime::Sporadic)}, - .algorithm = {writerFunction}, - }; - - return spec; -} - -enum FileType : int { - AOD, - DANGLING -}; - -// add sink for the AODs -DataProcessorSpec - CommonDataProcessors::getGlobalAODSink(std::shared_ptr dod, - std::vector const& outputInputs) -{ - - auto writerFunction = [dod, outputInputs](InitContext& ic) -> std::function { - LOGP(debug, "======== getGlobalAODSink::Init =========="); - - // find out if any table needs to be saved - bool hasOutputsToWrite = false; - for (auto& outobj : outputInputs) { - auto ds = dod->getDataOutputDescriptors(outobj); - if (ds.size() > 0) { - hasOutputsToWrite = true; - break; - } - } - - // if nothing needs to be saved then return a trivial functor - // this happens when nothing needs to be saved but there are dangling outputs - if (!hasOutputsToWrite) { - return [](ProcessingContext&) mutable -> void { - static bool once = false; - if (!once) { - LOG(info) << "No AODs to be saved."; - once = true; - } - }; - } - - // end of data functor is called at the end of the data stream - auto endofdatacb = [dod](EndOfStreamContext& context) { - dod->closeDataFiles(); - context.services().get().readyToQuit(QuitRequest::Me); - }; - - auto& callbacks = ic.services().get(); - callbacks.set(endofdatacb); - - // prepare map(startTime, tfNumber) - std::map tfNumbers; - std::map tfFilenames; - - std::vector aodMetaDataKeys; - std::vector aodMetaDataVals; - - // this functor is called once per time frame - return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals](ProcessingContext& pc) mutable -> void { - LOGP(debug, "======== getGlobalAODSink::processing =========="); - LOGP(debug, " processing data set with {} entries", pc.inputs().size()); - - // return immediately if pc.inputs() is empty. This should never happen! - if (pc.inputs().size() == 0) { - LOGP(info, "No inputs available!"); - return; - } - - // update tfNumbers - uint64_t startTime = 0; - uint64_t tfNumber = 0; - auto ref = pc.inputs().get("tfn"); - if (ref.spec && ref.payload) { - startTime = DataRefUtils::getHeader(ref)->startTime; - tfNumber = pc.inputs().get("tfn"); - tfNumbers.insert(std::pair(startTime, tfNumber)); - } - // update tfFilenames - std::string aodInputFile; - auto ref2 = pc.inputs().get("tff"); - if (ref2.spec && ref2.payload) { - startTime = DataRefUtils::getHeader(ref2)->startTime; - aodInputFile = pc.inputs().get("tff"); - tfFilenames.insert(std::pair(startTime, aodInputFile)); - } - - // close all output files if one has reached size limit - dod->checkFileSizes(); - - // loop over the DataRefs which are contained in pc.inputs() - for (const auto& ref : pc.inputs()) { - if (!ref.spec) { - LOGP(debug, "Invalid input will be skipped!"); - continue; - } - - // get metadata - if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataKeys"))) { - aodMetaDataKeys = pc.inputs().get>(ref.spec->binding); - } - if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataVals"))) { - aodMetaDataVals = pc.inputs().get>(ref.spec->binding); - } - - // skip non-AOD refs - if (!DataSpecUtils::partialMatch(*ref.spec, writableAODOrigins)) { - continue; - } - startTime = DataRefUtils::getHeader(ref)->startTime; - - // does this need to be saved? - auto dh = DataRefUtils::getHeader(ref); - auto tableName = dh->dataDescription.as(); - auto ds = dod->getDataOutputDescriptors(*dh); - if (ds.empty()) { - continue; - } - - // get TF number from startTime - auto it = tfNumbers.find(startTime); - if (it != tfNumbers.end()) { - tfNumber = (it->second / dod->getNumberTimeFramesToMerge()) * dod->getNumberTimeFramesToMerge(); - } else { - LOGP(fatal, "No time frame number found for output with start time {}", startTime); - throw std::runtime_error("Processing is stopped!"); - } - // get aod input file from startTime - auto it2 = tfFilenames.find(startTime); - if (it2 != tfFilenames.end()) { - aodInputFile = it2->second; - } - - // get the TableConsumer and corresponding arrow table - auto msg = pc.inputs().get(ref.spec->binding); - if (msg.header == nullptr) { - LOGP(error, "No header for message {}:{}", ref.spec->binding, DataSpecUtils::describe(*ref.spec)); - continue; - } - auto s = pc.inputs().get(ref.spec->binding); - auto table = s->asArrowTable(); - if (!table->Validate().ok()) { - LOGP(warning, "The table \"{}\" is not valid and will not be saved!", tableName); - continue; - } - if (table->schema()->fields().empty()) { - LOGP(debug, "The table \"{}\" is empty but will be saved anyway!", tableName); - } - - // loop over all DataOutputDescriptors - // a table can be saved in multiple ways - // e.g. different selections of columns to different files - for (auto d : ds) { - auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile); - auto treename = fileAndFolder.folderName + "/" + d->treename; - TableToTree ta2tr(table, - fileAndFolder.file, - treename.c_str()); - - // update metadata - if (fileAndFolder.file->FindObjectAny("metaData")) { - LOGF(debug, "Metadata: target file %s already has metadata, preserving it", fileAndFolder.file->GetName()); - } else if (!aodMetaDataKeys.empty() && !aodMetaDataVals.empty()) { - TMap aodMetaDataMap; - for (uint32_t imd = 0; imd < aodMetaDataKeys.size(); imd++) { - aodMetaDataMap.Add(new TObjString(aodMetaDataKeys[imd]), new TObjString(aodMetaDataVals[imd])); - } - fileAndFolder.file->WriteObject(&aodMetaDataMap, "metaData", "Overwrite"); - } - - if (!d->colnames.empty()) { - for (auto& cn : d->colnames) { - auto idx = table->schema()->GetFieldIndex(cn); - auto col = table->column(idx); - auto field = table->schema()->field(idx); - if (idx != -1) { - ta2tr.addBranch(col, field); - } - } - } else { - ta2tr.addAllBranches(); - } - ta2tr.process(); - } - } - }; - }; // end of writerFunction - - // the command line options relevant for the writer are global - // see runDataProcessing.h - DataProcessorSpec spec{ - "internal-dpl-aod-writer", - outputInputs, - Outputs{}, - AlgorithmSpec(writerFunction), - {}}; - - return spec; -} - DataProcessorSpec CommonDataProcessors::getGlobalFileSink(std::vector const& danglingOutputInputs, std::vector& unmatched) @@ -639,5 +227,4 @@ AlgorithmSpec CommonDataProcessors::wrapWithRateLimiting(AlgorithmSpec spec) }); } -#pragma GCC diagnostic pop } // namespace o2::framework diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index f9aa103300813..30246492b8b65 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. #include "WorkflowHelpers.h" +#include "AnalysisSupportHelpers.h" #include "Framework/AlgorithmSpec.h" #include "Framework/AODReaderHelpers.h" #include "Framework/ConfigParamsHelper.h" @@ -125,87 +126,6 @@ std::vector return S; } -void WorkflowHelpers::addMissingOutputsToReader(std::vector const& providedOutputs, - std::vector const& requestedInputs, - DataProcessorSpec& publisher) -{ - auto matchingOutputFor = [](InputSpec const& requested) { - return [&requested](OutputSpec const& provided) { - return DataSpecUtils::match(requested, provided); - }; - }; - for (InputSpec const& requested : requestedInputs) { - auto provided = std::find_if(providedOutputs.begin(), - providedOutputs.end(), - matchingOutputFor(requested)); - - if (provided != providedOutputs.end()) { - continue; - } - - auto inList = std::find_if(publisher.outputs.begin(), - publisher.outputs.end(), - matchingOutputFor(requested)); - if (inList != publisher.outputs.end()) { - continue; - } - - auto concrete = DataSpecUtils::asConcreteDataMatcher(requested); - publisher.outputs.emplace_back(OutputSpec{concrete.origin, concrete.description, concrete.subSpec, requested.lifetime, requested.metadata}); - } -} - -void WorkflowHelpers::addMissingOutputsToSpawner(std::vector const& providedSpecials, - std::vector const& requestedSpecials, - std::vector& requestedAODs, - DataProcessorSpec& publisher) -{ - for (auto& input : requestedSpecials) { - if (std::any_of(providedSpecials.begin(), providedSpecials.end(), [&input](auto const& x) { - return DataSpecUtils::match(input, x); - })) { - continue; - } - auto concrete = DataSpecUtils::asConcreteDataMatcher(input); - publisher.outputs.emplace_back(OutputSpec{concrete.origin, concrete.description, concrete.subSpec}); - for (auto& i : input.metadata) { - if ((i.type == VariantType::String) && (i.name.find("input:") != std::string::npos)) { - auto spec = DataSpecUtils::fromMetadataString(i.defaultValue.get()); - auto j = std::find(publisher.inputs.begin(), publisher.inputs.end(), spec); - if (j == publisher.inputs.end()) { - publisher.inputs.push_back(spec); - } - DataSpecUtils::updateInputList(requestedAODs, std::move(spec)); - } - } - } -} - -void WorkflowHelpers::addMissingOutputsToBuilder(std::vector const& requestedSpecials, - std::vector& requestedAODs, - std::vector& requestedDYNs, - DataProcessorSpec& publisher) -{ - for (auto& input : requestedSpecials) { - auto concrete = DataSpecUtils::asConcreteDataMatcher(input); - publisher.outputs.emplace_back(OutputSpec{concrete.origin, concrete.description, concrete.subSpec}); - for (auto& i : input.metadata) { - if ((i.type == VariantType::String) && (i.name.find("input:") != std::string::npos)) { - auto spec = DataSpecUtils::fromMetadataString(i.defaultValue.get()); - auto j = std::find_if(publisher.inputs.begin(), publisher.inputs.end(), [&](auto x) { return x.binding == spec.binding; }); - if (j == publisher.inputs.end()) { - publisher.inputs.push_back(spec); - } - if (DataSpecUtils::partialMatch(spec, AODOrigins)) { - DataSpecUtils::updateInputList(requestedAODs, std::move(spec)); - } else if (DataSpecUtils::partialMatch(spec, header::DataOrigin{"DYN"})) { - DataSpecUtils::updateInputList(requestedDYNs, std::move(spec)); - } - } - } - } -} - // get the default value for condition-backend std::string defaultConditionBackend() { @@ -321,24 +241,15 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext aodReader.options.emplace_back(ConfigParamSpec{"channel-config", VariantType::String, rateLimitingChannelConfigInput, {"how many timeframes can be in flight at the same time"}}); } - std::vector requestedAODs; - std::vector providedAODs; - std::vector requestedDYNs; - std::vector providedDYNs; - std::vector requestedIDXs; - + AnalysisContext ac; std::vector requestedCCDBs; std::vector providedCCDBs; - std::vector providedOutputObjHist; - - std::vector outTskMap; - std::vector outObjHistMap; for (size_t wi = 0; wi < workflow.size(); ++wi) { auto& processor = workflow[wi]; auto name = processor.name; auto hash = runtime_hash(name.c_str()); - outTskMap.push_back({hash, name}); + ac.outTskMap.push_back({hash, name}); std::string prefix = "internal-dpl-"; if (processor.inputs.empty() && processor.name.compare(0, prefix.size(), prefix) != 0) { @@ -435,13 +346,13 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext break; } if (DataSpecUtils::partialMatch(input, AODOrigins)) { - DataSpecUtils::updateInputList(requestedAODs, InputSpec{input}); + DataSpecUtils::updateInputList(ac.requestedAODs, InputSpec{input}); } if (DataSpecUtils::partialMatch(input, header::DataOrigin{"DYN"})) { - DataSpecUtils::updateInputList(requestedDYNs, InputSpec{input}); + DataSpecUtils::updateInputList(ac.requestedDYNs, InputSpec{input}); } if (DataSpecUtils::partialMatch(input, header::DataOrigin{"IDX"})) { - DataSpecUtils::updateInputList(requestedIDXs, InputSpec{input}); + DataSpecUtils::updateInputList(ac.requestedIDXs, InputSpec{input}); } } @@ -449,14 +360,14 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext for (auto& output : processor.outputs) { if (DataSpecUtils::partialMatch(output, AODOrigins)) { - providedAODs.emplace_back(output); + ac.providedAODs.emplace_back(output); } else if (DataSpecUtils::partialMatch(output, header::DataOrigin{"DYN"})) { - providedDYNs.emplace_back(output); + ac.providedDYNs.emplace_back(output); } else if (DataSpecUtils::partialMatch(output, header::DataOrigin{"ATSK"})) { - providedOutputObjHist.emplace_back(output); - auto it = std::find_if(outObjHistMap.begin(), outObjHistMap.end(), [&](auto&& x) { return x.id == hash; }); - if (it == outObjHistMap.end()) { - outObjHistMap.push_back({hash, {output.binding.value}}); + ac.providedOutputObjHist.emplace_back(output); + auto it = std::find_if(ac.outObjHistMap.begin(), ac.outObjHistMap.end(), [&](auto&& x) { return x.id == hash; }); + if (it == ac.outObjHistMap.end()) { + ac.outObjHistMap.push_back({hash, {output.binding.value}}); } else { it->bindings.push_back(output.binding.value); } @@ -469,12 +380,11 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext auto inputSpecLessThan = [](InputSpec const& lhs, InputSpec const& rhs) { return DataSpecUtils::describe(lhs) < DataSpecUtils::describe(rhs); }; auto outputSpecLessThan = [](OutputSpec const& lhs, OutputSpec const& rhs) { return DataSpecUtils::describe(lhs) < DataSpecUtils::describe(rhs); }; - std::sort(requestedDYNs.begin(), requestedDYNs.end(), inputSpecLessThan); - std::sort(providedDYNs.begin(), providedDYNs.end(), outputSpecLessThan); - std::vector spawnerInputs; - for (auto& input : requestedDYNs) { - if (std::none_of(providedDYNs.begin(), providedDYNs.end(), [&input](auto const& x) { return DataSpecUtils::match(input, x); })) { - spawnerInputs.emplace_back(input); + std::sort(ac.requestedDYNs.begin(), ac.requestedDYNs.end(), inputSpecLessThan); + std::sort(ac.providedDYNs.begin(), ac.providedDYNs.end(), outputSpecLessThan); + for (auto& input : ac.requestedDYNs) { + if (std::none_of(ac.providedDYNs.begin(), ac.providedDYNs.end(), [&input](auto const& x) { return DataSpecUtils::match(input, x); })) { + ac.spawnerInputs.emplace_back(input); } } @@ -482,21 +392,21 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext "internal-dpl-aod-spawner", {}, {}, - readers::AODReaderHelpers::aodSpawnerCallback(spawnerInputs), + readers::AODReaderHelpers::aodSpawnerCallback(ac.spawnerInputs), {}}; DataProcessorSpec indexBuilder{ "internal-dpl-aod-index-builder", {}, {}, - readers::AODReaderHelpers::indexBuilderCallback(requestedIDXs), + readers::AODReaderHelpers::indexBuilderCallback(ac.requestedIDXs), {}}; - addMissingOutputsToBuilder(requestedIDXs, requestedAODs, requestedDYNs, indexBuilder); - addMissingOutputsToSpawner({}, spawnerInputs, requestedAODs, aodSpawner); + AnalysisSupportHelpers::addMissingOutputsToBuilder(ac.requestedIDXs, ac.requestedAODs, ac.requestedDYNs, indexBuilder); + AnalysisSupportHelpers::addMissingOutputsToSpawner({}, ac.spawnerInputs, ac.requestedAODs, aodSpawner); - addMissingOutputsToReader(providedAODs, requestedAODs, aodReader); - addMissingOutputsToReader(providedCCDBs, requestedCCDBs, ccdbBackend); + AnalysisSupportHelpers::addMissingOutputsToReader(ac.providedAODs, ac.requestedAODs, aodReader); + AnalysisSupportHelpers::addMissingOutputsToReader(providedCCDBs, requestedCCDBs, ccdbBackend); std::vector extraSpecs; @@ -662,8 +572,8 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // This is to inject a file sink so that any dangling ATSK object is written // to a ROOT file. - if (providedOutputObjHist.empty() == false) { - auto rootSink = CommonDataProcessors::getOutputObjHistSink(outObjHistMap, outTskMap); + if (ac.providedOutputObjHist.empty() == false) { + auto rootSink = AnalysisSupportHelpers::getOutputObjHistSink(ac.outObjHistMap, ac.outTskMap); extraSpecs.push_back(rootSink); } @@ -694,7 +604,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // add TFNumber and TFFilename as input to the writer outputsInputsAOD.emplace_back(InputSpec{"tfn", "TFN", "TFNumber"}); outputsInputsAOD.emplace_back(InputSpec{"tff", "TFF", "TFFilename"}); - auto fileSink = CommonDataProcessors::getGlobalAODSink(dod, outputsInputsAOD); + auto fileSink = AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD); extraSpecs.push_back(fileSink); auto it = std::find_if(outputsInputs.begin(), outputsInputs.end(), [](InputSpec& spec) -> bool { diff --git a/Framework/Core/src/WorkflowHelpers.h b/Framework/Core/src/WorkflowHelpers.h index 055cae1d6011b..b20249b99edc8 100644 --- a/Framework/Core/src/WorkflowHelpers.h +++ b/Framework/Core/src/WorkflowHelpers.h @@ -22,9 +22,6 @@ namespace o2::framework { -static constexpr std::array AODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}}; -static constexpr std::array extendedAODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}, header::DataOrigin{"DYN"}, header::DataOrigin{"AMD"}}; -static constexpr std::array writableAODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}, header::DataOrigin{"DYN"}}; inline static std::string debugWorkflow(std::vector const& specs) { @@ -185,21 +182,6 @@ struct WorkflowHelpers { // @a ctx the context for the configuration phase static void injectServiceDevices(WorkflowSpec& workflow, ConfigContext const& ctx); - /// Helper functions to add AOD related internal devices. - /// FIXME: moved here until we have proper plugin based amendment - /// of device injection - static void addMissingOutputsToReader(std::vector const& providedOutputs, - std::vector const& requestedInputs, - DataProcessorSpec& publisher); - static void addMissingOutputsToSpawner(std::vector const& providedSpecials, - std::vector const& requestedSpecials, - std::vector& requestedAODs, - DataProcessorSpec& publisher); - static void addMissingOutputsToBuilder(std::vector const& requestedSpecials, - std::vector& requestedAODs, - std::vector& requestedDYNs, - DataProcessorSpec& publisher); - // Final adjustments to @a workflow after service devices have been injected. static void adjustTopology(WorkflowSpec& workflow, ConfigContext const& ctx); From c59403808d5cd68d562038c75d1086d3a9a26651 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 5 Sep 2024 16:18:20 +0200 Subject: [PATCH 0196/2205] GPU: WORKAROUND for CUDA bug exposing device code via host symbols --- DataFormats/Reconstruction/src/TrackParametrization.cxx | 4 +++- .../Reconstruction/src/TrackParametrizationWithError.cxx | 4 +++- Detectors/Base/src/Propagator.cxx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/DataFormats/Reconstruction/src/TrackParametrization.cxx b/DataFormats/Reconstruction/src/TrackParametrization.cxx index d79b6dcb7b474..ec63bc2e95db1 100644 --- a/DataFormats/Reconstruction/src/TrackParametrization.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrization.cxx @@ -956,8 +956,10 @@ GPUd() typename TrackParametrization::value_t TrackParametrization; -#ifndef GPUCA_GPUCODE_DEVICE +#endif +#ifndef GPUCA_GPUCODE template class TrackParametrization; #endif } // namespace o2::track diff --git a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx index dfe4d7c31b2ab..84b1da5f94a4f 100644 --- a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx @@ -1245,8 +1245,10 @@ GPUd() void TrackParametrizationWithError::printHexadecimal() namespace o2::track { +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. template class TrackParametrizationWithError; -#ifndef GPUCA_GPUCODE_DEVICE +#endif +#ifndef GPUCA_GPUCODE template class TrackParametrizationWithError; #endif } // namespace o2::track diff --git a/Detectors/Base/src/Propagator.cxx b/Detectors/Base/src/Propagator.cxx index 0d1b53b695536..b55ef22b857f0 100644 --- a/Detectors/Base/src/Propagator.cxx +++ b/Detectors/Base/src/Propagator.cxx @@ -786,8 +786,10 @@ GPUd() void PropagatorImpl::getFieldXYZ(const math_utils::Point3D; -#ifndef GPUCA_GPUCODE_DEVICE +#endif +#ifndef GPUCA_GPUCODE template class PropagatorImpl; #endif #ifndef __HIPCC__ // TODO: Fixme: must prevent HIP from compiling this, should file bug report From e7c79baa38850eebc3e6f7f38208c4c7fd710d24 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 5 Sep 2024 19:05:57 +0200 Subject: [PATCH 0197/2205] Possibility to have 1st calibration slot shorter than nominal --- Detectors/Calibration/README.md | 7 +++ .../TimeSlotCalibration.h | 43 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Detectors/Calibration/README.md b/Detectors/Calibration/README.md index 88bd201dab975..606493ea0cc32 100644 --- a/Detectors/Calibration/README.md +++ b/Detectors/Calibration/README.md @@ -42,6 +42,13 @@ In order to prepare only one CCDB object at the end of the run you can use `setU See e.g. LHCClockCalibrator.h/cxx in AliceO2/Detectors/TOF/calibration/include/TOFCalibration/LHCClockCalibrator.h and AliceO2/Detectors/TOF/calibration/srcLHCClockCalibrator.cxx +Sometimes it might be useful to define the 1st slot of the run shorter than the nominal slot length, e.g. to not rely to long on the previous run or default calibration. In this case one can impose to the +calibration class an offset using method `setStartOffsetFrac(float offset)`, where `offset` is a fractional of the nominal slot length to be subtracted from the nominal boundaries of all slots (except the +very 1st one, whose startTF is set to 0). The fractional offset should be in `[0:0.95)` range, any value outside this range will be overridden to the nearest boundary. +This feature is supported only for the finite slot-length calibrations. E.g. if the nominal slot length is 10 minutes `(==~210000 TFs)`, setting `setStartOffsetFrac(float 0.7)` will lead to 1st slot +finalized after the first 3 minutes, while the rest of the slots will be defined with nominal 10 minutes coverage. If statistics of this 1st short slot is insufficient, it will be merged as usual +with the next slot (note this if this happens, in the example above the 1st calibration will be available in 13 minutes...). + ## TimeSlot The TimeSlot is a templated class which takes as input type the Container that will hold the calibration data needed to produce the calibration objects (histograms, vectors, array...). Each calibration device could implement its own Container, according to its needs. diff --git a/Detectors/Calibration/include/DetectorsCalibration/TimeSlotCalibration.h b/Detectors/Calibration/include/DetectorsCalibration/TimeSlotCalibration.h index 36e9e209af878..87562afddf2ca 100644 --- a/Detectors/Calibration/include/DetectorsCalibration/TimeSlotCalibration.h +++ b/Detectors/Calibration/include/DetectorsCalibration/TimeSlotCalibration.h @@ -87,12 +87,35 @@ class TimeSlotCalibration setSlotLength(ntf); mSlotLengthInOrbits = 0; } + setStartOffsetFrac(mStartOffsetFrac); // set once more to account for eventual dependencies + mStartOffsetTFs = TFType(mSlotLength * mStartOffsetFrac); + } + + void setStartOffsetFrac(float f) + { + if (mUpdateAtTheEndOfRunOnly || mFinalizeWhenReady || mSlotLength == INFINITE_TF) { // offset makes no sense for run-wide objects + if (f) { + LOGP(info, "Start offset is not supported in the INFINITE_TF slot length or UpdateAtTheEndOfRunOnly or FinalizeWhenReady modes"); + } + return; + } + if (f < 0.) { + mStartOffsetFrac = 0.; + } else if (f > 0.95) { + mStartOffsetFrac = 0.95; + } else { + mStartOffsetFrac = f; + } + if (mStartOffsetFrac || f != mStartOffsetFrac) { + LOGP(info, "Imposing offset of {:4.2} x nominal slot length", mStartOffsetFrac); + } } void setFinalizeWhenReady() { mFinalizeWhenReady = true; setSlotLength(INFINITE_TF); + mStartOffsetFrac = 0; } void setUpdateAtTheEndOfRunOnly() { mUpdateAtTheEndOfRunOnly = kTRUE; } @@ -219,7 +242,6 @@ class TimeSlotCalibration } TFType tf2SlotMin(TFType tf) const; - std::deque mSlots; o2::dataformats::TFIDInfo mCurrentTFInfo{}; @@ -229,6 +251,8 @@ class TimeSlotCalibration TFType mFirstTF = 0; TFType mMaxSeenTF = 0; // largest TF processed TFType mSlotLength = 1; // slot length in TFs + TFType mStartOffsetTFs = 0; // shift start of all TFs backwards by this amount (to make 1st slot effectively shorter: run_1st_tf to run_1st_tf - offset + mSlotLength), derived from mStartOffsetFrac + float mStartOffsetFrac = 0.; // shift start of all TFs backwards mSlotLength*mStartOffsetFrac TFs. TFType mCheckIntervalInfiniteSlot = 1; // will be used if the TF length is INFINITE_TF_int64 to decide // when to check if to call the finalize; otherwise it is called // at every new TF; note that this is an approximation, @@ -381,16 +405,20 @@ void TimeSlotCalibration::finalizeOldestSlot() template inline TFType TimeSlotCalibration::tf2SlotMin(TFType tf) const { - // returns the min TF of the slot to which "tf" belongs - if (tf < mFirstTF) { throw std::runtime_error("invalid TF"); } if (mUpdateAtTheEndOfRunOnly) { return mFirstTF; } - uint64_t tft = int64_t(((tf - mFirstTF) / mSlotLength) * mSlotLength) + mFirstTF; + int64_t tft = 0; + tft = int64_t(((tf - mFirstTF + mStartOffsetTFs) / mSlotLength) * mSlotLength) + mFirstTF; + if (tft > mStartOffsetTFs) { + tft -= mStartOffsetTFs; + } else { + tft = 0; + } return tft < o2::calibration::INFINITE_TF ? TFType(tft) : INFINITE_TF; } @@ -415,7 +443,7 @@ TimeSlot& TimeSlotCalibration::getSlotForTF(TFType tf) auto tfmn = tf2SlotMin(mSlots.front().getTFStart() - 1); // min TF of the slot corresponding to a TF smaller than the first seen auto tftgt = tf2SlotMin(tf); // min TF of the slot to which the TF "tf" would belong while (tfmn >= tftgt) { - uint64_t tft = uint64_t(tfmn) + mSlotLength - 1; + uint64_t tft = mSlots.front().getTFStart() - 1; TFType tfmx = tft < o2::calibration::INFINITE_TF ? TFType(tft) : o2::calibration::INFINITE_TF; LOG(info) << "Adding new slot for " << tfmn << " <= TF <= " << tfmx; auto& sl = emplaceNewSlot(true, tfmn, tfmx); @@ -438,12 +466,15 @@ TimeSlot& TimeSlotCalibration::getSlotForTF(TFType tf) auto tfmn = mSlots.empty() ? tf2SlotMin(tf) : tf2SlotMin(mSlots.back().getTFEnd() + 1); do { uint64_t tft = uint64_t(tfmn) + mSlotLength - 1; + if (mSlots.empty() && mStartOffsetTFs && tf < mStartOffsetTFs) { // if this was lowest possible TF, its length might be smaller than mSlotLength + tft -= mStartOffsetTFs; + } TFType tfmx = tft < o2::calibration::INFINITE_TF ? TFType(tft) : o2::calibration::INFINITE_TF; LOG(info) << "Adding new slot for " << tfmn << " <= TF <= " << tfmx; auto& sl = emplaceNewSlot(false, tfmn, tfmx); sl.setRunStartOrbit(getRunStartOrbit()); sl.setStaticStartTimeMS(sl.getStartTimeMS()); - tfmn = tf2SlotMin(mSlots.back().getTFEnd() + 1); + tfmn = tft < o2::calibration::INFINITE_TF ? mSlots.back().getTFEnd() + 1 : tft; } while (tf > mSlots.back().getTFEnd()); return mSlots.back(); From e311d14b7175932c80daac4148a6a8e398f61b52 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 6 Sep 2024 03:24:17 +0200 Subject: [PATCH 0198/2205] Make TPC VDrift calib. 1st slot length 30% of nominal (3min) --- .../include/TPCCalibration/TPCVDriftTglCalibration.h | 4 +++- .../workflow/include/TPCWorkflow/TPCVDriftTglCalibSpec.h | 2 +- Detectors/TPC/workflow/src/TPCVDriftTglCalibSpec.cxx | 9 +++++---- .../workflow/src/tpc-vdrift-tgl-calibration-workflow.cxx | 2 ++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Detectors/TPC/calibration/include/TPCCalibration/TPCVDriftTglCalibration.h b/Detectors/TPC/calibration/include/TPCCalibration/TPCVDriftTglCalibration.h index 4964154732aea..c4028f727983f 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/TPCVDriftTglCalibration.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/TPCVDriftTglCalibration.h @@ -91,10 +91,12 @@ class TPCVDriftTglCalibration : public o2::calibration::TimeSlotCalibration req) : mCCDBRequest(req) + TPCVDriftTglCalibSpec(int ntgl, float tglMax, int ndtgl, float dtglMax, size_t slotL, float offset, float maxDelay, size_t minEnt, std::shared_ptr req) : mCCDBRequest(req) { - mCalibrator = std::make_unique(ntgl, tglMax, ndtgl, dtglMax, slotL, maxDelay, minEnt); + mCalibrator = std::make_unique(ntgl, tglMax, ndtgl, dtglMax, slotL, offset, maxDelay, minEnt); } void init(InitContext& ic) final @@ -113,7 +113,7 @@ void TPCVDriftTglCalibSpec::sendOutput(DataAllocator& output) } //_____________________________________________________________ -DataProcessorSpec getTPCVDriftTglCalibSpec(int ntgl, float tglMax, int ndtgl, float dtglMax, size_t slotL, float maxDelay, size_t minEnt) +DataProcessorSpec getTPCVDriftTglCalibSpec(int ntgl, float tglMax, int ndtgl, float dtglMax, size_t slotL, float slot0frac, float maxDelay, size_t minEnt) { using device = o2::tpc::TPCVDriftTglCalibSpec; @@ -132,12 +132,13 @@ DataProcessorSpec getTPCVDriftTglCalibSpec(int ntgl, float tglMax, int ndtgl, fl std::vector outputs; outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TPCVDTGL"}, Lifetime::Sporadic); outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TPCVDTGL"}, Lifetime::Sporadic); + slot0frac = 1. - slot0frac; return DataProcessorSpec{ "tpc-vd-tgl-calib", inputs, outputs, - AlgorithmSpec{adaptFromTask(ntgl, tglMax, ndtgl, dtglMax, slotL, maxDelay, minEnt, ccdbRequest)}, + AlgorithmSpec{adaptFromTask(ntgl, tglMax, ndtgl, dtglMax, slotL, slot0frac, maxDelay, minEnt, ccdbRequest)}, Options{{"vdtgl-histos-file-name", VariantType::String, "", {"file to save histos (if name provided)"}}}}; } diff --git a/Detectors/TPC/workflow/src/tpc-vdrift-tgl-calibration-workflow.cxx b/Detectors/TPC/workflow/src/tpc-vdrift-tgl-calibration-workflow.cxx index 26e5278c479ad..ee0ff470837d4 100644 --- a/Detectors/TPC/workflow/src/tpc-vdrift-tgl-calibration-workflow.cxx +++ b/Detectors/TPC/workflow/src/tpc-vdrift-tgl-calibration-workflow.cxx @@ -26,6 +26,7 @@ void customize(std::vector& workflowOptions) {"max-dtgl-itstpc", o2::framework::VariantType::Float, 0.15f, {"max range for tgL_ITS - tgl_TPC"}}, {"min-entries-per-slot", o2::framework::VariantType::Int, 10000, {"mininal number of entries per slot"}}, {"time-slot-seconds", o2::framework::VariantType::Int, 600, {"time slot length in seconds"}}, + {"first-slot-length-fraction", o2::framework::VariantType::Float, 0.3f, {"1st slot length as fraction of nominal"}}, {"max-slots-delay", o2::framework::VariantType::Float, 0.1f, {"difference in slot units between the current TF and oldest slot (end TF) to account for the TF"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}}; std::swap(workflowOptions, options); @@ -44,6 +45,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) configcontext.options().get("nbins-dtgl"), configcontext.options().get("max-dtgl-itstpc"), configcontext.options().get("time-slot-seconds"), + configcontext.options().get("first-slot-length-fraction"), configcontext.options().get("max-slots-delay"), configcontext.options().get("min-entries-per-slot"))); return specs; From 2dd3745d5211a5f6bbbd927016dda5b940dbeb0f Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 4 Sep 2024 12:48:30 +0200 Subject: [PATCH 0199/2205] ChipMappingMFT::cableHW2SW return 0xff for invalid HW cable ID --- .../include/ITSMFTReconstruction/ChipMappingMFT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/ChipMappingMFT.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/ChipMappingMFT.h index 4ae9ecb92be37..3fa94c2628f3a 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/ChipMappingMFT.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/ChipMappingMFT.h @@ -127,7 +127,7 @@ class ChipMappingMFT uint8_t cableHW2Pos(uint8_t ruType, uint8_t hwid) const { return mCableHW2Pos[ruType][hwid]; } ///< convert HW cable ID to SW ID for give RU type - uint8_t cableHW2SW(uint8_t ruType, uint8_t hwid) const { return mCableHW2SW[ruType][hwid]; } + uint8_t cableHW2SW(uint8_t ruType, uint8_t hwid) const { return hwid < mCableHW2SW[ruType].size() ? mCableHW2SW[ruType][hwid] : 0xff; } ///< convert cable iterator ID to its position on the ActiveLanes word in the GBT.header for given RU type uint8_t cablePos(uint8_t ruType, uint8_t id) const { return mCablePos[ruType][id]; } From 365214d7d01a4167b2c8fae8c6f25027437e8ab9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 5 Sep 2024 17:20:28 +0200 Subject: [PATCH 0200/2205] GPU: Do not allow any constructors that will use FlatObject in GPU code, were anyway not used but could create dangerous symbols --- Detectors/Base/include/DetectorsBase/MatLayerCyl.h | 2 ++ Detectors/Base/include/DetectorsBase/MatLayerCylSet.h | 2 ++ Detectors/Base/src/MatLayerCyl.cxx | 2 ++ Detectors/TRD/base/include/TRDBase/GeometryFlat.h | 2 +- GPU/GPUTracking/DataTypes/CalibdEdxContainer.h | 2 ++ GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h | 3 +-- GPU/Utils/FlatObject.h | 6 +++++- 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Detectors/Base/include/DetectorsBase/MatLayerCyl.h b/Detectors/Base/include/DetectorsBase/MatLayerCyl.h index 229bc327d3039..869234e03f6c1 100644 --- a/Detectors/Base/include/DetectorsBase/MatLayerCyl.h +++ b/Detectors/Base/include/DetectorsBase/MatLayerCyl.h @@ -54,9 +54,11 @@ class MatLayerCyl : public o2::gpu::FlatObject Within = 0, Above = 1 }; +#ifndef GPUCA_GPUCODE MatLayerCyl(); MatLayerCyl(const MatLayerCyl& src) CON_DELETE; ~MatLayerCyl() CON_DEFAULT; +#endif #ifndef GPUCA_ALIGPUCODE // this part is unvisible on GPU version MatLayerCyl(float rMin, float rMax, float zHalfSpan, float dzMin, float drphiMin); diff --git a/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h b/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h index 3ffa7424ee61e..83fed8caf42eb 100644 --- a/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h +++ b/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h @@ -51,9 +51,11 @@ class MatLayerCylSet : public o2::gpu::FlatObject { public: +#ifndef GPUCA_GPUCODE MatLayerCylSet() CON_DEFAULT; ~MatLayerCylSet() CON_DEFAULT; MatLayerCylSet(const MatLayerCylSet& src) CON_DELETE; +#endif GPUd() const MatLayerCylSetLayout* get() const { return reinterpret_cast(mFlatBufferPtr); } GPUd() MatLayerCylSetLayout* get() { return reinterpret_cast(mFlatBufferPtr); } diff --git a/Detectors/Base/src/MatLayerCyl.cxx b/Detectors/Base/src/MatLayerCyl.cxx index 04f68fb81866f..2346946ea6a8a 100644 --- a/Detectors/Base/src/MatLayerCyl.cxx +++ b/Detectors/Base/src/MatLayerCyl.cxx @@ -23,10 +23,12 @@ using namespace o2::base; using flatObject = o2::gpu::FlatObject; +#ifndef GPUCA_GPUCODE //________________________________________________________________________________ MatLayerCyl::MatLayerCyl() : mNZBins(0), mNPhiBins(0), mNPhiSlices(0), mZHalf(0.f), mRMin2(0.f), mRMax2(0.f), mDZ(0.f), mDZInv(0.f), mDPhi(0.f), mDPhiInv(0.f), mPhiBin2Slice(nullptr), mSliceCos(nullptr), mSliceSin(nullptr), mCells(nullptr) { } +#endif #ifndef GPUCA_ALIGPUCODE // this part is unvisible on GPU version //________________________________________________________________________________ diff --git a/Detectors/TRD/base/include/TRDBase/GeometryFlat.h b/Detectors/TRD/base/include/TRDBase/GeometryFlat.h index 73dd11247dd66..6474c73e55756 100644 --- a/Detectors/TRD/base/include/TRDBase/GeometryFlat.h +++ b/Detectors/TRD/base/include/TRDBase/GeometryFlat.h @@ -34,7 +34,7 @@ class Geometry; class GeometryFlat : public o2::gpu::FlatObject, public GeometryBase { public: -#ifndef GPUCA_GPUCODE_DEVICE +#ifndef GPUCA_GPUCODE GeometryFlat() = default; GeometryFlat(const GeometryFlat& v) : FlatObject(), GeometryBase() { diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h index 09efc8b250350..d860d1c0d340b 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h @@ -60,7 +60,9 @@ class CalibdEdxContainer : public o2::gpu::FlatObject { public: /// Default constructor: creates an empty uninitialized object +#ifndef GPUCA_GPUCODE CalibdEdxContainer() CON_DEFAULT; +#endif /// Copy constructor: disabled to avoid ambiguity. Use cloneFromObject() instead CalibdEdxContainer(const CalibdEdxContainer&) CON_DELETE; diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h index f9579cf5ebea2..2431e28bd2de0 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h @@ -53,13 +53,12 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \param fileName name of the input file containing the object /// \parma name name of the object CalibdEdxTrackTopologyPol(std::string_view fileName, std::string_view name = "CalibdEdxTrackTopologyPol") { loadFromFile(fileName.data(), name.data()); }; -#endif - /// Default constructor: creates an empty uninitialized object CalibdEdxTrackTopologyPol() CON_DEFAULT; /// destructor ~CalibdEdxTrackTopologyPol() CON_DEFAULT; +#endif #ifdef GPUCA_HAVE_O2HEADERS /// \return returns the track topology correction diff --git a/GPU/Utils/FlatObject.h b/GPU/Utils/FlatObject.h index 59bbde3ebeb42..ac06d7646abd7 100644 --- a/GPU/Utils/FlatObject.h +++ b/GPU/Utils/FlatObject.h @@ -178,10 +178,14 @@ class FlatObject /// _____________ Constructors / destructors __________________________ /// Default constructor / destructor - FlatObject() CON_DEFAULT; +#ifndef GPUCA_GPUCODE + FlatObject() CON_DEFAULT; // No object derrived from FlatObject should be created on the GPU ~FlatObject(); FlatObject(const FlatObject&) CON_DELETE; FlatObject& operator=(const FlatObject&) CON_DELETE; +#else + FlatObject() CON_DELETE; +#endif protected: /// _____________ Memory alignment __________________________ From c609033217da39fd442c0f5f69e8179cc57741b5 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 5 Sep 2024 17:20:43 +0200 Subject: [PATCH 0201/2205] GPU: Remove workaround which seems is no longer needed --- Detectors/Base/src/Propagator.cxx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Detectors/Base/src/Propagator.cxx b/Detectors/Base/src/Propagator.cxx index b55ef22b857f0..4ecb0e21a88ae 100644 --- a/Detectors/Base/src/Propagator.cxx +++ b/Detectors/Base/src/Propagator.cxx @@ -788,16 +788,12 @@ namespace o2::base { #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. template class PropagatorImpl; +template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackPar_t>(PropagatorImpl::TrackPar_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; +template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackParCov_t>(PropagatorImpl::TrackParCov_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; #endif #ifndef GPUCA_GPUCODE template class PropagatorImpl; -#endif -#ifndef __HIPCC__ // TODO: Fixme: must prevent HIP from compiling this, should file bug report -template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackPar_t>(PropagatorImpl::TrackPar_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; -template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackParCov_t>(PropagatorImpl::TrackParCov_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; -#ifndef GPUCA_GPUCODE_DEVICE template bool PropagatorImpl::propagateToAlphaX::TrackPar_t>(PropagatorImpl::TrackPar_t&, double, double, bool, double, double, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; template bool PropagatorImpl::propagateToAlphaX::TrackParCov_t>(PropagatorImpl::TrackParCov_t&, double, double, bool, double, double, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; #endif -#endif } // namespace o2::base From 1a27e5d02ef1cec98d958f171f5f2d4996f7978c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 10:54:26 +0200 Subject: [PATCH 0202/2205] GPU CMake: Raise required CUDA version to 12.6 --- dependencies/FindO2GPU.cmake | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index 771e326c21f53..b1ffc07fc212b 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -105,8 +105,8 @@ if(ENABLE_CUDA) message(${FAILURE_SEVERITY} "CUDA found but thrust not available") set(CMAKE_CUDA_COMPILER OFF) endif() - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.4") - message(${FAILURE_SEVERITY} "CUDA Version too old: ${CMAKE_CUDA_COMPILER_VERSION}, 11.4 required") + if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.6") + message(${FAILURE_SEVERITY} "CUDA Version too old: ${CMAKE_CUDA_COMPILER_VERSION}, 12.6 required") set(CMAKE_CUDA_COMPILER OFF) endif() endif() @@ -115,9 +115,6 @@ if(ENABLE_CUDA) if(GPUCA_KERNEL_RESOURCE_USAGE_VERBOSE) string(APPEND CMAKE_CUDA_FLAGS " -Xptxas -v") endif() - if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.3") - string(APPEND CMAKE_CUDA_FLAGS " -Xcudafe --diag_suppress=20257") # TODO: Cleanup - endif() if (NOT ENABLE_CUDA STREQUAL "AUTO") string(APPEND CMAKE_CUDA_FLAGS " --allow-unsupported-compiler") endif() From 3f23f529eee19772a248ecee498440766a2bbb82 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 10:56:48 +0200 Subject: [PATCH 0203/2205] GPU: Use GPUdi() macro instead of inline keyword --- Common/DCAFitter/include/DCAFitter/DCAFitterN.h | 14 +++++++------- .../TPC/include/DataFormatsTPC/TrackTPC.h | 10 +++++----- .../TrackParametrization.h | 6 +++--- .../include/ReconstructionDataFormats/TrackUtils.h | 2 +- .../tracking/GPU/ITStrackingGPU/ClusterLinesGPU.h | 2 +- .../SliceTracker/GPUTPCTrackLinearisation.h | 2 +- GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h index 226f008f5fce2..340a0be199c68 100644 --- a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h +++ b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h @@ -753,7 +753,7 @@ GPUd() void DCAFitterN::calcTrackResiduals() //___________________________________________________________________ template -GPUd() inline void DCAFitterN::calcTrackDerivatives() +GPUdi() void DCAFitterN::calcTrackDerivatives() { // calculate track derivatives over X param for (int i = N; i--;) { @@ -763,7 +763,7 @@ GPUd() inline void DCAFitterN::calcTrackDerivatives() //___________________________________________________________________ template -GPUd() inline double DCAFitterN::calcChi2() const +GPUdi() double DCAFitterN::calcChi2() const { // calculate current chi2 double chi2 = 0; @@ -777,7 +777,7 @@ GPUd() inline double DCAFitterN::calcChi2() const //___________________________________________________________________ template -GPUd() inline double DCAFitterN::calcChi2NoErr() const +GPUdi() double DCAFitterN::calcChi2NoErr() const { // calculate current chi2 of abs. distance minimization double chi2 = 0; @@ -842,7 +842,7 @@ GPUd() bool DCAFitterN::propagateTracksToVertex(int icand) //___________________________________________________________________ template -GPUd() inline o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int i, int icand) +GPUdi() o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int i, int icand) { // propagate tracks param only to current vertex (if not already done) int ord = mOrder[icand]; @@ -858,7 +858,7 @@ GPUd() inline o2::track::TrackPar DCAFitterN::getTrackParamAtPCA(int //___________________________________________________________________ template -GPUd() inline double DCAFitterN::getAbsMax(const VecND& v) +GPUdi() double DCAFitterN::getAbsMax(const VecND& v) { double mx = -1; for (int i = N; i--;) { @@ -1075,7 +1075,7 @@ GPUd() o2::track::TrackPar DCAFitterN::createParentTrackPar(int cand //___________________________________________________________________ template -GPUd() inline bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, float x) +GPUdi() bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, float x) { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { @@ -1091,7 +1091,7 @@ GPUd() inline bool DCAFitterN::propagateParamToX(o2::track::TrackPar //___________________________________________________________________ template -GPUd() inline bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, float x) +GPUdi() bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, float x) { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h index 42c098b7bdd54..cc446103b7fc1 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h @@ -79,7 +79,7 @@ class TrackTPC : public o2::track::TrackParCov GPUd() void setClusterRef(uint32_t entry, uint16_t ncl) { mClustersReference.set(entry, ncl); } template - GPUd() static inline void getClusterReference(T& clinfo, int nCluster, + GPUdi() static void getClusterReference(T& clinfo, int nCluster, uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex, const ClusRef& ref) { // data for given tracks starts at clinfo[ ref.getFirstEntry() ], @@ -95,14 +95,14 @@ class TrackTPC : public o2::track::TrackParCov } template - GPUd() inline void getClusterReference(T& clinfo, int nCluster, + GPUdi() void getClusterReference(T& clinfo, int nCluster, uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex) const { getClusterReference(clinfo, nCluster, sectorIndex, rowIndex, clusterIndex, mClustersReference); } template - GPUd() static inline const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, + GPUdi() static const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex, const ClusRef& ref) { uint32_t clusterIndex; @@ -111,14 +111,14 @@ class TrackTPC : public o2::track::TrackParCov } template - GPUd() inline const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, + GPUdi() const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex) const { return getCluster(clinfo, nCluster, clusters, sectorIndex, rowIndex, mClustersReference); } template - GPUd() inline const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, + GPUdi() const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, const o2::tpc::ClusterNativeAccess& clusters) const { uint8_t sectorIndex, rowIndex; diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h index 2ef5577ec6bf2..a988c96168170 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h @@ -199,9 +199,9 @@ class TrackParametrization GPUd() value_t getPt() const; GPUd() value_t getE2() const; GPUd() value_t getE() const; - GPUd() static inline value_t getdEdxBB(value_t betagamma) { return BetheBlochSolid(betagamma); } - GPUd() static inline value_t getdEdxBBOpt(value_t betagamma) { return BetheBlochSolidOpt(betagamma); } - GPUd() static inline value_t getBetheBlochSolidDerivativeApprox(value_T dedx, value_T bg) { return BetheBlochSolidDerivative(dedx, bg); } + GPUdi() static value_t getdEdxBB(value_t betagamma) { return BetheBlochSolid(betagamma); } + GPUdi() static value_t getdEdxBBOpt(value_t betagamma) { return BetheBlochSolidOpt(betagamma); } + GPUdi() static value_t getBetheBlochSolidDerivativeApprox(value_T dedx, value_T bg) { return BetheBlochSolidDerivative(dedx, bg); } GPUd() value_t getTheta() const; GPUd() value_t getEta() const; diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackUtils.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackUtils.h index 96ab53fde5e5c..0ee0ca4461ab0 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackUtils.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackUtils.h @@ -190,7 +190,7 @@ GPUd() value_T BetheBlochSolidOpt(value_T bg) //____________________________________________________ template -GPUd() value_T inline BetheBlochSolidDerivative(value_T dedx, value_T bg) +GPUdi() value_T BetheBlochSolidDerivative(value_T dedx, value_T bg) { // // This is approximate derivative of the BB over betagamm, NO check for the consistency of the provided dedx and bg is done diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/ClusterLinesGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/ClusterLinesGPU.h index ecb25b7bc9d71..75d75e0f67700 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/ClusterLinesGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/ClusterLinesGPU.h @@ -57,7 +57,7 @@ class ClusterLinesGPU final public: GPUd() ClusterLinesGPU(const Line& firstLine, const Line& secondLine); // poor man solution to calculate duplets' centroid GPUd() void computeClusterCentroid(); - GPUd() inline float* getVertex() { return mVertex; } + GPUdi() float* getVertex() { return mVertex; } private: float mAMatrix[6]; // AX=B diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h index 5b94992b0d708..a0802f1f05624 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h @@ -67,7 +67,7 @@ class GPUTPCTrackLinearisation float mQPt; // QPt }; -GPUd() MEM_CLASS_PRE2() inline GPUTPCTrackLinearisation::GPUTPCTrackLinearisation(const MEM_LG2(GPUTPCTrackParam) & GPUrestrict() t) : mSinPhi(t.SinPhi()), mCosPhi(0), mDzDs(t.DzDs()), mQPt(t.QPt()) +MEM_CLASS_PRE2() GPUdi() GPUTPCTrackLinearisation::GPUTPCTrackLinearisation(const MEM_LG2(GPUTPCTrackParam) & GPUrestrict() t) : mSinPhi(t.SinPhi()), mCosPhi(0), mDzDs(t.DzDs()), mQPt(t.QPt()) { if (mSinPhi > GPUCA_MAX_SIN_PHI) { mSinPhi = GPUCA_MAX_SIN_PHI; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h index 4b71a28401787..22517d4deae80 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h @@ -157,7 +157,7 @@ class GPUTPCTrackParam int mNDF; // the Number of Degrees of Freedom }; -GPUd() MEM_CLASS_PRE() inline void MEM_LG(GPUTPCTrackParam)::InitParam() +MEM_CLASS_PRE() GPUdi() void MEM_LG(GPUTPCTrackParam)::InitParam() { // Initialize Tracklet Parameters using default values SetSinPhi(0); From da6a839aa47605f9e806285d75dbe67b739ff105 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 10:57:13 +0200 Subject: [PATCH 0204/2205] SHA1: function in header file should be inline or static --- Framework/Foundation/3rdparty/include/Framework/SHA1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Foundation/3rdparty/include/Framework/SHA1.h b/Framework/Foundation/3rdparty/include/Framework/SHA1.h index cdf6bf18b17d9..3fd2a037302fb 100644 --- a/Framework/Foundation/3rdparty/include/Framework/SHA1.h +++ b/Framework/Foundation/3rdparty/include/Framework/SHA1.h @@ -263,7 +263,7 @@ static void SHA1Final( memset(&finalcount, '\0', sizeof(finalcount)); } -void SHA1( +static void SHA1( char* hash_out, const char* str, unsigned int len) From 5577abf429f07097180b898df5fc1e8af540be93 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 10:58:40 +0200 Subject: [PATCH 0205/2205] GPU: ConstantMem object should not be constructible / destructible in device code --- GPU/GPUTracking/Base/GPUConstantMem.h | 8 +++++--- .../Global/GPUChainTrackingDebugAndProfiling.cxx | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUConstantMem.h b/GPU/GPUTracking/Base/GPUConstantMem.h index 17e6268764606..7445233f02e8c 100644 --- a/GPU/GPUTracking/Base/GPUConstantMem.h +++ b/GPU/GPUTracking/Base/GPUConstantMem.h @@ -122,14 +122,16 @@ GPUdi() auto& GPUConstantMem::getTRDTracker<1>() #ifdef GPUCA_NOCOMPAT union GPUConstantMemCopyable { - GPUConstantMemCopyable() {} // NOLINT: We want an empty constructor, not a default one - ~GPUConstantMemCopyable() {} // NOLINT: We want an empty destructor, not a default one - GPUConstantMemCopyable(const GPUConstantMemCopyable& o) +#if !defined(__OPENCL__) || defined(__OPENCL_HOST__) + GPUh() GPUConstantMemCopyable() {} // NOLINT: We want an empty constructor, not a default one + GPUh() ~GPUConstantMemCopyable() {} // NOLINT: We want an empty destructor, not a default one + GPUh() GPUConstantMemCopyable(const GPUConstantMemCopyable& o) { for (unsigned int k = 0; k < sizeof(GPUConstantMem) / sizeof(int); k++) { ((int*)&v)[k] = ((int*)&o.v)[k]; } } +#endif GPUConstantMem v; }; #endif diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index da167ca9731bf..0737456df2302 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -244,7 +244,7 @@ void GPUChainTracking::PrintOutputStat() } snprintf(trdText, 1024, " - TRD Tracker reconstructed %d tracks (%d tracklets)", nTRDTracks, nTRDTracklets); } - GPUInfo("Output Tracks: %d (%d / %d / %d / %d clusters (fitted / attached / adjacent / total))%s", nTracks, nAttachedClustersFitted, nAttachedClusters, nAdjacentClusters, nCls, trdText); + GPUInfo("Output Tracks: %d (%d / %d / %d / %d clusters (fitted / attached / adjacent / total) - %s format)%s", nTracks, nAttachedClustersFitted, nAttachedClusters, nAdjacentClusters, nCls, ProcessingSettings().createO2Output > 1 ? "O2" : "GPU", trdText); } void GPUChainTracking::SanityCheck() From b1438a9af6cda72c16a54d635a71f47f87e75bb7 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 11:02:23 +0200 Subject: [PATCH 0206/2205] GPU: More WORKAROUNDs for CUDA bug exposing device code via host symbols --- .../TPC/include/DataFormatsTPC/TrackTPC.h | 10 +++++----- Detectors/Base/src/Propagator.cxx | 4 ++-- GPU/Common/GPUCommonDefAPI.h | 6 +++++- GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx | 8 +++++--- GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx | 8 +++++--- GPU/GPUTracking/Refit/GPUTrackingRefit.cxx | 14 ++++++++------ GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx | 6 ++++-- .../SliceTracker/GPUTPCTrackLinearisation.h | 3 ++- GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h | 3 ++- GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h | 2 ++ .../TRDTracking/GPUTRDTrackerKernels.cxx | 6 ++++-- dependencies/FindO2GPU.cmake | 1 + 12 files changed, 45 insertions(+), 26 deletions(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h index cc446103b7fc1..0b40090de1c2e 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackTPC.h @@ -80,7 +80,7 @@ class TrackTPC : public o2::track::TrackParCov template GPUdi() static void getClusterReference(T& clinfo, int nCluster, - uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex, const ClusRef& ref) + uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex, const ClusRef& ref) { // data for given tracks starts at clinfo[ ref.getFirstEntry() ], // 1st ref.getEntries() cluster indices are stored as uint32_t @@ -96,14 +96,14 @@ class TrackTPC : public o2::track::TrackParCov template GPUdi() void getClusterReference(T& clinfo, int nCluster, - uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex) const + uint8_t& sectorIndex, uint8_t& rowIndex, uint32_t& clusterIndex) const { getClusterReference(clinfo, nCluster, sectorIndex, rowIndex, clusterIndex, mClustersReference); } template GPUdi() static const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, - const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex, const ClusRef& ref) + const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex, const ClusRef& ref) { uint32_t clusterIndex; getClusterReference(clinfo, nCluster, sectorIndex, rowIndex, clusterIndex, ref); @@ -112,14 +112,14 @@ class TrackTPC : public o2::track::TrackParCov template GPUdi() const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, - const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex) const + const o2::tpc::ClusterNativeAccess& clusters, uint8_t& sectorIndex, uint8_t& rowIndex) const { return getCluster(clinfo, nCluster, clusters, sectorIndex, rowIndex, mClustersReference); } template GPUdi() const o2::tpc::ClusterNative& getCluster(T& clinfo, int nCluster, - const o2::tpc::ClusterNativeAccess& clusters) const + const o2::tpc::ClusterNativeAccess& clusters) const { uint8_t sectorIndex, rowIndex; return (getCluster(clinfo, nCluster, clusters, sectorIndex, rowIndex)); diff --git a/Detectors/Base/src/Propagator.cxx b/Detectors/Base/src/Propagator.cxx index 4ecb0e21a88ae..c7c7b461034e5 100644 --- a/Detectors/Base/src/Propagator.cxx +++ b/Detectors/Base/src/Propagator.cxx @@ -788,8 +788,8 @@ namespace o2::base { #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. template class PropagatorImpl; -template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackPar_t>(PropagatorImpl::TrackPar_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; -template bool GPUd() PropagatorImpl::propagateToAlphaX::TrackParCov_t>(PropagatorImpl::TrackParCov_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; +template bool GPUdni() PropagatorImpl::propagateToAlphaX::TrackPar_t>(PropagatorImpl::TrackPar_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; +template bool GPUdni() PropagatorImpl::propagateToAlphaX::TrackParCov_t>(PropagatorImpl::TrackParCov_t&, float, float, bool, float, float, int, PropagatorImpl::MatCorrType matCorr, track::TrackLTIntegral*, int) const; #endif #ifndef GPUCA_GPUCODE template class PropagatorImpl; diff --git a/GPU/Common/GPUCommonDefAPI.h b/GPU/Common/GPUCommonDefAPI.h index 52691e094590a..5a152de8a2216 100644 --- a/GPU/Common/GPUCommonDefAPI.h +++ b/GPU/Common/GPUCommonDefAPI.h @@ -152,7 +152,11 @@ #define GPUbarrierWarp() #define GPUAtomic(type) type #elif defined(__CUDACC__) //Defines for CUDA - #define GPUd() __device__ + #ifndef GPUCA_GPUCODE_DEVICE + #define GPUd() __device__ inline // FIXME: DR: Workaround: mark device function as inline such that nvcc does not create bogus host symbols + #else + #define GPUd() __device__ + #endif #define GPUdDefault() #define GPUhdDefault() #define GPUdi() __device__ inline diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx index 9f7e359d1630b..10bcb505c9562 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx @@ -1007,9 +1007,11 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks(int nBlocks, int nThreads, int iBl MergeBorderTracks(nBlocks, nThreads, iBlock, iThread, iSlice, b1, n1, jSlice, b2, n2, mergeMode); } -template GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); -template GPUd() void GPUTPCGMMerger::MergeBorderTracks<1>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); -template GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<1>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); +#endif GPUd() void GPUTPCGMMerger::MergeWithinSlicesPrepare(int nBlocks, int nThreads, int iBlock, int iThread) { diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx index 1a9f9c536565e..e7f9e7dbf3385 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx @@ -120,9 +120,11 @@ GPUdii() void GPUTPCGMMergerMergeBorders::Thread(int nBlocks, int nThreads, int { merger.MergeBorderTracks(nBlocks, nThreads, iBlock, iThread, args...); } -template GPUd() void GPUTPCGMMergerMergeBorders::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); -template GPUd() void GPUTPCGMMergerMergeBorders::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); -template GPUd() void GPUTPCGMMergerMergeBorders::Thread<3>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int N, int cmpMax); +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<3>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int N, int cmpMax); +#endif template <> GPUdii() void GPUTPCGMMergerMergeBorders::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode) { diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx index 5b42ad462cc84..a78565f020ab1 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx @@ -421,12 +421,14 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) return nFitted; } -template GPUd() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); -template GPUd() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); -template GPUd() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); -template GPUd() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); -template GPUd() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); -template GPUd() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. +template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); +template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); +template GPUdni() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); +template GPUdni() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); +template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); +template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); +#endif #ifndef GPUCA_GPUCODE void GPUTrackingRefit::SetPtrsFromGPUConstantMem(const GPUConstantMem* v, MEM_CONSTANT(GPUParam) * p) diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx index 5d1aba3c0d07d..87005299b9484 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx @@ -44,5 +44,7 @@ GPUdii() void GPUTrackingRefitKernel::Thread(int nBlocks, int nThreads, int iBlo } } } -template GPUd() void GPUTrackingRefitKernel::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); -template GPUd() void GPUTrackingRefitKernel::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. +template GPUdni() void GPUTrackingRefitKernel::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); +template GPUdni() void GPUTrackingRefitKernel::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); +#endif diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h index a0802f1f05624..d9f332beabd7d 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackLinearisation.h @@ -67,7 +67,8 @@ class GPUTPCTrackLinearisation float mQPt; // QPt }; -MEM_CLASS_PRE2() GPUdi() GPUTPCTrackLinearisation::GPUTPCTrackLinearisation(const MEM_LG2(GPUTPCTrackParam) & GPUrestrict() t) : mSinPhi(t.SinPhi()), mCosPhi(0), mDzDs(t.DzDs()), mQPt(t.QPt()) +MEM_CLASS_PRE2() +GPUdi() GPUTPCTrackLinearisation::GPUTPCTrackLinearisation(const MEM_LG2(GPUTPCTrackParam) & GPUrestrict() t) : mSinPhi(t.SinPhi()), mCosPhi(0), mDzDs(t.DzDs()), mQPt(t.QPt()) { if (mSinPhi > GPUCA_MAX_SIN_PHI) { mSinPhi = GPUCA_MAX_SIN_PHI; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h index 22517d4deae80..38d81c6e594b5 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h @@ -157,7 +157,8 @@ class GPUTPCTrackParam int mNDF; // the Number of Degrees of Freedom }; -MEM_CLASS_PRE() GPUdi() void MEM_LG(GPUTPCTrackParam)::InitParam() +MEM_CLASS_PRE() +GPUdi() void MEM_LG(GPUTPCTrackParam)::InitParam() { // Initialize Tracklet Parameters using default values SetSinPhi(0); diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h index 911efb04a7b19..e05b2e719c3d2 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h @@ -345,12 +345,14 @@ class GPUTRDTrackerDebug GPUd() void SetFindable(bool* findable) {} GPUd() void Output() {} }; +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. #ifndef GPUCA_ALIROOT_LIB template class GPUTRDTrackerDebug; #endif #if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE) template class GPUTRDTrackerDebug; #endif +#endif } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx index c221050816815..20db05948c598 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx @@ -42,7 +42,9 @@ GPUdii() void GPUTRDTrackerKernels::Thread(int nBlocks, int nThreads, int iBlock } } -template GPUd() void GPUTRDTrackerKernels::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTrackerGPU* externalInstance); +#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. +template GPUdni() void GPUTRDTrackerKernels::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTrackerGPU* externalInstance); #ifdef GPUCA_HAVE_O2HEADERS -template GPUd() void GPUTRDTrackerKernels::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTracker* externalInstance); +template GPUdni() void GPUTRDTrackerKernels::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTracker* externalInstance); #endif // GPUCA_HAVE_O2HEADERS +#endif diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index b1ffc07fc212b..fa82e2b6128d6 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -115,6 +115,7 @@ if(ENABLE_CUDA) if(GPUCA_KERNEL_RESOURCE_USAGE_VERBOSE) string(APPEND CMAKE_CUDA_FLAGS " -Xptxas -v") endif() + string(APPEND CMAKE_CUDA_FLAGS " -Xcudafe --diag_suppress=114") if (NOT ENABLE_CUDA STREQUAL "AUTO") string(APPEND CMAKE_CUDA_FLAGS " --allow-unsupported-compiler") endif() From 07364d792c62b6dd1f0ce20384c2977ddff2783d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 6 Sep 2024 17:04:07 +0200 Subject: [PATCH 0207/2205] GPU: Fix installation of GPUDataTypeHeaders headers --- GPU/GPUTracking/CMakeLists.txt | 2 + GPU/GPUTracking/DataTypes/GPUTRDTrack.cxx | 163 +----------------- GPU/GPUTracking/DataTypes/GPUTRDTrack.inc | 178 ++++++++++++++++++++ GPU/GPUTracking/DataTypes/GPUTRDTrackO2.cxx | 6 +- GPU/GPUTracking/DataTypes/GPUTRDTrackO2.h | 20 +++ 5 files changed, 206 insertions(+), 163 deletions(-) create mode 100644 GPU/GPUTracking/DataTypes/GPUTRDTrack.inc create mode 100644 GPU/GPUTracking/DataTypes/GPUTRDTrackO2.h diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index 23fb231634a13..c4ad13f2a888e 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -295,6 +295,8 @@ string(REPLACE ".cxx" ".h" HDRS_TMP "${SRCS_NO_CINT}") set(HDRS_INSTALL ${HDRS_INSTALL} ${HDRS_TMP}) string(REPLACE ".cxx" ".h" HDRS_TMP "${SRCS_DATATYPES}") set(HDRS_CINT_DATATYPES ${HDRS_CINT_DATATYPES} ${HDRS_TMP}) +string(REPLACE ".cxx" ".h" HDRS_TMP "${SRCS_DATATYPE_HEADERS}") +set(HDRS_INSTALL ${HDRS_INSTALL} ${HDRS_TMP}) unset(HDRS_TMP) # Main CMake part for O2 diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrack.cxx b/GPU/GPUTracking/DataTypes/GPUTRDTrack.cxx index a705371c47bff..ab3bec3434c37 100644 --- a/GPU/GPUTracking/DataTypes/GPUTRDTrack.cxx +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrack.cxx @@ -13,171 +13,12 @@ /// \author Ole Schmidt, Sergey Gorbunov #include "GPUTRDTrack.h" -#if !defined(GPU_TRD_TRACK_O2) #include "GPUTRDInterfaces.h" -#endif using namespace GPUCA_NAMESPACE::gpu; +#include "GPUTRDTrack.inc" -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t() -{ - // default constructor - initialize(); -} - -template -GPUd() void GPUTRDTrack_t::initialize() -{ - // set all members to their default values (needed since in-class initialization not possible with AliRoot) - mChi2 = 0.f; - mSignal = -1.f; - mRefGlobalTrackId = 0; - mCollisionId = -1; - mFlags = 0; - mIsCrossingNeighbor = 0; - for (int i = 0; i < kNLayers; ++i) { - mAttachedTracklets[i] = -1; - } -} - -#ifdef GPUCA_ALIROOT_LIB -#include "AliHLTExternalTrackParam.h" -#include "GPUTRDTrackData.h" - -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const AliHLTExternalTrackParam& t) : T(t) -{ - initialize(); -} - -template -GPUd() void GPUTRDTrack_t::ConvertTo(GPUTRDTrackDataRecord& t) const -{ - //------------------------------------------------------------------ - // convert to GPU structure - //------------------------------------------------------------------ - t.mAlpha = T::getAlpha(); - t.fX = T::getX(); - t.fY = T::getY(); - t.fZ = T::getZ(); - t.fq1Pt = T::getQ2Pt(); - t.mSinPhi = T::getSnp(); - t.fTgl = T::getTgl(); - for (int i = 0; i < 15; i++) { - t.fC[i] = T::getCov()[i]; - } - t.fTPCTrackID = getRefGlobalTrackIdRaw(); - for (int i = 0; i < kNLayers; i++) { - t.fAttachedTracklets[i] = getTrackletIndex(i); - } -} - -template -GPUd() void GPUTRDTrack_t::ConvertFrom(const GPUTRDTrackDataRecord& t) -{ - //------------------------------------------------------------------ - // convert from GPU structure - //------------------------------------------------------------------ - T::set(t.fX, t.mAlpha, &(t.fY), t.fC); - setRefGlobalTrackIdRaw(t.fTPCTrackID); - mChi2 = 0.f; - mSignal = -1.f; - mFlags = 0; - mIsCrossingNeighbor = 0; - mCollisionId = -1; - for (int iLayer = 0; iLayer < kNLayers; iLayer++) { - mAttachedTracklets[iLayer] = t.fAttachedTracklets[iLayer]; - } -} - -#endif - -#if defined(GPUCA_HAVE_O2HEADERS) -#include "ReconstructionDataFormats/TrackTPCITS.h" -#include "DataFormatsTPC/TrackTPC.h" - -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const o2::dataformats::TrackTPCITS& t) : T(t) -{ - initialize(); -} - -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const o2::tpc::TrackTPC& t) : T(t) -{ - initialize(); -} - -#endif - -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const GPUTRDTrack_t& t) - : T(t), mChi2(t.mChi2), mSignal(t.mSignal), mRefGlobalTrackId(t.mRefGlobalTrackId), mCollisionId(t.mCollisionId), mFlags(t.mFlags), mIsCrossingNeighbor(t.mIsCrossingNeighbor) -{ - // copy constructor - for (int i = 0; i < kNLayers; ++i) { - mAttachedTracklets[i] = t.mAttachedTracklets[i]; - } -} - -template -GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const T& t) : T(t) -{ - // copy constructor from anything - initialize(); -} - -template -GPUd() GPUTRDTrack_t& GPUTRDTrack_t::operator=(const GPUTRDTrack_t& t) -{ - // assignment operator - if (&t == this) { - return *this; - } - *(T*)this = t; - mChi2 = t.mChi2; - mSignal = t.mSignal; - mRefGlobalTrackId = t.mRefGlobalTrackId; - mCollisionId = t.mCollisionId; - mFlags = t.mFlags; - mIsCrossingNeighbor = t.mIsCrossingNeighbor; - for (int i = 0; i < kNLayers; ++i) { - mAttachedTracklets[i] = t.mAttachedTracklets[i]; - } - return *this; -} - -template -GPUd() int GPUTRDTrack_t::getNlayersFindable() const -{ - // returns number of layers in which the track is in active area of TRD - int retVal = 0; - for (int iLy = 0; iLy < kNLayers; iLy++) { - if ((mFlags >> iLy) & 0x1) { - ++retVal; - } - } - return retVal; -} - -template -GPUd() int GPUTRDTrack_t::getNmissingConsecLayers(int iLayer) const -{ - // returns number of consecutive layers in which the track was - // inside the deadzone up to (and including) the given layer - int retVal = 0; - while (!getIsFindable(iLayer)) { - ++retVal; - --iLayer; - if (iLayer < 0) { - break; - } - } - return retVal; -} - -#if !defined(GPUCA_GPUCODE) && !defined(GPU_TRD_TRACK_O2) +#if !defined(GPUCA_GPUCODE) namespace GPUCA_NAMESPACE { namespace gpu diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc b/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc new file mode 100644 index 0000000000000..bba48e6cfc7a1 --- /dev/null +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc @@ -0,0 +1,178 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUTRDTrack.inc +/// \author Ole Schmidt, Sergey Gorbunov + +#ifndef GPUTRDTRACK_INC_H +#define GPUTRDTRACK_INC_H + +#include "GPUTRDTrack.h" + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t() +{ + // default constructor + initialize(); +} + +template +GPUd() void GPUTRDTrack_t::initialize() +{ + // set all members to their default values (needed since in-class initialization not possible with AliRoot) + mChi2 = 0.f; + mSignal = -1.f; + mRefGlobalTrackId = 0; + mCollisionId = -1; + mFlags = 0; + mIsCrossingNeighbor = 0; + for (int i = 0; i < kNLayers; ++i) { + mAttachedTracklets[i] = -1; + } +} + +#ifdef GPUCA_ALIROOT_LIB +#include "AliHLTExternalTrackParam.h" +#include "GPUTRDTrackData.h" + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const AliHLTExternalTrackParam& t) : T(t) +{ + initialize(); +} + +template +GPUd() void GPUTRDTrack_t::ConvertTo(GPUTRDTrackDataRecord& t) const +{ + //------------------------------------------------------------------ + // convert to GPU structure + //------------------------------------------------------------------ + t.mAlpha = T::getAlpha(); + t.fX = T::getX(); + t.fY = T::getY(); + t.fZ = T::getZ(); + t.fq1Pt = T::getQ2Pt(); + t.mSinPhi = T::getSnp(); + t.fTgl = T::getTgl(); + for (int i = 0; i < 15; i++) { + t.fC[i] = T::getCov()[i]; + } + t.fTPCTrackID = getRefGlobalTrackIdRaw(); + for (int i = 0; i < kNLayers; i++) { + t.fAttachedTracklets[i] = getTrackletIndex(i); + } +} + +template +GPUd() void GPUTRDTrack_t::ConvertFrom(const GPUTRDTrackDataRecord& t) +{ + //------------------------------------------------------------------ + // convert from GPU structure + //------------------------------------------------------------------ + T::set(t.fX, t.mAlpha, &(t.fY), t.fC); + setRefGlobalTrackIdRaw(t.fTPCTrackID); + mChi2 = 0.f; + mSignal = -1.f; + mFlags = 0; + mIsCrossingNeighbor = 0; + mCollisionId = -1; + for (int iLayer = 0; iLayer < kNLayers; iLayer++) { + mAttachedTracklets[iLayer] = t.fAttachedTracklets[iLayer]; + } +} + +#endif + +#if defined(GPUCA_HAVE_O2HEADERS) +#include "ReconstructionDataFormats/TrackTPCITS.h" +#include "DataFormatsTPC/TrackTPC.h" + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const o2::dataformats::TrackTPCITS& t) : T(t) +{ + initialize(); +} + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const o2::tpc::TrackTPC& t) : T(t) +{ + initialize(); +} + +#endif + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const GPUTRDTrack_t& t) + : T(t), mChi2(t.mChi2), mSignal(t.mSignal), mRefGlobalTrackId(t.mRefGlobalTrackId), mCollisionId(t.mCollisionId), mFlags(t.mFlags), mIsCrossingNeighbor(t.mIsCrossingNeighbor) +{ + // copy constructor + for (int i = 0; i < kNLayers; ++i) { + mAttachedTracklets[i] = t.mAttachedTracklets[i]; + } +} + +template +GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const T& t) : T(t) +{ + // copy constructor from anything + initialize(); +} + +template +GPUd() GPUTRDTrack_t& GPUTRDTrack_t::operator=(const GPUTRDTrack_t& t) +{ + // assignment operator + if (&t == this) { + return *this; + } + *(T*)this = t; + mChi2 = t.mChi2; + mSignal = t.mSignal; + mRefGlobalTrackId = t.mRefGlobalTrackId; + mCollisionId = t.mCollisionId; + mFlags = t.mFlags; + mIsCrossingNeighbor = t.mIsCrossingNeighbor; + for (int i = 0; i < kNLayers; ++i) { + mAttachedTracklets[i] = t.mAttachedTracklets[i]; + } + return *this; +} + +template +GPUd() int GPUTRDTrack_t::getNlayersFindable() const +{ + // returns number of layers in which the track is in active area of TRD + int retVal = 0; + for (int iLy = 0; iLy < kNLayers; iLy++) { + if ((mFlags >> iLy) & 0x1) { + ++retVal; + } + } + return retVal; +} + +template +GPUd() int GPUTRDTrack_t::getNmissingConsecLayers(int iLayer) const +{ + // returns number of consecutive layers in which the track was + // inside the deadzone up to (and including) the given layer + int retVal = 0; + while (!getIsFindable(iLayer)) { + ++retVal; + --iLayer; + if (iLayer < 0) { + break; + } + } + return retVal; +} + +#endif // GPUTRDTRACK_INC_H diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.cxx b/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.cxx index 6141a8bd9d958..d2404f9d3b74b 100644 --- a/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.cxx +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.cxx @@ -12,8 +12,10 @@ /// \file GPUTRDTrackO2.cxx /// \author David Rohr -#define GPU_TRD_TRACK_O2 -#include "GPUTRDTrack.cxx" +#include "GPUTRDTrackO2.h" +using namespace GPUCA_NAMESPACE::gpu; + +#include "GPUTRDTrack.inc" #include "ReconstructionDataFormats/GlobalTrackID.h" #include "ReconstructionDataFormats/Track.h" diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.h b/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.h new file mode 100644 index 0000000000000..d7f811b004e02 --- /dev/null +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrackO2.h @@ -0,0 +1,20 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUTRDTrackO2.h +/// \author David Rohr + +#ifndef GPUTRDTRACKO2_H +#define GPUTRDTRACKO2_H + +#include "GPUTRDTrack.h" + +#endif // GPUTRDTRACKO2_H From 683588af7c05122faf1e6731c482c32805050ded Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 7 Sep 2024 10:29:56 +0200 Subject: [PATCH 0208/2205] GPU: Some fixes for char / unsigned char handling --- GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx | 2 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 2 +- GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx | 2 +- GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx | 4 ++-- GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx index 3fcd4853573e0..8d68509e42473 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx @@ -33,7 +33,7 @@ GPUdii() void GPUTPCCompressionKernels::Thread0: break after n rejected hits, <0: reject at max -n hits") AddOptionRTC(dEdxTruncLow, unsigned char, 2, "", 0, "Low truncation threshold, fraction of 128") diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx index 10bcb505c9562..671ec9a7794a0 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx @@ -2089,7 +2089,7 @@ GPUd() void GPUTPCGMMerger::Finalize1(int nBlocks, int nThreads, int iBlock, int if (!trk.OK() || trk.NClusters() == 0) { continue; } - char goodLeg = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].leg; + unsigned char goodLeg = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].leg; for (unsigned int j = 0; j < trk.NClusters(); j++) { int id = mClusters[trk.FirstClusterRef() + j].num; unsigned int weight = mTrackOrderAttach[i] | attachAttached; diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx b/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx index 8be4e31fa22e3..54f6591d2286c 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx +++ b/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx @@ -167,7 +167,7 @@ void GPUDisplayFrontendGlfw::GetKey(int key, int scancode, int mods, int& keyOut if (specialKey) { keyOut = keyPressOut = specialKey; } else { - keyOut = keyPressOut = localeKey; + keyOut = keyPressOut = (unsigned char)localeKey; if (keyPressOut >= 'a' && keyPressOut <= 'z') { keyPressOut += 'A' - 'a'; } @@ -193,7 +193,7 @@ void GPUDisplayFrontendGlfw::key_callback(GLFWwindow* window, int key, int scanc if (action == GLFW_PRESS) { me->mLastKeyDown = handleKey; } else if (action == GLFW_RELEASE) { - keyPress = me->mKeyDownMap[handleKey]; + keyPress = (unsigned char)me->mKeyDownMap[handleKey]; me->mKeys[keyPress] = false; me->mKeysShift[keyPress] = false; } diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx b/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx index 2be2e243f83c1..7e397813c12f2 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx +++ b/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx @@ -147,7 +147,7 @@ void GPUDisplayFrontendX11::GetKey(XEvent& event, int& keyOut, int& keyPressOut) tmpString[0] = 0; } int specialKey = GetKey(sym); - int localeKey = tmpString[0]; + int localeKey = (unsigned char)tmpString[0]; // GPUInfo("Key: keycode %d -> sym %d (%c) key %d (%c) special %d (%c)", (int)event.xkey.keycode, (int)sym, (char)sym, (int)localeKey, (char)localeKey, (int)specialKey, (char)specialKey); if (specialKey) { From 03cc6abe235478cb1b4d987d70b778f4362a9ba7 Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:52:32 +0200 Subject: [PATCH 0209/2205] MFT-MCH matching: Implementing save of N best matching candidates (#13478) * Implementing saving N matching candidates * Clang format * Adding comments * Fixing mistake in merging --- .../include/GlobalTracking/MatchGlobalFwd.h | 5 ++- .../GlobalTracking/MatchGlobalFwdParam.h | 4 +- .../GlobalTracking/src/MatchGlobalFwd.cxx | 41 ++++++++++++++++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h index 164bdb8d9f1f4..7aaadaad8ffff 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h @@ -333,11 +333,14 @@ class MatchGlobalFwd std::vector mMFTMatchPlaneParams; ///< MFT track parameters at matching plane std::vector mMCHMatchPlaneParams; ///< MCH track parameters at matching plane + std::map>> mCandidates; ///< map each MCH track id to vector of best match candidates + const o2::itsmft::TopologyDictionary* mMFTDict{nullptr}; // cluster patterns dictionary o2::itsmft::ChipMappingMFT mMFTMapping; bool mMCTruthON = false; ///< Flag availability of MC truth bool mUseMIDMCHMatch = false; ///< Flag for using MCHMID matches (TrackMCHMID) - int mSaveMode = 0; ///< Output mode [0 = SaveBestMatch; 1 = SaveAllMatches; 2 = SaveTrainingData] + int mSaveMode = 0; ///< Output mode [0 = SaveBestMatch; 1 = SaveAllMatches; 2 = SaveTrainingData; 3 = SaveNCandidates] + int mNCandidates = 5; ///< Numbers of matching candidates to save in savemode=3 MatchingType mMatchingType = MATCHINGUNDEFINED; TGeoManager* mGeoManager; }; diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwdParam.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwdParam.h index 9ba6563cec334..5633decb80985 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwdParam.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwdParam.h @@ -26,7 +26,8 @@ namespace globaltracking enum SaveMode { kBestMatch = 0, kSaveAll, - kSaveTrainingData }; + kSaveTrainingData, + kSaveNCandidates }; struct GlobalFwdMatchingParam : public o2::conf::ConfigurableParamHelper { @@ -41,6 +42,7 @@ struct GlobalFwdMatchingParam : public o2::conf::ConfigurableParamHelper using namespace o2::globaltracking; @@ -66,6 +67,8 @@ void MatchGlobalFwd::init() mSaveMode = matchingParam.saveMode; LOG(info) << "Save mode MFTMCH candidates = " << mSaveMode; + + mNCandidates = matchingParam.nCandidates; } //_________________________________________________________ @@ -98,6 +101,9 @@ void MatchGlobalFwd::run(const o2::globaltracking::RecoContainer& inp) case kSaveTrainingData: doMatching(); break; + case kSaveNCandidates: + doMatching(); + break; default: LOG(fatal) << "Invalid MFTMCH save mode"; } @@ -132,6 +138,7 @@ void MatchGlobalFwd::clear() mMatchLabels.clear(); mMFTTrackROFContMapping.clear(); mMatchingInfo.clear(); + mCandidates.clear(); } //_________________________________________________________ @@ -400,6 +407,25 @@ void MatchGlobalFwd::doMatching() if (mMCTruthON) { LOG(info) << " MFT-MCH Matching: nFakes = " << nFakes << " nTrue = " << nTrue; } + } else if constexpr (saveAllMode == SaveMode::kSaveNCandidates) { + int nFakes = 0, nTrue = 0; + auto& matchAllChi2 = mMatchingFunctionMap["matchALL"]; + for (auto MCHId = 0; MCHId < mMCHWork.size(); MCHId++) { + auto& thisMCHTrack = mMCHWork[MCHId]; + for (auto& pairCandidate : mCandidates[MCHId]) { + thisMCHTrack.setMFTTrackID(pairCandidate.second); + auto& thisMFTTrack = mMFTWork[pairCandidate.second]; + auto chi2 = matchAllChi2(thisMCHTrack, thisMFTTrack); // Matching chi2 is stored independently + thisMCHTrack.setMFTMCHMatchingScore(pairCandidate.first); + thisMCHTrack.setMFTMCHMatchingChi2(chi2); + mMatchedTracks.emplace_back(thisMCHTrack); + mMatchingInfo.emplace_back(thisMCHTrack); + if (mMCTruthON) { + mMatchLabels.push_back(computeLabel(MCHId, pairCandidate.second)); + mMatchLabels.back().isFake() ? nFakes++ : nTrue++; + } + } + } } } @@ -413,6 +439,10 @@ void MatchGlobalFwd::ROFMatch(int MFTROFId, int firstMCHROFId, int lastMCHROFId) const auto& lastMCHROF = mMCHTrackROFRec[lastMCHROFId]; int nFakes = 0, nTrue = 0; + auto compare = [](const std::pair& a, const std::pair& b) { + return a.first < b.first; + }; + auto firstMFTTrackID = thisMFTROF.getFirstEntry(); auto lastMFTTrackID = firstMFTTrackID + thisMFTROF.getNEntries() - 1; @@ -464,12 +494,21 @@ void MatchGlobalFwd::ROFMatch(int MFTROFId, int firstMCHROFId, int lastMCHROFId) } } + if constexpr (saveAllMode == SaveMode::kSaveNCandidates) { // In saveAllmode save all pairs to output container + auto score = mMatchFunc(thisMCHTrack, thisMFTTrack); + std::pair scoreID = {score, MFTId}; + mCandidates[MCHId].push_back(scoreID); + std::sort(mCandidates[MCHId].begin(), mCandidates[MCHId].end(), compare); + if (mCandidates[MCHId].size() > mNCandidates) { + mCandidates[MCHId].pop_back(); + } + } + if constexpr (saveAllMode == SaveMode::kSaveTrainingData) { // In save training data mode store track parameters at matching plane thisMCHTrack.setMFTTrackID(MFTId); mMatchingInfo.emplace_back(thisMCHTrack); mMCHMatchPlaneParams.emplace_back(thisMCHTrack); mMFTMatchPlaneParams.emplace_back(static_cast(thisMFTTrack)); - if (mMCTruthON) { mMatchLabels.push_back(matchLabel); mMatchLabels.back().isFake() ? nFakes++ : nTrue++; From 87efa1653983df03a01d04882523badefb40201f Mon Sep 17 00:00:00 2001 From: Andreas Molander Date: Thu, 5 Sep 2024 13:58:50 +0300 Subject: [PATCH 0210/2205] FIT: Set correct path for macro installations --- Detectors/FIT/macros/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/FIT/macros/CMakeLists.txt b/Detectors/FIT/macros/CMakeLists.txt index 320cc19b00b8c..81f2cc05e0b25 100644 --- a/Detectors/FIT/macros/CMakeLists.txt +++ b/Detectors/FIT/macros/CMakeLists.txt @@ -40,5 +40,5 @@ o2_add_test_root_macro(readFITDCSdata.C O2::CCDB LABELS fit) -o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/readFITDCSdata.C) -o2_data_file(COPY readFITDeadChannelMap.C DESTINATION Detectors/FIT/macros/readFITDeadChannelMap.C) \ No newline at end of file +o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/) +o2_data_file(COPY readFITDeadChannelMap.C DESTINATION Detectors/FIT/macros/) \ No newline at end of file From 5ad9b1e09320955241af75cef799bab92d595c15 Mon Sep 17 00:00:00 2001 From: nicolovalle <35177278+nicolovalle@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:55:35 +0200 Subject: [PATCH 0211/2205] ITS - DeadMapBuilder, adding protection for end of stream (#13466) * ITS - DeadMapBuilder, adding protection for end of stream * Implementing suggestions for s/s/s * dummy --- .../ITSMFTWorkflow/DeadMapBuilderSpec.h | 1 + .../workflow/src/DeadMapBuilderSpec.cxx | 37 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h index 00f9fc931e679..7bce60d172222 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DeadMapBuilderSpec.h @@ -102,6 +102,7 @@ class ITSMFTDeadMapBuilder : public Task std::vector mDeadMapTF{}; + int mRunNumber = -1; unsigned long mFirstOrbitTF = 0x0; unsigned long mFirstOrbitRun = 0x0; diff --git a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx index 39d1bb7df7728..c97c3440afcc3 100644 --- a/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DeadMapBuilderSpec.cxx @@ -64,6 +64,7 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) mLocalOutputDir = ic.options().get("output-dir"); mSkipStaticMap = ic.options().get("skip-static-map"); + isEnded = false; mTimeStart = o2::ccdb::getCurrentTimestamp(); if (mRunMFT) { @@ -89,7 +90,7 @@ void ITSMFTDeadMapBuilder::init(InitContext& ic) } /////////////////////////////////////////////////////////////////// -// TODO: can ChipMappingITS help here? +// TODO: can ChipMappingITS help here? std::vector ITSMFTDeadMapBuilder::getChipIDsOnSameCable(uint16_t chip) { if (mRunMFT || chip < N_CHIPS_ITSIB) { @@ -178,19 +179,32 @@ void ITSMFTDeadMapBuilder::finalizeOutput() void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) { + // Skip everything in case of garbage (potentially at EoS) + if (pc.services().get().firstTForbit == -1U) { + LOG(info) << "Skipping the processing of inputs for timeslice " << pc.services().get().timeslice << " (firstTForbit is " << pc.services().get().firstTForbit << ")"; + return; + } + std::chrono::time_point start; std::chrono::time_point end; start = std::chrono::high_resolution_clock::now(); - mTFCounter++; - - mFirstOrbitTF = pc.services().get().firstTForbit; + const auto& tinfo = pc.services().get(); - if (mFirstOrbitRun == 0x0) { + if (tinfo.globalRunNumberChanged || mFirstOrbitRun == 0x0) { // new run is starting + mRunNumber = tinfo.runNumber; mFirstOrbitRun = mFirstOrbitTF; + mTFCounter = 0; + isEnded = false; } + if (isEnded) { + return; + } + mFirstOrbitTF = tinfo.firstTForbit; + mTFCounter++; + long sampled_orbit = mFirstOrbitTF - mFirstOrbitRun; if (!acceptTF(sampled_orbit)) { @@ -198,7 +212,7 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) } mStepCounter++; - LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " TF received. First orbit " << mFirstOrbitTF; + LOG(info) << "Processing step #" << mStepCounter << " out of " << mTFCounter << " good TF received. First orbit " << mFirstOrbitTF; mDeadMapTF.clear(); @@ -280,6 +294,12 @@ void ITSMFTDeadMapBuilder::run(ProcessingContext& pc) LOG(info) << "Elapsed time in TF processing: " << difference / 1000. << " ms"; + if (pc.transitionState() == TransitionHandlingState::Requested && !isEnded) { + std::string detname = mRunMFT ? "MFT" : "ITS"; + LOG(warning) << "Transition state requested for " << detname << " process, calling stop() and stopping the process of new data."; + stop(); + } + return; } @@ -291,8 +311,7 @@ void ITSMFTDeadMapBuilder::PrepareOutputCcdb(EndOfStreamContext* ec, std::string long tend = o2::ccdb::getCurrentTimestamp(); - std::map md = { - {"map_version", MAP_VERSION}}; + std::map md = {{"map_version", MAP_VERSION}, {"runNumber", std::to_string(mRunNumber)}}; std::string path = mRunMFT ? "MFT/Calib/" : "ITS/Calib/"; std::string name_str = "TimeDeadMap"; @@ -355,6 +374,7 @@ void ITSMFTDeadMapBuilder::endOfStream(EndOfStreamContext& ec) } else { LOG(warning) << "Time-dependent dead map is empty and will not be forwarded as output"; } + LOG(info) << "Stop process of new data because of endOfStream"; isEnded = true; } return; @@ -374,6 +394,7 @@ void ITSMFTDeadMapBuilder::stop() } else { LOG(alarm) << "endOfStream not processed. Nothing forwarded as output."; } + LOG(info) << "Stop process of new data because of stop() call."; isEnded = true; } return; From 32159e7af5b564b7d0c05781c9112dd6704d5394 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 7 Sep 2024 23:29:02 +0200 Subject: [PATCH 0212/2205] Add getTgl method to MCTrack --- .../simulation/include/SimulationDataFormat/MCTrack.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h b/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h index a5322b2f53dbf..b4cf26b11f82e 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h @@ -139,6 +139,12 @@ class MCTrackT } } + Double_t GetTgl() const + { + auto pT = GetPt(); + return pT > 1e-6 ? mStartVertexMomentumZ / pT : (GetStartVertexMomentumZ() > 0 ? 999. : -999.); + } + Double_t GetTheta() const { double mz(mStartVertexMomentumZ); From 8e069e5735a51f08cd9db6fc65663e4c5fd56a64 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 28 Aug 2024 18:17:23 +0200 Subject: [PATCH 0213/2205] Follow MC single track and decays reco status --- .../study/CMakeLists.txt | 6 +- .../GlobalTrackingStudy/TrackMCStudy.h | 10 +- .../GlobalTrackingStudy/TrackMCStudyConfig.h | 34 + .../GlobalTrackingStudy/TrackMCStudyTypes.h | 68 ++ .../study/src/GlobalTrackingStudyLinkDef.h | 9 +- .../study/src/TrackMCStudy.cxx | 608 ++++++++++++------ .../study/src/TrackMCStudyConfig.cxx | 14 + .../study/src/TrackMCStudyTypes.cxx | 12 + .../study/src/trackMCStudy-workflow.cxx | 10 +- 9 files changed, 543 insertions(+), 228 deletions(-) create mode 100644 Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h create mode 100644 Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h create mode 100644 Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyConfig.cxx create mode 100644 Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx diff --git a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt index 17bad37b3c14e..adae8dcfb8b10 100644 --- a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt +++ b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt @@ -9,7 +9,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -# add_compile_options(-O0 -g -fPIC) +add_compile_options(-O0 -g -fPIC) o2_add_library(GlobalTrackingStudy SOURCES src/TPCTrackStudy.cxx @@ -21,6 +21,8 @@ o2_add_library(GlobalTrackingStudy src/DumpTracks.cxx src/V0Ext.cxx src/TrackInfoExt.cxx + src/TrackMCStudyConfig.cxx + src/TrackMCStudyTypes.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTracking O2::GlobalTrackingWorkflowReaders O2::GlobalTrackingWorkflowHelpers @@ -33,6 +35,8 @@ o2_target_root_dictionary( GlobalTrackingStudy HEADERS include/GlobalTrackingStudy/V0Ext.h include/GlobalTrackingStudy/TrackInfoExt.h + include/GlobalTrackingStudy/TrackMCStudyConfig.h + include/GlobalTrackingStudy/TrackMCStudyTypes.h ) o2_add_executable(study-workflow diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h index 3dd315909ed1e..f7d402577a18c 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h @@ -12,17 +12,15 @@ #ifndef O2_TRACKING_STUDY_H #define O2_TRACKING_STUDY_H -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" -#include "ReconstructionDataFormats/Track.h" -#include "MathUtils/detail/Bracket.h" -#include "DataFormatsTPC/ClusterNative.h" +#include "Framework/Task.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" namespace o2::trackstudy { + /// create a processor spec -o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool checkMatching); +o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus); } // namespace o2::trackstudy diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h new file mode 100644 index 0000000000000..8ba48ea2010a4 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h @@ -0,0 +1,34 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_TRACKING_STUDY_CONFIG_H +#define O2_TRACKING_STUDY_CONFIG_H +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2::trackstudy +{ +struct TrackMCStudyConfig : o2::conf::ConfigurableParamHelper { + float minPt = 0.05; + float maxTgl = 1.2; + float minPtMC = 0.05; + float maxTglMC = 1.2; + float minRMC = 33.; + float maxPosTglMC = 2.; + float maxPVZOffset = 15.; + float decayMotherMaxT = 0.1; // max TOF in ns for mother particles to study + bool requireITSorTPCTrackRefs = true; + int decayPDG[5] = {310, 3122, -1, -1, -1}; // decays to study, must end by -1 + O2ParamDef(TrackMCStudyConfig, "trmcconf"); +}; +} // namespace o2::trackstudy + +#endif diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h new file mode 100644 index 0000000000000..0334af3448fba --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h @@ -0,0 +1,68 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_TRACKING_STUDY_TYPES_H +#define O2_TRACKING_STUDY_TYPES_H +#include "ReconstructionDataFormats/GlobalTrackID.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/Track.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "Framework/Task.h" + +namespace o2::trackstudy +{ +struct MCTrackInfo { + o2::track::TrackPar track{}; + o2::MCCompLabel label{}; + float occTPC = -1.f; + int bcInTF = -1; + int pdg = 0; + int pdgParent = 0; + int16_t nTPCCl = 0; + int16_t nTPCClShared = 0; + uint8_t minTPCRow = -1; + uint8_t maxTPCRow = 0; + int8_t nITSCl = 0; + int8_t pattITSCl = 0; + ClassDefNV(MCTrackInfo, 1); +}; + +struct RecTrack { + o2::track::TrackParCov track{}; + o2::dataformats::VtxTrackIndex gid{}; + uint8_t nClITS = 0; + uint8_t nClTPC = 0; + uint8_t pattITS = 0; + int8_t lowestPadRow = -1; + bool isFake = false; + ClassDefNV(RecTrack, 1); +}; + +struct TrackFamily { // set of tracks related to the same MC label + MCTrackInfo mcTrackInfo{}; + std::vector recTracks{}; + int8_t entITS = -1; + int8_t entTPC = -1; + int8_t entITSTPC = -1; + bool contains(const o2::dataformats::VtxTrackIndex& ref) const + { + for (const auto& tr : recTracks) { + if (ref == tr.gid) { + return true; + } + } + return false; + } + + ClassDefNV(TrackFamily, 1); +}; +} // namespace o2::trackstudy +#endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h index 9b14e24d03cb4..a0cfc30726e9a 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h +++ b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h @@ -21,5 +21,12 @@ #pragma link C++ class std::vector < o2::dataformats::TrackInfoExt> + ; #pragma link C++ class std::vector < o2::dataformats::ProngInfoExt> + ; #pragma link C++ class std::vector < o2::dataformats::V0Ext> + ; - +#pragma link C++ class o2::trackstudy::TrackMCStudyConfig + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::trackstudy::TrackMCStudyConfig> + ; +#pragma link C++ class o2::trackstudy::RecTrack + ; +#pragma link C++ class std::vector < o2::trackstudy::RecTrack> + ; +#pragma link C++ class o2::trackstudy::TrackFamily + ; +#pragma link C++ class std::vector < o2::trackstudy::TrackFamily> + ; +#pragma link C++ class o2::trackstudy::MCTrackInfo + ; +#pragma link C++ class std::vector < o2::trackstudy::MCTrackInfo> + ; #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index 4a20e3d2e022d..bd259ff499ae2 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -16,11 +16,13 @@ #include "ReconstructionDataFormats/TrackTPCITS.h" #include "ReconstructionDataFormats/GlobalTrackID.h" #include "TPCCalibration/VDriftHelper.h" -#include "ITSMFTBase/DPLAlpideParam.h" +#include "TPCCalibration/CorrectionMapsLoader.h" +#include "ITSMFTReconstruction/ChipMappingITS.h" #include "DetectorsBase/Propagator.h" #include "DetectorsBase/GeometryManager.h" #include "SimulationDataFormat/MCEventLabel.h" #include "SimulationDataFormat/MCUtils.h" +#include "SimulationDataFormat/O2DatabasePDG.h" #include "CommonDataFormat/BunchFilling.h" #include "CommonUtils/NameConf.h" #include "DataFormatsFT0/RecPoints.h" @@ -32,6 +34,8 @@ #include "DetectorsCommonDataFormats/DetID.h" #include "DetectorsBase/GRPGeomHelper.h" #include "GlobalTrackingStudy/TrackMCStudy.h" +#include "GlobalTrackingStudy/TrackMCStudyConfig.h" +#include "GlobalTrackingStudy/TrackMCStudyTypes.h" #include "GlobalTracking/MatchTPCITSParams.h" #include "TPCBase/ParameterElectronics.h" #include "ReconstructionDataFormats/PrimaryVertex.h" @@ -41,10 +45,17 @@ #include "ReconstructionDataFormats/VtxTrackRef.h" #include "ReconstructionDataFormats/DCA.h" #include "Steer/MCKinematicsReader.h" +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" +#include "GPUO2InterfaceRefit.h" +#include "GPUParam.h" +#include "GPUParam.inc" #include "MathUtils/fit.h" #include +#include #include #include +#include // workflow to study relation of reco tracks to MCTruth // o2-trackmc-study-workflow --device-verbosity 3 -b --run @@ -68,27 +79,38 @@ using timeEst = o2::dataformats::TimeStampWithError; class TrackMCStudy : public Task { public: - TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src, bool checkMatching) - : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src), mCheckMatching(checkMatching) {} + TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src) + : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src) {} ~TrackMCStudy() final = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; void endOfStream(EndOfStreamContext& ec) final; void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final; - void process(o2::globaltracking::RecoContainer& recoData); + void process(const o2::globaltracking::RecoContainer& recoData); private: - void prepareITSData(o2::globaltracking::RecoContainer& recoData); + void loadTPCOccMap(const o2::globaltracking::RecoContainer& recoData); + void fillMCClusterInfo(const o2::globaltracking::RecoContainer& recoData); + void prepareITSData(const o2::globaltracking::RecoContainer& recoData); + bool processMCParticle(int src, int ev, int trid); + bool addMCParticle(const MCTrack& mctr, const o2::MCCompLabel& lb, TParticlePDG* pPDG = nullptr); + bool acceptMCCharged(const MCTrack& tr, const o2::MCCompLabel& lb, int followDec = -1); bool propagateToRefX(o2::track::TrackParCov& trcTPC, o2::track::TrackParCov& trcITS); void updateTimeDependentParams(ProcessingContext& pc); float getDCAYCut(float pt) const; + gsl::span mCurrMCTracks; + TVector3 mCurrMCVertex; o2::tpc::VDriftHelper mTPCVDriftHelper{}; std::shared_ptr mDataRequest; std::shared_ptr mGGCCDBRequest; std::unique_ptr mDBGOut; + std::vector mTBinClOcc; ///< TPC occupancy histo: i-th entry is the integrated occupancy for ~1 orbit starting from the TB = i*mNTPCOccBinLength + std::vector mIntBC; ///< interaction global BC wrt TF start + std::vector mTPCOcc; ///< TPC occupancy for this interaction time + int mNTPCOccBinLength = 0; ///< TPC occ. histo bin length in TBs + float mNTPCOccBinLengthInv; int mVerbose = 0; - bool mCheckMatching = false; float mITSTimeBiasMUS = 0.f; float mITSROFrameLengthMUS = 0.f; ///< ITS RO frame in mus float mTPCTBinMUS = 0.; ///< TPC time bin duration in microseconds @@ -96,15 +118,24 @@ class TrackMCStudy : public Task float mTPCDCAYCut = 2.; float mTPCDCAZCut = 2.; float mMinX = 6.; - float mMaxEta = 0.8; - float mMinPt = 0.03; int mMinTPCClusters = 10; + int mNCheckDecays = 0; std::string mDCAYFormula = "0.0105 + 0.0350 / pow(x, 1.1)"; GTrackID::mask_t mTracksSrc{}; o2::steer::MCKinematicsReader mcReader; // reader of MC information std::vector mITSROF; std::vector mITSROFBracket; + std::vector mDecProdLblPool; // labels of decay products to watch, added to MC map + struct DecayRef { + o2::MCCompLabel mother{}; + o2::track::TrackPar parent{}; + int pdg = 0; + int daughterFirst = -1; + int daughterLast = -1; + }; + std::vector> mDecaysMaps; // for every parent particle to watch store its label and entries of 1st/last decay product labels in mDecProdLblPool + std::unordered_map mSelMCTracks; static constexpr float MaxSnp = 0.9; // max snp of ITS or TPC track at xRef to be matched }; @@ -119,15 +150,28 @@ void TrackMCStudy::init(InitContext& ic) mTPCDCAYCut = ic.options().get("max-tpc-dcay"); mTPCDCAZCut = ic.options().get("max-tpc-dcaz"); mMinX = ic.options().get("min-x-prop"); - mMaxEta = ic.options().get("max-eta"); - mMinPt = ic.options().get("min-pt"); mMinTPCClusters = ic.options().get("min-tpc-clusters"); mDCAYFormula = ic.options().get("dcay-vs-pt"); + + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + for (int id = 0; id < sizeof(params.decayPDG) / sizeof(int); id++) { + if (params.decayPDG[id] < 0) { + break; + } + mNCheckDecays++; + } + mDecaysMaps.resize(mNCheckDecays); } void TrackMCStudy::run(ProcessingContext& pc) { o2::globaltracking::RecoContainer recoData; + for (int i = 0; i < mNCheckDecays; i++) { + mDecaysMaps[i].clear(); + } + mDecProdLblPool.clear(); + mCurrMCTracks = {}; + recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions process(recoData); @@ -156,8 +200,9 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc) } } -void TrackMCStudy::process(o2::globaltracking::RecoContainer& recoData) +void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) { + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); auto pvvec = recoData.getPrimaryVertices(); auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs @@ -166,10 +211,8 @@ void TrackMCStudy::process(o2::globaltracking::RecoContainer& recoData) float vdriftTB = mTPCVDriftHelper.getVDriftObject().getVDrift() * o2::tpc::ParameterElectronics::Instance().ZbinWidth; // VDrift expressed in cm/TimeBin float itsBias = 0.5 * mITSROFrameLengthMUS + o2::itsmft::DPLAlpideParam::Instance().roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // ITS time is supplied in \mus as beginning of ROF - if (mCheckMatching) { - prepareITSData(recoData); - } - + prepareITSData(recoData); + loadTPCOccMap(recoData); auto getITSPatt = [&](GTrackID gid, uint8_t& ncl) { int16_t patt = 0; if (gid.getSource() == VTIndex::ITSAB) { @@ -204,10 +247,42 @@ void TrackMCStudy::process(o2::globaltracking::RecoContainer& recoData) return -1; }; - std::map> MCTRMap; + const auto* digconst = mcReader.getDigitizationContext(); + const auto& mcEvRecords = digconst->getEventRecords(false); + for (const auto& mcIR : mcEvRecords) { + long tbc = mcIR.differenceInBC(recoData.startIR); + mIntBC.push_back(tbc); + int occBin = tbc / 8 * mNTPCOccBinLengthInv; + mTPCOcc.push_back(occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin])); + } + // collect interesting MC particle (tracks and parents) + int curSrcMC = 0, curEvMC = 0; + for (curSrcMC = 0; curSrcMC < (int)mcReader.getNSources(); curSrcMC++) { + if (mVerbose > 1) { + LOGP(info, "Source {}", curSrcMC); + } + for (curEvMC = 0; curEvMC < (int)mcReader.getNEvents(curSrcMC); curEvMC++) { + if (mVerbose > 1) { + LOGP(info, "Event {}", curEvMC); + } + const auto& mt = mcReader.getTracks(curSrcMC, curEvMC); + mCurrMCTracks = gsl::span(mt.data(), mt.size()); + const_cast(mcReader.getMCEventHeader(curSrcMC, curEvMC)).GetVertex(mCurrMCVertex); + for (int itr = 0; itr < mCurrMCTracks.size(); itr++) { + processMCParticle(curSrcMC, curEvMC, itr); + } + } + } + if (mVerbose > 0) { + for (int id = 0; id < mNCheckDecays; id++) { + LOGP(info, "Decay PDG={} : {} entries", params.decayPDG[id], mDecaysMaps[id].size()); + } + } + + // add reconstruction info to MC particles. If MC particle was not selected before but was reconstrected, account MC info for (int iv = 0; iv < nv; iv++) { - if (mVerbose > 0) { + if (mVerbose > 1) { LOGP(info, "processing PV {} of {}", iv, nv); } const auto& vtref = vtxRefs[iv]; @@ -220,222 +295,171 @@ void TrackMCStudy::process(o2::globaltracking::RecoContainer& recoData) for (int i = idMin; i < idMax; i++) { auto vid = trackIndex[i]; const auto& trc = recoData.getTrackParam(vid); - if (trc.getPt() < mMinPt) { + if (trc.getPt() < params.minPt || std::abs(trc.getTgl()) > params.maxTgl) { continue; } auto lbl = recoData.getTrackMCLabel(vid); if (lbl.isValid()) { lbl.setFakeFlag(false); - auto& vvids = MCTRMap[lbl]; - if (vid.isAmbiguous() || vvids.empty()) { // do not repeat ambiguous tracks - bool skip = false; - for (const auto& va : vvids) { - if (va.second == vid) { - skip = true; - break; - } + auto entry = mSelMCTracks.find(lbl); + if (entry == mSelMCTracks.end()) { // add the track which was not added during MC scan + if (lbl.getSourceID() != curSrcMC || lbl.getEventID() != curEvMC) { + curSrcMC = lbl.getSourceID(); + curEvMC = lbl.getEventID(); + const auto& mt = mcReader.getTracks(curSrcMC, curEvMC); + mCurrMCTracks = gsl::span(mt.data(), mt.size()); + const_cast(mcReader.getMCEventHeader(curSrcMC, curEvMC)).GetVertex(mCurrMCVertex); } - if (skip) { + if (!acceptMCCharged(mCurrMCTracks[lbl.getTrackID()], lbl)) { continue; } + entry = mSelMCTracks.find(lbl); } - vvids.emplace_back(iv, vid); + auto& trackFamily = entry->second; + if (vid.isAmbiguous()) { // do not repeat ambiguous tracks + if (trackFamily.contains(vid)) { + continue; + } + } + auto& trf = trackFamily.recTracks.emplace_back(); + trf.gid = vid; // account(iv, vid); + if (mVerbose > 1) { + LOGP(info, "Matched rec track {} to MC track {}", vid.asString(), entry->first.asString()); + } + } else { + continue; } } } } - o2::track::TrackParCov dummyTrackParCov; - o2::track::TrackPar dummyTrackPar; - dummyTrackParCov.invalidate(); - dummyTrackPar.invalidate(); - - const std::vector* mcTracks = nullptr; - o2::MCCompLabel prevLbl; - std::vector recTracks; - std::vector recGIDs; - std::vector recFakes; - std::vector lowestPadrows; - std::vector itsPatterns; - std::vector tpcNcls; - std::vector itsNcls; - LOGP(info, "Recorded {} reconstructed tracks", MCTRMap.size()); - size_t count = 0; - for (auto ent : MCTRMap) { - count++; - auto lbl = ent.first; - if (lbl.getEventID() != prevLbl.getEventID() || lbl.getSourceID() != prevLbl.getSourceID()) { - if (mVerbose > 0) { - LOGP(info, "Loading MC Event={} / Src={}", lbl.getEventID(), lbl.getSourceID()); - } - mcTracks = &mcReader.getTracks(lbl.getSourceID(), lbl.getEventID()); - prevLbl = lbl; - } - const auto& mcPart = (*mcTracks)[lbl.getTrackID()]; - int pdg = mcPart.GetPdgCode(), pdgParent = 0; - std::array xyz{(float)mcPart.GetStartVertexCoordinatesX(), (float)mcPart.GetStartVertexCoordinatesY(), (float)mcPart.GetStartVertexCoordinatesZ()}; - std::array pxyz{(float)mcPart.GetStartVertexMomentumX(), (float)mcPart.GetStartVertexMomentumY(), (float)mcPart.GetStartVertexMomentumZ()}; - TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(pdg); - if (!pPDG) { - LOGP(error, "Unknown particle {}, skip. Was at {} of {}", pdg, count, MCTRMap.size()); - continue; - } - o2::track::TrackPar mctrO2(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); - bool primary = mcPart.isPrimary(); - auto parID = primary ? -1 : mcPart.getMotherTrackId(); - if (parID >= 0) { - const auto& mcPartPar = (*mcTracks)[parID]; - pdgParent = mcPartPar.GetPdgCode(); - } - auto& vgids = ent.second; - // make sure the more global tracks come 1st - if (vgids.size() > 1) { - std::sort(vgids.begin(), vgids.end(), [](VTIndexV& lhs, VTIndexV& rhs) { return lhs.second.getSource() > rhs.second.getSource(); }); + // collect ITS/TPC cluster info for selected MC particles + fillMCClusterInfo(recoData); + + LOGP(info, "collected {} MC tracks", mSelMCTracks.size()); + int mcnt = 0; + for (auto& entry : mSelMCTracks) { + auto& trackFam = entry.second; + auto& tracks = trackFam.recTracks; + mcnt++; + if (tracks.empty()) { + continue; } - recTracks.clear(); - recGIDs.clear(); - recFakes.clear(); - lowestPadrows.clear(); - itsPatterns.clear(); - itsNcls.clear(); - tpcNcls.clear(); if (mVerbose > 1) { - LOGP(info, "[{}] Lbl:{} PDG:{:+5d} (par: {:+5d}) | MC: {}", vgids.size(), lbl.asString(), pdg, pdgParent, mctrO2.asString()); + LOGP(info, "Processing MC track#{} {} -> {} reconstructed tracks", mcnt - 1, entry.first.asString(), tracks.size()); } - int entITS = -1, entTPC = -1, entITSTPC = -1; - for (size_t i = 0; i < vgids.size(); i++) { - auto vid = vgids[i].second; - auto lbl = recoData.getTrackMCLabel(vid); - const auto& trc = recoData.getTrackParam(vid); - int16_t itsPatt = 0; - uint8_t nclITS = 0; - uint8_t nclTPC = 0; - if (mVerbose > 1) { - LOGP(info, " :{} {:22} | [{}] {}", lbl.asString(), vid.asString(), i, ((const o2::track::TrackPar&)trc).asString()); - } - recTracks.push_back(trc); - recGIDs.push_back(vid); - recFakes.push_back(recoData.getTrackMCLabel(vid).isFake()); - auto msk = vid.getSourceDetectorsMask(); - if (mCheckMatching) { - lowestPadrows.push_back(-1); - } - if (msk[DetID::ITS]) { - auto gidITS = recoData.getITSContributorGID(vid); - itsPatt = getITSPatt(gidITS, nclITS); - if (vid.getSource() == VTIndex::ITS) { - entITS = i; - } - if (msk[DetID::TPC]) { - entITSTPC = i; - } - } - if (msk[DetID::TPC]) { - if (vid.getSource() == VTIndex::TPC) { - entTPC = i; + // sort according to the gid complexity (in principle, should be already sorted due to the backwards loop over NSources above + std::sort(tracks.begin(), tracks.end(), [](RecTrack& lhs, RecTrack& rhs) { return lhs.gid.getSource() > rhs.gid.getSource(); }); + // fill track params + int tcnt = 0; + for (auto& tref : tracks) { + if (tref.gid.isSourceSet()) { + tref.track = recoData.getTrackParam(tref.gid); + tref.isFake = recoData.getTrackMCLabel(tref.gid).isFake(); + auto msk = tref.gid.getSourceDetectorsMask(); + if (msk[DetID::ITS]) { + auto gidITS = recoData.getITSContributorGID(tref.gid); + tref.pattITS = getITSPatt(gidITS, tref.nClITS); + if (tref.gid.getSource() == VTIndex::ITS && trackFam.entITS < 0) { + trackFam.entITS = tcnt; + } + if (msk[DetID::TPC] && trackFam.entITSTPC < 0) { + trackFam.entITSTPC = tcnt; + } } - auto gidTPC = recoData.getTPCContributorGID(vid); - const auto& trtpc = recoData.getTPCTrack(gidTPC); - nclTPC = trtpc.getNClusters(); - if (mCheckMatching) { - auto& lr = lowestPadrows.back(); - lr = getLowestPadrow(recoData.getTPCTrack(recoData.getTPCContributorGID(vid))); + if (msk[DetID::TPC] && trackFam.entTPC < 0) { + if (tref.gid.getSource() == VTIndex::TPC) { + trackFam.entTPC = tcnt; + } + auto gidTPC = recoData.getTPCContributorGID(tref.gid); + const auto& trtpc = recoData.getTPCTrack(gidTPC); + tref.nClTPC = trtpc.getNClusters(); + tref.lowestPadRow = getLowestPadrow(recoData.getTPCTrack(gidTPC)); } + } else { + LOGP(info, "Invalid entry {} of {} getTrackMCLabel {}", tcnt, tracks.size(), tref.gid.asString()); } - tpcNcls.push_back(nclTPC); - itsNcls.push_back(nclITS); - itsPatterns.push_back(itsPatt); + tcnt++; } - (*mDBGOut) << "tracks" - << "lbl=" << lbl - << "mcTr=" << mctrO2 - << "pdg=" << pdg - << "pdgPar=" << pdgParent - << "recTr=" << recTracks - << "recGID=" << recGIDs - << "recFake=" << recFakes - << "itsPatt=" << itsPatterns - << "nClITS=" << itsNcls - << "nClTPC=" << tpcNcls; - if (mCheckMatching) { - (*mDBGOut) << "tracks" - << "lowestPadRow=" << lowestPadrows; + if (trackFam.entITSTPC < 0 && trackFam.entITS > -1 && trackFam.entTPC > -1) { // ITS and TPC were found but matching failed + auto vidITS = tracks[trackFam.entITS].gid; + auto vidTPC = tracks[trackFam.entTPC].gid; + auto trcTPC = recoData.getTrackParam(vidTPC); + auto trcITS = recoData.getTrackParamOut(vidITS); + if (!propagateToRefX(trcTPC, trcITS)) { + // break; + } } - (*mDBGOut) << "tracks" - << "\n"; - - // special ITS-TPC matching failure output - while (mCheckMatching) { - if (entITSTPC < 0 && entITS > -1 && entTPC > -1) { // ITS and TPC were found but matching failed - auto vidITS = vgids[entITS].second; - auto vidTPC = recoData.getTPCContributorGID(vgids[entTPC].second); // might be TPC match to outer detector, extract TPC - auto trcTPC = recoData.getTrackParam(vidTPC); - auto trcITS = recoData.getTrackParam(vidITS); - if (!propagateToRefX(trcTPC, trcITS)) { - break; + } + + // single tracks + for (auto& entry : mSelMCTracks) { + auto& trackFam = entry.second; + (*mDBGOut) << "tracks" << "tr=" << trackFam << "\n"; + } + // decays + std::vector decFam; + for (int id = 0; id < mNCheckDecays; id++) { + std::string decTreeName = fmt::format("dec{}", params.decayPDG[id]); + for (const auto& dec : mDecaysMaps[id]) { + decFam.clear(); + for (int idd = dec.daughterFirst; idd <= dec.daughterLast; idd++) { + auto dtLbl = mDecProdLblPool[idd]; // daughter MC label + const auto& dtFamily = mSelMCTracks[dtLbl]; + if (dtFamily.mcTrackInfo.pdgParent != dec.pdg) { + LOGP(error, "{}-th decay (pdg={}): {} in {}:{} range refers to MC track with pdgParent = {}", id, params.decayPDG[id], idd, dec.daughterFirst, dec.daughterLast, dtFamily.mcTrackInfo.pdgParent); + continue; } - const auto& trcTPCOrig = recoData.getTPCTrack(vidTPC); - const auto& trcITSOrig = recoData.getITSTrack(vidITS); - int lowestTPCRow = lowestPadrows[entTPC]; - float tpcT0 = trcTPCOrig.getTime0(), tF = trcTPCOrig.getDeltaTFwd(), tB = trcTPCOrig.getDeltaTBwd(); - TBracket tpcBr((tpcT0 - tB) * mTPCTBinMUS, (tpcT0 + tF) * mTPCTBinMUS); - - (*mDBGOut) << "failMatch" - << "mcTr=" << mctrO2 - << "pdg=" << pdg - << "pdgPar=" << pdgParent - << "labelITS=" << recoData.getTrackMCLabel(vidITS) - << "labelTPC=" << recoData.getTrackMCLabel(vidTPC) - << "gidITS=" << vidITS - << "gidTPC=" << vidTPC - << "itsBracket=" << mITSROFBracket[mITSROF[vidITS.getIndex()]] - << "tpcBracket=" << tpcBr - << "itsRef=" << trcITS - << "tpcRef=" << trcTPC - << "itsOrig=" << trcITSOrig - << "tpcOrig=" << trcTPCOrig - << "itsPatt=" << itsPatterns[entITS] - << "tpcLowestRow=" << lowestTPCRow - << "\n"; - } else if (entITSTPC > -1) { // match was found - auto contribIDs = recoData.getSingleDetectorRefs(vgids[entITSTPC].second); - auto vidMatch = contribIDs[VTIndex::ITSTPC]; - auto vidTPC = contribIDs[VTIndex::TPC]; - auto vidITS = contribIDs[VTIndex::ITSAB].isSourceSet() ? contribIDs[VTIndex::ITSAB] : contribIDs[VTIndex::ITS]; - const auto& trcTPCOrig = recoData.getTPCTrack(vidTPC); - o2::MCCompLabel itsLb; - int nITScl = 0; - if (vidITS.getSource() == VTIndex::ITS) { - itsLb = recoData.getTrackMCLabel(vidITS); - nITScl = recoData.getITSTrack(vidITS).getNClusters(); - } else { - itsLb = recoData.getITSABMCLabels()[vidITS]; - nITScl = recoData.getITSABRefs()[vidITS].getNClusters(); + decFam.push_back(dtFamily); + } + (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "\n"; + } + } +} + +void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& recoData) +{ + // TPC clusters info + const auto& TPCClusterIdxStruct = recoData.inputsTPCclusters->clusterIndex; + const auto* TPCClMClab = recoData.inputsTPCclusters->clusterIndex.clustersMCTruth; + for (int sector = 0; sector < 36; sector++) { + for (int row = 0; row < 152; row++) { + unsigned int offs = TPCClusterIdxStruct.clusterOffset[sector][row]; + for (unsigned int icl0 = 0; icl0 < TPCClusterIdxStruct.nClusters[sector][row]; icl0++) { + const auto labels = TPCClMClab->getLabels(icl0 + offs); + for (const auto& lbl : labels) { + auto entry = mSelMCTracks.find(lbl); + if (entry == mSelMCTracks.end()) { // not selected + continue; + } + auto& mctr = entry->second.mcTrackInfo; + mctr.nTPCCl++; + if (mctr.maxTPCRow < row) { + mctr.maxTPCRow = row; + } + if (mctr.minTPCRow > row) { + mctr.minTPCRow = row; + } + if (labels.size() > 1) { + mctr.nTPCClShared++; + } } - int lowestTPCRow = lowestPadrows[entITSTPC]; - const auto& trackITSTPC = recoData.getTPCITSTrack(vidMatch); - float timeTB = trackITSTPC.getTimeMUS().getTimeStamp() / o2::constants::lhc::LHCBunchSpacingMUS / 8; // ITS-TPC time in TPC timebins - - (*mDBGOut) << "match" - << "mcTr=" << mctrO2 - << "pdg=" << pdg - << "pdgPar=" << pdgParent - << "labelMatch=" << recoData.getTrackMCLabel(vidMatch) - << "labelTPC=" << recoData.getTrackMCLabel(vidTPC) - << "labelITS=" << itsLb - << "gidTPC=" << vidTPC - << "gidITS=" << vidITS - << "tpcOrig=" << trcTPCOrig - << "nClITS=" << itsNcls[entITSTPC] - << "itsPatt=" << itsPatterns[entITSTPC] - << "itstpc=" << ((o2::track::TrackParCov&)trackITSTPC) - << "matchChi2=" << trackITSTPC.getChi2Match() - << "refitChi2=" << trackITSTPC.getChi2Refit() - << "timeTB=" << timeTB - << "tpcLowestRow=" << lowestTPCRow - << "\n"; } - break; + } + } + // fill ITS cluster info + const auto* mcITSClusters = recoData.getITSClustersMCLabels(); + const auto& ITSClusters = recoData.getITSClusters(); + for (unsigned int icl = 0; icl < ITSClusters.size(); icl++) { + const auto labels = mcITSClusters->getLabels(icl); + for (const auto& lbl : labels) { + auto entry = mSelMCTracks.find(lbl); + if (entry == mSelMCTracks.end()) { // not selected + continue; + } + auto& mctr = entry->second.mcTrackInfo; + mctr.nITSCl++; + mctr.pattITSCl |= 0x1 << o2::itsmft::ChipMappingITS::getLayer(ITSClusters[icl].getChipID()); } } } @@ -498,7 +522,7 @@ void TrackMCStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) } //_____________________________________________________ -void TrackMCStudy::prepareITSData(o2::globaltracking::RecoContainer& recoData) +void TrackMCStudy::prepareITSData(const o2::globaltracking::RecoContainer& recoData) { auto ITSTracksArray = recoData.getITSTracks(); auto ITSTrackROFRec = recoData.getITSTracksROFRecords(); @@ -525,7 +549,167 @@ float TrackMCStudy::getDCAYCut(float pt) const return fun.Eval(pt); } -DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool checkMatching) +bool TrackMCStudy::processMCParticle(int src, int ev, int trid) +{ + const auto& mcPart = mCurrMCTracks[trid]; + int pdg = mcPart.GetPdgCode(); + bool res = false; + while (true) { + auto lbl = o2::MCCompLabel(trid, ev, src); + int decay = -1; // is this decay to watch? + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + if (mcPart.T() < params.decayMotherMaxT) { + for (int id = 0; id < mNCheckDecays; id++) { + if (params.decayPDG[id] == std::abs(pdg)) { + decay = id; + break; + } + } + if (decay >= 0) { // check if decay and kinematics is acceptable + int idd0 = mcPart.getFirstDaughterTrackId(), idd1 = mcPart.getLastDaughterTrackId(); // we want only charged and trackable daughters + int dtStart = mDecProdLblPool.size(), dtEnd = -1; + if (idd0 < 0) { + break; + } + for (int idd = idd0; idd <= idd1; idd++) { + const auto& product = mCurrMCTracks[idd]; + auto lbld = o2::MCCompLabel(idd, ev, src); + if (!acceptMCCharged(product, lbld, decay)) { + decay = -1; // discard decay + mDecProdLblPool.resize(dtStart); + break; + } + mDecProdLblPool.push_back(lbld); // register prong entry and label + } + if (decay >= 0) { + // account decay + dtEnd = mDecProdLblPool.size() - 1; + std::array xyz{(float)mcPart.GetStartVertexCoordinatesX(), (float)mcPart.GetStartVertexCoordinatesY(), (float)mcPart.GetStartVertexCoordinatesZ()}; + std::array pxyz{(float)mcPart.GetStartVertexMomentumX(), (float)mcPart.GetStartVertexMomentumY(), (float)mcPart.GetStartVertexMomentumZ()}; + mDecaysMaps[decay].emplace_back(DecayRef{lbl, + o2::track::TrackPar(xyz, pxyz, TMath::Nint(O2DatabasePDG::Instance()->GetParticle(mcPart.GetPdgCode())->Charge() / 3), false), + mcPart.GetPdgCode(), dtStart, dtEnd}); + if (mVerbose > 1) { + LOGP(info, "Adding MC parent pdg={} {}, with prongs in {}:{} range", pdg, lbl.asString(), dtStart, dtEnd); + } + res = true; // Accept! + } + break; + } + } + // check if this is a charged which should be processed but was not accounted as a decay product + if (mSelMCTracks.find(lbl) == mSelMCTracks.end()) { + res = acceptMCCharged(mcPart, lbl); + } + break; + } + return res; +} + +bool TrackMCStudy::acceptMCCharged(const MCTrack& tr, const o2::MCCompLabel& lb, int followDecay) +{ + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + if (tr.GetPt() < params.minPtMC || + std::abs(tr.GetTgl()) > params.maxTglMC || + tr.R2() > params.minRMC * params.minRMC) { + if (mVerbose > 1 && followDecay > -1) { + LOGP(info, "rejecting decay {} prong : pdg={}, pT={}, tgL={}, r={}", followDecay, tr.GetPdgCode(), tr.GetPt(), tr.GetTgl(), std::sqrt(tr.R2())); + } + return false; + } + float dx = tr.GetStartVertexCoordinatesX() - mCurrMCVertex.X(), dy = tr.GetStartVertexCoordinatesY() - mCurrMCVertex.Y(), dz = tr.GetStartVertexCoordinatesZ() - mCurrMCVertex.Z(); + float r2 = dx * dx + dy * dy; + float posTgl2 = r2 > 1 && std::abs(dz) < 20 ? dz * dz / r2 : 0; + if (posTgl2 > params.maxPosTglMC * params.maxPosTglMC) { + if (mVerbose > 1 && followDecay > -1) { + LOGP(info, "rejecting decay {} prong : pdg={}, pT={}, tgL={}, dr={}, dz={} r={}, z={}, posTgl={}", followDecay, tr.GetPdgCode(), tr.GetPt(), tr.GetTgl(), std::sqrt(r2), dz, std::sqrt(tr.R2()), tr.GetStartVertexCoordinatesZ(), std::sqrt(posTgl2)); + } + return false; + } + if (params.requireITSorTPCTrackRefs) { + auto trspan = mcReader.getTrackRefs(lb.getSourceID(), lb.getEventID(), lb.getTrackID()); + bool ok = false; + for (const auto& trf : trspan) { + if (trf.getDetectorId() == DetID::ITS || trf.getDetectorId() == DetID::TPC) { + ok = true; + break; + } + } + if (!ok) { + return false; + } + } + TParticlePDG* pPDG = O2DatabasePDG::Instance()->GetParticle(tr.GetPdgCode()); + if (!pPDG) { + LOGP(debug, "Unknown particle {}", tr.GetPdgCode()); + return false; + } + if (pPDG->Charge() == 0.) { + return false; + } + return addMCParticle(tr, lb, pPDG); +} + +bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& lb, TParticlePDG* pPDG) +{ + std::array xyz{(float)mcPart.GetStartVertexCoordinatesX(), (float)mcPart.GetStartVertexCoordinatesY(), (float)mcPart.GetStartVertexCoordinatesZ()}; + std::array pxyz{(float)mcPart.GetStartVertexMomentumX(), (float)mcPart.GetStartVertexMomentumY(), (float)mcPart.GetStartVertexMomentumZ()}; + if (!pPDG && !(pPDG = O2DatabasePDG::Instance()->GetParticle(mcPart.GetPdgCode()))) { + LOGP(debug, "Unknown particle {}", mcPart.GetPdgCode()); + return false; + } + auto& mcEntry = mSelMCTracks[lb]; + mcEntry.mcTrackInfo.pdg = mcPart.GetPdgCode(); + mcEntry.mcTrackInfo.track = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); + mcEntry.mcTrackInfo.label = lb; + mcEntry.mcTrackInfo.bcInTF = mIntBC[lb.getEventID()]; + mcEntry.mcTrackInfo.occTPC = mTPCOcc[lb.getEventID()]; + int moth = -1; + o2::MCCompLabel mclbPar; + if (!mcPart.isPrimary() && (moth = mcPart.getMotherTrackId()) >= 0) { + const auto& mcPartPar = mCurrMCTracks[moth]; + mcEntry.mcTrackInfo.pdgParent = mcPartPar.GetPdgCode(); + } + if (mVerbose > 1) { + LOGP(info, "Adding charged MC pdg={} {} ", mcPart.GetPdgCode(), lb.asString()); + } + return true; +} + +void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoData) +{ + auto NHBPerTF = o2::base::GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); + o2::tpc::CorrectionMapsLoader TPCCorrMapsLoader{}; + const auto& TPCOccMap = recoData.occupancyMapTPC; + auto prop = o2::base::Propagator::Instance(); + auto TPCRefitter = std::make_unique(&recoData.inputsTPCclusters->clusterIndex, &TPCCorrMapsLoader, prop->getNominalBz(), + recoData.getTPCTracksClusterRefs().data(), 0, recoData.clusterShMapTPC.data(), TPCOccMap.data(), TPCOccMap.size(), nullptr, prop); + mNTPCOccBinLength = TPCRefitter->getParam()->rec.tpc.occupancyMapTimeBins; + mTBinClOcc.clear(); + if (mNTPCOccBinLength > 1 && TPCOccMap.size()) { + mNTPCOccBinLengthInv = 1. / mNTPCOccBinLength; + int nTPCBins = NHBPerTF * o2::constants::lhc::LHCMaxBunches / 8, ninteg = 0; + int nTPCOccBins = nTPCBins * mNTPCOccBinLengthInv, sumBins = std::max(1, int(o2::constants::lhc::LHCMaxBunches / 8 * mNTPCOccBinLengthInv)); + mTBinClOcc.resize(nTPCOccBins); + std::vector mltHistTB(nTPCOccBins); + float sm = 0., tb = 0.5 * mNTPCOccBinLength; + for (int i = 0; i < nTPCOccBins; i++) { + mltHistTB[i] = TPCRefitter->getParam()->GetUnscaledMult(tb); + tb += mNTPCOccBinLength; + } + for (int i = nTPCOccBins; i--;) { + sm += mltHistTB[i]; + if (i + sumBins < nTPCOccBins) { + sm -= mltHistTB[i + sumBins]; + } + mTBinClOcc[i] = sm; + } + } else { + mTBinClOcc.resize(1); + } +} + +DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters) { std::vector outputs; auto dataRequest = std::make_shared(); @@ -548,15 +732,13 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask "track-mc-study", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks, checkMatching)}, + AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks)}, Options{ {"device-verbosity", VariantType::Int, 0, {"Verbosity level"}}, {"dcay-vs-pt", VariantType::String, "0.0105 + 0.0350 / pow(x, 1.1)", {"Formula for global tracks DCAy vs pT cut"}}, {"min-tpc-clusters", VariantType::Int, 60, {"Cut on TPC clusters"}}, {"max-tpc-dcay", VariantType::Float, 2.f, {"Cut on TPC dcaY"}}, {"max-tpc-dcaz", VariantType::Float, 2.f, {"Cut on TPC dcaZ"}}, - {"max-eta", VariantType::Float, 1.5f, {"Cut on track eta"}}, - {"min-pt", VariantType::Float, 0.02f, {"Cut on track pT"}}, {"min-x-prop", VariantType::Float, 6.f, {"track should be propagated to this X at least"}}, }}; } diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyConfig.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyConfig.cxx new file mode 100644 index 0000000000000..300e69c514ae3 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyConfig.cxx @@ -0,0 +1,14 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "GlobalTrackingStudy/TrackMCStudyConfig.h" + +O2ParamImpl(o2::trackstudy::TrackMCStudyConfig); diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx new file mode 100644 index 0000000000000..b95fda9699420 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx @@ -0,0 +1,12 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "GlobalTrackingStudy/TrackMCStudyTypes.h" diff --git a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx index 93e549dcc2ef3..3674fd5f3e3a8 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx @@ -40,7 +40,6 @@ void customize(std::vector& workflowOptions) {"cluster-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of cluster sources to use"}}, {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation, never use it"}}, - {"check-its-tpc", VariantType::Bool, false, {"Special output for failed ITS-TPC matches"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; o2::raw::HBFUtilsInitializer::addConfigOption(options); std::swap(workflowOptions, options); @@ -57,22 +56,19 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (!useMC) { throw std::runtime_error("MC cannot be disabled for this workflow"); } - bool checkMatching = configcontext.options().get("check-its-tpc"); GID::mask_t allowedSourcesTrc = GID::getSourcesMask("ITS,TPC,ITS-TPC,TPC-TOF,TPC-TRD,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF"); - GID::mask_t allowedSourcesClus = GID::getSourcesMask(checkMatching ? "TPC" : "none"); + GID::mask_t allowedSourcesClus = GID::getSourcesMask("ITS,TPC"); // Update the (declared) parameters if changed from the command line o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); GID::mask_t srcTrc = allowedSourcesTrc & GID::getSourcesMask(configcontext.options().get("track-sources")); GID::mask_t srcCls = allowedSourcesClus & GID::getSourcesMask(configcontext.options().get("cluster-sources")); - if (checkMatching) { - srcCls |= GID::getSourcesMask("TPC"); - } + srcCls |= GID::getSourcesMask("ITS,TPC"); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, true); // P-vertex is always needed - specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, checkMatching)); + specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls)); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); From 46615df968a4f34d3c96cf2320044eb7095b7893 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 28 Aug 2024 09:11:58 +0200 Subject: [PATCH 0214/2205] ITS3: Move to tracking interface Signed-off-by: Felix Schlepper --- .../ITS3/reconstruction/CMakeLists.txt | 10 +- .../ITS3Reconstruction/TrackingInterface.h | 42 +++ .../ITS3/reconstruction/src/IOUtils.cxx | 3 + .../reconstruction/src/TrackingInterface.cxx | 74 ++++ .../Upgrades/ITS3/workflow/CMakeLists.txt | 2 +- .../include/ITS3Workflow/TrackerSpec.h | 52 ++- .../ITS3/workflow/src/TrackerSpec.cxx | 355 ++---------------- 7 files changed, 190 insertions(+), 348 deletions(-) create mode 100644 Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TrackingInterface.h create mode 100644 Detectors/Upgrades/ITS3/reconstruction/src/TrackingInterface.cxx diff --git a/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt b/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt index 128e145b31317..a666e15cc21e4 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/reconstruction/CMakeLists.txt @@ -19,7 +19,6 @@ o2_add_library(ITS3Reconstruction src/BuildTopologyDictionary.cxx src/LookUp.cxx src/IOUtils.cxx - # src/FastMultEst.cxx PUBLIC_LINK_LIBRARIES O2::ITSMFTBase O2::ITSMFTReconstruction O2::ITS3Base @@ -41,6 +40,15 @@ o2_target_root_dictionary( include/ITS3Reconstruction/IOUtils.h ) +o2_add_library(ITS3TrackingInterface + TARGETVARNAME targetName + SOURCES src/TrackingInterface.cxx + PRIVATE_LINK_LIBRARIES + O2::ITS3Reconstruction + O2::ITSTrackingInterface + O2::Framework + O2::GPUTracking) + if (OpenMP_CXX_FOUND) target_compile_definitions(${targetName} PRIVATE WITH_OPENMP) target_link_libraries(${targetName} PRIVATE OpenMP::OpenMP_CXX) diff --git a/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TrackingInterface.h b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TrackingInterface.h new file mode 100644 index 0000000000000..ab2ff0086200b --- /dev/null +++ b/Detectors/Upgrades/ITS3/reconstruction/include/ITS3Reconstruction/TrackingInterface.h @@ -0,0 +1,42 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_ITS3_TRACKINGINTERFACE +#define O2_ITS3_TRACKINGINTERFACE + +#include "ITStracking/TrackingInterface.h" +#include "ITS3Reconstruction/TopologyDictionary.h" + +namespace o2::its3 +{ + +class ITS3TrackingInterface final : public its::ITSTrackingInterface +{ + public: + using its::ITSTrackingInterface::ITSTrackingInterface; + + void setClusterDictionary(const o2::its3::TopologyDictionary* d) { mDict = d; } + void updateTimeDependentParams(framework::ProcessingContext& pc) final; + void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final; + + protected: + void loadROF(gsl::span& trackROFspan, + gsl::span clusters, + gsl::span::iterator& pattIt, + const dataformats::MCTruthContainer* mcLabels) final; + + private: + const o2::its3::TopologyDictionary* mDict{nullptr}; +}; + +} // namespace o2::its3 + +#endif diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx index f4cf31deb1ef8..50e651f7f5675 100644 --- a/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx +++ b/Detectors/Upgrades/ITS3/reconstruction/src/IOUtils.cxx @@ -119,6 +119,9 @@ int loadROFrameDataITS3(its::TimeFrame* tf, for (auto& v : tf->mNTrackletsPerCluster) { v.resize(tf->getUnsortedClusters()[1].size()); } + for (auto& v : tf->mNTrackletsPerClusterSum) { + v.resize(tf->getUnsortedClusters()[1].size() + 1); + } if (mcLabels != nullptr) { tf->mClusterLabels = mcLabels; diff --git a/Detectors/Upgrades/ITS3/reconstruction/src/TrackingInterface.cxx b/Detectors/Upgrades/ITS3/reconstruction/src/TrackingInterface.cxx new file mode 100644 index 0000000000000..10c6b9265a8bb --- /dev/null +++ b/Detectors/Upgrades/ITS3/reconstruction/src/TrackingInterface.cxx @@ -0,0 +1,74 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITS3Reconstruction/TrackingInterface.h" +#include "ITS3Reconstruction/IOUtils.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITSMFTBase/DPLAlpideParam.h" +#include "DetectorsBase/GRPGeomHelper.h" + +namespace o2::its3 +{ + +void ITS3TrackingInterface::updateTimeDependentParams(framework::ProcessingContext& pc) +{ + o2::base::GRPGeomHelper::instance().checkUpdates(pc); + static bool initOnceDone = false; + if (!initOnceDone) { // this params need to be queried only once + initOnceDone = true; + pc.inputs().get("cldict"); // just to trigger the finaliseCCDB + pc.inputs().get*>("alppar"); + if (pc.inputs().getPos("itsTGeo") >= 0) { + pc.inputs().get("itsTGeo"); + } + auto geom = its::GeometryTGeo::Instance(); + geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); + getConfiguration(pc); + } +} + +void ITS3TrackingInterface::finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) +{ + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } + if (matcher == framework::ConcreteDataMatcher("IT3", "CLUSDICT", 0)) { + LOG(info) << "cluster dictionary updated"; + setClusterDictionary((const o2::its3::TopologyDictionary*)obj); + return; + } + if (matcher == framework::ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) { + LOG(info) << "Alpide param updated"; + const auto& par = o2::itsmft::DPLAlpideParam::Instance(); + par.printKeyValues(); + return; + } + if (matcher == framework::ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) { + LOGP(info, "Mean vertex acquired"); + setMeanVertex((const o2::dataformats::MeanVertexObject*)obj); + return; + } + if (matcher == framework::ConcreteDataMatcher("ITS", "GEOMTGEO", 0)) { + LOG(info) << "ITS GeometryTGeo loaded from ccdb"; + o2::its::GeometryTGeo::adopt((o2::its::GeometryTGeo*)obj); + return; + } +} + +void ITS3TrackingInterface::loadROF(gsl::span& trackROFspan, + gsl::span clusters, + gsl::span::iterator& pattIt, + const dataformats::MCTruthContainer* mcLabels) +{ + ioutils::loadROFrameDataITS3(mTimeFrame, trackROFspan, clusters, pattIt, mDict, mcLabels); +} + +} // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt b/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt index c4867f0e94ec1..649e4d737d42c 100644 --- a/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt +++ b/Detectors/Upgrades/ITS3/workflow/CMakeLists.txt @@ -19,7 +19,6 @@ o2_add_library(ITS3Workflow src/ClustererSpec.cxx src/ClusterWriterSpec.cxx src/TrackerSpec.cxx - # src/CookedTrackerSpec.cxx src/TrackWriterSpec.cxx src/TrackReaderSpec.cxx src/VertexReaderSpec.cxx @@ -31,6 +30,7 @@ o2_add_library(ITS3Workflow O2::ITStracking O2::ITSMFTReconstruction O2::ITS3Reconstruction + O2::ITS3TrackingInterface O2::ITSWorkflow O2::GPUTracking O2::ITSBase) diff --git a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h index f350c09b0192c..f5c1d7bf0e947 100644 --- a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h +++ b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/TrackerSpec.h @@ -15,57 +15,55 @@ #define O2_ITS3_TRACKERDPL #include "DataFormatsParameters/GRPObject.h" -#include "ITS3Reconstruction/TopologyDictionary.h" +#include "DataFormatsITSMFT/TopologyDictionary.h" +#include "DataFormatsCalibration/MeanVertexObject.h" #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" -#include "ITStracking/TimeFrame.h" -#include "ITStracking/Tracker.h" -#include "ITStracking/TrackerTraits.h" -#include "ITStracking/Vertexer.h" -#include "ITStracking/VertexerTraits.h" +#include "ITS3Reconstruction/TrackingInterface.h" -#include "GPUO2Interface.h" -#include "GPUReconstruction.h" -#include "GPUChainITS.h" -#include "CommonUtils/StringUtils.h" -#include "TStopwatch.h" +#include "GPUDataTypes.h" #include "DetectorsBase/GRPGeomHelper.h" +#include "TStopwatch.h" + namespace o2::its3 { class TrackerDPL : public framework::Task { public: - TrackerDPL(std::shared_ptr gr, bool isMC, int trgType, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType = o2::gpu::GPUDataTypes::DeviceType::CPU); + TrackerDPL(std::shared_ptr gr, + bool isMC, + int trgType, + const its::TrackingMode& trMode = its::TrackingMode::Unset, + const bool overrBeamEst = false, + gpu::GPUDataTypes::DeviceType dType = gpu::GPUDataTypes::DeviceType::CPU); + ~TrackerDPL() override = default; + TrackerDPL(const TrackerDPL&) = delete; + TrackerDPL(TrackerDPL&&) = delete; + TrackerDPL& operator=(const TrackerDPL&) = delete; + TrackerDPL& operator=(TrackerDPL&&) = delete; + void init(framework::InitContext& ic) final; void run(framework::ProcessingContext& pc) final; void endOfStream(framework::EndOfStreamContext& ec) final; void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final; - void setClusterDictionary(const o2::its3::TopologyDictionary* d) { mDict = d; } + void stop() final; private: void updateTimeDependentParams(framework::ProcessingContext& pc); - - std::shared_ptr mGGCCDBRequest{}; - bool mIsMC{false}; - int mUseTriggers{0}; - std::string mMode{"sync"}; - std::unique_ptr mRecChain{}; - bool mRunVertexer{true}; - bool mCosmicsProcessing{false}; - const o2::its3::TopologyDictionary* mDict{}; - std::unique_ptr mChainITS{}; - std::unique_ptr mTracker{}; - std::unique_ptr mVertexer{}; - TStopwatch mTimer{}; + std::unique_ptr mRecChain = nullptr; + std::unique_ptr mChainITS = nullptr; + std::shared_ptr mGGCCDBRequest; + ITS3TrackingInterface mITS3TrackingInterface; + TStopwatch mTimer; }; /// create a processor spec /// run ITS CA tracker -framework::DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, int useTrig, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType); +framework::DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, int useTrig, const std::string& trMode, const bool overrBeamEst = false, gpu::GPUDataTypes::DeviceType dType = gpu::GPUDataTypes::DeviceType::CPU); } // namespace o2::its3 diff --git a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx index cc0cbcf333dd3..90f94e625d6ea 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/TrackerSpec.cxx @@ -46,346 +46,57 @@ namespace its3 { using Vertex = o2::dataformats::Vertex>; -TrackerDPL::TrackerDPL(std::shared_ptr gr, bool isMC, int trgType, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) : mGGCCDBRequest(gr), mIsMC{isMC}, mUseTriggers{trgType}, mMode{trModeS}, mRecChain{o2::gpu::GPUReconstruction::CreateInstance(dType, true)} +TrackerDPL::TrackerDPL(std::shared_ptr gr, + bool isMC, + int trgType, + const its::TrackingMode& trMode, + const bool overrBeamEst, + o2::gpu::GPUDataTypes::DeviceType dType) : mGGCCDBRequest(gr), + mRecChain{o2::gpu::GPUReconstruction::CreateInstance(dType, true)}, + mITS3TrackingInterface{isMC, trgType, overrBeamEst} { - std::transform(mMode.begin(), mMode.end(), mMode.begin(), [](unsigned char c) { return std::tolower(c); }); + mITS3TrackingInterface.setTrackingMode(trMode); } -void TrackerDPL::init(InitContext& /*ic*/) +void TrackerDPL::init(InitContext& ic) { mTimer.Stop(); mTimer.Reset(); - o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); - mChainITS.reset(mRecChain->AddChain()); - mVertexer = std::make_unique(mChainITS->GetITSVertexerTraits()); - mTracker = std::make_unique(mChainITS->GetITSTrackerTraits()); - mRunVertexer = true; - mCosmicsProcessing = false; - std::vector trackParams; - - if (mMode == "async") { - - trackParams.resize(3); - trackParams[1].TrackletMinPt = 0.2f; - trackParams[1].CellDeltaTanLambdaSigma *= 2.; - trackParams[2].TrackletMinPt = 0.1f; - trackParams[2].CellDeltaTanLambdaSigma *= 4.; - trackParams[2].MinTrackLength = 4; - - LOG(info) << "Initializing tracker in async. phase reconstruction with " << trackParams.size() << " passes"; - - } else if (mMode == "async_misaligned") { - - trackParams.resize(3); - trackParams[0].PhiBins = 32; - trackParams[0].ZBins = 64; - trackParams[0].CellDeltaTanLambdaSigma *= 3.; - trackParams[0].SystErrorZ2[0] = 1.e-4; - trackParams[0].SystErrorZ2[1] = 1.e-4; - trackParams[0].SystErrorZ2[2] = 1.e-4; - std::copy(trackParams[0].SystErrorZ2.begin(), trackParams[0].SystErrorZ2.end(), trackParams[0].SystErrorY2.begin()); - trackParams[0].MaxChi2ClusterAttachment = 60.; - trackParams[0].MaxChi2NDF = 40.; - trackParams[1] = trackParams[0]; - trackParams[2] = trackParams[0]; - trackParams[1].MinTrackLength = 6; - trackParams[2].MinTrackLength = 4; - LOG(info) << "Initializing tracker in misaligned async. phase reconstruction with " << trackParams.size() << " passes"; - - } else if (mMode == "sync_misaligned") { - - trackParams.resize(3); - trackParams[0].PhiBins = 32; - trackParams[0].ZBins = 64; - trackParams[0].CellDeltaTanLambdaSigma *= 3.; - trackParams[0].SystErrorZ2[0] = 1.e-4; - trackParams[0].SystErrorZ2[1] = 1.e-4; - trackParams[0].SystErrorZ2[2] = 1.e-4; - trackParams[0].SystErrorZ2[3] = 9.e-4; - trackParams[0].SystErrorZ2[4] = 9.e-4; - trackParams[0].SystErrorZ2[5] = 9.e-4; - trackParams[0].SystErrorZ2[6] = 9.e-4; - std::copy(trackParams[0].SystErrorZ2.begin(), trackParams[0].SystErrorZ2.end(), trackParams[0].SystErrorY2.begin()); - trackParams[0].MaxChi2ClusterAttachment = 60.; - trackParams[0].MaxChi2NDF = 40.; - trackParams[1] = trackParams[0]; - trackParams[2] = trackParams[0]; - trackParams[1].MinTrackLength = 6; - trackParams[2].MinTrackLength = 4; - LOG(info) << "Initializing tracker in misaligned sync. phase reconstruction with " << trackParams.size() << " passes"; - - } else if (mMode == "sync") { - trackParams.resize(1); - LOG(info) << "Initializing tracker in sync. phase reconstruction with " << trackParams.size() << " passes"; - } else if (mMode == "cosmics") { - mCosmicsProcessing = true; - mRunVertexer = false; - trackParams.resize(1); - trackParams[0].MinTrackLength = 4; - trackParams[0].CellDeltaTanLambdaSigma *= 10; - trackParams[0].PhiBins = 4; - trackParams[0].ZBins = 16; - trackParams[0].PVres = 1.e5f; - trackParams[0].MaxChi2ClusterAttachment = 60.; - trackParams[0].MaxChi2NDF = 40.; - trackParams[0].TrackletsPerClusterLimit = 100.; - trackParams[0].CellsPerClusterLimit = 100.; - LOG(info) << "Initializing tracker in reconstruction for cosmics with " << trackParams.size() << " passes"; - - } else { - throw std::runtime_error(fmt::format("Unsupported ITS tracking mode {:s} ", mMode)); - } - - for (auto& params : trackParams) { - params.CorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT; - for (int iLayer{0}; iLayer < params.NLayers - 4; ++iLayer) { // initialise ITS3 radii and lengths - params.LayerZ[iLayer] = constants::segment::lengthSensitive; - params.LayerRadii[iLayer] = constants::radii[iLayer]; - } - } + mITS3TrackingInterface.setTraitsFromProvider(mChainITS->GetITSVertexerTraits(), + mChainITS->GetITSTrackerTraits(), + mChainITS->GetITSTimeframe()); + mITS3TrackingInterface.initialise(); +} - mTracker->setParameters(trackParams); +void TrackerDPL::stop() +{ + LOGF(info, "CPU Reconstruction total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } void TrackerDPL::run(ProcessingContext& pc) { + auto cput = mTimer.CpuTime(); + auto realt = mTimer.RealTime(); mTimer.Start(false); - updateTimeDependentParams(pc); - auto compClusters = pc.inputs().get>("compClusters"); - gsl::span patterns = pc.inputs().get>("patterns"); - gsl::span physTriggers; - std::vector fromTRD; - if (mUseTriggers == 2) { // use TRD triggers - o2::InteractionRecord ir{0, pc.services().get().firstTForbit}; - auto trdTriggers = pc.inputs().get>("phystrig"); - for (const auto& trig : trdTriggers) { - if (trig.getBCData() >= ir && trig.getNumberOfTracklets()) { - ir = trig.getBCData(); - fromTRD.emplace_back(o2::itsmft::PhysTrigger{ir, 0}); - } - } - physTriggers = gsl::span(fromTRD.data(), fromTRD.size()); - } else if (mUseTriggers == 1) { // use Phys triggers from ITS stream - physTriggers = pc.inputs().get>("phystrig"); - } - - // code further down does assignment to the rofs and the altered object is used for output - // we therefore need a copy of the vector rather than an object created directly on the input data, - // the output vector however is created directly inside the message memory thus avoiding copy by - // snapshot - auto orig = o2::header::gDataOriginITS; - auto rofsinput = pc.inputs().get>("ROframes"); - auto& rofs = pc.outputs().make>(Output{orig, "ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end()); - - auto& irFrames = pc.outputs().make>(Output{orig, "IRFRAMES", 0}); - - const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); // RS: this should come from CCDB - int nBCPerTF = alpParams.roFrameLengthInBC; - - LOG(info) << "ITS3Tracker pulled " << compClusters.size() << " clusters, " << rofs.size() << " RO frames"; - - const dataformats::MCTruthContainer* labels = nullptr; - gsl::span mc2rofs; - if (mIsMC) { - labels = pc.inputs().get*>("labels").release(); - // get the array as read-only span, a snapshot is send forward - mc2rofs = pc.inputs().get>("MC2ROframes"); - LOG(info) << labels->getIndexedSize() << " MC label objects , in " << mc2rofs.size() << " MC events"; - } - - auto& allClusIdx = pc.outputs().make>(Output{orig, "TRACKCLSID", 0}); - std::vector trackLabels; - std::vector verticesLabels; - auto& allTracks = pc.outputs().make>(Output{orig, "TRACKS", 0}); - std::vector allTrackLabels; - std::vector allVerticesLabels; - std::vector allVerticesPurities; - - auto& vertROFvec = pc.outputs().make>(Output{orig, "VERTICESROF", 0}); - auto& vertices = pc.outputs().make>(Output{orig, "VERTICES", 0}); - - TimeFrame* timeFrame = mChainITS->GetITSTimeframe(); - timeFrame->resizeVectors(7); - mTracker->adoptTimeFrame(*timeFrame); - - mTracker->setBz(o2::base::Propagator::Instance()->getNominalBz()); - mVertexer->adoptTimeFrame(*timeFrame); - auto pattIt = patterns.begin(); - - const gsl::span rofspan(rofs); - ioutils::loadROFrameDataITS3(timeFrame, rofspan, compClusters, pattIt, mDict, labels); - std::vector savedROF; - auto logger = [&](const std::string& s) { LOG(info) << s; }; - auto errorLogger = [&](const std::string& s) { LOG(error) << s; }; - - // o2::its3::FastMultEst multEst; // mult estimator - std::vector processingMask(rofs.size(), true); // Override mult estimator - int cutVertexMult{0}; - // int cutRandomMult = int(rofs.size()) - multEst.selectROFs(rofs, compClusters, physTriggers, processingMask); - timeFrame->setMultiplicityCutMask(processingMask); - float vertexerElapsedTime{0.f}; - if (mRunVertexer) { - // Run seeding vertexer - vertexerElapsedTime = mVertexer->clustersToVertices(logger); - } - const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts - gsl::span> vMCRecInfo; - for (size_t iRof{0}; iRof < rofspan.size(); ++iRof) { - std::vector vtxVecLoc; - auto& vtxROF = vertROFvec.emplace_back(rofspan[iRof]); - vtxROF.setFirstEntry(vertices.size()); - if (mRunVertexer) { - auto vtxSpan = timeFrame->getPrimaryVertices(iRof); - if (mIsMC) { - vMCRecInfo = timeFrame->getPrimaryVerticesMCRecInfo(iRof); - } - vtxROF.setNEntries(vtxSpan.size()); - bool selROF = vtxSpan.size() == 0; - for (size_t iV{0}; iV < vtxSpan.size(); ++iV) { - auto& v = vtxSpan[iV]; - if (multEstConf.isVtxMultCutRequested() && !multEstConf.isPassingVtxMultCut(v.getNContributors())) { - continue; // skip vertex of unwanted multiplicity - } - selROF = true; - vertices.push_back(v); - if (mIsMC) { - allVerticesLabels.push_back(vMCRecInfo[iV].first); - allVerticesPurities.push_back(vMCRecInfo[iV].second); - } - } - if (processingMask[iRof] && !selROF) { // passed selection in clusters and not in vertex multiplicity - // LOG(debug) << fmt::format("ROF {} rejected by the vertex multiplicity selection [{},{}]", - // iRof, - // multEstConf.cutMultVtxLow, - // multEstConf.cutMultVtxHigh); - processingMask[iRof] = selROF; - cutVertexMult++; - } - } else { // cosmics - vtxVecLoc.emplace_back(Vertex()); - vtxVecLoc.back().setNContributors(1); - vtxROF.setNEntries(vtxVecLoc.size()); - for (auto& v : vtxVecLoc) { - vertices.push_back(v); - } - timeFrame->addPrimaryVertices(vtxVecLoc, iRof, 0); - } - } - // LOG(info) << fmt::format(" - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}", cutRandomMult + cutVertexMult, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult); - LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms for {} vertices found in {} ROFs", vertexerElapsedTime, timeFrame->getPrimaryVerticesNum(), rofspan.size()); - LOG(info) << fmt::format(" - Beam position computed for the TF: {}, {}", timeFrame->getBeamX(), timeFrame->getBeamY()); - - if (mCosmicsProcessing && compClusters.size() > 1500 * rofspan.size()) { - LOG(error) << "Cosmics processing was requested with an average detector occupancy exceeding 1.e-7, skipping TF processing."; - } else { - - timeFrame->setMultiplicityCutMask(processingMask); - // Run CA tracker - mTracker->clustersToTracks(logger, errorLogger); - if (timeFrame->hasBogusClusters() != 0) { - LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", timeFrame->hasBogusClusters()); - } - - for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) { - auto& rof{rofs[iROF]}; - auto& tracks = timeFrame->getTracks(iROF); - trackLabels = timeFrame->getTracksLabel(iROF); - auto number{tracks.size()}; - auto first{allTracks.size()}; - rof.setFirstEntry(first); - rof.setNEntries(number); - if (processingMask[iROF]) { - irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size(); - } - - std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels)); - // Some conversions that needs to be moved in the tracker internals - for (unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) { - auto& trc{tracks[iTrk]}; - trc.setFirstClusterEntry(allClusIdx.size()); // before adding tracks, create final cluster indices - int nclf = 0, ncl = (int)allClusIdx.size(); - for (int ic = TrackITSExt::MaxClusters; (ic--) != 0;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!! - auto clid = trc.getClusterIndex(ic); - if (clid >= 0) { - trc.setClusterSize(ic, timeFrame->getClusterSize(clid)); - allClusIdx.push_back(clid); - nclf++; - } - } - assert(ncl == nclf); - allTracks.emplace_back(trc); - } - } - - LOGP(info, "ITS3Tracker pushed {} tracks and {} vertices", allTracks.size(), vertices.size()); - if (mIsMC) { - LOGP(info, "ITS3Tracker pushed {} track labels", allTrackLabels.size()); - LOGP(info, "ITS3Tracker pushed {} vertex labels", allVerticesLabels.size()); - - pc.outputs().snapshot(Output{orig, "TRACKSMCTR", 0}, allTrackLabels); - pc.outputs().snapshot(Output{orig, "VERTICESMCTR", 0}, allVerticesLabels); - pc.outputs().snapshot(Output{orig, "VERTICESMCPUR", 0}, allVerticesPurities); - pc.outputs().snapshot(Output{orig, "ITSTrackMC2ROF", 0}, mc2rofs); - } - } + mITS3TrackingInterface.updateTimeDependentParams(pc); + mITS3TrackingInterface.run(pc); mTimer.Stop(); + LOGP(info, "CPU Reconstruction time for this TF {} s (cpu), {} s (wall)", mTimer.CpuTime() - cput, mTimer.RealTime() - realt); } -///_______________________________________ -void TrackerDPL::updateTimeDependentParams(ProcessingContext& pc) -{ - o2::base::GRPGeomHelper::instance().checkUpdates(pc); - static bool initOnceDone = false; - if (!initOnceDone) { // this params need to be queried only once - initOnceDone = true; - pc.inputs().get("cldict"); // just to trigger the finaliseCCDB - pc.inputs().get*>("alppar"); - - // Check if lightweight geometry was requested, otherwise full geometry is loaded - if (pc.inputs().getPos("itsTGeo") >= 0) { - pc.inputs().get("itsTGeo"); - } - o2::its::GeometryTGeo* geom = o2::its::GeometryTGeo::Instance(); - geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); - mVertexer->getGlobalConfiguration(); - mTracker->getGlobalConfiguration(); - } -} - -///_______________________________________ void TrackerDPL::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { - if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { - return; - } - if (matcher == ConcreteDataMatcher("IT3", "CLUSDICT", 0)) { - LOG(info) << "cluster dictionary updated"; - setClusterDictionary((o2::its3::TopologyDictionary*)obj); - return; - } - if (matcher == ConcreteDataMatcher("ITS", "GEOMTGEO", 0)) { - LOG(info) << "IT3 GeometryTGeo loaded from ccdb"; - o2::its::GeometryTGeo::adopt((o2::its::GeometryTGeo*)obj); - return; - } - // Note: strictly speaking, for Configurable params we don't need finaliseCCDB check, the singletons are updated at the CCDB fetcher level - if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) { - LOG(info) << "Alpide param updated"; - const auto& par = o2::itsmft::DPLAlpideParam::Instance(); - par.printKeyValues(); - return; - } + mITS3TrackingInterface.finaliseCCDB(matcher, obj); } void TrackerDPL::endOfStream(EndOfStreamContext& ec) { - LOGF(info, "ITS3 CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", - mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); + LOGF(info, "ITS3 CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, const std::string& trModeS, o2::gpu::GPUDataTypes::DeviceType dType) +DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, int trgType, const std::string& trModeS, const bool overrBeamEst, o2::gpu::GPUDataTypes::DeviceType dType) { std::vector inputs; inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe); @@ -399,7 +110,7 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, co inputs.emplace_back("cldict", "IT3", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/ClusterDictionary")); inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")); auto ggRequest = std::make_shared(false, // orbitResetTime - false, // GRPECS + true, // GRPECS false, // GRPLHCIF true, // GRPMagField true, // askMatLUT @@ -410,6 +121,9 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, co if (!useGeom) { // load light-weight geometry inputs.emplace_back("itsTGeo", "ITS", "GEOMTGEO", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/Geometry")); } + if (overrBeamEst) { + inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1)); + } std::vector outputs; outputs.emplace_back("ITS", "TRACKS", 0, Lifetime::Timeframe); @@ -420,8 +134,8 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, co outputs.emplace_back("ITS", "IRFRAMES", 0, Lifetime::Timeframe); if (useMC) { - inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); - inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); + inputs.emplace_back("itsmclabels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe); + inputs.emplace_back("ITSMC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "VERTICESMCTR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "VERTICESMCPUR", 0, Lifetime::Timeframe); outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe); @@ -432,7 +146,10 @@ DataProcessorSpec getTrackerSpec(bool useMC, bool useGeom, const int trgType, co "its3-tracker", inputs, outputs, - AlgorithmSpec{adaptFromTask(ggRequest, useMC, trgType, trModeS, dType)}, + AlgorithmSpec{adaptFromTask(ggRequest, useMC, trgType, + trModeS == "sync" ? o2::its::TrackingMode::Sync : trModeS == "async" ? o2::its::TrackingMode::Async + : o2::its::TrackingMode::Cosmics, + overrBeamEst, dType)}, Options{}}; } From 44df33bf1351061356621a03bdd233736375762c Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 9 Sep 2024 13:35:19 +0200 Subject: [PATCH 0215/2205] Possibility to limit raw data dumps from ITS/MFT decoder 1) If argument of --raw-data-dumps is negative, the dumps will be allowed only from 1st decoded pipeline (as before, 1 corresponds to dumping only the links with detected errors, 2 - to whole TF). 2) New option --stop-raw-data-dumps-after-size sets max allowed total size in MB for dumps (of given pipeline), dumping will be disabled once this size is exceeded. --- .../ITSMFTReconstruction/RawPixelDecoder.h | 2 +- .../reconstruction/src/RawPixelDecoder.cxx | 6 ++++- .../include/ITSMFTWorkflow/STFDecoderSpec.h | 3 +++ .../common/workflow/src/STFDecoderSpec.cxx | 22 +++++++++++++++---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h index 4846eab140773..810bff1037513 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h @@ -95,7 +95,7 @@ class RawPixelDecoder final : public PixelReader bool getAlwaysParseTrigger() const { return mAlwaysParseTrigger; } void printReport(bool decstat = true, bool skipNoErr = true) const; - void produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo); + size_t produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo); void clearStat(bool resetRaw = false); diff --git a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx index 209a9fde82632..dc61bea9f406e 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/RawPixelDecoder.cxx @@ -515,8 +515,9 @@ void RawPixelDecoder::clearStat(bool resetRaw) ///______________________________________________________________________ template -void RawPixelDecoder::produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo) +size_t RawPixelDecoder::produceRawDataDumps(int dump, const o2::framework::TimingInfo& tinfo) { + size_t outSize = 0; bool dumpFullTF = false; for (auto& ru : mRUDecodeVec) { if (ru.linkHBFToDump.size()) { @@ -550,6 +551,7 @@ void RawPixelDecoder::produceRawDataDumps(int dump, const o2::framework break; } ostrm.write(reinterpret_cast(piece->data), piece->size); + outSize += piece->size; entry++; } LOG(info) << "produced " << std::filesystem::current_path().c_str() << '/' << fnm; @@ -569,11 +571,13 @@ void RawPixelDecoder::produceRawDataDumps(int dump, const o2::framework for (size_t i = 0; i < lnk.rawData.getNPieces(); i++) { const auto* piece = lnk.rawData.getPiece(i); ostrm.write(reinterpret_cast(piece->data), piece->size); + outSize += piece->size; } } LOG(info) << "produced " << std::filesystem::current_path().c_str() << '/' << fnm; break; } + return outSize; } ///______________________________________________________________________ diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/STFDecoderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/STFDecoderSpec.h index 297cfb446f8ef..a6876c456842d 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/STFDecoderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/STFDecoderSpec.h @@ -81,6 +81,7 @@ class STFDecoder : public Task bool mApplyNoiseMap = true; bool mUseClusterDictionary = true; bool mVerifyDecoder = false; + bool mDumpFrom1stPipeline = false; int mDumpOnError = 0; int mNThreads = 1; int mVerbosity = 0; @@ -91,6 +92,8 @@ class STFDecoder : public Task size_t mEstNClusPatt = 0; size_t mEstNCalib = 0; size_t mEstNROF = 0; + size_t mMaxRawDumpsSize = 0; + size_t mRawDumpedSize = 0; std::string mInputSpec; std::string mSelfName; std::unique_ptr> mDecoder; diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index bbd1a52a919e5..d798bbc62204d 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -87,8 +87,16 @@ void STFDecoder::init(InitContext& ic) mDecoder->setNThreads(mNThreads); mUnmutExtraLanes = ic.options().get("unmute-extra-lanes"); mVerbosity = ic.options().get("decoder-verbosity"); + auto dmpSz = ic.options().get("stop-raw-data-dumps-after-size"); + if (dmpSz > 0) { + mMaxRawDumpsSize = size_t(dmpSz) * 1024 * 1024; + } mDumpOnError = ic.options().get("raw-data-dumps"); - if (mDumpOnError < 0 || mDumpOnError >= int(GBTLink::RawDataDumps::DUMP_NTYPES)) { + if (mDumpOnError < 0) { + mDumpOnError = -mDumpOnError; + mDumpFrom1stPipeline = true; + } + if (mDumpOnError >= int(GBTLink::RawDataDumps::DUMP_NTYPES)) { throw std::runtime_error(fmt::format("unknown raw data dump level {} requested", mDumpOnError)); } auto dumpDir = ic.options().get("raw-data-dumps-directory"); @@ -243,8 +251,13 @@ void STFDecoder::run(ProcessingContext& pc) pc.outputs().snapshot(Output{orig, "PHYSTRIG", 0}, mDecoder->getExternalTriggers()); - if (mDumpOnError != int(GBTLink::RawDataDumps::DUMP_NONE)) { - mDecoder->produceRawDataDumps(mDumpOnError, pc.services().get()); + if (mDumpOnError != int(GBTLink::RawDataDumps::DUMP_NONE) && + (!mDumpFrom1stPipeline || pc.services().get().inputTimesliceId == 0)) { + mRawDumpedSize += mDecoder->produceRawDataDumps(mDumpOnError, pc.services().get()); + if (mRawDumpedSize > mMaxRawDumpsSize && mMaxRawDumpsSize > 0) { + LOGP(info, "Max total dumped size {} MB exceeded allowed limit, disabling further dumping", mRawDumpedSize / (1024 * 1024)); + mDumpOnError = int(GBTLink::RawDataDumps::DUMP_NONE); + } } if (mDoClusters) { @@ -417,8 +430,9 @@ DataProcessorSpec getSTFDecoderSpec(const STFDecoderInp& inp) {"nthreads", VariantType::Int, 1, {"Number of decoding/clustering threads"}}, {"decoder-verbosity", VariantType::Int, 0, {"Verbosity level (-1: silent, 0: errors, 1: headers, 2: data, 3: raw data dump) of 1st lane"}}, {"always-parse-trigger", VariantType::Bool, false, {"parse trigger word even if flags continuation of old trigger"}}, - {"raw-data-dumps", VariantType::Int, int(GBTLink::RawDataDumps::DUMP_NONE), {"Raw data dumps on error (0: none, 1: HBF for link, 2: whole TF for all links"}}, + {"raw-data-dumps", VariantType::Int, int(GBTLink::RawDataDumps::DUMP_NONE), {"Raw data dumps on error (0: none, 1: HBF for link, 2: whole TF for all links. If negative, dump only on from 1st pipeline."}}, {"raw-data-dumps-directory", VariantType::String, "", {"Destination directory for the raw data dumps"}}, + {"stop-raw-data-dumps-after-size", VariantType::Int, 1024, {"Stop dumping once this size in MB is accumulated. 0: no limit"}}, {"unmute-extra-lanes", VariantType::Bool, false, {"allow extra lanes to be as verbose as 1st one"}}, {"allow-empty-rofs", VariantType::Bool, false, {"record ROFs w/o any hit"}}, {"ignore-noise-map", VariantType::Bool, false, {"do not mask pixels flagged in the noise map"}}, From 0eec04648c79d725df0ca6ba38ef856f99275ae8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Mon, 9 Sep 2024 23:24:02 +0200 Subject: [PATCH 0216/2205] DCAFitter GPU: add test to validate the implementation (#13447) --- Common/DCAFitter/GPU/CMakeLists.txt | 30 +- Common/DCAFitter/GPU/DCAFitterN.cu | 38 -- Common/DCAFitter/GPU/cuda/CMakeLists.txt | 32 + Common/DCAFitter/GPU/cuda/DCAFitterN.cu | 106 ++++ .../GPU/cuda/test/testDCAFitterNGPU.cxx | 556 ++++++++++++++++++ Common/DCAFitter/GPU/hip/CMakeLists.txt | 34 ++ .../DCAFitter/GPU/test/testDCAFitterNCUDA.cu | 37 -- .../DCAFitter/include/DCAFitter/DCAFitterN.h | 54 +- .../DCAFitter/include/DCAFitter/HelixHelper.h | 46 +- .../MathUtils/include/MathUtils/Cartesian.h | 12 + .../MathUtils/include/MathUtils/SMatrixGPU.h | 63 +- Common/MathUtils/include/MathUtils/Utils.h | 6 +- .../src/TrackParametrization.cxx | 11 - GPU/Common/GPUCommonMath.h | 2 +- 14 files changed, 844 insertions(+), 183 deletions(-) delete mode 100644 Common/DCAFitter/GPU/DCAFitterN.cu create mode 100644 Common/DCAFitter/GPU/cuda/CMakeLists.txt create mode 100644 Common/DCAFitter/GPU/cuda/DCAFitterN.cu create mode 100644 Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx create mode 100644 Common/DCAFitter/GPU/hip/CMakeLists.txt delete mode 100644 Common/DCAFitter/GPU/test/testDCAFitterNCUDA.cu diff --git a/Common/DCAFitter/GPU/CMakeLists.txt b/Common/DCAFitter/GPU/CMakeLists.txt index f2206c0bc6ddf..faf15f8aab3df 100644 --- a/Common/DCAFitter/GPU/CMakeLists.txt +++ b/Common/DCAFitter/GPU/CMakeLists.txt @@ -9,28 +9,10 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -if(CUDA_ENABLED) -# o2_add_library(DCAFitterCUDA -# TARGETVARNAME targetName -# SOURCES DCAFitterN.cu -# # src/FwdDCAFitterN.cxx -# PUBLIC_INCLUDE_DIRECTORIES ../include -# PUBLIC_LINK_LIBRARIES O2::MathUtils -# O2::ReconstructionDataFormats -# O2::DetectorsBase) - -# o2_add_test(DCAFitterNCUDA NAME testDCAFitterNCUDA -# SOURCES test/testDCAFitterNCUDA.cu -# COMPONENT_NAME DCAFitterCUDA -# PUBLIC_LINK_LIBRARIES O2::DCAFitter -# COMPONENT_NAME GPU -# LABELS gpu vertexing) +if (CUDA_ENABLED) +add_subdirectory(cuda) endif() -# if (HIP_ENABLED) -# o2_add_test(DCAFitterNHIP NAME testDCAFitterNHIP -# SOURCES test/testDCAFitterNCUDA.cu -# HIPIFIED test -# PUBLIC_LINK_LIBRARIES O2::DCAFitterHIP -# COMPONENT_NAME GPU -# LABELS gpu vertexing) -# endif() \ No newline at end of file + +if (HIP_ENABLED) +add_subdirectory(hip) +endif() \ No newline at end of file diff --git a/Common/DCAFitter/GPU/DCAFitterN.cu b/Common/DCAFitter/GPU/DCAFitterN.cu deleted file mode 100644 index 10f2c40dc41e1..0000000000000 --- a/Common/DCAFitter/GPU/DCAFitterN.cu +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifdef __HIPCC__ -#include "hip/hip_runtime.h" -#else -#include -#endif - -#include "GPUCommonDef.h" -#include "DCAFitter/DCAFitterN.h" - -namespace o2 -{ -namespace vertexing -{ -GPUg() void __dummy_instance__() -{ -#ifdef GPUCA_GPUCODE_DEVICE -#pragma message "Compiling device code" -#endif - DCAFitter2 ft2; - DCAFitter3 ft3; - o2::track::TrackParCov tr; - ft2.process(tr, tr); - ft3.process(tr, tr, tr); -} - -} // namespace vertexing -} // namespace o2 \ No newline at end of file diff --git a/Common/DCAFitter/GPU/cuda/CMakeLists.txt b/Common/DCAFitter/GPU/cuda/CMakeLists.txt new file mode 100644 index 0000000000000..a498d0c350202 --- /dev/null +++ b/Common/DCAFitter/GPU/cuda/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(DCAFitterCUDA + TARGETVARNAME targetName + SOURCES DCAFitterN.cu + PUBLIC_INCLUDE_DIRECTORIES ../../include + PUBLIC_LINK_LIBRARIES O2::MathUtils + O2::ReconstructionDataFormats + O2::DetectorsBase + PRIVATE_LINK_LIBRARIES O2::GPUTrackingCUDAExternalProvider) +set_property(TARGET ${targetName} PROPERTY CUDA_SEPARABLE_COMPILATION ON) + +o2_add_test(DCAFitterNCUDA + SOURCES test/testDCAFitterNGPU.cxx + PUBLIC_LINK_LIBRARIES O2::ReconstructionDataFormats + O2::DCAFitterCUDA + O2::DCAFitter + ROOT::Core + ROOT::Physics + COMPONENT_NAME gpu + LABELS vertexing + ENVIRONMENT O2_ROOT=${CMAKE_BINARY_DIR}/stage + VMCWORKDIR=${CMAKE_BINARY_DIR}/stage/${CMAKE_INSTALL_DATADIR}) \ No newline at end of file diff --git a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu new file mode 100644 index 0000000000000..f543b7bc7cdd4 --- /dev/null +++ b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu @@ -0,0 +1,106 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __HIPCC__ +#include "hip/hip_runtime.h" +#else +#include +#endif + +#include "GPUCommonDef.h" +#include "DCAFitter/DCAFitterN.h" +// #include "MathUtils/SMatrixGPU.h" + +#define gpuCheckError(x) \ + { \ + gpuAssert((x), __FILE__, __LINE__); \ + } +inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort = true) +{ + if (code != cudaSuccess) { + std::cout << "GPUassert: " << cudaGetErrorString(code) << " " << file << " " << line << std::endl; + if (abort) { + throw std::runtime_error("GPU assert failed."); + } + } +} +namespace o2::vertexing::device +{ +namespace kernel +{ +GPUg() void printKernel(o2::vertexing::DCAFitterN<2>* ft) +{ + if (threadIdx.x == 0) { + printf(" =============== GPU DCA Fitter ================\n"); + ft->print(); + printf(" ===============================================\n"); + } +} + +GPUg() void processKernel(o2::vertexing::DCAFitterN<2>* ft, o2::track::TrackParCov* t1, o2::track::TrackParCov* t2, int* res) +{ + *res = ft->process(*t1, *t2); +} +} // namespace kernel + +void print(o2::vertexing::DCAFitterN<2>* ft, + const int nBlocks, + const int nThreads) +{ + DCAFitterN<2>* ft_device; + gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(o2::vertexing::DCAFitterN<2>))); + gpuCheckError(cudaMemcpy(ft_device, ft, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyHostToDevice)); + + kernel::printKernel<<>>(ft_device); + + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); +} + +int process(o2::vertexing::DCAFitterN<2>* fitter, + o2::track::TrackParCov& track1, + o2::track::TrackParCov& track2, + const int nBlocks, + const int nThreads) +{ + DCAFitterN<2>* ft_device; + o2::track::TrackParCov* t1_device; + o2::track::TrackParCov* t2_device; + int result, *result_device; + + gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(o2::vertexing::DCAFitterN<2>))); + gpuCheckError(cudaMalloc(reinterpret_cast(&t1_device), sizeof(o2::track::TrackParCov))); + gpuCheckError(cudaMalloc(reinterpret_cast(&t2_device), sizeof(o2::track::TrackParCov))); + gpuCheckError(cudaMalloc(reinterpret_cast(&result_device), sizeof(int))); + + gpuCheckError(cudaMemcpy(ft_device, fitter, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyHostToDevice)); + gpuCheckError(cudaMemcpy(t1_device, &track1, sizeof(o2::track::TrackParCov), cudaMemcpyHostToDevice)); + gpuCheckError(cudaMemcpy(t2_device, &track2, sizeof(o2::track::TrackParCov), cudaMemcpyHostToDevice)); + + kernel::processKernel<<>>(ft_device, t1_device, t2_device, result_device); + + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); + + gpuCheckError(cudaMemcpy(&result, result_device, sizeof(int), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaMemcpy(fitter, ft_device, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaMemcpy(&track1, t1_device, sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaMemcpy(&track2, t2_device, sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaFree(ft_device)); + gpuCheckError(cudaFree(t1_device)); + gpuCheckError(cudaFree(t2_device)); + + gpuCheckError(cudaFree(result_device)); + + return result; +} + +} // namespace o2::vertexing::device \ No newline at end of file diff --git a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx new file mode 100644 index 0000000000000..829ecb808f5c2 --- /dev/null +++ b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx @@ -0,0 +1,556 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#define BOOST_TEST_MODULE Test DCAFitterN class +#define BOOST_TEST_MAIN +#define BOOST_TEST_DYN_LINK +#include + +#include "DCAFitter/DCAFitterN.h" +#include "CommonUtils/TreeStreamRedirector.h" +#include +#include +#include +#include +#include +#include + +namespace o2 +{ +namespace vertexing +{ + +using Vec3D = ROOT::Math::SVector; + +template +float checkResults(o2::utils::TreeStreamRedirector& outs, std::string& treeName, FITTER& fitter, + Vec3D& vgen, TLorentzVector& genPar, const std::vector& dtMass) +{ + int nCand = fitter.getNCandidates(); + std::array p; + float distMin = 1e9; + bool absDCA = fitter.getUseAbsDCA(); + bool useWghDCA = fitter.getWeightedFinalPCA(); + for (int ic = 0; ic < nCand; ic++) { + const auto& vtx = fitter.getPCACandidate(ic); + auto df = vgen; + df -= vtx; + + TLorentzVector moth, prong; + for (int i = 0; i < fitter.getNProngs(); i++) { + const auto& trc = fitter.getTrack(i, ic); + trc.getPxPyPzGlo(p); + prong.SetVectM({p[0], p[1], p[2]}, dtMass[i]); + moth += prong; + } + auto nIter = fitter.getNIterations(ic); + auto chi2 = fitter.getChi2AtPCACandidate(ic); + double dst = TMath::Sqrt(df[0] * df[0] + df[1] * df[1] + df[2] * df[2]); + distMin = dst < distMin ? dst : distMin; + auto parentTrack = fitter.createParentTrackParCov(ic); + // float genX + outs << treeName.c_str() << "cand=" << ic << "ncand=" << nCand << "nIter=" << nIter << "chi2=" << chi2 + << "genPart=" << genPar << "recPart=" << moth + << "genX=" << vgen[0] << "genY=" << vgen[1] << "genZ=" << vgen[2] + << "dx=" << df[0] << "dy=" << df[1] << "dz=" << df[2] << "dst=" << dst + << "useAbsDCA=" << absDCA << "useWghDCA=" << useWghDCA << "parent=" << parentTrack; + for (int i = 0; i < fitter.getNProngs(); i++) { + outs << treeName.c_str() << fmt::format("prong{}=", i).c_str() << fitter.getTrack(i, ic); + } + outs << treeName.c_str() << "\n"; + } + return distMin; +} + +TLorentzVector generate(Vec3D& vtx, std::vector& vctr, float bz, + TGenPhaseSpace& genPHS, double parMass, const std::vector& dtMass, std::vector forceQ) +{ + const float errYZ = 1e-2, errSlp = 1e-3, errQPT = 2e-2; + std::array covm = { + errYZ * errYZ, + 0., errYZ * errYZ, + 0, 0., errSlp * errSlp, + 0., 0., 0., errSlp * errSlp, + 0., 0., 0., 0., errQPT * errQPT}; + bool accept = true; + TLorentzVector parent, d0, d1, d2; + do { + accept = true; + double y = gRandom->Rndm() - 0.5; + double pt = 0.1 + gRandom->Rndm() * 3; + double mt = TMath::Sqrt(parMass * parMass + pt * pt); + double pz = mt * TMath::SinH(y); + double phi = gRandom->Rndm() * TMath::Pi() * 2; + double en = mt * TMath::CosH(y); + double rdec = 10.; // radius of the decay + vtx[0] = rdec * TMath::Cos(phi); + vtx[1] = rdec * TMath::Sin(phi); + vtx[2] = rdec * pz / pt; + parent.SetPxPyPzE(pt * TMath::Cos(phi), pt * TMath::Sin(phi), pz, en); + int nd = dtMass.size(); + genPHS.SetDecay(parent, nd, dtMass.data()); + genPHS.Generate(); + vctr.clear(); + float p[4]; + for (int i = 0; i < nd; i++) { + auto* dt = genPHS.GetDecay(i); + if (dt->Pt() < 0.05) { + accept = false; + break; + } + dt->GetXYZT(p); + float s, c, x; + std::array params; + o2::math_utils::sincos(dt->Phi(), s, c); + o2::math_utils::rotateZInv(vtx[0], vtx[1], x, params[0], s, c); + + params[1] = vtx[2]; + params[2] = 0.; // since alpha = phi + params[3] = 1. / TMath::Tan(dt->Theta()); + params[4] = (i % 2 ? -1. : 1.) / dt->Pt(); + covm[14] = errQPT * errQPT * params[4] * params[4]; + // + // randomize + float r1, r2; + gRandom->Rannor(r1, r2); + params[0] += r1 * errYZ; + params[1] += r2 * errYZ; + gRandom->Rannor(r1, r2); + params[2] += r1 * errSlp; + params[3] += r2 * errSlp; + params[4] *= gRandom->Gaus(1., errQPT); + if (forceQ[i] == 0) { + params[4] = 0.; // impose straight track + } + auto& trc = vctr.emplace_back(x, dt->Phi(), params, covm); + float rad = forceQ[i] == 0 ? 600. : TMath::Abs(1. / trc.getCurvature(bz)); + if (!trc.propagateTo(trc.getX() + (gRandom->Rndm() - 0.5) * rad * 0.05, bz) || + !trc.rotate(trc.getAlpha() + (gRandom->Rndm() - 0.5) * 0.2)) { + printf("Failed to randomize "); + trc.print(); + } + } + } while (!accept); + + return parent; +} + +BOOST_AUTO_TEST_CASE(DCAFitterNProngs) +{ + constexpr int NTest = 10000; + o2::utils::TreeStreamRedirector outStream("dcafitterNTest.root"); + + TGenPhaseSpace genPHS; + constexpr double ele = 0.00051; + constexpr double gamma = 2 * ele + 1e-6; + constexpr double pion = 0.13957; + constexpr double k0 = 0.49761; + constexpr double kch = 0.49368; + constexpr double dch = 1.86965; + std::vector gammadec = {ele, ele}; + std::vector k0dec = {pion, pion}; + std::vector dchdec = {pion, kch, pion}; + std::vector vctracks; + Vec3D vtxGen; + + double bz = 5.0; + // 2 prongs vertices + { + LOG(info) << "Processing 2-prong Helix - Helix case"; + std::vector forceQ{1, 1}; + + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::string treeName2A = "pr2a", treeName2AW = "pr2aw", treeName2W = "pr2w"; + TStopwatch swA, swAW, swW; + int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + double meanDA = 0, meanDAW = 0, meanDW = 0; + swA.Stop(); + swAW.Stop(); + swW.Stop(); + for (int iev = 0; iev < NTest; iev++) { + auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + ft.setUseAbsDCA(true); + swA.Start(false); + int ncA = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swA.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + if (ncA) { + auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); + meanDA += minD; + nfoundA++; + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + swAW.Start(false); + int ncAW = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAW.Stop(); + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncAW) { + auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); + meanDAW += minD; + nfoundAW++; + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + swW.Start(false); + int ncW = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swW.Stop(); + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncW) { + auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); + meanDW += minD; + nfoundW++; + } + } + ft.print(); + device::print(&ft, 1, 1); + meanDA /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundA ? nfoundA : 1; + meanDW /= nfoundW ? nfoundW : 1; + LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + << " mean.dist to truth: " << meanDA << " GPU time: " << swA.CpuTime(); + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + << " mean.dist to truth: " << meanDAW << " GPU time: " << swAW.CpuTime(); + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + << " mean.dist to truth: " << meanDW << " GPU time: " << swW.CpuTime(); + BOOST_CHECK(nfoundA > 0.99 * NTest); + // BOOST_CHECK(nfoundAW > 0.99 * NTest); + // BOOST_CHECK(nfoundW > 0.99 * NTest); + // BOOST_CHECK(meanDA < 0.1); + // BOOST_CHECK(meanDAW < 0.1); + // BOOST_CHECK(meanDW < 0.1); + } + + // // 2 prongs vertices with collinear tracks (gamma conversion) + // { + // LOG(info) << "Processing 2-prong Helix - Helix case gamma conversion"; + // std::vector forceQ{1, 1}; + + // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + // ft.setBz(bz); + // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + // ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway + // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + // std::string treeName2A = "gpr2a", treeName2AW = "gpr2aw", treeName2W = "gpr2w"; + // TStopwatch swA, swAW, swW; + // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + // double meanDA = 0, meanDAW = 0, meanDW = 0; + // swA.Stop(); + // swAW.Stop(); + // swW.Stop(); + // for (int iev = 0; iev < NTest; iev++) { + // auto genParent = generate(vtxGen, vctracks, bz, genPHS, gamma, gammadec, forceQ); + + // ft.setUseAbsDCA(true); + // swA.Start(false); + // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swA.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncA) { + // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, gammadec); + // meanDA += minD; + // nfoundA++; + // } + + // ft.setUseAbsDCA(true); + // ft.setWeightedFinalPCA(true); + // swAW.Start(false); + // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swAW.Stop(); + // LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncAW) { + // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, gammadec); + // meanDAW += minD; + // nfoundAW++; + // } + + // ft.setUseAbsDCA(false); + // ft.setWeightedFinalPCA(false); + // swW.Start(false); + // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swW.Stop(); + // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncW) { + // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, gammadec); + // meanDW += minD; + // nfoundW++; + // } + // } + // ft.print(); + // meanDA /= nfoundA ? nfoundA : 1; + // meanDAW /= nfoundA ? nfoundA : 1; + // meanDW /= nfoundW ? nfoundW : 1; + // LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; + // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + // BOOST_CHECK(nfoundA > 0.99 * NTest); + // BOOST_CHECK(nfoundAW > 0.99 * NTest); + // BOOST_CHECK(nfoundW > 0.99 * NTest); + // BOOST_CHECK(meanDA < 2.1); + // BOOST_CHECK(meanDAW < 2.1); + // BOOST_CHECK(meanDW < 2.1); + // } + + // // 2 prongs vertices with one of charges set to 0: Helix : Line + // { + // std::vector forceQ{1, 1}; + // LOG(info) << "Processing 2-prong Helix - Line case"; + // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + // ft.setBz(bz); + // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + // std::string treeName2A = "pr2aHL", treeName2AW = "pr2awHL", treeName2W = "pr2wHL"; + // TStopwatch swA, swAW, swW; + // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + // double meanDA = 0, meanDAW = 0, meanDW = 0; + // swA.Stop(); + // swAW.Stop(); + // swW.Stop(); + // for (int iev = 0; iev < NTest; iev++) { + // forceQ[iev % 2] = 1; + // forceQ[1 - iev % 2] = 0; + // auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + + // ft.setUseAbsDCA(true); + // swA.Start(false); + // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swA.Stop(); + // LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncA) { + // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); + // meanDA += minD; + // nfoundA++; + // } + + // ft.setUseAbsDCA(true); + // ft.setWeightedFinalPCA(true); + // swAW.Start(false); + // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swAW.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncAW) { + // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); + // meanDAW += minD; + // nfoundAW++; + // } + + // ft.setUseAbsDCA(false); + // ft.setWeightedFinalPCA(false); + // swW.Start(false); + // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swW.Stop(); + // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncW) { + // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); + // meanDW += minD; + // nfoundW++; + // } + // } + // ft.print(); + // meanDA /= nfoundA ? nfoundA : 1; + // meanDAW /= nfoundAW ? nfoundAW : 1; + // meanDW /= nfoundW ? nfoundW : 1; + // LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; + // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + // BOOST_CHECK(nfoundA > 0.99 * NTest); + // BOOST_CHECK(nfoundAW > 0.99 * NTest); + // BOOST_CHECK(nfoundW > 0.99 * NTest); + // BOOST_CHECK(meanDA < 0.1); + // BOOST_CHECK(meanDAW < 0.1); + // BOOST_CHECK(meanDW < 0.1); + // } + + // // 2 prongs vertices with both of charges set to 0: Line : Line + // { + // std::vector forceQ{0, 0}; + // LOG(info) << "Processing 2-prong Line - Line case"; + // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + // ft.setBz(bz); + // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + // std::string treeName2A = "pr2aLL", treeName2AW = "pr2awLL", treeName2W = "pr2wLL"; + // TStopwatch swA, swAW, swW; + // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + // double meanDA = 0, meanDAW = 0, meanDW = 0; + // swA.Stop(); + // swAW.Stop(); + // swW.Stop(); + // for (int iev = 0; iev < NTest; iev++) { + // forceQ[0] = forceQ[1] = 0; + // auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + + // ft.setUseAbsDCA(true); + // swA.Start(false); + // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swA.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncA) { + // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); + // meanDA += minD; + // nfoundA++; + // } + + // ft.setUseAbsDCA(true); + // ft.setWeightedFinalPCA(true); + // swAW.Start(false); + // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swAW.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncAW) { + // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); + // meanDAW += minD; + // nfoundAW++; + // } + + // ft.setUseAbsDCA(false); + // ft.setWeightedFinalPCA(false); + // swW.Start(false); + // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + // swW.Stop(); + // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncW) { + // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); + // meanDW += minD; + // nfoundW++; + // } + // } + // ft.print(); + // meanDA /= nfoundA ? nfoundA : 1; + // meanDAW /= nfoundAW ? nfoundAW : 1; + // meanDW /= nfoundW ? nfoundW : 1; + // LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; + // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + // BOOST_CHECK(nfoundA > 0.99 * NTest); + // BOOST_CHECK(nfoundAW > 0.99 * NTest); + // BOOST_CHECK(nfoundW > 0.99 * NTest); + // BOOST_CHECK(meanDA < 0.1); + // BOOST_CHECK(meanDAW < 0.1); + // BOOST_CHECK(meanDW < 0.1); + // } + + // // 3 prongs vertices + // { + // std::vector forceQ{1, 1, 1}; + + // o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter + // ft.setBz(bz); + // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + // std::string treeName3A = "pr3a", treeName3AW = "pr3aw", treeName3W = "pr3w"; + // TStopwatch swA, swAW, swW; + // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + // double meanDA = 0, meanDAW = 0, meanDW = 0; + // swA.Stop(); + // swAW.Stop(); + // swW.Stop(); + // for (int iev = 0; iev < NTest; iev++) { + // auto genParent = generate(vtxGen, vctracks, bz, genPHS, dch, dchdec, forceQ); + + // ft.setUseAbsDCA(true); + // swA.Start(false); + // int ncA = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + // swA.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncA) { + // auto minD = checkResults(outStream, treeName3A, ft, vtxGen, genParent, dchdec); + // meanDA += minD; + // nfoundA++; + // } + + // ft.setUseAbsDCA(true); + // ft.setWeightedFinalPCA(true); + // swAW.Start(false); + // int ncAW = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + // swAW.Stop(); + // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncAW) { + // auto minD = checkResults(outStream, treeName3AW, ft, vtxGen, genParent, dchdec); + // meanDAW += minD; + // nfoundAW++; + // } + + // ft.setUseAbsDCA(false); + // ft.setWeightedFinalPCA(false); + // swW.Start(false); + // int ncW = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + // swW.Stop(); + // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + // if (ncW) { + // auto minD = checkResults(outStream, treeName3W, ft, vtxGen, genParent, dchdec); + // meanDW += minD; + // nfoundW++; + // } + // } + // ft.print(); + // meanDA /= nfoundA ? nfoundA : 1; + // meanDAW /= nfoundAW ? nfoundAW : 1; + // meanDW /= nfoundW ? nfoundW : 1; + // LOG(info) << "Processed " << NTest << " 3-prong vertices"; + // LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + // LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + // LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + // BOOST_CHECK(nfoundA > 0.99 * NTest); + // BOOST_CHECK(nfoundAW > 0.99 * NTest); + // BOOST_CHECK(nfoundW > 0.99 * NTest); + // BOOST_CHECK(meanDA < 0.1); + // BOOST_CHECK(meanDAW < 0.1); + // BOOST_CHECK(meanDW < 0.1); + // } + + outStream.Close(); +} + +} // namespace vertexing +} // namespace o2 \ No newline at end of file diff --git a/Common/DCAFitter/GPU/hip/CMakeLists.txt b/Common/DCAFitter/GPU/hip/CMakeLists.txt new file mode 100644 index 0000000000000..272d18a81bab4 --- /dev/null +++ b/Common/DCAFitter/GPU/hip/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +set(CMAKE_HIP_FLAGS "${CMAKE_HIP_FLAGS} -fgpu-rdc") +o2_add_hipified_library(DCAFitterHIP + SOURCES ../cuda/DCAFitterN.cu + PUBLIC_INCLUDE_DIRECTORIES ../../include + PUBLIC_LINK_LIBRARIES O2::MathUtils + O2::ReconstructionDataFormats + O2::DetectorsBase + hip::host + PRIVATE_LINK_LIBRARIES O2::GPUTrackingHIPExternalProvider + TARGETVARNAME targetNAme) + +o2_add_test(DCAFitterNHIP + SOURCES ../cuda/test/testDCAFitterNGPU.cxx + PUBLIC_LINK_LIBRARIES O2::ReconstructionDataFormats + O2::DCAFitterHIP + O2::DCAFitter + ROOT::Core + ROOT::Physics + HIPIFIED test + COMPONENT_NAME gpu + LABELS vertexing + ENVIRONMENT O2_ROOT=${CMAKE_BINARY_DIR}/stage + VMCWORKDIR=${CMAKE_BINARY_DIR}/stage/${CMAKE_INSTALL_DATADIR}) \ No newline at end of file diff --git a/Common/DCAFitter/GPU/test/testDCAFitterNCUDA.cu b/Common/DCAFitter/GPU/test/testDCAFitterNCUDA.cu deleted file mode 100644 index 6e5a3e1b225e9..0000000000000 --- a/Common/DCAFitter/GPU/test/testDCAFitterNCUDA.cu +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -/// \author matteo.concas@cern.ch -#define BOOST_TEST_MODULE Test DCAFitterN class on GPU - -#ifdef __HIPCC__ -#define GPUPLATFORM "HIP" -#include "hip/hip_runtime.h" -#else -#define GPUPLATFORM "CUDA" -#include -#endif - -#include "DCAFitter/DCAFitterN.h" -#include "GPUCommonDef.h" -#include - -namespace gpu -{ -GPUg() void testDCAFitterInstanceKernel() -{ - o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter - ft.setBz(0.f); -} -} // namespace gpu -BOOST_AUTO_TEST_CASE(DCAFitterNProngs) -{ -} \ No newline at end of file diff --git a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h index 340a0be199c68..b74fec89d9f37 100644 --- a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h +++ b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h @@ -48,7 +48,7 @@ struct TrackCovI { syz = -cyz * detYZI; szz = cyy * detYZI; } else { -#ifndef GPUCA_GPUCODE_DEVICE +#ifndef GPUCA_GPUCODE throw std::runtime_error("invalid track covariance"); #endif } @@ -122,10 +122,10 @@ class DCAFitterN ///< prepare copies of tracks at the V0 candidate (no check for the candidate validity) /// must be called before getTrack(i,cand) query - bool propagateTracksToVertex(int cand = 0); + GPUd() bool propagateTracksToVertex(int cand = 0); ///< check if propagation of tracks to candidate vertex was done - bool isPropagateTracksToVertexDone(int cand = 0) const { return mTrPropDone[mOrder[cand]]; } + GPUd() bool isPropagateTracksToVertexDone(int cand = 0) const { return mTrPropDone[mOrder[cand]]; } ///< check if propagation of tracks to candidate vertex was done bool isPropagationFailure(int cand = 0) const { return mPropFailed[mOrder[cand]]; } @@ -153,18 +153,18 @@ class DCAFitterN } ///< create parent track param with errors for decay vertex - o2::track::TrackParCov createParentTrackParCov(int cand = 0, bool sectorAlpha = true) const; + GPUd() o2::track::TrackParCov createParentTrackParCov(int cand = 0, bool sectorAlpha = true) const; ///< create parent track param w/o errors for decay vertex - o2::track::TrackPar createParentTrackPar(int cand = 0, bool sectorAlpha = true) const; + GPUd() o2::track::TrackPar createParentTrackPar(int cand = 0, bool sectorAlpha = true) const; ///< calculate on the fly track param (no cov mat) at candidate, check isValid to make sure propagation was successful - o2::track::TrackPar getTrackParamAtPCA(int i, int cand = 0); + GPUd() o2::track::TrackPar getTrackParamAtPCA(int i, int cand = 0); ///< recalculate PCA as a cov-matrix weighted mean, even if absDCA method was used - bool recalculatePCAWithErrors(int cand = 0); + GPUd() bool recalculatePCAWithErrors(int cand = 0); - MatSym3D calcPCACovMatrix(int cand = 0) const; + GPUd() MatSym3D calcPCACovMatrix(int cand = 0) const; o2::gpu::gpustd::array calcPCACovMatrixFlat(int cand = 0) const { @@ -517,7 +517,7 @@ GPUd() void DCAFitterN::calcResidDerivatives() dr2[2] += trDx.d2zdx2; } } // track over which we differentiate - } // residual being differentiated + } // residual being differentiated } //__________________________________________________________________________ @@ -567,7 +567,7 @@ GPUd() void DCAFitterN::calcResidDerivativesNoErr() dr2ji[2] = -trDxi.d2zdx2 * NInv; } // track over which we differentiate - } // residual being differentiated + } // residual being differentiated } //__________________________________________________________________________ @@ -1011,10 +1011,21 @@ GPUd() bool DCAFitterN::closerToAlternative() const template GPUd() void DCAFitterN::print() const { +#ifndef GPUCA_GPUCODE_DEVICE LOG(info) << N << "-prong vertex fitter in " << (mUseAbsDCA ? "abs." : "weighted") << " distance minimization mode"; LOG(info) << "Bz: " << mBz << " MaxIter: " << mMaxIter << " MaxChi2: " << mMaxChi2; LOG(info) << "Stopping condition: Max.param change < " << mMinParamChange << " Rel.Chi2 change > " << mMinRelChi2Change; LOG(info) << "Discard candidates for : Rvtx > " << getMaxR() << " DZ between tracks > " << mMaxDZIni; +#else + if (mUseAbsDCA) { + printf("%d-prong vertex fitter in abs. distance minimization mode\n", N); + } else { + printf("%d-prong vertex fitter in weighted distance minimization mode\n", N); + } + printf("Bz: %f MaxIter: %d MaxChi2: %f\n", mBz, mMaxIter, mMaxChi2); + printf("Stopping condition: Max.param change < %f Rel.Chi2 change > %f\n", mMinParamChange, mMinRelChi2Change); + printf("Discard candidates for : Rvtx > %f DZ between tracks > %f\n", getMaxR(), mMaxDZIni); +#endif } //___________________________________________________________________ @@ -1079,7 +1090,9 @@ GPUdi() bool DCAFitterN::propagateParamToX(o2::track::TrackPar& t, f { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { +#ifndef GPUCA_GPUCODE res = o2::base::Propagator::Instance()->PropagateToXBxByBz(t, x, mMaxSnp, mMaxStep, mMatCorr); +#endif } else { res = t.propagateParamTo(x, mBz); } @@ -1095,7 +1108,9 @@ GPUdi() bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, flo { bool res = true; if (mUsePropagator || mMatCorr != o2::base::Propagator::MatCorrType::USEMatCorrNONE) { +#ifndef GPUCA_GPUCODE res = o2::base::Propagator::Instance()->PropagateToXBxByBz(t, x, mMaxSnp, mMaxStep, mMatCorr); +#endif } else { res = t.propagateTo(x, mBz); } @@ -1107,7 +1122,24 @@ GPUdi() bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, flo using DCAFitter2 = DCAFitterN<2, o2::track::TrackParCov>; using DCAFitter3 = DCAFitterN<3, o2::track::TrackParCov>; - +#ifdef GPUCA_GPUCODE +namespace gpu::kernel +{ +GPUg() void printKernel(o2::vertexing::DCAFitterN<2>* ft); +GPUg() void processKernel(o2::vertexing::DCAFitterN<2>* ft, o2::track::TrackParCov* t1, o2::track::TrackParCov* t2, int* res); +} // namespace gpu::kernel +#endif +namespace device +{ +void print(o2::vertexing::DCAFitterN<2>*, + const int nBlocks = 1, + const int nThreads = 1); +int process(o2::vertexing::DCAFitterN<2>*, + o2::track::TrackParCov&, + o2::track::TrackParCov&, + const int nBlocks = 1, + const int nThreads = 1); +} // namespace device } // namespace vertexing } // namespace o2 #endif // _ALICEO2_DCA_FITTERN_ diff --git a/Common/DCAFitter/include/DCAFitter/HelixHelper.h b/Common/DCAFitter/include/DCAFitter/HelixHelper.h index 39dee1d399848..ee6d6838b3ed9 100644 --- a/Common/DCAFitter/include/DCAFitter/HelixHelper.h +++ b/Common/DCAFitter/include/DCAFitter/HelixHelper.h @@ -41,7 +41,7 @@ struct TrackAuxPar : public o2::math_utils::CircleXYf_t { float sinDif(const TrackAuxPar& t) const { return s * t.c - c * t.s; } // sin(alpha_this - alha_t) template - void set(const T& trc, float bz) + GPUd() void set(const T& trc, float bz) { trc.getCircleParams(bz, *this, s, c); cc = c * c; @@ -59,13 +59,13 @@ struct CrossInfo { float yDCA[2] = {}; int nDCA = 0; - int circlesCrossInfo(const TrackAuxPar& trax0, const TrackAuxPar& trax1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) + GPUd() int circlesCrossInfo(const TrackAuxPar& trax0, const TrackAuxPar& trax1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) { const auto& trcA = trax0.rC > trax1.rC ? trax0 : trax1; // designate the largest circle as A const auto& trcB = trax0.rC > trax1.rC ? trax1 : trax0; float xDist = trcB.xC - trcA.xC, yDist = trcB.yC - trcA.yC; - float dist2 = xDist * xDist + yDist * yDist, dist = std::sqrt(dist2), rsum = trcA.rC + trcB.rC; - if (std::abs(dist) < 1e-12) { + float dist2 = xDist * xDist + yDist * yDist, dist = o2::gpu::GPUCommonMath::Sqrt(dist2), rsum = trcA.rC + trcB.rC; + if (o2::gpu::GPUCommonMath::Sqrt(dist) < 1e-12) { return nDCA; // circles are concentric? } if (dist > rsum) { // circles don't touch, chose a point in between @@ -89,13 +89,13 @@ struct CrossInfo { xDCA[0] = r2_r * trcA.xC + r1_r * trcB.xC; yDCA[0] = r2_r * trcA.yC + r1_r * trcB.yC; nDCA = 1; - } else if (std::abs(xDist) < std::abs(yDist)) { + } else if (o2::gpu::GPUCommonMath::Sqrt(xDist) < o2::gpu::GPUCommonMath::Sqrt(yDist)) { // to simplify calculations, we move to new frame x->x+Xc0, y->y+Yc0, so that // the 1st one is centered in origin float a = (trcA.rC * trcA.rC - trcB.rC * trcB.rC + dist2) / (2. * yDist), b = -xDist / yDist, ab = a * b, bb = b * b; float det = ab * ab - (1. + bb) * (a * a - trcA.rC * trcA.rC); if (det > 0.) { - det = std::sqrt(det); + det = o2::gpu::GPUCommonMath::Sqrt(det); xDCA[0] = (-ab + det) / (1. + b * b); yDCA[0] = a + b * xDCA[0] + trcA.yC; xDCA[0] += trcA.xC; @@ -110,7 +110,7 @@ struct CrossInfo { float a = (trcA.rC * trcA.rC - trcB.rC * trcB.rC + dist2) / (2. * xDist), b = -yDist / xDist, ab = a * b, bb = b * b; float det = ab * ab - (1. + bb) * (a * a - trcA.rC * trcA.rC); if (det > 0.) { - det = std::sqrt(det); + det = o2::gpu::GPUCommonMath::Sqrt(det); yDCA[0] = (-ab + det) / (1. + bb); xDCA[0] = a + b * yDCA[0] + trcA.xC; yDCA[0] += trcA.yC; @@ -126,14 +126,14 @@ struct CrossInfo { return nDCA; } - void notTouchingXY(float dist, float xDist, float yDist, const TrackAuxPar& trcA, float rBSign, bool isCollinear = false) + GPUd() void notTouchingXY(float dist, float xDist, float yDist, const TrackAuxPar& trcA, float rBSign, bool isCollinear = false) { if (isCollinear) { /// for collinear tracks it is better to take /// a weighted average of the crossing points as a radius - float r2r = trcA.rC + std::abs(rBSign); + float r2r = trcA.rC + o2::gpu::GPUCommonMath::Sqrt(rBSign); float r1_r = trcA.rC / r2r; - float r2_r = std::abs(rBSign) / r2r; + float r2_r = o2::gpu::GPUCommonMath::Sqrt(rBSign) / r2r; xDCA[0] = r2_r * trcA.xC + r1_r * (xDist + trcA.xC); yDCA[0] = r2_r * trcA.yC + r1_r * (yDist + trcA.yC); } else { @@ -151,8 +151,8 @@ struct CrossInfo { } template - int linesCrossInfo(const TrackAuxPar& trax0, const T& tr0, - const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef) + GPUd() int linesCrossInfo(const TrackAuxPar& trax0, const T& tr0, + const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef) { /// closest approach of 2 straight lines /// TrackParam propagation can be parameterized in lab in a form @@ -172,14 +172,14 @@ struct CrossInfo { float dy = trax1.yC - trax0.yC; // float dz = tr1.getZ() - tr0.getZ(); auto csp0i2 = 1. / tr0.getCsp2(); // 1 / csp^2 - auto csp0i = std::sqrt(csp0i2); + auto csp0i = o2::gpu::GPUCommonMath::Sqrt(csp0i2); auto tgp0 = tr0.getSnp() * csp0i; float kx0 = trax0.c - trax0.s * tgp0; float ky0 = trax0.s + trax0.c * tgp0; float kz0 = tr0.getTgl() * csp0i; auto csp1i2 = 1. / tr1.getCsp2(); // 1 / csp^2 - auto csp1i = std::sqrt(csp1i2); - auto tgp1 = tr1.getSnp() * std::sqrt(csp1i2); + auto csp1i = o2::gpu::GPUCommonMath::Sqrt(csp1i2); + auto tgp1 = tr1.getSnp() * o2::gpu::GPUCommonMath::Sqrt(csp1i2); float kx1 = trax1.c - trax1.s * tgp1; float ky1 = trax1.s + trax1.c * tgp1; float kz1 = tr1.getTgl() * csp1i; @@ -194,7 +194,7 @@ struct CrossInfo { float a00 = (1.f + tr0.getTgl() * tr0.getTgl()) * csp0i2, a11 = (1.f + tr1.getTgl() * tr1.getTgl()) * csp1i2, a01 = -(kx0 * kx1 + ky0 * ky1 + kz0 * kz1); float b0 = dx * kx0 + dy * ky0 + dz * kz0, b1 = -(dx * kx1 + dy * ky1 + dz * kz1); float det = a00 * a11 - a01 * a01, det0 = b0 * a11 - b1 * a01, det1 = a00 * b1 - a01 * b0; - if (std::abs(det) > o2::constants::math::Almost0) { + if (o2::gpu::GPUCommonMath::Sqrt(det) > o2::constants::math::Almost0) { auto detI = 1. / det; auto t0 = det0 * detI; auto t1 = det1 * detI; @@ -212,8 +212,8 @@ struct CrossInfo { } template - int circleLineCrossInfo(const TrackAuxPar& trax0, const T& tr0, - const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef) + GPUd() int circleLineCrossInfo(const TrackAuxPar& trax0, const T& tr0, + const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef) { /// closest approach of line and circle /// TrackParam propagation can be parameterized in lab in a form @@ -238,14 +238,14 @@ struct CrossInfo { float dy = traxL.yC - traxH.yC; // Y... // t^2(kx^2+ky^2) + 2t(dx*kx+dy*ky) + dx^2 + dy^2 - r^2 = 0 auto cspi2 = 1. / trcL.getCsp2(); // 1 / csp^2 == kx^2 + ky^2 - auto cspi = std::sqrt(cspi2); + auto cspi = o2::gpu::GPUCommonMath::Sqrt(cspi2); auto tgp = trcL.getSnp() * cspi; float kx = traxL.c - traxL.s * tgp; float ky = traxL.s + traxL.c * tgp; double dk = dx * kx + dy * ky; double det = dk * dk - cspi2 * (dx * dx + dy * dy - traxH.rC * traxH.rC); if (det > 0) { // 2 crossings - det = std::sqrt(det); + det = o2::gpu::GPUCommonMath::Sqrt(det); float t0 = (-dk + det) * cspi2; float t1 = (-dk - det) * cspi2; xDCA[0] = traxL.xC + kx * t0; @@ -257,7 +257,7 @@ struct CrossInfo { // there is no crossing, find the point of the closest approach on the line which is closest to the circle center float t = -dk * cspi2; float xL = traxL.xC + kx * t, yL = traxL.yC + ky * t; // point on the line, need to average with point on the circle - float dxc = xL - traxH.xC, dyc = yL - traxH.yC, dist = std::sqrt(dxc * dxc + dyc * dyc); + float dxc = xL - traxH.xC, dyc = yL - traxH.yC, dist = o2::gpu::GPUCommonMath::Sqrt(dxc * dxc + dyc * dyc); if (dist - traxH.rC > maxDistXY) { // too large distance return nDCA; } @@ -271,7 +271,7 @@ struct CrossInfo { } template - int set(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) + GPUd() int set(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) { // calculate up to 2 crossings between 2 circles nDCA = 0; @@ -286,7 +286,7 @@ struct CrossInfo { return nDCA; } - CrossInfo() = default; + GPUdDefault() CrossInfo() = default; template CrossInfo(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) diff --git a/Common/MathUtils/include/MathUtils/Cartesian.h b/Common/MathUtils/include/MathUtils/Cartesian.h index 67e17ae6bd47d..9b917707835a6 100644 --- a/Common/MathUtils/include/MathUtils/Cartesian.h +++ b/Common/MathUtils/include/MathUtils/Cartesian.h @@ -264,6 +264,18 @@ inline SMatrix> Similarity(const SMatrix +GPUdi() T Dot(const SVector& lhs, const SVector& rhs) +{ + return o2::math_utils::detail::Dot(lhs, rhs); +} + +template +GPUdi() SMatrix> Similarity(const SMatrix& lhs, const SMatrix>& rhs) +{ + return o2::math_utils::detail::Similarity(lhs, rhs); +} #endif // Disable for GPU } // namespace math_utils diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index fdb5bb2a5da66..1372b2a861409 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -67,9 +67,9 @@ class SVectorGPU GPUd() SVectorGPU(); GPUd() SVectorGPU(const SVectorGPU& rhs); - GPUd() const T& operator[](unsigned int i) const; + GPUhd() const T& operator[](unsigned int i) const; + GPUhd() T& operator[](unsigned int i); GPUd() const T& operator()(unsigned int i) const; - GPUd() T& operator[](unsigned int i); GPUd() T& operator()(unsigned int i); GPUd() const T* Array() const; GPUd() T* Array(); @@ -114,19 +114,19 @@ GPUdi() const T* SVectorGPU::end() const } template -GPUdi() const T& SVectorGPU::operator[](unsigned int i) const +GPUhdi() const T& SVectorGPU::operator[](unsigned int i) const { return mArray[i]; } template -GPUdi() const T& SVectorGPU::operator()(unsigned int i) const +GPUhdi() T& SVectorGPU::operator[](unsigned int i) { return mArray[i]; } template -GPUdi() T& SVectorGPU::operator[](unsigned int i) +GPUdi() const T& SVectorGPU::operator()(unsigned int i) const { return mArray[i]; } @@ -205,7 +205,7 @@ GPUdi() SVectorGPU& SVectorGPU::operator-=(const SVectorGPU& r } template -GPUd() SVectorGPU& SVectorGPU::operator+=(const SVectorGPU& rhs) +GPUdi() SVectorGPU& SVectorGPU::operator+=(const SVectorGPU& rhs) { for (unsigned int i = 0; i < D; ++i) { mArray[i] += rhs.apply(i); @@ -304,31 +304,11 @@ class MatRepSymGPU public: typedef T value_type; GPUdDefault() MatRepSymGPU() = default; - GPUdi() T& operator()(unsigned int i, unsigned int j) - { - return mArray[offset(i, j)]; - } - - GPUdi() T const& operator()(unsigned int i, unsigned int j) const - { - return mArray[offset(i, j)]; - } - - GPUdi() T& operator[](unsigned int i) - { - return mArray[off(i)]; - } - - GPUdi() T const& operator[](unsigned int i) const - { - return mArray[off(i)]; - } - - GPUdi() T apply(unsigned int i) const - { - return mArray[off(i)]; - } - + GPUdi() T& operator()(unsigned int i, unsigned int j) { return mArray[offset(i, j)]; } + GPUdi() T const& operator()(unsigned int i, unsigned int j) const { return mArray[offset(i, j)]; } + GPUhdi() T& operator[](unsigned int i) { return mArray[off(i)]; } + GPUdi() T const& operator[](unsigned int i) const { return mArray[off(i)]; } + GPUdi() T apply(unsigned int i) const { return mArray[off(i)]; } GPUdi() T* Array() { return mArray; } GPUdi() const T* Array() const { return mArray; } @@ -481,9 +461,10 @@ class SMatrixGPU kCols = D2, // columns kSize = D1 * D2 // rows*columns }; - GPUd() T apply(unsigned int i) const; - GPUd() const T* Array() const; - GPUd() T* Array(); + // https://root.cern/doc/master/SMatrix_8icc_source.html#l00627 + GPUd() T apply(unsigned int i) const { return mRep[i]; } + GPUd() const T* Array() const { return mRep.Array(); } + GPUd() T* Array() { return mRep.Array(); } GPUd() iterator begin(); GPUd() iterator end(); GPUd() const T& operator()(unsigned int i, unsigned int j) const; @@ -518,6 +499,9 @@ class SMatrixGPU GPUd() SMatrixRowGPUconst operator[](unsigned int i) const { return SMatrixRowGPUconst(*this, i); } GPUd() SMatrixRowGPU operator[](unsigned int i) { return SMatrixRowGPU(*this, i); } + template + GPUd() SMatrixGPU& operator+=(const SMatrixGPU& rhs); + GPUd() bool Invert(); GPUd() bool IsInUse(const T* p) const; @@ -676,7 +660,7 @@ GPUdi() SMatrixGPU& SMatrixGPU::operator=(const Expr template template -GPUdi() SMatrixGPU& SMatrixGPU::operator=(const M& rhs) +GPUdi() SMatrixGPU& SMatrixGPU::operator=(const M & rhs) { mRep = rhs.mRep; return *this; @@ -1399,6 +1383,14 @@ GPUdi() bool SMatrixGPU::Invert() return Inverter::Dinv((*this).mRep); } +template +template +GPUdi() SMatrixGPU& SMatrixGPU::operator+=(const SMatrixGPU& rhs) +{ + mRep += rhs.mRep; + return *this; +} + template struct TranspPolicyGPU { enum { @@ -1425,6 +1417,7 @@ class TransposeOpGPU { return mRhs.apply((i % D1) * D2 + i / D1); } + GPUdi() T operator()(unsigned int i, unsigned j) const { return mRhs(j, i); diff --git a/Common/MathUtils/include/MathUtils/Utils.h b/Common/MathUtils/include/MathUtils/Utils.h index 618d3e379f6d2..79263b4142216 100644 --- a/Common/MathUtils/include/MathUtils/Utils.h +++ b/Common/MathUtils/include/MathUtils/Utils.h @@ -128,17 +128,17 @@ GPUdi() void rotateZd(double xL, double yL, double& xG, double& yG, double snAlp return detail::rotateZ(xL, yL, xG, yG, snAlp, csAlp); } -#ifndef GPUCA_GPUCODE_DEVICE -inline void rotateZInv(float xG, float yG, float& xL, float& yL, float snAlp, float csAlp) +GPUdi() void rotateZInv(float xG, float yG, float& xL, float& yL, float snAlp, float csAlp) { detail::rotateZInv(xG, yG, xL, yL, snAlp, csAlp); } -inline void rotateZInvd(double xG, double yG, double& xL, double& yL, double snAlp, double csAlp) +GPUdi() void rotateZInvd(double xG, double yG, double& xL, double& yL, double snAlp, double csAlp) { detail::rotateZInv(xG, yG, xL, yL, snAlp, csAlp); } +#ifndef GPUCA_GPUCODE_DEVICE inline std::tuple rotateZInv(float xG, float yG, float snAlp, float csAlp) { return detail::rotateZInv(xG, yG, snAlp, csAlp); diff --git a/DataFormats/Reconstruction/src/TrackParametrization.cxx b/DataFormats/Reconstruction/src/TrackParametrization.cxx index ec63bc2e95db1..3f60455bc45f8 100644 --- a/DataFormats/Reconstruction/src/TrackParametrization.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrization.cxx @@ -14,17 +14,6 @@ /// @since Oct 1, 2020 /// @brief -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - #include "ReconstructionDataFormats/TrackParametrization.h" #include "ReconstructionDataFormats/Vertex.h" #include "ReconstructionDataFormats/DCA.h" diff --git a/GPU/Common/GPUCommonMath.h b/GPU/Common/GPUCommonMath.h index abb35e1af1655..b926188e5f39a 100644 --- a/GPU/Common/GPUCommonMath.h +++ b/GPU/Common/GPUCommonMath.h @@ -325,7 +325,7 @@ GPUhdi() float GPUCommonMath::Hypot(float x, float y, float z, float w) } template -void _swap(T& a, T& b) +GPUd() void _swap(T& a, T& b) { T tmp = a; a = b; From 128db8ce21f6f09d49c4731f32bcbd5e9ca0aa8b Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 10 Sep 2024 21:55:49 +0200 Subject: [PATCH 0217/2205] ITS3: Update Readme + tracking interface fix (#13497) --- Detectors/Upgrades/ITS3/README.md | 24 +++++++++++-------- .../include/ITS3Workflow/RecoWorkflow.h | 3 ++- .../ITS3/workflow/src/RecoWorkflow.cxx | 5 ++-- .../ITS3/workflow/src/its3-reco-workflow.cxx | 9 +++---- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Detectors/Upgrades/ITS3/README.md b/Detectors/Upgrades/ITS3/README.md index 145fb0712e039..6d3b0d8d821fb 100644 --- a/Detectors/Upgrades/ITS3/README.md +++ b/Detectors/Upgrades/ITS3/README.md @@ -20,7 +20,7 @@ The run number is needed to retrieve objects from the CCDB. There are specific r - 311901—311999 _Note: For now the same topology dictionary will be used for both collision-systems_ -_Last Update of file here (jira)[https://its.cern.ch/jira/browse/O2-4698]_ +_Last Update of file here (jira)[https://its.cern.ch/jira/browse/O2-5293]_ ## Simulation @@ -42,12 +42,16 @@ Simulate diamond ### Local Tracking +0. Optionally, if not provided in the ccdb + +Create the general run parameters, see _GRPECS_. + 1. Simulate Simulate PIPE and ITS3 ```bash -o2-sim -g pythia8pp -j10 -m PIPE IT3 --run 303901 -n1000 +o2-sim -g pythia8pp --detectorList ALICE2.1 -m PIPE IT3 --run 303901 -n1000 --field ccdb ``` In the previous command: @@ -60,7 +64,7 @@ In the previous command: 2. Digitization ```bash -o2-sim-digitizer-workflow -b --interactionRate 50000 --run --configKeyValues="HBFUtils.runNumber=303901;" --onlyDet IT3 +o2-sim-digitizer-workflow -b --interactionRate 500000 --run --configKeyValues="HBFUtils.runNumber=303901;" --onlyDet IT3 root -x -l ${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckDigitsITS3.C++ ``` @@ -74,13 +78,7 @@ root -x -l ${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckT ### Global Tracking -1. Simulate - -Simulate all detectors but replacing ITS with IT3 - -```bash -o2-sim -g pythia8pp -j10 --detectorList ALICE2.1 --run 303901 -n20 -m IT3 -``` +TODO ## Creating CCDB Objects @@ -131,6 +129,12 @@ root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/Compa root -x -l '${ALIBUILD_WORK_DIR}/../O2/Detectors/Upgrades/ITS3/macros/test/CheckClusterSize.C++("o2clus_its.root", "o2sim_Kine.root", "IT3dictionary.root", false)' ``` +### GRPECS + +``` bash +o2-grp-simgrp-tool createGRPs --detectorList ALICE2.1 --run 303901 --bcPatternFile bcPattern.root --hbfpertf 128 --field -5 --publishto ccdb +``` + ### Using external generators based on AliRoot It is also possible to simulate heavy-ion collision using external generators based on AliRoot. In this case, it is necessary to load both O2 and AliROOT (the order is important): diff --git a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/RecoWorkflow.h b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/RecoWorkflow.h index 81dbf3c9f432b..bac8a128c5b39 100644 --- a/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/RecoWorkflow.h +++ b/Detectors/Upgrades/ITS3/workflow/include/ITS3Workflow/RecoWorkflow.h @@ -30,7 +30,8 @@ framework::WorkflowSpec getWorkflow(bool useMC, bool upstreamClusters, bool disableRootOutput, bool useGeom, - int useTrig); + int useTrig, + bool overrideBeamPosition); } #endif diff --git a/Detectors/Upgrades/ITS3/workflow/src/RecoWorkflow.cxx b/Detectors/Upgrades/ITS3/workflow/src/RecoWorkflow.cxx index 5b884fdc677eb..721ef36335631 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/RecoWorkflow.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/RecoWorkflow.cxx @@ -21,7 +21,7 @@ namespace o2::its3::reco_workflow { framework::WorkflowSpec getWorkflow(bool useMC, const std::string& trmode, o2::gpu::GPUDataTypes::DeviceType dtype, - bool upstreamDigits, bool upstreamClusters, bool disableRootOutput, bool useGeom, int useTrig) + bool upstreamDigits, bool upstreamClusters, bool disableRootOutput, bool useGeom, int useTrig, bool overrideBeamPosition) { framework::WorkflowSpec specs; @@ -38,8 +38,7 @@ framework::WorkflowSpec getWorkflow(bool useMC, const std::string& trmode, o2::g } if (trmode != "off") { - LOGP(info, "Active tracking: '{}'", trmode); - specs.emplace_back(o2::its3::getTrackerSpec(useMC, useGeom, useTrig, trmode, dtype)); + specs.emplace_back(o2::its3::getTrackerSpec(useMC, useGeom, useTrig, trmode, overrideBeamPosition, dtype)); if (!disableRootOutput) { specs.emplace_back(o2::its3::getTrackWriterSpec(useMC)); diff --git a/Detectors/Upgrades/ITS3/workflow/src/its3-reco-workflow.cxx b/Detectors/Upgrades/ITS3/workflow/src/its3-reco-workflow.cxx index 48dfb158a80d9..b8aec2541d31f 100644 --- a/Detectors/Upgrades/ITS3/workflow/src/its3-reco-workflow.cxx +++ b/Detectors/Upgrades/ITS3/workflow/src/its3-reco-workflow.cxx @@ -43,12 +43,12 @@ void customize(std::vector& workflowOptions) {"clusters-from-upstream", o2::framework::VariantType::Bool, false, {"clusters will be provided from upstream, skip clusterizer"}}, {"disable-root-output", o2::framework::VariantType::Bool, false, {"do not write output root files"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation even if available"}}, + {"ccdb-meanvertex-seed", o2::framework::VariantType::Bool, false, {"use MeanVertex from CCDB if available to provide beam position seed (default: false)"}}, {"select-with-triggers", o2::framework::VariantType::String, "none", {"use triggers to prescale processed ROFs: phys, trd, none"}}, {"tracking-mode", o2::framework::VariantType::String, "off", {"off,sync,async,cosmics"}}, - {"entropy-encoding", o2::framework::VariantType::Bool, false, {"produce entropy encoded data"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}, {"use-full-geometry", o2::framework::VariantType::Bool, false, {"use full geometry instead of the light-weight IT3 part"}}, - {"gpuDevice", o2::framework::VariantType::Int, 1, {"use gpu device: CPU=1,CUDA=2,HIP=3 (default: CPU)"}}}; + {"gpu-device", o2::framework::VariantType::Int, 1, {"use gpu device: CPU=1,CUDA=2,HIP=3 (default: CPU)"}}}; o2::raw::HBFUtilsInitializer::addConfigOption(options); std::swap(workflowOptions, options); } @@ -59,9 +59,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) { // Update the (declared) parameters if changed from the command line auto useMC = !configcontext.options().get("disable-mc"); + auto beamPosOVerride = configcontext.options().get("ccdb-meanvertex-seed"); auto trmode = configcontext.options().get("tracking-mode"); auto selTrig = configcontext.options().get("select-with-triggers"); - auto gpuDevice = static_cast(configcontext.options().get("gpuDevice")); + auto gpuDevice = static_cast(configcontext.options().get("gpu-device")); auto extDigits = configcontext.options().get("digits-from-upstream"); auto extClusters = configcontext.options().get("clusters-from-upstream"); auto disableRootOutput = configcontext.options().get("disable-root-output"); @@ -79,7 +80,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) LOG(fatal) << "Unknown trigger type requested for events prescaling: " << selTrig; } } - auto wf = o2::its3::reco_workflow::getWorkflow(useMC, trmode, gpuDevice, extDigits, extClusters, disableRootOutput, useGeom, trType); + auto wf = o2::its3::reco_workflow::getWorkflow(useMC, trmode, gpuDevice, extDigits, extClusters, disableRootOutput, useGeom, trType, beamPosOVerride); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); From 053e8623f60404136961c5b90eb0061c7de4d7b9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sun, 8 Sep 2024 17:10:33 +0200 Subject: [PATCH 0218/2205] GPU Build: Add optional linker version script to demote symbols (currently unused) --- GPU/GPUTracking/Base/cuda/CMakeLists.txt | 2 ++ GPU/GPUTracking/Base/cuda/version_script.ld | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 GPU/GPUTracking/Base/cuda/version_script.ld diff --git a/GPU/GPUTracking/Base/cuda/CMakeLists.txt b/GPU/GPUTracking/Base/cuda/CMakeLists.txt index 8569756221798..7fe4df4b3b8b5 100644 --- a/GPU/GPUTracking/Base/cuda/CMakeLists.txt +++ b/GPU/GPUTracking/Base/cuda/CMakeLists.txt @@ -150,6 +150,8 @@ endif() # Setting target architecture and adding GPU libraries target_link_libraries(${targetName} PRIVATE cuda cudart nvrtc) set_target_cuda_arch(${targetName}) +#target_link_options(${targetName} PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version_script.ld") +#set_target_properties(${targetName} PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/version_script.ld) if(OpenMP_CXX_FOUND) # Must be private, depending libraries might be compiled by compiler not understanding -fopenmp diff --git a/GPU/GPUTracking/Base/cuda/version_script.ld b/GPU/GPUTracking/Base/cuda/version_script.ld new file mode 100644 index 0000000000000..14340c03343e9 --- /dev/null +++ b/GPU/GPUTracking/Base/cuda/version_script.ld @@ -0,0 +1,11 @@ +{ + global: + extern "C++" { + "GPUReconstruction_Create_CUDA"; + "o2::gpu::cuda::*" + }; + local: + extern "C++" { + o2::*; + }; +}; From 158e6f82f363c201e5aa632340bcbd341b02f80d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 9 Sep 2024 15:50:01 +0200 Subject: [PATCH 0219/2205] GPU CMake: Add check for minimum ROCm version --- dependencies/FindO2GPU.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index fa82e2b6128d6..0db27d1f177fd 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -267,6 +267,9 @@ if(ENABLE_HIP) elseif(NOT ENABLE_HIP STREQUAL "AUTO") message(FATAL_ERROR "HIP requested, but CMAKE_PREFIX_PATH env variable does not contain rocm folder!") endif() + if(hip_FOUND AND NOT hip_VERSION VERSION_GREATER_EQUAL "5.5") + set(hip_FOUND 0) + endif() if(hip_FOUND AND hipcub_FOUND AND rocthrust_FOUND AND rocprim_FOUND AND hip_HIPCC_EXECUTABLE AND hip_HIPIFY_PERL_EXECUTABLE) set(HIP_ENABLED ON) set_target_properties(roc::rocthrust PROPERTIES IMPORTED_GLOBAL TRUE) From 29072b4d8ee72d0af3e7b6ca1979bedec7fdadeb Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 9 Sep 2024 15:50:23 +0200 Subject: [PATCH 0220/2205] DPL: Gather TF status if complete/incomplete/empty, to be sent as message --- .../Core/src/ExternalFairMQDeviceProxy.cxx | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx index 239dd5f40e82f..5a88be2dde6e1 100644 --- a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx +++ b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx @@ -240,10 +240,13 @@ void injectMissingData(fair::mq::Device& device, fair::mq::Parts& parts, std::ve { // Check for missing data. static std::vector present; + static std::vector ignored; static std::vector dataSizes; static std::vector showSize; present.clear(); present.resize(routes.size(), false); + ignored.clear(); + ignored.resize(routes.size(), false); dataSizes.clear(); dataSizes.resize(routes.size(), 0); showSize.clear(); @@ -260,7 +263,7 @@ void injectMissingData(fair::mq::Device& device, fair::mq::Parts& parts, std::ve for (size_t pi = 0; pi < present.size(); ++pi) { auto& spec = routes[pi].matcher; if (DataSpecUtils::asConcreteDataTypeMatcher(spec).description == header::DataDescription("DISTSUBTIMEFRAME")) { - present[pi] = true; + ignored[pi] = true; continue; } if (routes[pi].timeslice == 0) { @@ -269,6 +272,7 @@ void injectMissingData(fair::mq::Device& device, fair::mq::Parts& parts, std::ve } size_t foundDataSpecs = 0; + bool skipAsAllFound = false; for (int msgidx = 0; msgidx < parts.Size(); msgidx += 2) { bool allFound = true; int addToSize = -1; @@ -300,24 +304,24 @@ void injectMissingData(fair::mq::Device& device, fair::mq::Parts& parts, std::ve dph = o2::header::get(parts.At(msgidx)->GetData()); for (size_t pi = 0; pi < present.size(); ++pi) { if (routes[pi].timeslice != (dph->startTime % routes[pi].maxTimeslices)) { - present[pi] = true; + ignored[pi] = true; } } } for (size_t pi = 0; pi < present.size(); ++pi) { - if (present[pi] && !doPrintSizes) { + if ((present[pi] || ignored[pi]) && !doPrintSizes) { continue; } // Consider uninvolved pipelines as present. if (routes[pi].timeslice != (dph->startTime % routes[pi].maxTimeslices)) { - present[pi] = true; + ignored[pi] = true; continue; } allFound = false; auto& spec = routes[pi].matcher; OutputSpec query{dh->dataOrigin, dh->dataDescription, dh->subSpecification}; if (DataSpecUtils::match(spec, query)) { - if (!present[pi]) { + if (!present[pi] && !ignored[pi]) { ++foundDataSpecs; present[pi] = true; showSize[pi] = true; @@ -336,16 +340,27 @@ void injectMissingData(fair::mq::Device& device, fair::mq::Parts& parts, std::ve // Skip the rest of the block of messages. We subtract 2 because above we increment by 2. msgidx = msgidxLast - 2; if (allFound && !doPrintSizes) { - return; + skipAsAllFound = true; + break; } } + bool emptyTf = true; for (size_t pi = 0; pi < present.size(); ++pi) { - if (!present[pi]) { + if (present[pi] && !ignored[pi]) { + emptyTf = false; + } + if (!present[pi] && !ignored[pi]) { showSize[pi] = true; unmatchedDescriptions.push_back(pi); } } + int timeframeCompleteness = emptyTf ? 0 : (unmatchedDescriptions.size() ? -1 : 1); + (void)timeframeCompleteness; // To be sent as message + + if (skipAsAllFound && !doPrintSizes) { + return; + } if (firstDH && doPrintSizes) { std::string sizes = ""; From daf4569fd40c22f2b98a5bd6b5eb1b71444b2038 Mon Sep 17 00:00:00 2001 From: Ruben Shahoyan Date: Wed, 11 Sep 2024 10:46:39 +0200 Subject: [PATCH 0221/2205] Fix ITS track pattern building, add vertex info, add LinkDef for dictionary (#13496) * Fix ITS track pattern building, add LinkDef for dictionary * Add ITS occupancy at MC event time * Add vertexing and matching info --- .../study/CMakeLists.txt | 14 +- .../GlobalTrackingStudy/TrackMCStudyConfig.h | 10 +- .../GlobalTrackingStudy/TrackMCStudyTypes.h | 36 +++- .../study/src/GlobalTrackingStudyLinkDef.h | 5 + .../study/src/TrackMCStudy.cxx | 160 +++++++++++++----- 5 files changed, 173 insertions(+), 52 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt index adae8dcfb8b10..950f071c80232 100644 --- a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt +++ b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt @@ -9,7 +9,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -add_compile_options(-O0 -g -fPIC) +# add_compile_options(-O0 -g -fPIC) o2_add_library(GlobalTrackingStudy SOURCES src/TPCTrackStudy.cxx @@ -31,12 +31,12 @@ o2_add_library(GlobalTrackingStudy O2::TPCWorkflow O2::SimulationDataFormat) -o2_target_root_dictionary( - GlobalTrackingStudy - HEADERS include/GlobalTrackingStudy/V0Ext.h - include/GlobalTrackingStudy/TrackInfoExt.h - include/GlobalTrackingStudy/TrackMCStudyConfig.h - include/GlobalTrackingStudy/TrackMCStudyTypes.h +o2_target_root_dictionary(GlobalTrackingStudy + HEADERS include/GlobalTrackingStudy/V0Ext.h + include/GlobalTrackingStudy/TrackInfoExt.h + include/GlobalTrackingStudy/TrackMCStudyConfig.h + include/GlobalTrackingStudy/TrackMCStudyTypes.h + LINKDEF src/GlobalTrackingStudyLinkDef.h ) o2_add_executable(study-workflow diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h index 8ba48ea2010a4..895cb5222deac 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h @@ -18,15 +18,15 @@ namespace o2::trackstudy { struct TrackMCStudyConfig : o2::conf::ConfigurableParamHelper { float minPt = 0.05; - float maxTgl = 1.2; + float maxTgl = 1.5; float minPtMC = 0.05; - float maxTglMC = 1.2; - float minRMC = 33.; + float maxTglMC = 1.5; + float maxRMC = 33.; float maxPosTglMC = 2.; float maxPVZOffset = 15.; - float decayMotherMaxT = 0.1; // max TOF in ns for mother particles to study + float decayMotherMaxT = 1.0f; // max TOF in ns for mother particles to study bool requireITSorTPCTrackRefs = true; - int decayPDG[5] = {310, 3122, -1, -1, -1}; // decays to study, must end by -1 + int decayPDG[5] = {310, 3122, 411, 421, -1}; // decays to study, must end by -1 O2ParamDef(TrackMCStudyConfig, "trmcconf"); }; } // namespace o2::trackstudy diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h index 0334af3448fba..f99ba9f4ef68e 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h @@ -15,14 +15,22 @@ #include "ReconstructionDataFormats/VtxTrackIndex.h" #include "ReconstructionDataFormats/Track.h" #include "SimulationDataFormat/MCCompLabel.h" -#include "Framework/Task.h" +#include "SimulationDataFormat/MCEventLabel.h" +#include "CommonConstants/LHCConstants.h" +#include "CommonDataFormat/TimeStamp.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include namespace o2::trackstudy { struct MCTrackInfo { + + inline float getMCTimeMUS() const { return bcInTF * o2::constants::lhc::LHCBunchSpacingMUS; } + o2::track::TrackPar track{}; o2::MCCompLabel label{}; float occTPC = -1.f; + int occITS = -1.f; int bcInTF = -1; int pdg = 0; int pdgParent = 0; @@ -38,6 +46,9 @@ struct MCTrackInfo { struct RecTrack { o2::track::TrackParCov track{}; o2::dataformats::VtxTrackIndex gid{}; + o2::dataformats::TimeStampWithError ts{}; + o2::MCEventLabel pvLabel{}; + int pvID = -1; uint8_t nClITS = 0; uint8_t nClTPC = 0; uint8_t pattITS = 0; @@ -49,9 +60,12 @@ struct RecTrack { struct TrackFamily { // set of tracks related to the same MC label MCTrackInfo mcTrackInfo{}; std::vector recTracks{}; + o2::track::TrackParCov trackITSProp{}; + o2::track::TrackParCov trackTPCProp{}; int8_t entITS = -1; int8_t entTPC = -1; int8_t entITSTPC = -1; + float tpcT0 = -999.; bool contains(const o2::dataformats::VtxTrackIndex& ref) const { for (const auto& tr : recTracks) { @@ -64,5 +78,25 @@ struct TrackFamily { // set of tracks related to the same MC label ClassDefNV(TrackFamily, 1); }; + +struct RecPV { + o2::dataformats::PrimaryVertex pv{}; + o2::MCEventLabel mcEvLbl{}; + ClassDefNV(RecPV, 1); +}; + +struct MCVertex { + float getX() const { return pos[0]; } + float getY() const { return pos[1]; } + float getZ() const { return pos[2]; } + + std::array pos{0., 0., -1999.f}; + float ts = 0; + int nTrackSel = 0; // number of selected MC charged tracks + int ID = -1; + std::vector recVtx{}; + ClassDefNV(MCVertex, 1); +}; + } // namespace o2::trackstudy #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h index a0cfc30726e9a..f4d56b50ec6ec 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h +++ b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h @@ -29,4 +29,9 @@ #pragma link C++ class std::vector < o2::trackstudy::TrackFamily> + ; #pragma link C++ class o2::trackstudy::MCTrackInfo + ; #pragma link C++ class std::vector < o2::trackstudy::MCTrackInfo> + ; +#pragma link C++ class o2::trackstudy::RecPV + ; +#pragma link C++ class std::vector < o2::trackstudy::RecPV> + ; +#pragma link C++ class o2::trackstudy::MCVertex + ; +#pragma link C++ class std::vector < o2::trackstudy::MCVertex> + ; + #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index bd259ff499ae2..0ac45f20004a8 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -108,6 +108,7 @@ class TrackMCStudy : public Task std::vector mTBinClOcc; ///< TPC occupancy histo: i-th entry is the integrated occupancy for ~1 orbit starting from the TB = i*mNTPCOccBinLength std::vector mIntBC; ///< interaction global BC wrt TF start std::vector mTPCOcc; ///< TPC occupancy for this interaction time + std::vector mITSOcc; //< N ITS clusters in the ROF containing collision int mNTPCOccBinLength = 0; ///< TPC occ. histo bin length in TBs float mNTPCOccBinLengthInv; int mVerbose = 0; @@ -115,18 +116,15 @@ class TrackMCStudy : public Task float mITSROFrameLengthMUS = 0.f; ///< ITS RO frame in mus float mTPCTBinMUS = 0.; ///< TPC time bin duration in microseconds - float mTPCDCAYCut = 2.; - float mTPCDCAZCut = 2.; - float mMinX = 6.; - int mMinTPCClusters = 10; int mNCheckDecays = 0; - std::string mDCAYFormula = "0.0105 + 0.0350 / pow(x, 1.1)"; GTrackID::mask_t mTracksSrc{}; o2::steer::MCKinematicsReader mcReader; // reader of MC information std::vector mITSROF; std::vector mITSROFBracket; std::vector mDecProdLblPool; // labels of decay products to watch, added to MC map + std::vector mMCVtVec{}; + struct DecayRef { o2::MCCompLabel mother{}; o2::track::TrackPar parent{}; @@ -147,11 +145,6 @@ void TrackMCStudy::init(InitContext& ic) mDBGOut = std::make_unique("trackMCStudy.root", "recreate"); mVerbose = ic.options().get("device-verbosity"); - mTPCDCAYCut = ic.options().get("max-tpc-dcay"); - mTPCDCAZCut = ic.options().get("max-tpc-dcaz"); - mMinX = ic.options().get("min-x-prop"); - mMinTPCClusters = ic.options().get("min-tpc-clusters"); - mDCAYFormula = ic.options().get("dcay-vs-pt"); const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); for (int id = 0; id < sizeof(params.decayPDG) / sizeof(int); id++) { @@ -170,6 +163,7 @@ void TrackMCStudy::run(ProcessingContext& pc) mDecaysMaps[i].clear(); } mDecProdLblPool.clear(); + mMCVtVec.clear(); mCurrMCTracks = {}; recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer @@ -202,19 +196,21 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc) void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) { + constexpr float SQRT12Inv = 0.288675f; const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); auto pvvec = recoData.getPrimaryVertices(); + auto pvvecLbl = recoData.getPrimaryVertexMCLabels(); auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs auto prop = o2::base::Propagator::Instance(); int nv = vtxRefs.size(); float vdriftTB = mTPCVDriftHelper.getVDriftObject().getVDrift() * o2::tpc::ParameterElectronics::Instance().ZbinWidth; // VDrift expressed in cm/TimeBin - float itsBias = 0.5 * mITSROFrameLengthMUS + o2::itsmft::DPLAlpideParam::Instance().roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // ITS time is supplied in \mus as beginning of ROF + float itsBias = 0.5 * mITSROFrameLengthMUS + o2::itsmft::DPLAlpideParam::Instance().roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingMUS; // ITS time is supplied in \mus as beginning of ROF prepareITSData(recoData); loadTPCOccMap(recoData); auto getITSPatt = [&](GTrackID gid, uint8_t& ncl) { - int16_t patt = 0; + int8_t patt = 0; if (gid.getSource() == VTIndex::ITSAB) { const auto& itsTrf = recoData.getITSABRefs()[gid]; ncl = itsTrf.getNClusters(); @@ -223,7 +219,7 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) patt |= 0x1 << il; } } - patt = -patt; + patt |= 0x1 << 7; } else { const auto& itsTr = recoData.getITSTrack(gid); for (int il = 0; il < 7; il++) { @@ -247,28 +243,67 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) return -1; }; - const auto* digconst = mcReader.getDigitizationContext(); - const auto& mcEvRecords = digconst->getEventRecords(false); - for (const auto& mcIR : mcEvRecords) { - long tbc = mcIR.differenceInBC(recoData.startIR); - mIntBC.push_back(tbc); - int occBin = tbc / 8 * mNTPCOccBinLengthInv; - mTPCOcc.push_back(occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin])); + { + const auto* digconst = mcReader.getDigitizationContext(); + const auto& mcEvRecords = digconst->getEventRecords(false); + int ITSTimeBias = o2::itsmft::DPLAlpideParam::Instance().roFrameBiasInBC; + int ITSROFLen = o2::itsmft::DPLAlpideParam::Instance().roFrameLengthInBC; + unsigned int rofCount = 0; + const auto ITSClusROFRec = recoData.getITSClustersROFRecords(); + for (const auto& mcIR : mcEvRecords) { + long tbc = mcIR.differenceInBC(recoData.startIR); + auto& mcVtx = mMCVtVec.emplace_back(); + mcVtx.ts = tbc * o2::constants::lhc::LHCBunchSpacingMUS + mcIR.getTimeOffsetWrtBC() * 1e-3; + mcVtx.ID = mIntBC.size(); + mIntBC.push_back(tbc); + int occBin = tbc / 8 * mNTPCOccBinLengthInv; + mTPCOcc.push_back(occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin])); + // fill ITS occupancy + long gbc = mcIR.toLong(); + while (rofCount < ITSClusROFRec.size()) { + long rofbcMin = ITSClusROFRec[rofCount].getBCData().toLong() + ITSTimeBias, rofbcMax = rofbcMin + ITSROFLen; + if (gbc < rofbcMin) { // IRs and ROFs are sorted, so this IR is prior of all ROFs + mITSOcc.push_back(0); + } else if (gbc < rofbcMax) { + mITSOcc.push_back(ITSClusROFRec[rofCount].getNEntries()); + } else { + rofCount++; // test next ROF + continue; + } + break; + } + if (rofCount >= ITSClusROFRec.size()) { + mITSOcc.push_back(0); // IR after the last ROF + } + } } - // collect interesting MC particle (tracks and parents) int curSrcMC = 0, curEvMC = 0; for (curSrcMC = 0; curSrcMC < (int)mcReader.getNSources(); curSrcMC++) { if (mVerbose > 1) { LOGP(info, "Source {}", curSrcMC); } - for (curEvMC = 0; curEvMC < (int)mcReader.getNEvents(curSrcMC); curEvMC++) { + int nev = mcReader.getNEvents(curSrcMC); + bool okAccVtx = true; + if (nev != (int)mMCVtVec.size()) { + LOGP(error, "source {} has {} events while {} MC vertices were booked", curSrcMC, nev, mMCVtVec.size()); + okAccVtx = false; + } + for (curEvMC = 0; curEvMC < nev; curEvMC++) { if (mVerbose > 1) { LOGP(info, "Event {}", curEvMC); } const auto& mt = mcReader.getTracks(curSrcMC, curEvMC); mCurrMCTracks = gsl::span(mt.data(), mt.size()); const_cast(mcReader.getMCEventHeader(curSrcMC, curEvMC)).GetVertex(mCurrMCVertex); + if (okAccVtx) { + auto& pos = mMCVtVec[curEvMC].pos; + if (pos[2] < -999) { + pos[0] = mCurrMCVertex.X(); + pos[1] = mCurrMCVertex.Y(); + pos[2] = mCurrMCVertex.Z(); + } + } for (int itr = 0; itr < mCurrMCTracks.size(); itr++) { processMCParticle(curSrcMC, curEvMC, itr); } @@ -285,6 +320,15 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) if (mVerbose > 1) { LOGP(info, "processing PV {} of {}", iv, nv); } + o2::MCEventLabel pvLbl; + int pvID = -1; + if (iv < (int)pvvecLbl.size()) { + pvLbl = pvvecLbl[iv]; + pvID = iv; + if (pvLbl.isSet() && pvLbl.getEventID() < mMCVtVec.size()) { + mMCVtVec[pvLbl.getEventID()].recVtx.emplace_back(RecPV{pvvec[iv], pvLbl}); + } + } const auto& vtref = vtxRefs[iv]; for (int is = GTrackID::NSources; is--;) { DetID::mask_t dm = GTrackID::getSourceDetectorsMask(is); @@ -323,6 +367,8 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } auto& trf = trackFamily.recTracks.emplace_back(); trf.gid = vid; // account(iv, vid); + trf.pvID = pvID; + trf.pvLabel = pvLbl; if (mVerbose > 1) { LOGP(info, "Matched rec track {} to MC track {}", vid.asString(), entry->first.asString()); } @@ -349,7 +395,15 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) LOGP(info, "Processing MC track#{} {} -> {} reconstructed tracks", mcnt - 1, entry.first.asString(), tracks.size()); } // sort according to the gid complexity (in principle, should be already sorted due to the backwards loop over NSources above - std::sort(tracks.begin(), tracks.end(), [](RecTrack& lhs, RecTrack& rhs) { return lhs.gid.getSource() > rhs.gid.getSource(); }); + std::sort(tracks.begin(), tracks.end(), [](const RecTrack& lhs, const RecTrack& rhs) { + const auto mskL = lhs.gid.getSourceDetectorsMask(); + const auto mskR = rhs.gid.getSourceDetectorsMask(); + bool itstpcL = mskL[DetID::ITS] && mskL[DetID::TPC], itstpcR = mskR[DetID::ITS] && mskR[DetID::TPC]; + if (itstpcL && !itstpcR) { // to avoid TPC/TRD or TPC/TOF shadowing ITS/TPC + return true; + } + return lhs.gid.getSource() > rhs.gid.getSource(); + }); // fill track params int tcnt = 0; for (auto& tref : tracks) { @@ -360,35 +414,51 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) if (msk[DetID::ITS]) { auto gidITS = recoData.getITSContributorGID(tref.gid); tref.pattITS = getITSPatt(gidITS, tref.nClITS); - if (tref.gid.getSource() == VTIndex::ITS && trackFam.entITS < 0) { + if (gidITS.getSource() == VTIndex::ITS && trackFam.entITS < 0) { // has ITS track rather than AB tracklet trackFam.entITS = tcnt; } - if (msk[DetID::TPC] && trackFam.entITSTPC < 0) { + if (msk[DetID::TPC] && trackFam.entITSTPC < 0) { // has both ITS and TPC contribution trackFam.entITSTPC = tcnt; } } - if (msk[DetID::TPC] && trackFam.entTPC < 0) { - if (tref.gid.getSource() == VTIndex::TPC) { - trackFam.entTPC = tcnt; - } + if (msk[DetID::TPC]) { auto gidTPC = recoData.getTPCContributorGID(tref.gid); const auto& trtpc = recoData.getTPCTrack(gidTPC); tref.nClTPC = trtpc.getNClusters(); - tref.lowestPadRow = getLowestPadrow(recoData.getTPCTrack(gidTPC)); + tref.lowestPadRow = getLowestPadrow(trtpc); + if (trackFam.entTPC < 0) { + trackFam.entTPC = tcnt; + trackFam.tpcT0 = trtpc.getTime0(); + } + } + float ts = 0, terr = 0; + if (tref.gid.getSource() != GTrackID::ITS) { + recoData.getTrackTime(tref.gid, ts, terr); + tref.ts = timeEst{ts, terr}; + } else { + const auto& itsBra = mITSROFBracket[mITSROF[tref.gid.getIndex()]]; + tref.ts = timeEst{itsBra.mean(), itsBra.delta() * SQRT12Inv}; } } else { LOGP(info, "Invalid entry {} of {} getTrackMCLabel {}", tcnt, tracks.size(), tref.gid.asString()); } tcnt++; } - if (trackFam.entITSTPC < 0 && trackFam.entITS > -1 && trackFam.entTPC > -1) { // ITS and TPC were found but matching failed + if (trackFam.entITS > -1 && trackFam.entTPC > -1) { // ITS and TPC were found but matching failed auto vidITS = tracks[trackFam.entITS].gid; auto vidTPC = tracks[trackFam.entTPC].gid; auto trcTPC = recoData.getTrackParam(vidTPC); auto trcITS = recoData.getTrackParamOut(vidITS); - if (!propagateToRefX(trcTPC, trcITS)) { - // break; + if (propagateToRefX(trcTPC, trcITS)) { + trackFam.trackITSProp = trcITS; + trackFam.trackTPCProp = trcTPC; + } else { + trackFam.trackITSProp.invalidate(); + trackFam.trackTPCProp.invalidate(); } + } else { + trackFam.trackITSProp.invalidate(); + trackFam.trackTPCProp.invalidate(); } } @@ -407,7 +477,7 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) auto dtLbl = mDecProdLblPool[idd]; // daughter MC label const auto& dtFamily = mSelMCTracks[dtLbl]; if (dtFamily.mcTrackInfo.pdgParent != dec.pdg) { - LOGP(error, "{}-th decay (pdg={}): {} in {}:{} range refers to MC track with pdgParent = {}", id, params.decayPDG[id], idd, dec.daughterFirst, dec.daughterLast, dtFamily.mcTrackInfo.pdgParent); + LOGP(error, "{}-th decay (pdg={}): {} in {}:{} range refers to MC track with pdgParent = {}", id, params.decayPDG[id], idd, dec.daughterFirst, dec.daughterLast, dtFamily.mcTrackInfo.pdgParent); continue; } decFam.push_back(dtFamily); @@ -415,6 +485,13 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "\n"; } } + + for (auto& mcVtx : mMCVtVec) { // sort rec.vertices in mult. order + std::sort(mcVtx.recVtx.begin(), mcVtx.recVtx.end(), [](const RecPV& lhs, const RecPV& rhs) { + return lhs.pv.getNContributors() > rhs.pv.getNContributors(); + }); + (*mDBGOut) << "mcVtxTree" << "mcVtx=" << mcVtx << "\n"; + } } void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& recoData) @@ -524,8 +601,8 @@ void TrackMCStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) //_____________________________________________________ void TrackMCStudy::prepareITSData(const o2::globaltracking::RecoContainer& recoData) { - auto ITSTracksArray = recoData.getITSTracks(); - auto ITSTrackROFRec = recoData.getITSTracksROFRecords(); + const auto ITSTracksArray = recoData.getITSTracks(); + const auto ITSTrackROFRec = recoData.getITSTracksROFRecords(); int nROFs = ITSTrackROFRec.size(); mITSROF.clear(); mITSROFBracket.clear(); @@ -542,12 +619,13 @@ void TrackMCStudy::prepareITSData(const o2::globaltracking::RecoContainer& recoD } } } - +/* float TrackMCStudy::getDCAYCut(float pt) const { static TF1 fun("dcayvspt", mDCAYFormula.c_str(), 0, 20); return fun.Eval(pt); } +*/ bool TrackMCStudy::processMCParticle(int src, int ev, int trid) { @@ -611,7 +689,7 @@ bool TrackMCStudy::acceptMCCharged(const MCTrack& tr, const o2::MCCompLabel& lb, const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); if (tr.GetPt() < params.minPtMC || std::abs(tr.GetTgl()) > params.maxTglMC || - tr.R2() > params.minRMC * params.minRMC) { + tr.R2() > params.maxRMC * params.maxRMC) { if (mVerbose > 1 && followDecay > -1) { LOGP(info, "rejecting decay {} prong : pdg={}, pT={}, tgL={}, r={}", followDecay, tr.GetPdgCode(), tr.GetPt(), tr.GetTgl(), std::sqrt(tr.R2())); } @@ -660,16 +738,20 @@ bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& l } auto& mcEntry = mSelMCTracks[lb]; mcEntry.mcTrackInfo.pdg = mcPart.GetPdgCode(); - mcEntry.mcTrackInfo.track = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); + mcEntry.mcTrackInfo.track = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), true); mcEntry.mcTrackInfo.label = lb; mcEntry.mcTrackInfo.bcInTF = mIntBC[lb.getEventID()]; mcEntry.mcTrackInfo.occTPC = mTPCOcc[lb.getEventID()]; + mcEntry.mcTrackInfo.occITS = mITSOcc[lb.getEventID()]; int moth = -1; o2::MCCompLabel mclbPar; if (!mcPart.isPrimary() && (moth = mcPart.getMotherTrackId()) >= 0) { const auto& mcPartPar = mCurrMCTracks[moth]; mcEntry.mcTrackInfo.pdgParent = mcPartPar.GetPdgCode(); } + if (mcPart.isPrimary() && mcReader.getNEvents(lb.getSourceID()) == mMCVtVec.size()) { + mMCVtVec[lb.getEventID()].nTrackSel++; + } if (mVerbose > 1) { LOGP(info, "Adding charged MC pdg={} {} ", mcPart.GetPdgCode(), lb.asString()); } From b943e693d9dda7649ba33567e9dcfc496f89256e Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Wed, 11 Sep 2024 18:20:56 +0200 Subject: [PATCH 0222/2205] Support reading remotely in the strainer --- Framework/AODMerger/src/aodStrainer.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Framework/AODMerger/src/aodStrainer.cxx b/Framework/AODMerger/src/aodStrainer.cxx index f3f78a616951c..ca53a33fd0b96 100644 --- a/Framework/AODMerger/src/aodStrainer.cxx +++ b/Framework/AODMerger/src/aodStrainer.cxx @@ -98,6 +98,9 @@ int main(int argc, char* argv[]) auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", 505); TDirectory* outputDir = nullptr; TString line(inputAO2D.c_str()); + if (line.BeginsWith("alien://")) { + TGrid::Connect("alien:"); + } printf("Processing input file: %s\n", line.Data()); auto inputFile = TFile::Open(line); if (!inputFile) { From 71163f805e26e401c28cca7e9bfc82e972ff243b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 11 Sep 2024 18:43:35 +0200 Subject: [PATCH 0223/2205] GPU CMake: Prepend a couple of Standalone CMake options with GPUCA_ --- GPU/GPUTracking/Base/cuda/CMakeLists.txt | 2 +- GPU/GPUTracking/Base/hip/CMakeLists.txt | 2 +- GPU/GPUTracking/CMakeLists.txt | 6 +-- GPU/GPUTracking/Standalone/CMakeLists.txt | 48 +++++++++---------- GPU/GPUTracking/Standalone/cmake/config.cmake | 24 +++++----- GPU/GPUTracking/display/CMakeLists.txt | 2 +- GPU/GPUTracking/kernels.cmake | 4 +- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/GPU/GPUTracking/Base/cuda/CMakeLists.txt b/GPU/GPUTracking/Base/cuda/CMakeLists.txt index 7fe4df4b3b8b5..a24092f50ebaf 100644 --- a/GPU/GPUTracking/Base/cuda/CMakeLists.txt +++ b/GPU/GPUTracking/Base/cuda/CMakeLists.txt @@ -212,7 +212,7 @@ if(NOT GPUCA_CUDA_COMPILE_MODE STREQUAL "rdc") set_target_properties(${targetName} PROPERTIES LINKER_LANGUAGE CXX) endif() -if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR CONFIG_O2_EXTENSIONS) +if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR GPUCA_CONFIG_O2_EXTENSIONS) add_library(GPUTrackingCUDAExternalProvider OBJECT GPUReconstructionCUDAExternalProvider.cu) add_library(O2::GPUTrackingCUDAExternalProvider ALIAS GPUTrackingCUDAExternalProvider) set_property(TARGET GPUTrackingCUDAExternalProvider PROPERTY CUDA_SEPARABLE_COMPILATION ON) diff --git a/GPU/GPUTracking/Base/hip/CMakeLists.txt b/GPU/GPUTracking/Base/hip/CMakeLists.txt index f500220008536..f488ce8c7dd14 100644 --- a/GPU/GPUTracking/Base/hip/CMakeLists.txt +++ b/GPU/GPUTracking/Base/hip/CMakeLists.txt @@ -275,7 +275,7 @@ if(NOT GPUCA_HIP_COMPILE_MODE STREQUAL "rdc") target_link_options(${targetName} PRIVATE $<$:-fno-gpu-rdc>) endif() -if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR CONFIG_O2_EXTENSIONS) +if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR GPUCA_CONFIG_O2_EXTENSIONS) add_library(GPUTrackingHIPExternalProvider OBJECT ${GPUCA_HIP_SOURCE_DIR}/GPUReconstructionHIPExternalProvider.hip) add_library(O2::GPUTrackingHIPExternalProvider ALIAS GPUTrackingHIPExternalProvider) target_compile_options(GPUTrackingHIPExternalProvider PRIVATE $<$:-fgpu-rdc>) diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index c4ad13f2a888e..caed8a8a26d09 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -28,7 +28,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "ALIROOT") include("cmake/kernel_helpers.cmake") endif() else() - if((ALIGPU_BUILD_TYPE STREQUAL "Standalone" AND BUILD_EVENT_DISPLAY) OR (ALIGPU_BUILD_TYPE STREQUAL "O2" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET AliceO2::DebugGUI AND OPENGL_FOUND AND GLFW_FOUND)) + if((ALIGPU_BUILD_TYPE STREQUAL "Standalone" AND GPUCA_BUILD_EVENT_DISPLAY) OR (ALIGPU_BUILD_TYPE STREQUAL "O2" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET AliceO2::DebugGUI AND OPENGL_FOUND AND GLFW_FOUND)) set(GPUCA_EVENT_DISPLAY ON) endif() if(ROOT_FOUND) @@ -171,7 +171,7 @@ set(HDRS_INSTALL if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR ALIGPU_BUILD_TYPE STREQUAL "Standalone") set(SRCS_NO_CINT ${SRCS_NO_CINT} display/GPUDisplayInterface.cxx) endif() -if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR CONFIG_O2_EXTENSIONS) +if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR GPUCA_CONFIG_O2_EXTENSIONS) set(SRCS_NO_CINT ${SRCS_NO_CINT} Global/GPUChainITS.cxx @@ -490,7 +490,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "Standalone") add_library(O2::${MODULE} ALIAS ${MODULE}) install(TARGETS ${MODULE}) - if(CONFIG_ROOT) + if(GPUCA_CONFIG_ROOT) ROOT_GENERATE_DICTIONARY(G__${MODULE} ${HDRS_CINT_O2} ${HDRS_CINT_DATATYPES} ${HDRS_CINT_O2_ADDITIONAL} GPUTrackingLinkDef_Standalone.h) target_sources(${MODULE} PRIVATE G__${MODULE}) INSTALL(FILES diff --git a/GPU/GPUTracking/Standalone/CMakeLists.txt b/GPU/GPUTracking/Standalone/CMakeLists.txt index 643b09a332b2c..f7ff04700418d 100644 --- a/GPU/GPUTracking/Standalone/CMakeLists.txt +++ b/GPU/GPUTracking/Standalone/CMakeLists.txt @@ -28,16 +28,16 @@ if(NOT EXISTS "${CMAKE_BINARY_DIR}/config.cmake") file(COPY "${CMAKE_SOURCE_DIR}/cmake/config.cmake" DESTINATION "${CMAKE_BINARY_DIR}") endif() include("${CMAKE_BINARY_DIR}/config.cmake") -if(DEFINED CONFIG_COMPILER) - if(CONFIG_COMPILER STREQUAL "clang") +if(DEFINED GPUCA_CONFIG_COMPILER) + if(GPUCA_CONFIG_COMPILER STREQUAL "clang") set(CMAKE_C_COMPILER "clang") set(CMAKE_CXX_COMPILER "clang++") - elseif(CONFIG_COMPILER STREQUAL "gcc") + elseif(GPUCA_CONFIG_COMPILER STREQUAL "gcc") set(CMAKE_C_COMPILER "gcc") set(CMAKE_CXX_COMPILER "c++") else() - set(CMAKE_C_COMPILER "${CONFIG_COMPILER}") - set(CMAKE_CXX_COMPILER "${CONFIG_COMPILER}") + set(CMAKE_C_COMPILER "${GPUCA_CONFIG_COMPILER}") + set(CMAKE_CXX_COMPILER "${GPUCA_CONFIG_COMPILER}") endif() endif() @@ -48,7 +48,7 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -if(BUILD_DEBUG) +if(GPUCA_BUILD_DEBUG) set(CMAKE_CXX_FLAGS "-O0 -ggdb") # -fsanitize=address,undefined -fno-sanitize=vptr set(CMAKE_BUILD_TYPE DEBUG) else() @@ -75,56 +75,56 @@ else() set(OpenMP_CXX_FOUND OFF) endif() -if(CONFIG_VC) +if(GPUCA_CONFIG_VC) find_package(Vc REQUIRED) else() set(Vc_FOUND OFF) add_definitions(-DGPUCA_NO_VC) endif() -if(BUILD_EVENT_DISPLAY) +if(GPUCA_BUILD_EVENT_DISPLAY) find_package(GLFW NAMES glfw3 CONFIG REQUIRED) find_package(GLEW REQUIRED) find_package(GLUT REQUIRED) find_package(OpenGL REQUIRED) find_package(X11 REQUIRED) - if(BUILD_EVENT_DISPLAY_FREETYPE) + if(GPUCA_BUILD_EVENT_DISPLAY_FREETYPE) find_package(Freetype REQUIRED) find_package(Fontconfig REQUIRED) endif() - if(BUILD_EVENT_DISPLAY_VULKAN) + if(GPUCA_BUILD_EVENT_DISPLAY_VULKAN) find_package(Vulkan REQUIRED) if (Vulkan_GLSLC_EXECUTABLE STREQUAL "Vulkan_GLSLC_EXECUTABLE-NOTFOUND") message(FATAL_ERROR ${Vulkan_GLSLC_EXECUTABLE}) endif() - if(BUILD_EVENT_DISPLAY_WAYLAND) + if(GPUCA_BUILD_EVENT_DISPLAY_WAYLAND) find_package(O2GPUWayland REQUIRED) endif() else() set(Vulkan_FOUND OFF) endif() - if(BUILD_EVENT_DISPLAY_QT) + if(GPUCA_BUILD_EVENT_DISPLAY_QT) find_package(Qt5 COMPONENTS Widgets REQUIRED) endif() else() set(OpenGL_FOUND OFF) endif() -if(CONFIG_O2) +if(GPUCA_CONFIG_O2) add_definitions(-DGPUCA_TPC_GEOMETRY_O2) endif() -if(CONFIG_ROOT) +if(GPUCA_CONFIG_ROOT) find_package(ROOT CONFIG REQUIRED) else() add_definitions(-DGPUCA_NO_ROOT) endif() -if(CONFIG_O2_EXTENSIONS) +if(GPUCA_CONFIG_O2_EXTENSIONS) add_definitions(-DGPUCA_HAVE_O2HEADERS) find_package(Microsoft.GSL REQUIRED HINTS "$ENV{MS_GSL_ROOT}/share/cmake") endif() -if(CONFIG_FMT) +if(GPUCA_CONFIG_FMT) find_package(fmt REQUIRED HINTS $ENV{FMT_ROOT}) else() add_definitions(-DGPUCA_NO_FMT) @@ -154,7 +154,7 @@ include_directories(${GPU_DIR}/Common ${GPUTRACKING_DIR}/DataCompression ${GPUTRACKING_DIR}/TRDTracking) -if(CONFIG_O2_EXTENSIONS) +if(GPUCA_CONFIG_O2_EXTENSIONS) include_directories(${GPUTRACKING_DIR}/TPCClusterFinder ${GPUTRACKING_DIR}/ITS ${GPUTRACKING_DIR}/Interface @@ -201,7 +201,7 @@ target_compile_definitions(ca PUBLIC $) # Add all sources and dependencies to to support based on Config File -if(CONFIG_O2_EXTENSIONS) +if(GPUCA_CONFIG_O2_EXTENSIONS) target_sources(standalone_support PRIVATE ${O2_DIR}/Common/Field/src/MagFieldFast.cxx ${O2_DIR}/DataFormats/Detectors/TPC/src/CompressedClusters.cxx @@ -230,25 +230,25 @@ if(CONFIG_O2_EXTENSIONS) endif() endif() -if(CONFIG_FMT) +if(GPUCA_CONFIG_FMT) target_link_libraries(standalone_support PUBLIC fmt::fmt) target_link_libraries(TPCFastTransformation PUBLIC fmt::fmt) endif() -if(CONFIG_VC) +if(GPUCA_CONFIG_VC) target_link_libraries(standalone_support PUBLIC Vc::Vc) target_link_libraries(TPCFastTransformation PUBLIC Vc::Vc) endif() -if(BUILD_EVENT_DISPLAY) - if(CONFIG_GL3W) +if(GPUCA_BUILD_EVENT_DISPLAY) + if(GPUCA_CONFIG_GL3W) target_sources(GPUTrackingDisplay PRIVATE ${GPUTRACKING_DIR}/display/3rdparty/gl3w.c) endif() target_sources(GPUTracking PRIVATE ${GPUTRACKING_DIR}/display/3rdparty/HandMadeMath/HandMadeMathImpl.cxx) target_include_directories(GPUTracking SYSTEM PUBLIC ${GPUTRACKING_DIR}/display/3rdparty) endif() -if(CONFIG_ROOT) +if(GPUCA_CONFIG_ROOT) target_link_libraries(standalone_support PUBLIC ROOT::Core ROOT::RIO @@ -256,7 +256,7 @@ if(CONFIG_ROOT) ROOT::Gui ROOT::Tree) endif() -if(CONFIG_O2_EXTENSIONS) +if(GPUCA_CONFIG_O2_EXTENSIONS) target_link_libraries(standalone_support PUBLIC Microsoft.GSL::GSL TPCFastTransformation) endif() diff --git a/GPU/GPUTracking/Standalone/cmake/config.cmake b/GPU/GPUTracking/Standalone/cmake/config.cmake index 04f4b41cd0c87..2dd5d2e6fd27e 100644 --- a/GPU/GPUTracking/Standalone/cmake/config.cmake +++ b/GPU/GPUTracking/Standalone/cmake/config.cmake @@ -17,18 +17,18 @@ set(ENABLE_HIP AUTO) set(ENABLE_OPENCL1 AUTO) set(ENABLE_OPENCL2 AUTO) set(CONFIG_OPENMP 1) -set(CONFIG_VC 1) -set(CONFIG_FMT 1) -set(CONFIG_ROOT 1) -set(CONFIG_O2_EXTENSIONS 1) -set(BUILD_EVENT_DISPLAY 1) -set(BUILD_EVENT_DISPLAY_FREETYPE 1) -set(BUILD_EVENT_DISPLAY_VULKAN 1) -set(BUILD_EVENT_DISPLAY_WAYLAND 1) -set(BUILD_EVENT_DISPLAY_QT 1) -set(CONFIG_GL3W 0) -set(CONFIG_O2 1) -set(BUILD_DEBUG 0) +set(GPUCA_CONFIG_VC 1) +set(GPUCA_CONFIG_FMT 1) +set(GPUCA_CONFIG_ROOT 1) +set(GPUCA_CONFIG_O2_EXTENSIONS 1) +set(GPUCA_BUILD_EVENT_DISPLAY 1) +set(GPUCA_BUILD_EVENT_DISPLAY_FREETYPE 1) +set(GPUCA_BUILD_EVENT_DISPLAY_VULKAN 1) +set(GPUCA_BUILD_EVENT_DISPLAY_WAYLAND 1) +set(GPUCA_BUILD_EVENT_DISPLAY_QT 1) +set(GPUCA_CONFIG_GL3W 0) +set(GPUCA_CONFIG_O2 1) +set(GPUCA_BUILD_DEBUG 0) set(GPUCA_NO_FAST_MATH 0) #set(GPUCA_CUDA_GCCBIN c++-13) #set(GPUCA_OPENCL_CLANGBIN clang-18) diff --git a/GPU/GPUTracking/display/CMakeLists.txt b/GPU/GPUTracking/display/CMakeLists.txt index 8e91f570c93dd..50c9c0e4a3bfb 100644 --- a/GPU/GPUTracking/display/CMakeLists.txt +++ b/GPU/GPUTracking/display/CMakeLists.txt @@ -172,7 +172,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "Standalone") target_link_libraries(${targetName} PRIVATE glfw) target_compile_definitions(${targetName} PRIVATE GPUCA_BUILD_EVENT_DISPLAY_GLFW) endif() - if(CONFIG_GL3W) + if(GPUCA_CONFIG_GL3W) target_compile_definitions(${targetName} PRIVATE GPUCA_DISPLAY_GL3W) else() target_link_libraries(${targetName} PRIVATE ${GLEW_LIBRARIES}) diff --git a/GPU/GPUTracking/kernels.cmake b/GPU/GPUTracking/kernels.cmake index 272890ac8df78..1789e8f6b46c4 100644 --- a/GPU/GPUTracking/kernels.cmake +++ b/GPU/GPUTracking/kernels.cmake @@ -17,7 +17,7 @@ o2_gpu_kernel_file_list(TPCTRACKER ERRORS GPUTPCTrackParam.cxx GPUTPCTrack.cxx G o2_gpu_kernel_file_list(TPCTRACKLETCONS GPUTPCTrackletConstructor.cxx) o2_gpu_kernel_file_list(TPCSLICEDATA TPCTRACKER GPUTPCSliceData.cxx) o2_gpu_kernel_file_list(TPCOCCUPANCY GPUTPCClusterOccupancyMap.cxx) -if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR CONFIG_O2_EXTENSIONS) +if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR GPUCA_CONFIG_O2_EXTENSIONS) o2_gpu_kernel_file_list(TPCDEDX GPUdEdx.cxx) o2_gpu_kernel_file_list(MATLUT MatLayerCylSet.cxx MatLayerCyl.cxx Ray.cxx) o2_gpu_kernel_file_list(TPCMERGER ERRORS GPUTPCGMMerger.cxx GPUTPCGMSliceTrack.cxx GPUTPCGMTrackParam.cxx GPUTPCGMPhysicalTrackModel.cxx GPUTPCGMPropagator.cxx) @@ -89,7 +89,7 @@ o2_gpu_add_kernel("GPUTPCGMMergerMergeLoopers, step0" "GPUTPCGMM o2_gpu_add_kernel("GPUTPCGMMergerMergeLoopers, step1" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerMergeLoopers, step2" "GPUTPCGMMergerGPU TPCMERGER" LB simple) -if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR CONFIG_O2_EXTENSIONS) +if(ALIGPU_BUILD_TYPE STREQUAL "O2" OR GPUCA_CONFIG_O2_EXTENSIONS) o2_gpu_add_kernel("GPUTPCGMO2Output, prepare" "= TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMO2Output, sort" "= TPCMERGER" NO simple) o2_gpu_add_kernel("GPUTPCGMO2Output, output" "= TPCMERGER" LB simple) From cc647855c104d5b7584e8a58852a29437a9fc560 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 11 Sep 2024 19:04:49 +0200 Subject: [PATCH 0224/2205] GPU: GPUCA_BUILD_DEBUG makes sure all possible source files are compiled for all kernels --- GPU/GPUTracking/CMakeLists.txt | 1 + GPU/GPUTracking/cmake/kernel_helpers.cmake | 28 ++++++++++++---------- dependencies/FindO2GPU.cmake | 3 +++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index caed8a8a26d09..a4ca1f126f013 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -13,6 +13,7 @@ set(MODULE GPUTracking) cmake_minimum_required(VERSION 3.27 FATAL_ERROR) # set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER} "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} -O0") # to uncomment if needed, tired of typing this... +# set(GPUCA_BUILD_DEBUG 1) if(NOT "${GPUCA_NO_FAST_MATH}" AND NOT CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math") diff --git a/GPU/GPUTracking/cmake/kernel_helpers.cmake b/GPU/GPUTracking/cmake/kernel_helpers.cmake index 30fe2850ff3eb..42fd6b3d2402a 100644 --- a/GPU/GPUTracking/cmake/kernel_helpers.cmake +++ b/GPU/GPUTracking/cmake/kernel_helpers.cmake @@ -69,19 +69,23 @@ function(o2_gpu_add_kernel kernel_name kernel_files kernel_bounds kernel_type) # add_custom_command OUTPUT option does not support target-dependend generator expressions, thus this workaround set(O2_GPU_KERNEL_TEMPLATE_FILES "GPUConstantMem.h") - list(LENGTH kernel_files n) - if(n GREATER 1) - math(EXPR n "${n} - 1") - foreach(i RANGE 1 ${n}) - list(GET kernel_files ${i} TMP_KERNEL_FILE_LIST) - get_target_property(TMP_FILE_LIST O2_GPU_KERNELS O2_GPU_KERNELS_FILE_LIST_${TMP_KERNEL_FILE_LIST}) - if(NOT TMP_FILE_LIST) - message(FATAL_ERROR "Invalid file list ${TMP_KERNEL_FILE_LIST}") - endif() - list(APPEND O2_GPU_KERNEL_TEMPLATE_FILES ${TMP_FILE_LIST}) - endforeach() + if (GPUCA_BUILD_DEBUG) + list(APPEND O2_GPU_KERNEL_TEMPLATE_FILES "GPUReconstructionIncludesDeviceAll.h") + else() + list(LENGTH kernel_files n) + if(n GREATER 1) + math(EXPR n "${n} - 1") + foreach(i RANGE 1 ${n}) + list(GET kernel_files ${i} TMP_KERNEL_FILE_LIST) + get_target_property(TMP_FILE_LIST O2_GPU_KERNELS O2_GPU_KERNELS_FILE_LIST_${TMP_KERNEL_FILE_LIST}) + if(NOT TMP_FILE_LIST) + message(FATAL_ERROR "Invalid file list ${TMP_KERNEL_FILE_LIST}") + endif() + list(APPEND O2_GPU_KERNEL_TEMPLATE_FILES ${TMP_FILE_LIST}) + endforeach() + endif() + list(APPEND O2_GPU_KERNEL_TEMPLATE_FILES "${TMP_KERNEL_CLASS_FILE}.cxx") endif() - list(APPEND O2_GPU_KERNEL_TEMPLATE_FILES "${TMP_KERNEL_CLASS_FILE}.cxx") list(REMOVE_DUPLICATES O2_GPU_KERNEL_TEMPLATE_FILES) list(FILTER O2_GPU_KERNEL_TEMPLATE_FILES EXCLUDE REGEX "^-$") list(TRANSFORM O2_GPU_KERNEL_TEMPLATE_FILES APPEND "\"") diff --git a/dependencies/FindO2GPU.cmake b/dependencies/FindO2GPU.cmake index 0db27d1f177fd..c9420de2b704b 100644 --- a/dependencies/FindO2GPU.cmake +++ b/dependencies/FindO2GPU.cmake @@ -28,6 +28,9 @@ string(TOUPPER "${ENABLE_HIP}" ENABLE_HIP) if(NOT DEFINED CMAKE_BUILD_TYPE_UPPER) string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER) endif() +if(CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG") + set(GPUCA_BUILD_DEBUG 1) +endif() if(CUDA_COMPUTETARGET AND CUDA_COMPUTETARGET STREQUAL "default") set(CUDA_COMPUTETARGET 86 89) From 7e6992921eeb1fb6a67612ffec30b6ac180ea22a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 11 Sep 2024 19:17:08 +0200 Subject: [PATCH 0225/2205] GPU: Clarify error message --- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 95575eb6b9c0e..054272823b83b 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -314,7 +314,7 @@ bool GPUChainTracking::ValidateSettings() return false; } if (!(GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCCompression) || !(GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding) || param().rec.fwdTPCDigitsAsClusters) { - GPUError("Invalid reconstruction settings for double pipeline"); + GPUError("Invalid reconstruction settings for double pipeline: Needs compression and cluster finding"); return false; } } From b084166aadb2ff626a6b99f48ed0b03f5961d349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Wed, 11 Sep 2024 15:56:39 +0200 Subject: [PATCH 0226/2205] Fix data model doc generation --- .github/workflows/datamodel-doc.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/datamodel-doc.yml b/.github/workflows/datamodel-doc.yml index 0871a64e10008..294fc2e50f50b 100644 --- a/.github/workflows/datamodel-doc.yml +++ b/.github/workflows/datamodel-doc.yml @@ -48,6 +48,7 @@ jobs: run: | python3 -m pip install --user -U numpy nltk python3 -m nltk.downloader -d ~/nltk_data punkt + python3 -m nltk.downloader -d ~/nltk_data punkt_tab - name: Generate documentation run: exec bash -exo pipefail O2/scripts/datamodel-doc/update-datamodel.sh @@ -71,7 +72,7 @@ jobs: # Send pull request # We need to use "gh" ourselves because alisw/pull-request gets # confused when multiple repos are checked out. - GH_TOKEN="$GITHUB_TOKEN" gh pr create -B master \ + GH_TOKEN="$GITHUB_TOKEN" gh pr create -R AliceO2Group/analysis-framework -B master \ --no-maintainer-edit -t 'Automatic data model update' -b "This update \ to the data model documentation was automatically created from \ tonight's O2 dev branch." || true From ef786dc62b5495666da8e1d56b90a15d2dcad467 Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Wed, 11 Sep 2024 22:05:59 +0200 Subject: [PATCH 0227/2205] Strainer: safeguard for missing AliEn connection --- Framework/AODMerger/src/aodStrainer.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Framework/AODMerger/src/aodStrainer.cxx b/Framework/AODMerger/src/aodStrainer.cxx index ca53a33fd0b96..a8c83d23e7361 100644 --- a/Framework/AODMerger/src/aodStrainer.cxx +++ b/Framework/AODMerger/src/aodStrainer.cxx @@ -98,8 +98,9 @@ int main(int argc, char* argv[]) auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", 505); TDirectory* outputDir = nullptr; TString line(inputAO2D.c_str()); - if (line.BeginsWith("alien://")) { - TGrid::Connect("alien:"); + if (line.BeginsWith("alien://") && !gGrid && !TGrid::Connect("alien:")) { + printf("Error: Could not connect to AliEn.\n"); + return -1; } printf("Processing input file: %s\n", line.Data()); auto inputFile = TFile::Open(line); From a6b59568f4118112d7f1e23cf1b047783f81eeda Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 11 Sep 2024 15:56:09 +0200 Subject: [PATCH 0228/2205] Add getters for analysis of TrackMCStudy output --- .../GlobalTrackingStudy/TrackMCStudyTypes.h | 34 +++++++++- .../study/src/TrackMCStudy.cxx | 67 ++++++++++++++++--- .../study/src/TrackMCStudyTypes.cxx | 66 ++++++++++++++++++ 3 files changed, 155 insertions(+), 12 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h index f99ba9f4ef68e..c501686bf69e1 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h @@ -26,6 +26,11 @@ namespace o2::trackstudy struct MCTrackInfo { inline float getMCTimeMUS() const { return bcInTF * o2::constants::lhc::LHCBunchSpacingMUS; } + inline bool hasITSHitOnLr(int i) const { return (pattITSCl & ((0x1 << i) & 0x7f)) != 0; } + int getNITSClusCont() const; + int getNITSClusForAB() const; + int getLowestITSLayer() const; + int getHighestITSLayer() const; o2::track::TrackPar track{}; o2::MCCompLabel label{}; @@ -44,16 +49,33 @@ struct MCTrackInfo { }; struct RecTrack { + enum FakeFlag { + FakeITS = 0x1 << 0, + FakeTPC = 0x1 << 1, + FakeTRD = 0x1 << 2, + FakeTOF = 0x1 << 3, + FakeITSTPC = 0x1 << 4, + FakeITSTPCTRD = 0x1 << 5, + FakeGLO = 0x1 << 7 + }; o2::track::TrackParCov track{}; o2::dataformats::VtxTrackIndex gid{}; o2::dataformats::TimeStampWithError ts{}; o2::MCEventLabel pvLabel{}; - int pvID = -1; + short pvID = -1; + uint8_t flags = 0; uint8_t nClITS = 0; uint8_t nClTPC = 0; uint8_t pattITS = 0; int8_t lowestPadRow = -1; - bool isFake = false; + + bool isFakeGLO() const { return flags & FakeGLO; } + bool isFakeITS() const { return flags & FakeITS; } + bool isFakeTPC() const { return flags & FakeTPC; } + bool isFakeTRD() const { return flags & FakeTRD; } + bool isFakeTOF() const { return flags & FakeTOF; } + bool isFakeITSTPC() const { return flags & FakeITSTPC; } + ClassDefNV(RecTrack, 1); }; @@ -65,7 +87,10 @@ struct TrackFamily { // set of tracks related to the same MC label int8_t entITS = -1; int8_t entTPC = -1; int8_t entITSTPC = -1; + int8_t entITSFound = -1; // ITS track for this MC track, regardless if it was matched to TPC of another track + int8_t flags = 0; float tpcT0 = -999.; + bool contains(const o2::dataformats::VtxTrackIndex& ref) const { for (const auto& tr : recTracks) { @@ -75,6 +100,11 @@ struct TrackFamily { // set of tracks related to the same MC label } return false; } + const RecTrack& getTrackWithITS() const { return entITS < 0 ? dummyRecTrack : recTracks[entITS]; } + const RecTrack& getTrackWithTPC() const { return entTPC < 0 ? dummyRecTrack : recTracks[entTPC]; } + const RecTrack& getTrackWithITSTPC() const { return entITSTPC < 0 ? dummyRecTrack : recTracks[entITSTPC]; } + const RecTrack& getTrackWithITSFound() const { return entITSFound < 0 ? dummyRecTrack : recTracks[entITSFound]; } + static RecTrack dummyRecTrack; // ClassDefNV(TrackFamily, 1); }; diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index 0ac45f20004a8..d39e9bdb13710 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -369,6 +369,28 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) trf.gid = vid; // account(iv, vid); trf.pvID = pvID; trf.pvLabel = pvLbl; + while (dm[DetID::ITS] && dm[DetID::TPC]) { // this track should have both ITS and TPC parts, if ITS was mismatched, fill it to its proper MC track slot + auto gidSet = recoData.getSingleDetectorRefs(vid); + if (!gidSet[GTrackID::ITS].isSourceSet()) { + break; // AB track, nothing to check + } + auto lblITS = recoData.getTrackMCLabel(gidSet[GTrackID::ITS]); + if (lblITS == trackFamily.mcTrackInfo.label) { + break; // correct match, no need for special treatment + } + const auto& trcITSF = recoData.getTrackParam(gidSet[GTrackID::ITS]); + if (trcITSF.getPt() < params.minPt || std::abs(trcITSF.getTgl()) > params.maxTgl) { + break; // ignore this track + } + auto entryOfFake = mSelMCTracks.find(lblITS); + if (entryOfFake == mSelMCTracks.end()) { // this MC track was not selected + break; + } + auto& trackFamilyOfFake = entryOfFake->second; + auto& trfOfFake = trackFamilyOfFake.recTracks.emplace_back(); + trfOfFake.gid = gidSet[GTrackID::ITS]; // account(iv, vid); + break; + } if (mVerbose > 1) { LOGP(info, "Matched rec track {} to MC track {}", vid.asString(), entry->first.asString()); } @@ -408,28 +430,49 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) int tcnt = 0; for (auto& tref : tracks) { if (tref.gid.isSourceSet()) { + auto gidSet = recoData.getSingleDetectorRefs(tref.gid); tref.track = recoData.getTrackParam(tref.gid); - tref.isFake = recoData.getTrackMCLabel(tref.gid).isFake(); + if (recoData.getTrackMCLabel(tref.gid).isFake()) { + tref.flags |= RecTrack::FakeGLO; + } auto msk = tref.gid.getSourceDetectorsMask(); if (msk[DetID::ITS]) { - auto gidITS = recoData.getITSContributorGID(tref.gid); - tref.pattITS = getITSPatt(gidITS, tref.nClITS); - if (gidITS.getSource() == VTIndex::ITS && trackFam.entITS < 0) { // has ITS track rather than AB tracklet - trackFam.entITS = tcnt; + if (gidSet[GTrackID::ITS].isSourceSet()) { // has ITS track rather than AB tracklet + tref.pattITS = getITSPatt(gidSet[GTrackID::ITS], tref.nClITS); + if (trackFam.entITS < 0) { + trackFam.entITS = tcnt; + } + auto lblITS = recoData.getTrackMCLabel(gidSet[GTrackID::ITS]); + if (lblITS.isFake()) { + tref.flags |= RecTrack::FakeITS; + } + if (lblITS == trackFam.mcTrackInfo.label) { + trackFam.entITSFound = tcnt; + } + } else { // AB ITS tracklet + tref.pattITS = getITSPatt(gidSet[GTrackID::ITSAB], tref.nClITS); + if (recoData.getTrackMCLabel(gidSet[GTrackID::ITSAB]).isFake()) { + tref.flags |= RecTrack::FakeITS; + } } if (msk[DetID::TPC] && trackFam.entITSTPC < 0) { // has both ITS and TPC contribution trackFam.entITSTPC = tcnt; + if (recoData.getTrackMCLabel(gidSet[GTrackID::ITSTPC]).isFake()) { + tref.flags |= RecTrack::FakeITSTPC; + } } } if (msk[DetID::TPC]) { - auto gidTPC = recoData.getTPCContributorGID(tref.gid); - const auto& trtpc = recoData.getTPCTrack(gidTPC); + const auto& trtpc = recoData.getTPCTrack(gidSet[GTrackID::TPC]); tref.nClTPC = trtpc.getNClusters(); tref.lowestPadRow = getLowestPadrow(trtpc); if (trackFam.entTPC < 0) { trackFam.entTPC = tcnt; trackFam.tpcT0 = trtpc.getTime0(); } + if (recoData.getTrackMCLabel(gidSet[GTrackID::TPC]).isFake()) { + tref.flags |= RecTrack::FakeTPC; + } } float ts = 0, terr = 0; if (tref.gid.getSource() != GTrackID::ITS) { @@ -473,16 +516,20 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) std::string decTreeName = fmt::format("dec{}", params.decayPDG[id]); for (const auto& dec : mDecaysMaps[id]) { decFam.clear(); + bool skip = false; for (int idd = dec.daughterFirst; idd <= dec.daughterLast; idd++) { auto dtLbl = mDecProdLblPool[idd]; // daughter MC label const auto& dtFamily = mSelMCTracks[dtLbl]; if (dtFamily.mcTrackInfo.pdgParent != dec.pdg) { LOGP(error, "{}-th decay (pdg={}): {} in {}:{} range refers to MC track with pdgParent = {}", id, params.decayPDG[id], idd, dec.daughterFirst, dec.daughterLast, dtFamily.mcTrackInfo.pdgParent); - continue; + skip = true; + break; } decFam.push_back(dtFamily); } - (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "\n"; + if (!skip) { + (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "\n"; + } } } @@ -745,7 +792,7 @@ bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& l mcEntry.mcTrackInfo.occITS = mITSOcc[lb.getEventID()]; int moth = -1; o2::MCCompLabel mclbPar; - if (!mcPart.isPrimary() && (moth = mcPart.getMotherTrackId()) >= 0) { + if ((moth = mcPart.getMotherTrackId()) >= 0) { const auto& mcPartPar = mCurrMCTracks[moth]; mcEntry.mcTrackInfo.pdgParent = mcPartPar.GetPdgCode(); } diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx index b95fda9699420..92107d90b48ed 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudyTypes.cxx @@ -10,3 +10,69 @@ // or submit itself to any jurisdiction. #include "GlobalTrackingStudy/TrackMCStudyTypes.h" + +namespace o2::trackstudy +{ + +RecTrack TrackFamily::dummyRecTrack; + +// get longest number of clusters on consecutive layers +int MCTrackInfo::getNITSClusCont() const +{ + if (nITSCl < 2) { + return nITSCl; + } + int longest = 0, current = 0; + for (int i = 0; i < 7; i++) { + if (pattITSCl & (0x1 << i)) { + longest = ++current; + } else { + current = 0; + } + } + return longest; +} + +// check how many clusters ITS-TPC afterburner could see (consecutively occupied layers starting from the last one) +int MCTrackInfo::getNITSClusForAB() const +{ + int ncl = 0; + if (nITSCl) { + for (int i = 6; i > 2; i--) { + if (pattITSCl & (0x1 << i)) { + ncl++; + } else { + break; + } + } + } + return ncl; +} + +// lowest ITS layer with cluster +int MCTrackInfo::getLowestITSLayer() const +{ + if (nITSCl) { + for (int i = 0; i < 7; i++) { + if (pattITSCl & (0x1 << i)) { + return i; + } + } + } + return -1; +} + +// highest ITS layer with cluster +int MCTrackInfo::getHighestITSLayer() const +{ + if (nITSCl) { + for (int i = 7; i--;) { + if (pattITSCl & (0x1 << i)) { + return i; + } + } + } + return -1; +} + +} // namespace o2::trackstudy From 2d5edce21b506551053d2590fb5f02d14f680b37 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 12 Sep 2024 16:10:16 +0200 Subject: [PATCH 0229/2205] Fix in TOF-TPC matching for tracks seeing multiple sectors. When TPC track candidate which should be checked in 2 sectors, replicate also its mVZtpcOnly entries. --- Detectors/GlobalTracking/src/MatchTOF.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Detectors/GlobalTracking/src/MatchTOF.cxx b/Detectors/GlobalTracking/src/MatchTOF.cxx index d67708608df55..2db453b0f62be 100644 --- a/Detectors/GlobalTracking/src/MatchTOF.cxx +++ b/Detectors/GlobalTracking/src/MatchTOF.cxx @@ -449,6 +449,7 @@ bool MatchTOF::prepareTPCData() mTracksLblWork[sector][trkType::UNCONS].emplace_back(mTracksLblWork[sec][trkType::UNCONS][it]); } mLTinfos[sector][trkType::UNCONS].emplace_back(mLTinfos[sec][trkType::UNCONS][it]); + mVZtpcOnly[sector].push_back(mVZtpcOnly[sec][it]); mTracksSectIndexCache[trkType::UNCONS][sector].push_back(itnew); } } From 0e734e8a74fc8cfb375eea64ce33ea8341f7403f Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 14:05:58 +0200 Subject: [PATCH 0230/2205] GPU TRD: Fix Geometry must be reinitialized after receiving geometry from CCDB --- GPU/GPUTracking/Global/GPUChainTracking.cxx | 16 +++++++++ GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx | 33 +++++++++++-------- GPU/GPUTracking/TRDTracking/GPUTRDTracker.h | 9 +++-- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 054272823b83b..8cb17fc8bb847 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -655,6 +655,22 @@ int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) pDst[i] = pSrc[i]; } } + if (mNewCalibObjects->trdGeometry && (GetRecoSteps() & GPUDataTypes::RecoStep::TRDTracking)) { +#ifdef GPUCA_HAVE_O2HEADERS + if (GetProcessingSettings().trdTrackModelO2) { + processors()->trdTrackerO2.UpdateGeometry(); + if (mRec->IsGPU()) { + TransferMemoryResourceLinkToGPU(RecoStep::NoRecoStep, processors()->trdTrackerO2.MemoryPermanent(), stream); + } + } else +#endif + { + processors()->trdTrackerGPU.UpdateGeometry(); + if (mRec->IsGPU()) { + TransferMemoryResourceLinkToGPU(RecoStep::NoRecoStep, processors()->trdTrackerGPU.MemoryPermanent(), stream); + } + } + } if (mRec->IsGPU()) { std::array oldFlatPtrs, oldFlatPtrsDevice; memcpy(oldFlatPtrs.data(), (void*)&mFlatObjectsShadow, oldFlatPtrs.size()); diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx index 09db87f154319..20c7e2932367a 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx @@ -124,11 +124,29 @@ void GPUTRDTracker_t::InitializeProcessor() //-------------------------------------------------------------------- // Initialise tracker //-------------------------------------------------------------------- + +#ifdef GPUCA_ALIROOT_LIB + for (int iCandidate = 0; iCandidate < mNCandidates * 2 * mMaxThreads; ++iCandidate) { + new (&mCandidates[iCandidate]) TRDTRK; + } +#endif + + UpdateGeometry(); + + mDebug->ExpandVectors(); + mIsInitialized = true; +} + +template +void GPUTRDTracker_t::UpdateGeometry() +{ + //-------------------------------------------------------------------- + // Update Geometry of TRDTracker + //-------------------------------------------------------------------- mGeo = (TRD_GEOMETRY_CONST GPUTRDGeometry*)GetConstantMem()->calibObjects.trdGeometry; if (!mGeo) { - GPUError("TRD geometry must be provided externally"); + GPUFatal("TRD geometry must be provided externally"); } - float Bz = Param().bzkG; float resRPhiIdeal2 = Param().rec.trd.trkltResRPhiIdeal * Param().rec.trd.trkltResRPhiIdeal; GPUInfo("Initializing with B-field: %f kG", Bz); @@ -165,12 +183,6 @@ void GPUTRDTracker_t::InitializeProcessor() mRPhiA2 = 1.f; } -#ifdef GPUCA_ALIROOT_LIB - for (int iCandidate = 0; iCandidate < mNCandidates * 2 * mMaxThreads; ++iCandidate) { - new (&mCandidates[iCandidate]) TRDTRK; - } -#endif - // obtain average radius of TRD chambers float x0[kNLayers] = {300.2f, 312.8f, 325.4f, 338.0f, 350.6f, 363.2f}; // used as default value in case no transformation matrix can be obtained auto* matrix = mGeo->GetClusterMatrix(0); @@ -185,9 +197,6 @@ void GPUTRDTracker_t::InitializeProcessor() matrix->LocalToMaster(loc, glb); mR[iDet] = glb[0]; } - - mDebug->ExpandVectors(); - mIsInitialized = true; } template @@ -284,8 +293,6 @@ void GPUTRDTracker_t::StartDebugging() mDebug->CreateStreamer(); } - - #endif //! GPUCA_GPUCODE template <> diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h index da1d294b679a6..743d8512f0281 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h @@ -61,6 +61,7 @@ class GPUTRDTracker_t : public GPUProcessor void SetMaxData(const GPUTrackingInOutPointers& io); void RegisterMemoryAllocation(); void InitializeProcessor(); + void UpdateGeometry(); void* SetPointersBase(void* base); void* SetPointersTracklets(void* base); void* SetPointersTracks(void* base); @@ -100,8 +101,6 @@ class GPUTRDTracker_t : public GPUProcessor }; short MemoryPermanent() const { return mMemoryPermanent; } - short MemoryTracklets() const { return mMemoryTracklets; } - short MemoryTracks() const { return mMemoryTracks; } GPUhd() void OverrideGPUGeometry(TRD_GEOMETRY_CONST GPUTRDGeometry* geo) { mGeo = geo; } void Reset(); @@ -164,9 +163,9 @@ class GPUTRDTracker_t : public GPUProcessor bool mProcessPerTimeFrame; // if true, tracking is done per time frame instead of on a single events basis short mNAngleHistogramBins; // number of bins per chamber for the angular difference histograms float mAngleHistogramRange; // range of impact angles covered by each histogram - short mMemoryPermanent; // size of permanent memory for the tracker - short mMemoryTracklets; // size of memory for TRD tracklets - short mMemoryTracks; // size of memory for tracks (used for i/o) + short mMemoryPermanent; // memory id of permanent memory for the tracker + short mMemoryTracklets; // memory id of memory for TRD tracklets + short mMemoryTracks; // memory id of memory for tracks (used for i/o) int mNMaxCollisions; // max number of collisions to process (per time frame) int mNMaxTracks; // max number of tracks the tracker can handle (per event) int mNMaxSpacePoints; // max number of space points hold by the tracker (per event) From 105235d42ae1e6b46154dcecb5ea576b8647070c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 14:16:23 +0200 Subject: [PATCH 0231/2205] GPU Standalone: --runGPUforce setting was not respected correctly --- GPU/GPUTracking/Standalone/Benchmark/standalone.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index a0cd415ba21e3..f6aadc38c64ce 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -266,7 +266,12 @@ int ReadConfiguration(int argc, char** argv) } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) { configStandalone.gpuType = "OCL"; } else { + if (configStandalone.runGPUforce) { + printf("No GPU backend / device found, running on CPU is disabled due to runGPUforce\n"); + return 1; + } configStandalone.runGPU = false; + configStandalone.gpuType = "CPU"; } } From f0f8f9a6b1b9035f9d75e449106adea9931fd1f1 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 15:17:26 +0200 Subject: [PATCH 0232/2205] GPU: Fix an incorrect sanity check related to TRD tracking --- GPU/GPUTracking/Global/GPUChainTracking.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 8cb17fc8bb847..d4ab0aad4bc40 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -331,8 +331,8 @@ bool GPUChainTracking::ValidateSettings() GPUError("TRD tracking can only run on GPU TPC tracks if the createO2Output setting does not suppress them"); return false; } - if ((((GetRecoStepsGPU() & RecoStep::TRDTracking) && !GetProcessingSettings().trdTrackModelO2) || ((GetRecoStepsGPU() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && (!GetProcessingSettings().o2PropagatorUseGPUField || processors()->calibObjects.matLUT == nullptr)) { - GPUError("Cannot use TRD tracking or Refit on GPU without GPU polynomial field map or matlut table"); + if ((((GetRecoStepsGPU() & RecoStep::TRDTracking) && GetProcessingSettings().trdTrackModelO2) || ((GetRecoStepsGPU() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && (!GetProcessingSettings().o2PropagatorUseGPUField || (GetMatLUT() == nullptr && !GetProcessingSettings().willProvideO2PropagatorLate))) { + GPUError("Cannot use TRD tracking or Refit on GPU without GPU polynomial field map (%d) or matlut table (%p)", (int)GetProcessingSettings().o2PropagatorUseGPUField, (void*)GetMatLUT()); return false; } } From c9f21797658d0147083c7e40a58dbfa1b9e94725 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 15:17:55 +0200 Subject: [PATCH 0233/2205] GPU Workflow: If track output is not disabled, we should not force createO2Output to 2 but leave it at its value --- GPU/Workflow/src/GPUWorkflowSpec.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index f2a9ec635443c..f38256e795bbf 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -231,7 +231,9 @@ void GPURecoWorkflowSpec::init(InitContext& ic) if (mSpecConfig.outputSharedClusterMap) { mConfig->configProcessing.outputSharedClusterMap = true; } - mConfig->configProcessing.createO2Output = mSpecConfig.outputTracks ? 2 : 0; // Disable O2 TPC track format output if no track output requested + if (!mSpecConfig.outputTracks) { + mConfig->configProcessing.createO2Output = 0; // Disable O2 TPC track format output if no track output requested + } mConfig->configProcessing.param.tpcTriggerHandling = mSpecConfig.tpcTriggerHandling; if (mConfParam->transformationFile.size() || mConfParam->transformationSCFile.size()) { From 5240fec7cfd51e37215a4aadf795795b86176833 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 14:45:31 +0200 Subject: [PATCH 0234/2205] GPU TRD: Fix GPU instance of TRDTracker for o2::Propagator track model was never initialized correctly --- GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx index 8e27de9511af4..39b9492417400 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx @@ -30,11 +30,11 @@ template int GPUChainTracking::RunTRDTracking() { #ifndef GPUCA_ALIROOT_LIB - if (!processors()->trdTrackerGPU.IsInitialized()) { + auto& Tracker = processors()->getTRDTracker(); + if (!Tracker.IsInitialized()) { return 1; } - auto& Tracker = processors()->getTRDTracker(); Tracker.Reset(); if (mIOPtrs.nTRDTracklets == 0) { return 0; @@ -182,7 +182,7 @@ int GPUChainTracking::DoTRDGPUTracking(T* externalInstance) processorsShadow()->ioPtrs.trdTrigRecMask = nullptr; } WriteToConstantMemory(RecoStep::TRDTracking, (char*)&processors()->ioPtrs - (char*)processors(), &processorsShadow()->ioPtrs, sizeof(processorsShadow()->ioPtrs), useStream); - WriteToConstantMemory(RecoStep::TRDTracking, (char*)&processors()->trdTrackerGPU - (char*)processors(), TrackerShadow, sizeof(*TrackerShadow), useStream); + WriteToConstantMemory(RecoStep::TRDTracking, (char*)&processors()->getTRDTracker() - (char*)processors(), TrackerShadow, sizeof(*TrackerShadow), useStream); } TransferMemoryResourcesToGPU(RecoStep::TRDTracking, Tracker, useStream); From b471a4b400edbf92f80178b4003a8b9cf72d420d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 11 Sep 2024 19:31:28 +0200 Subject: [PATCH 0235/2205] GPU Standalone: fix --setO2Settings parameters --- GPU/GPUTracking/Standalone/Benchmark/standalone.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index f6aadc38c64ce..c6813f9b33b50 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -230,7 +230,9 @@ int ReadConfiguration(int argc, char** argv) } } if (configStandalone.setO2Settings) { - configStandalone.proc.forceHostMemoryPoolSize = 1024 * 1024 * 1024; + if (configStandalone.runGPU) { + configStandalone.proc.forceHostMemoryPoolSize = 1024 * 1024 * 1024; + } configStandalone.rec.tpc.nWaysOuter = 1; configStandalone.rec.tpc.trackReferenceX = 83; configStandalone.proc.outputSharedClusterMap = 1; From b8cec0e9b0e28e0739d1773584dc463ad0b39810 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 11:14:05 +0200 Subject: [PATCH 0236/2205] GPU: Use 64bit integer for us timing output to avoid overflows with large TFs on very slow systems --- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index f8dbcdf5c7b46..abdaab020179a 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -271,7 +271,7 @@ int GPUReconstructionCPU::RunChains() if (mTimers[i]->memSize && mStatNEvents && time != 0.) { snprintf(bandwidth, 256, " (%6.3f GB/s - %'14lu bytes)", mTimers[i]->memSize / time * 1e-9, (unsigned long)(mTimers[i]->memSize / mStatNEvents)); } - printf("Execution Time: Task (%c %8ux): %50s Time: %'10d us%s\n", type, mTimers[i]->count, mTimers[i]->name.c_str(), (int)(time * 1000000 / mStatNEvents), bandwidth); + printf("Execution Time: Task (%c %8ux): %50s Time: %'10lu us%s\n", type, mTimers[i]->count, mTimers[i]->name.c_str(), (unsigned long)(time * 1000000 / mStatNEvents), bandwidth); if (mProcessingSettings.resetTimers) { mTimers[i]->count = 0; mTimers[i]->memSize = 0; @@ -279,14 +279,14 @@ int GPUReconstructionCPU::RunChains() } for (int i = 0; i < GPUDataTypes::N_RECO_STEPS; i++) { if (kernelStepTimes[i] != 0. || mTimersRecoSteps[i].timerTotal.GetElapsedTime() != 0.) { - printf("Execution Time: Step : %11s %38s Time: %'10d us ( Total Time : %'14d us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], (int)(kernelStepTimes[i] * 1000000 / mStatNEvents), (int)(mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: Step : %11s %38s Time: %'10lu us ( Total Time : %'14lu us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(kernelStepTimes[i] * 1000000 / mStatNEvents), (unsigned long)(mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents)); } if (mTimersRecoSteps[i].bytesToGPU) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10d us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], (int)(mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents), mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToGPU / mStatNEvents, mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].countToGPU); } if (mTimersRecoSteps[i].bytesToHost) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10d us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], (int)(mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents), mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToHost / mStatNEvents, mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].countToHost); } if (mProcessingSettings.resetTimers) { @@ -300,14 +300,14 @@ int GPUReconstructionCPU::RunChains() } for (int i = 0; i < GPUDataTypes::N_GENERAL_STEPS; i++) { if (mTimersGeneralSteps[i].GetElapsedTime() != 0.) { - printf("Execution Time: General Step : %50s Time: %'10d us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], (int)(mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: General Step : %50s Time: %'10lu us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], (unsigned long)(mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents)); } } mStatKernelTime = kernelTotal * 1000000 / mStatNEvents; - printf("Execution Time: Total : %50s Time: %'10d us%s\n", "Total Kernel", (int)mStatKernelTime, nEventReport.c_str()); - printf("Execution Time: Total : %50s Time: %'10d us%s\n", "Total Wall", (int)mStatWallTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Kernel", (unsigned long)mStatKernelTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Wall", (unsigned long)mStatWallTime, nEventReport.c_str()); } else if (GetProcessingSettings().debugLevel >= 0) { - GPUInfo("Total Wall Time: %d us%s", (int)mStatWallTime, nEventReport.c_str()); + GPUInfo("Total Wall Time: %lu us%s", (unsigned long)mStatWallTime, nEventReport.c_str()); } if (mProcessingSettings.resetTimers) { mStatNEvents = 0; From 4952f34f33ce25a16023f7db36eeb94bb5ed0f95 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 22:42:03 +0200 Subject: [PATCH 0237/2205] GPU Display: fix drawing of propagated tracks --- GPU/GPUTracking/display/GPUDisplay.cxx | 9 ++++----- GPU/GPUTracking/utils/qconfig.cxx | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index d99333bf651c5..ca362f7e380e7 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -1019,8 +1019,6 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s trkParam.Set(mclocal[0], mclocal[1], mc.z - ZOffset, mclocal[2], mclocal[3], mc.pZ, charge); #endif } - trkParam.X() += mCfgH.xAdd; - x += mCfgH.xAdd; float z0 = trkParam.Z(); if (iMC && inFlyDirection == 0) { buffer.clear(); @@ -1070,7 +1068,8 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s break; } float sa = sinf(alpha), ca = cosf(alpha); - useBuffer.emplace_back((ca * trkParam.X() - sa * trkParam.Y()) / GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * trkParam.X()) / GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) / GL_SCALE_FACTOR); + float drawX = trkParam.X() + mCfgH.xAdd; + useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) / GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor / GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) / GL_SCALE_FACTOR); x += inFlyDirection ? 1 : -1; } @@ -1196,8 +1195,8 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) float x2Tmp = xyzGlb2[0]; xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); - mVertexBuffer[sector].emplace_back(xyzGlb1[0] / GL_SCALE_FACTOR, xyzGlb1[1] / GL_SCALE_FACTOR, xyzGlb1[2] / GL_SCALE_FACTOR); - mVertexBuffer[sector].emplace_back(xyzGlb2[0] / GL_SCALE_FACTOR, xyzGlb2[1] / GL_SCALE_FACTOR, xyzGlb2[2] / GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb1[0] / GL_SCALE_FACTOR, xyzGlb1[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] / GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb2[0] / GL_SCALE_FACTOR, xyzGlb2[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] / GL_SCALE_FACTOR); } } } diff --git a/GPU/GPUTracking/utils/qconfig.cxx b/GPU/GPUTracking/utils/qconfig.cxx index 82cd8df3a5036..1ce2395a4dad8 100644 --- a/GPU/GPUTracking/utils/qconfig.cxx +++ b/GPU/GPUTracking/utils/qconfig.cxx @@ -477,10 +477,12 @@ static inline void qConfigHelp(const char* subConfig = nullptr, int followSub = if (followSub < 2) { printf("Usage Info:"); } - #define QCONFIG_HELP #include "qconfig.h" #undef QCONFIG_HELP + if (followSub < 2) { + printf("\n"); + } } // Create parser for configuration From 2980ae38e3e58e95203a1f6d7d0f1484910806b6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 23:05:24 +0200 Subject: [PATCH 0238/2205] GPU Display: make GL_SCALE_FACTOR multiplicative --- GPU/GPUTracking/display/GPUDisplay.cxx | 56 +++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index ca362f7e380e7..3d61bd46f531f 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -77,7 +77,7 @@ constexpr hmm_mat4 MY_HMM_FROM(float (&v)[16]) { return {{{v[0], v[1], v[2], v[3 using namespace GPUCA_NAMESPACE::gpu; -#define GL_SCALE_FACTOR 100.f +#define GL_SCALE_FACTOR (1.f / 100.f) #define SEPERATE_GLOBAL_TRACKS_LIMIT (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT) @@ -1069,7 +1069,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } float sa = sinf(alpha), ca = cosf(alpha); float drawX = trkParam.X() + mCfgH.xAdd; - useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) / GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor / GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) / GL_SCALE_FACTOR); + useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) * GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor * GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) * GL_SCALE_FACTOR); x += inFlyDirection ? 1 : -1; } @@ -1111,8 +1111,8 @@ GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) zz1 -= mCfgH.zAdd; zz2 -= mCfgH.zAdd; } - mVertexBuffer[iSlice].emplace_back(xx1 / GL_SCALE_FACTOR, yy1 / GL_SCALE_FACTOR * mYFactor, zz1 / GL_SCALE_FACTOR); - mVertexBuffer[iSlice].emplace_back(xx2 / GL_SCALE_FACTOR, yy2 / GL_SCALE_FACTOR * mYFactor, zz2 / GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); } for (int j = 0; j <= (signed)row.Grid().Nz(); j++) { float y1 = row.Grid().YMin(); @@ -1129,8 +1129,8 @@ GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) zz1 -= mCfgH.zAdd; zz2 -= mCfgH.zAdd; } - mVertexBuffer[iSlice].emplace_back(xx1 / GL_SCALE_FACTOR, yy1 / GL_SCALE_FACTOR * mYFactor, zz1 / GL_SCALE_FACTOR); - mVertexBuffer[iSlice].emplace_back(xx2 / GL_SCALE_FACTOR, yy2 / GL_SCALE_FACTOR * mYFactor, zz2 / GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); } } insertVertexList(tracker.ISlice(), startCountInner, mVertexBuffer[iSlice].size()); @@ -1175,8 +1175,8 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) float x2Tmp = xyzGlb2[0]; xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); - mVertexBuffer[sector].emplace_back(xyzGlb1[0] / GL_SCALE_FACTOR, xyzGlb1[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] / GL_SCALE_FACTOR); - mVertexBuffer[sector].emplace_back(xyzGlb2[0] / GL_SCALE_FACTOR, xyzGlb2[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] / GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); } for (int j = 0; j < pp->GetNcols(); ++j) { float xyzLoc1[3]; @@ -1195,8 +1195,8 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) float x2Tmp = xyzGlb2[0]; xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); - mVertexBuffer[sector].emplace_back(xyzGlb1[0] / GL_SCALE_FACTOR, xyzGlb1[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] / GL_SCALE_FACTOR); - mVertexBuffer[sector].emplace_back(xyzGlb2[0] / GL_SCALE_FACTOR, xyzGlb2[1] / GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] / GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); } } } @@ -1364,9 +1364,9 @@ void GPUDisplay::DrawGLScene_updateEventData() mMaxClusterZ = fabsf(ptr->z); } ptr->z += iSlice < 18 ? mCfgH.zAdd : -mCfgH.zAdd; - ptr->x /= GL_SCALE_FACTOR; - ptr->y /= GL_SCALE_FACTOR; - ptr->z /= GL_SCALE_FACTOR; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; ptr->w = tCLUSTER; } } @@ -1390,9 +1390,9 @@ void GPUDisplay::DrawGLScene_updateEventData() if (fabsf(ptr->z) > mMaxClusterZ) { mMaxClusterZ = fabsf(ptr->z); } - ptr->x /= GL_SCALE_FACTOR; - ptr->y /= GL_SCALE_FACTOR; - ptr->z /= GL_SCALE_FACTOR; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; ptr->w = tTRDCLUSTER; ptr = &mGlobalPosTRD2[i]; mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd + 4.5f, sp.getY() + 1.5f * sp.getDy(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); @@ -1400,9 +1400,9 @@ void GPUDisplay::DrawGLScene_updateEventData() if (fabsf(ptr->z) > mMaxClusterZ) { mMaxClusterZ = fabsf(ptr->z); } - ptr->x /= GL_SCALE_FACTOR; - ptr->y /= GL_SCALE_FACTOR; - ptr->z /= GL_SCALE_FACTOR; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; ptr->w = tTRDCLUSTER; } @@ -1420,9 +1420,9 @@ void GPUDisplay::DrawGLScene_updateEventData() if (fabsf(ptr->z) > mMaxClusterZ) { mMaxClusterZ = fabsf(ptr->z); } - ptr->x /= GL_SCALE_FACTOR; - ptr->y /= GL_SCALE_FACTOR; - ptr->z /= GL_SCALE_FACTOR; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; ptr->w = tTOFCLUSTER; #endif } @@ -1459,9 +1459,9 @@ void GPUDisplay::DrawGLScene_updateEventData() if (fabsf(ptr->z) > mMaxClusterZ) { mMaxClusterZ = fabsf(ptr->z); } - ptr->x /= GL_SCALE_FACTOR; - ptr->y /= GL_SCALE_FACTOR; - ptr->z /= GL_SCALE_FACTOR; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; ptr->w = tITSCLUSTER; i++; } @@ -1485,7 +1485,7 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla if (mCfgL.drawSlice != -1) { scalefactor *= 0.2f; } - float sqrdist = sqrtf(sqrtf(mViewMatrixP[12] * mViewMatrixP[12] + mViewMatrixP[13] * mViewMatrixP[13] + mViewMatrixP[14] * mViewMatrixP[14]) / GL_SCALE_FACTOR) * 0.8f; + float sqrdist = sqrtf(sqrtf(mViewMatrixP[12] * mViewMatrixP[12] + mViewMatrixP[13] * mViewMatrixP[13] + mViewMatrixP[14] * mViewMatrixP[14]) * GL_SCALE_FACTOR) * 0.8f; if (sqrdist < 0.2f) { sqrdist = 0.2f; } @@ -1584,7 +1584,7 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}}); } } else if (mResetScene) { - nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, mParam->par.continuousTracking ? (-mMaxClusterZ / GL_SCALE_FACTOR - 8) : -8}}); + nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, mParam->par.continuousTracking ? (-mMaxClusterZ * GL_SCALE_FACTOR - 8) : -8}}); mViewMatrix = MY_HMM_IDENTITY; mModelMatrix = MY_HMM_IDENTITY; @@ -2208,7 +2208,7 @@ void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) // Draw Event nextViewMatrix = nextViewMatrix * mModelMatrix; - const float zFar = ((mParam->par.continuousTracking ? (mMaxClusterZ / GL_SCALE_FACTOR) : 8.f) + 50.f) * 2.f; + const float zFar = ((mParam->par.continuousTracking ? (mMaxClusterZ * GL_SCALE_FACTOR) : 8.f) + 50.f) * 2.f; const hmm_mat4 proj = HMM_Perspective(mCfgR.fov, (float)mBackend->mRenderWidth / (float)mBackend->mRenderHeight, 0.1f, zFar); mBackend->prepareDraw(proj, nextViewMatrix, doScreenshot || mRequestScreenshot, renderToMixBuffer, mixSlaveImage); mBackend->pointSizeFactor(1); From 851e834e517ac7c0b4a6e87db8ff17188e1c9271 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 23:13:31 +0200 Subject: [PATCH 0239/2205] GPU Display GUI: Fix static isRunning variable --- GPU/GPUTracking/display/GPUDisplayFrontend.cxx | 9 +++++++++ GPU/GPUTracking/display/GPUDisplayFrontend.h | 1 + GPU/GPUTracking/display/GPUDisplayGUI.cxx | 3 +-- GPU/GPUTracking/display/GPUDisplayKeys.cxx | 4 +--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/GPU/GPUTracking/display/GPUDisplayFrontend.cxx b/GPU/GPUTracking/display/GPUDisplayFrontend.cxx index 52b68c1efc65b..fc5bec4a3d6fb 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontend.cxx +++ b/GPU/GPUTracking/display/GPUDisplayFrontend.cxx @@ -105,6 +105,15 @@ int GPUDisplayFrontend::startGUI() return retVal; } +bool GPUDisplayFrontend::isGUIRunning() +{ + bool retVal = false; +#ifdef GPUCA_BUILD_EVENT_DISPLAY_QT + retVal = mGUI && mGUI->isRunning(); +#endif + return retVal; +} + GPUDisplayFrontend* GPUDisplayFrontend::getFrontend(const char* type) { #if !defined(GPUCA_STANDALONE) && defined(GPUCA_BUILD_EVENT_DISPLAY_GLFW) diff --git a/GPU/GPUTracking/display/GPUDisplayFrontend.h b/GPU/GPUTracking/display/GPUDisplayFrontend.h index de81ee5c4df54..146cf42b9eb17 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontend.h +++ b/GPU/GPUTracking/display/GPUDisplayFrontend.h @@ -72,6 +72,7 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface int startGUI(); void stopGUI(); + bool isGUIRunning(); // volatile variables to exchange control informations between display and backend volatile int mDisplayControl = 0; // Control for next event (=1) or quit (=2) diff --git a/GPU/GPUTracking/display/GPUDisplayGUI.cxx b/GPU/GPUTracking/display/GPUDisplayGUI.cxx index 5346f87289578..019292228b157 100644 --- a/GPU/GPUTracking/display/GPUDisplayGUI.cxx +++ b/GPU/GPUTracking/display/GPUDisplayGUI.cxx @@ -18,8 +18,7 @@ using namespace o2::gpu; -GPUDisplayGUI::GPUDisplayGUI(QWidget* parent) - : QMainWindow(parent), ui(new Ui::GPUDisplayGUI) +GPUDisplayGUI::GPUDisplayGUI(QWidget* parent) : QMainWindow(parent), ui(new Ui::GPUDisplayGUI) { ui->setupUi(this); } diff --git a/GPU/GPUTracking/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/GPUDisplayKeys.cxx index b0ae3f50aafeb..16f76468c663a 100644 --- a/GPU/GPUTracking/display/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/GPUDisplayKeys.cxx @@ -470,15 +470,13 @@ void GPUDisplay::HandleKey(unsigned char key) SetInfo("Showing help text", 1); } } else if (key == 'q') { - static bool GUIStarted = false; - if (GUIStarted) { + if (mFrontend->isGUIRunning()) { SetInfo("Stopping GUI", 1); mFrontend->stopGUI(); } else { SetInfo("Starting GUI", 1); mFrontend->startGUI(); } - GUIStarted = !GUIStarted; } /* else if (key == '^') From 091bbf514273d93105d27dbfd067e6f2d44fc2b9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 23:19:10 +0200 Subject: [PATCH 0240/2205] GPU Display: Use better default z camera position in case of xy-projected mode --- GPU/GPUTracking/display/GPUDisplay.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 3d61bd46f531f..45ca53aa729fc 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -1584,7 +1584,8 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}}); } } else if (mResetScene) { - nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, mParam->par.continuousTracking ? (-mMaxClusterZ * GL_SCALE_FACTOR - 8) : -8}}); + const float initialZpos = mCfgH.projectXY ? 16 : (mParam->par.continuousTracking ? (mMaxClusterZ * GL_SCALE_FACTOR + 8) : 8); + nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, -initialZpos}}); mViewMatrix = MY_HMM_IDENTITY; mModelMatrix = MY_HMM_IDENTITY; From 5d1616800b0c2e7f008d0b0503c44472d2703fd5 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 23:32:36 +0200 Subject: [PATCH 0241/2205] GPU Display control: shortcut to exit display should be ESC not q, also from the console --- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index d4ab0aad4bc40..fb5c6974e03c3 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -873,7 +873,7 @@ int GPUChainTracking::RunChainFinalize() Sleep(10); if (GetProcessingSettings().eventDisplay->EnableSendKey()) { iKey = kbhit() ? getch() : 0; - if (iKey == 'q') { + if (iKey == 27) { GetProcessingSettings().eventDisplay->setDisplayControl(2); } else if (iKey == 'n') { break; From e21326ea1fb4d08907d3f1ddce4e60bc3b905395 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 12 Sep 2024 23:41:39 +0200 Subject: [PATCH 0242/2205] GPU MC: Remove obsolete files --- GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCPoint.cxx | 0 GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCPoint.h | 0 GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCTrack.cxx | 0 GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCTrack.h | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCPoint.cxx (100%) rename GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCPoint.h (100%) rename GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCTrack.cxx (100%) rename GPU/GPUTracking/{SliceTracker => oldFiles}/GPUTPCMCTrack.h (100%) diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCMCPoint.cxx b/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.cxx similarity index 100% rename from GPU/GPUTracking/SliceTracker/GPUTPCMCPoint.cxx rename to GPU/GPUTracking/oldFiles/GPUTPCMCPoint.cxx diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCMCPoint.h b/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h similarity index 100% rename from GPU/GPUTracking/SliceTracker/GPUTPCMCPoint.h rename to GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCMCTrack.cxx b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx similarity index 100% rename from GPU/GPUTracking/SliceTracker/GPUTPCMCTrack.cxx rename to GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCMCTrack.h b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h similarity index 100% rename from GPU/GPUTracking/SliceTracker/GPUTPCMCTrack.h rename to GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h From 107142f5884889755315db34fa66c9bb485e5ec2 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 00:14:56 +0200 Subject: [PATCH 0243/2205] GPU QA / Display: Fixes to process run2 data --- GPU/GPUTracking/display/GPUDisplay.cxx | 8 +++++--- GPU/GPUTracking/qa/GPUQA.cxx | 7 ++++--- GPU/GPUTracking/qa/GPUQA.h | 7 ++++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 45ca53aa729fc..1dc20d403a525 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -590,13 +590,15 @@ GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned in const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth; for (int cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { const int cid = GET_CID(iSlice, cidInSlice); -#ifdef GPUCA_HAVE_O2HEADERS +#ifdef GPUCA_TPC_GEOMETRY_O2 if (checkClusterCollision) { const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid); if (labels.size() ? (iCol != mQA->GetMCLabelCol(labels[0])) : (iCol != 0)) { continue; } } +#else + (void)checkClusterCollision; #endif if (mCfgH.hideUnmatchedClusters && mQA && mQA->SuppressHit(cid)) { continue; @@ -1814,7 +1816,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() } } if (mConfig.showTPCTracksFromO2Format) { -#ifdef GPUCA_HAVE_O2HEADERS +#ifdef GPUCA_TPC_GEOMETRY_O2 unsigned int col = 0; GPUCA_OPENMP(for) for (unsigned int i = 0; i < mIOPtrs->nOutputTracksTPCO2; i++) { @@ -1847,7 +1849,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() #ifdef GPUCA_TPC_GEOMETRY_O2 col = mQA->GetMCLabelCol(label); #else - while (col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSLICES] < label) { + while (label.isValid() && col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSLICES] < label.track) { col++; } #endif diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index b0df26c0e80d8..e5352cf37470f 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -213,7 +213,7 @@ static constexpr Color_t defaultColorNums[COLORCOUNT] = {kRed, kBlue, kGreen, kM static inline int GPUQA_O2_ConvertFakeLabel(int label) { return label >= 0x7FFFFFFE ? -1 : label; } inline unsigned int GPUQA::GetNMCCollissions() const { return mMCInfosCol.size(); } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mMCInfosCol[iCol].num; } -inline unsigned int GPUQA::GetNMCTracks(const mcLabel_t& label) const { return mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].num; } +inline unsigned int GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].num; } inline unsigned int GPUQA::GetNMCLabels() const { return mClNative->clustersMCTruth ? mClNative->clustersMCTruth->getIndexedSize() : 0; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mMCInfos[mMCInfosCol[iCol].first + iTrk]; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return mMCInfos[mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].first + label.getTrackID()]; } @@ -238,7 +238,7 @@ inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) inline bool GPUQA::mcLabelI_t::operator==(const GPUQA::mcLabel_t& l) { return AbsLabelID(track) == l.fMCID; } inline unsigned int GPUQA::GetNMCCollissions() const { return 1; } inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mTracking->mIOPtrs.nMCInfosTPC; } -inline unsigned int GPUQA::GetNMCTracks(const mcLabel_t& label) const { return mTracking->mIOPtrs.nMCInfosTPC; } +inline unsigned int GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mTracking->mIOPtrs.nMCInfosTPC; } inline unsigned int GPUQA::GetNMCLabels() const { return mTracking->mIOPtrs.nMCLabelsTPC; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mTracking->mIOPtrs.mcInfosTPC[AbsLabelID(iTrk)]; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return GetMCTrack(label.fMCID, 0); } @@ -260,7 +260,7 @@ inline int GPUQA::FakeLabelID(int id) { return id < 0 ? id : (-2 - id); } inline int GPUQA::AbsLabelID(int id) { return id >= 0 ? id : (-id - 2); } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && GetNMCLabels() && GetNMCTracks(0); } unsigned int GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return 0; } -GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? MC_LABEL_INVALID : mTrackMCLabels[trackId]; } +GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? mcLabelI_t() : mTrackMCLabels[trackId]; } #define TRACK_EXPECTED_REFERENCE_X TRACK_EXPECTED_REFERENCE_X_DEFAULT #endif template @@ -336,6 +336,7 @@ void GPUQA::clearGarbagageCollector() GPUQA::GPUQA(GPUChainTracking* chain, const GPUSettingsQA* config, const GPUParam* param) : mTracking(chain), mConfig(config ? *config : GPUQA_GetConfig(chain)), mParam(param ? param : &chain->GetParam()), mGarbageCollector(std::make_unique()) { + mMCEventOffset.resize(1, 0); } GPUQA::~GPUQA() diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index 622c7726dd268..be8b00972439a 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -105,7 +105,11 @@ class GPUQA #else using mcLabels_t = AliHLTTPCClusterMCLabel; using mcLabel_t = AliHLTTPCClusterMCWeight; + + private: struct mcLabelI_t; + + public: #endif void UpdateParam(const GPUParam* param) { mParam = param; } @@ -185,6 +189,7 @@ class GPUQA struct mcLabelI_t { int getTrackID() const { return AbsLabelID(track); } int getEventID() const { return 0; } + int getSourceID() const { return 0; } long int getTrackEventSourceID() const { return getTrackID(); } bool isFake() const { return track < 0; } bool isValid() const { return track != MC_LABEL_INVALID; } @@ -208,7 +213,7 @@ class GPUQA unsigned int GetNMCCollissions() const; unsigned int GetNMCTracks(int iCol) const; - unsigned int GetNMCTracks(const mcLabel_t& label) const; + unsigned int GetNMCTracks(const mcLabelI_t& label) const; unsigned int GetNMCLabels() const; const mcInfo_t& GetMCTrack(unsigned int iTrk, unsigned int iCol); const mcInfo_t& GetMCTrack(const mcLabel_t& label); From 80c50bd3e80ed271db6434611a7b7d459cfeaf8a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 00:20:24 +0200 Subject: [PATCH 0244/2205] GPU Display: Fix drawing of MC tracks --- GPU/GPUTracking/display/GPUDisplay.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 1dc20d403a525..6c2cb4389ffab 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -1010,7 +1010,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s x = mclocal[0]; #ifdef GPUCA_TPC_GEOMETRY_O2 - trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, charge); + trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, -charge); // TODO: DR: unclear to me why we need -charge here if (mParam->par.continuousTracking) { ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, mc.t0, mParam->par.continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1); } From 440488e9e0ed8ac3b97ba4283ce61155640c0512 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 00:34:01 +0200 Subject: [PATCH 0245/2205] GPU QA: Fix some ROOT warnings with ROOT >= 6.30 --- GPU/GPUTracking/qa/GPUQA.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index e5352cf37470f..9380a823b2a41 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -2224,8 +2224,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) dst[1]->SetBinContent(bin, proj->GetMean()); dst[1]->SetBinError(bin, std::sqrt(proj->GetRMS())); } else { - proj->GetXaxis()->SetRangeUser(proj->GetMean() - 6. * proj->GetRMS(), proj->GetMean() + 6. * proj->GetRMS()); - proj->GetXaxis()->SetRangeUser(proj->GetMean() - 3. * proj->GetRMS(), proj->GetMean() + 3. * proj->GetRMS()); + proj->GetXaxis()->SetRange(0, 0); + proj->GetXaxis()->SetRangeUser(std::max(proj->GetXaxis()->GetXmin(), proj->GetMean() - 3. * proj->GetRMS()), std::min(proj->GetXaxis()->GetXmax(), proj->GetMean() + 3. * proj->GetRMS())); bool forceLogLike = proj->GetMaximum() < 20; for (int k = forceLogLike ? 2 : 0; k < 3; k++) { proj->Fit("gaus", forceLogLike || k == 2 ? "sQl" : k ? "sQww" : "sQ"); From 8d91d67856395c1a113bf39fc7702a9a7b2052a2 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 00:39:59 +0200 Subject: [PATCH 0246/2205] GPU QA: Suppress ROOT Info messages when writing pdf and root output files --- GPU/GPUTracking/qa/GPUQA.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 9380a823b2a41..6b505e133f88e 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -1886,6 +1886,8 @@ void GPUQA::resetHists() int GPUQA::DrawQAHistograms(TObjArray* qcout) { + const auto oldRootIgnoreLevel = gErrorIgnoreLevel; + gErrorIgnoreLevel = kWarning; if (!mQAInitialized) { throw std::runtime_error("QA not initialized"); } @@ -2772,6 +2774,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) if (!qcout) { clearGarbagageCollector(); } + GPUInfo("GPU TPC QA histograms have been written to %s files", mConfig.writeRootFiles ? ".pdf and .root" : ".pdf"); + gErrorIgnoreLevel = oldRootIgnoreLevel; return (0); } From 28491e9f38cc5df4a823dbfccf897f637a4841fe Mon Sep 17 00:00:00 2001 From: mcoquet642 Date: Fri, 13 Sep 2024 11:03:51 +0200 Subject: [PATCH 0247/2205] Fix typo in mft-mch matching savemode 3 --- .../GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h | 2 +- Detectors/GlobalTracking/src/MatchGlobalFwd.cxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h index 7aaadaad8ffff..c3de0cdc74ed3 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchGlobalFwd.h @@ -333,7 +333,7 @@ class MatchGlobalFwd std::vector mMFTMatchPlaneParams; ///< MFT track parameters at matching plane std::vector mMCHMatchPlaneParams; ///< MCH track parameters at matching plane - std::map>> mCandidates; ///< map each MCH track id to vector of best match candidates + std::map>> mCandidates; ///< map each MCH track id to vector of best match candidates const o2::itsmft::TopologyDictionary* mMFTDict{nullptr}; // cluster patterns dictionary o2::itsmft::ChipMappingMFT mMFTMapping; diff --git a/Detectors/GlobalTracking/src/MatchGlobalFwd.cxx b/Detectors/GlobalTracking/src/MatchGlobalFwd.cxx index 422dd92787105..ab6fd6b5383d6 100644 --- a/Detectors/GlobalTracking/src/MatchGlobalFwd.cxx +++ b/Detectors/GlobalTracking/src/MatchGlobalFwd.cxx @@ -494,9 +494,9 @@ void MatchGlobalFwd::ROFMatch(int MFTROFId, int firstMCHROFId, int lastMCHROFId) } } - if constexpr (saveAllMode == SaveMode::kSaveNCandidates) { // In saveAllmode save all pairs to output container + if constexpr (saveAllMode == SaveMode::kSaveNCandidates) { // Save best N matching candidates auto score = mMatchFunc(thisMCHTrack, thisMFTTrack); - std::pair scoreID = {score, MFTId}; + std::pair scoreID = {score, MFTId}; mCandidates[MCHId].push_back(scoreID); std::sort(mCandidates[MCHId].begin(), mCandidates[MCHId].end(), compare); if (mCandidates[MCHId].size() > mNCandidates) { From 16df06f81d3eb60161bd5968ccc18a7cfd04e6d5 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 13:15:41 +0200 Subject: [PATCH 0248/2205] GPU Display: Move different source files to subfolders to clean up display folders a bit" --- GPU/GPUTracking/display/CMakeLists.txt | 43 ++++++++++--------- GPU/GPUTracking/display/GPUDisplay.cxx | 6 +-- GPU/GPUTracking/display/GPUDisplay.h | 4 +- .../{ => backend}/GPUDisplayBackend.cxx | 2 +- .../display/{ => backend}/GPUDisplayBackend.h | 0 .../{ => backend}/GPUDisplayBackendOpenGL.cxx | 2 +- .../{ => backend}/GPUDisplayBackendOpenGL.h | 0 .../{ => backend}/GPUDisplayBackendVulkan.cxx | 0 .../{ => backend}/GPUDisplayBackendVulkan.h | 0 .../{ => frontend}/GPUDisplayFrontend.cxx | 0 .../{ => frontend}/GPUDisplayFrontend.h | 0 .../{ => frontend}/GPUDisplayFrontendGlfw.cxx | 2 +- .../{ => frontend}/GPUDisplayFrontendGlfw.h | 0 .../{ => frontend}/GPUDisplayFrontendGlut.cxx | 2 +- .../{ => frontend}/GPUDisplayFrontendGlut.h | 0 .../{ => frontend}/GPUDisplayFrontendNone.cxx | 0 .../{ => frontend}/GPUDisplayFrontendNone.h | 0 .../GPUDisplayFrontendWayland.cxx | 2 +- .../GPUDisplayFrontendWayland.h | 0 .../GPUDisplayFrontendWindows.cxx | 2 +- .../GPUDisplayFrontendWindows.h | 0 .../{ => frontend}/GPUDisplayFrontendX11.cxx | 2 +- .../{ => frontend}/GPUDisplayFrontendX11.h | 0 .../display/{ => frontend}/GPUDisplayGUI.cxx | 0 .../display/{ => frontend}/GPUDisplayGUI.h | 0 .../display/{ => frontend}/GPUDisplayGUI.ui | 0 .../{ => frontend}/GPUDisplayGUIWrapper.cxx | 0 .../{ => frontend}/GPUDisplayGUIWrapper.h | 0 .../display/{ => frontend}/GPUDisplayKeys.cxx | 0 .../GPUDisplayBackendOpenGLMagneticField.cxx | 4 +- .../{ => helpers}/GPUDisplayInterpolation.cxx | 0 .../{ => helpers}/GPUDisplayLoader.cxx | 2 +- .../{ => helpers}/GPUDisplayMagneticField.cxx | 0 .../{ => helpers}/GPUDisplayMagneticField.h | 0 .../{ => helpers}/GPUDisplayQuaternion.cxx | 0 .../display/{ => helpers}/GPUDisplayROOT.cxx | 0 .../display/{ => helpers}/bitmapfile.h | 0 .../field-uniform-exporter.cxx | 2 +- .../display/{ => shaders}/GPUDisplayShaders.h | 0 39 files changed, 38 insertions(+), 37 deletions(-) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackend.cxx (99%) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackend.h (100%) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackendOpenGL.cxx (99%) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackendOpenGL.h (100%) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackendVulkan.cxx (100%) rename GPU/GPUTracking/display/{ => backend}/GPUDisplayBackendVulkan.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontend.cxx (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontend.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendGlfw.cxx (99%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendGlfw.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendGlut.cxx (99%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendGlut.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendNone.cxx (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendNone.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendWayland.cxx (99%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendWayland.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendWindows.cxx (99%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendWindows.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendX11.cxx (99%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayFrontendX11.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayGUI.cxx (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayGUI.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayGUI.ui (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayGUIWrapper.cxx (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayGUIWrapper.h (100%) rename GPU/GPUTracking/display/{ => frontend}/GPUDisplayKeys.cxx (100%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayBackendOpenGLMagneticField.cxx (99%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayInterpolation.cxx (100%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayLoader.cxx (97%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayMagneticField.cxx (100%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayMagneticField.h (100%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayQuaternion.cxx (100%) rename GPU/GPUTracking/display/{ => helpers}/GPUDisplayROOT.cxx (100%) rename GPU/GPUTracking/display/{ => helpers}/bitmapfile.h (100%) rename GPU/GPUTracking/display/{tools => helpers}/field-uniform-exporter.cxx (99%) rename GPU/GPUTracking/display/{ => shaders}/GPUDisplayShaders.h (100%) diff --git a/GPU/GPUTracking/display/CMakeLists.txt b/GPU/GPUTracking/display/CMakeLists.txt index 50c9c0e4a3bfb..d4de5e5fbe835 100644 --- a/GPU/GPUTracking/display/CMakeLists.txt +++ b/GPU/GPUTracking/display/CMakeLists.txt @@ -51,23 +51,23 @@ endif() set(SRCS ../utils/qsem.cxx GPUDisplay.cxx - GPUDisplayMagneticField.cxx - GPUDisplayFrontend.cxx - GPUDisplayBackend.cxx - GPUDisplayBackendOpenGL.cxx - GPUDisplayFrontendGlfw.cxx) + helpers/GPUDisplayMagneticField.cxx + frontend/GPUDisplayFrontend.cxx + frontend/GPUDisplayFrontendGlfw.cxx + backend/GPUDisplayBackend.cxx + backend/GPUDisplayBackendOpenGL.cxx) -set(SRCS_NO_H GPUDisplayLoader.cxx - GPUDisplayBackendOpenGLMagneticField.cxx - GPUDisplayQuaternion.cxx - GPUDisplayInterpolation.cxx - GPUDisplayKeys.cxx - GPUDisplayROOT.cxx) +set(SRCS_NO_H helpers/GPUDisplayLoader.cxx + helpers/GPUDisplayBackendOpenGLMagneticField.cxx + helpers/GPUDisplayQuaternion.cxx + helpers/GPUDisplayInterpolation.cxx + helpers/GPUDisplayROOT.cxx + frontend/GPUDisplayKeys.cxx) -set(HDRS_INSTALL GPUDisplayShaders.h) +set(HDRS_INSTALL shaders/GPUDisplayShaders.h) if(GPUCA_EVENT_DISPLAY_VULKAN) - set(SRCS ${SRCS} GPUDisplayBackendVulkan.cxx) + set(SRCS ${SRCS} backend/GPUDisplayBackendVulkan.cxx) if(GPUCA_EVENT_DISPLAY_WAYLAND) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-client-protocol.h @@ -94,19 +94,19 @@ if(GPUCA_EVENT_DISPLAY_VULKAN) MAIN_DEPENDENCY ${O2GPUWayland_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml COMMENT "Preparing Wayland xdg-decoration-protocol.c") - set_property(SOURCE GPUDisplayFrontendWayland.cxx ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-protocol.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-decoration-client-protocol.h) - set_property(SOURCE GPUDisplayFrontendWayland.cxx APPEND PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/) + set_property(SOURCE frontend/GPUDisplayFrontendWayland.cxx ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-protocol.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-decoration-client-protocol.h) + set_property(SOURCE frontend/GPUDisplayFrontendWayland.cxx APPEND PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/) - set(SRCS_NO_H ${SRCS_NO_H} GPUDisplayFrontendWayland.cxx ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-protocol.c ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-decoration-protocol.c) + set(SRCS_NO_H ${SRCS_NO_H} frontend/GPUDisplayFrontendWayland.cxx ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-shell-protocol.c ${CMAKE_CURRENT_BINARY_DIR}/xdg-gen/xdg-decoration-protocol.c) endif() endif() if(X11_FOUND) - set(SRCS ${SRCS} GPUDisplayFrontendX11.cxx) + set(SRCS ${SRCS} frontend/GPUDisplayFrontendX11.cxx) endif() if(GLUT_FOUND) - set(SRCS ${SRCS} GPUDisplayFrontendGlut.cxx) + set(SRCS ${SRCS} frontend/GPUDisplayFrontendGlut.cxx) endif() if(GPUCA_EVENT_DISPLAY_QT) @@ -114,8 +114,8 @@ if(GPUCA_EVENT_DISPLAY_QT) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) - set(SRCS ${SRCS} GPUDisplayGUI.cxx GPUDisplayGUIWrapper.cxx) - set(SRCS_NO_H ${SRCS_NO_H} GPUDisplayGUI.ui) + set(SRCS ${SRCS} frontend/GPUDisplayGUI.cxx frontend/GPUDisplayGUIWrapper.cxx) + set(SRCS_NO_H ${SRCS_NO_H} frontend/GPUDisplayGUI.ui) endif() string(REPLACE ".cxx" ".h" HDRS "${SRCS}") @@ -136,7 +136,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "O2") TARGETVARNAME exporterName COMPONENT_NAME gpu PUBLIC_LINK_LIBRARIES O2::Field O2::GPUTracking Boost::program_options - SOURCES tools/field-uniform-exporter.cxx GPUDisplayMagneticField.cxx) + SOURCES helpers/field-uniform-exporter.cxx helpers/GPUDisplayMagneticField.cxx) target_compile_definitions(${exporterName} PRIVATE $) endif() @@ -156,6 +156,7 @@ endif() message(STATUS "Building GPU Event Display (Vulkan ${GPUCA_EVENT_DISPLAY_VULKAN}, Wayland ${GPUCA_EVENT_DISPLAY_WAYLAND}, Freetype ${GPUCA_EVENT_DISPLAY_FREETYPE}, Fontconfig ${Fontconfig_FOUND}, Qt ${GPUCA_EVENT_DISPLAY_QT})") target_link_libraries(${targetName} PUBLIC ${GLFW_LIBRARIES} OpenGL::GL) +target_include_directories(${targetName} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) if(X11_FOUND) target_link_libraries(${targetName} PRIVATE X11::X11) diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 6c2cb4389ffab..8881d1fc05cbe 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -29,7 +29,7 @@ #include #ifndef _WIN32 -#include "bitmapfile.h" +#include "helpers/bitmapfile.h" #include "../utils/linux_helpers.h" #endif #ifdef WITH_OPENMP @@ -69,8 +69,8 @@ #include "ITSMFTBase/DPLAlpideParam.h" #endif -#include "GPUDisplayFrontend.h" -#include "GPUDisplayBackend.h" +#include "frontend/GPUDisplayFrontend.h" +#include "backend/GPUDisplayBackend.h" constexpr hmm_mat4 MY_HMM_IDENTITY = {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; constexpr hmm_mat4 MY_HMM_FROM(float (&v)[16]) { return {{{v[0], v[1], v[2], v[3]}, {v[4], v[5], v[6], v[7]}, {v[8], v[9], v[10], v[11]}, {v[12], v[13], v[14], v[15]}}}; } diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index f50034d608874..33624aa33fa4d 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -16,8 +16,8 @@ #define GPUDISPLAY_H #include "GPUSettings.h" -#include "GPUDisplayFrontend.h" -#include "GPUDisplayBackend.h" +#include "frontend/GPUDisplayFrontend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayInterface.h" #include "GPUChainTracking.h" diff --git a/GPU/GPUTracking/display/GPUDisplayBackend.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayBackend.cxx rename to GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx index 245a5138d84d5..86722d5d44df6 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackend.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx @@ -13,7 +13,7 @@ /// \author David Rohr #include "GPUDisplayBackend.h" -#include "GPUDisplayMagneticField.h" +#include "helpers/GPUDisplayMagneticField.h" #include "GPUDisplayBackendOpenGL.h" diff --git a/GPU/GPUTracking/display/GPUDisplayBackend.h b/GPU/GPUTracking/display/backend/GPUDisplayBackend.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayBackend.h rename to GPU/GPUTracking/display/backend/GPUDisplayBackend.h diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx rename to GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx index 35ac7421520af..20943f609c4aa 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx @@ -25,7 +25,7 @@ #include "GPUCommonDef.h" #include "GPUDisplayBackendOpenGL.h" -#include "GPUDisplayShaders.h" +#include "shaders/GPUDisplayShaders.h" #include "GPUDisplay.h" #define OPENGL_EMULATE_MULTI_DRAW 0 diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayBackendOpenGL.h rename to GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h diff --git a/GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayBackendVulkan.cxx rename to GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayBackendVulkan.h b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayBackendVulkan.h rename to GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontend.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontend.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayFrontend.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontend.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx index 54f6591d2286c..1644bb23d5b94 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx @@ -13,7 +13,7 @@ /// \author David Rohr #include "GPUDisplayFrontendGlfw.h" -#include "GPUDisplayBackend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayGUIWrapper.h" #include "GPULogging.h" diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendGlfw.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendGlfw.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendGlut.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayFrontendGlut.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx index 388032f53cbd3..a165e51840e0c 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendGlut.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx @@ -14,7 +14,7 @@ // Now the other headers #include "GPUDisplayFrontendGlut.h" -#include "GPUDisplayBackend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayGUIWrapper.h" #include "GPULogging.h" #include diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendGlut.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendGlut.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendNone.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendNone.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendNone.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendNone.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendWayland.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayFrontendWayland.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx index 86c07f63f3021..6c85336f9791a 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendWayland.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx @@ -14,7 +14,7 @@ // Now the other headers #include "GPUDisplayFrontendWayland.h" -#include "GPUDisplayBackend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayGUIWrapper.h" #include "GPUDisplay.h" #include "GPULogging.h" diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendWayland.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendWayland.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendWindows.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayFrontendWindows.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx index dd54ba8ea04aa..75a1d04e2fc51 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendWindows.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx @@ -17,7 +17,7 @@ #include #include #include "GPUDisplayFrontendWindows.h" -#include "GPUDisplayBackend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayGUIWrapper.h" #include "GPULogging.h" #include diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendWindows.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendWindows.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx index 7e397813c12f2..c1fae89b7227f 100644 --- a/GPU/GPUTracking/display/GPUDisplayFrontendX11.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx @@ -14,7 +14,7 @@ // Now the other headers #include "GPUDisplayFrontendX11.h" -#include "GPUDisplayBackend.h" +#include "backend/GPUDisplayBackend.h" #include "GPUDisplayGUIWrapper.h" #include "GPULogging.h" #include diff --git a/GPU/GPUTracking/display/GPUDisplayFrontendX11.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayFrontendX11.h rename to GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h diff --git a/GPU/GPUTracking/display/GPUDisplayGUI.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayGUI.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayGUI.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayGUI.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayGUI.h b/GPU/GPUTracking/display/frontend/GPUDisplayGUI.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayGUI.h rename to GPU/GPUTracking/display/frontend/GPUDisplayGUI.h diff --git a/GPU/GPUTracking/display/GPUDisplayGUI.ui b/GPU/GPUTracking/display/frontend/GPUDisplayGUI.ui similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayGUI.ui rename to GPU/GPUTracking/display/frontend/GPUDisplayGUI.ui diff --git a/GPU/GPUTracking/display/GPUDisplayGUIWrapper.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayGUIWrapper.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayGUIWrapper.h b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayGUIWrapper.h rename to GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h diff --git a/GPU/GPUTracking/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayKeys.cxx rename to GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx similarity index 99% rename from GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx index 6affd22b3573b..d3fe6e71a91b2 100644 --- a/GPU/GPUTracking/display/GPUDisplayBackendOpenGLMagneticField.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx @@ -28,8 +28,8 @@ #include "GPUCommonDef.h" #include "GPUDisplayMagneticField.h" -#include "GPUDisplayBackendOpenGL.h" -#include "GPUDisplayShaders.h" +#include "backend/GPUDisplayBackendOpenGL.h" +#include "shaders/GPUDisplayShaders.h" #include "GPUDisplay.h" using namespace GPUCA_NAMESPACE::gpu; diff --git a/GPU/GPUTracking/display/GPUDisplayInterpolation.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayInterpolation.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayLoader.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayLoader.cxx similarity index 97% rename from GPU/GPUTracking/display/GPUDisplayLoader.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayLoader.cxx index 090aec7d06e32..27f0355e95583 100644 --- a/GPU/GPUTracking/display/GPUDisplayLoader.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayLoader.cxx @@ -13,7 +13,7 @@ /// \author David Rohr #include "GPUDisplay.h" -#include "GPUDisplayFrontend.h" +#include "frontend/GPUDisplayFrontend.h" #include "GPUDisplayInterface.h" #include diff --git a/GPU/GPUTracking/display/GPUDisplayMagneticField.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayMagneticField.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayMagneticField.h b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayMagneticField.h rename to GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h diff --git a/GPU/GPUTracking/display/GPUDisplayQuaternion.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayQuaternion.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayQuaternion.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayQuaternion.cxx diff --git a/GPU/GPUTracking/display/GPUDisplayROOT.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayROOT.cxx rename to GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx diff --git a/GPU/GPUTracking/display/bitmapfile.h b/GPU/GPUTracking/display/helpers/bitmapfile.h similarity index 100% rename from GPU/GPUTracking/display/bitmapfile.h rename to GPU/GPUTracking/display/helpers/bitmapfile.h diff --git a/GPU/GPUTracking/display/tools/field-uniform-exporter.cxx b/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx similarity index 99% rename from GPU/GPUTracking/display/tools/field-uniform-exporter.cxx rename to GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx index 11cea294672f4..3f564f5bc8e5b 100644 --- a/GPU/GPUTracking/display/tools/field-uniform-exporter.cxx +++ b/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx @@ -18,7 +18,7 @@ #include #include -#include "../GPUDisplayMagneticField.h" +#include "GPUDisplayMagneticField.h" namespace bpo = boost::program_options; using namespace GPUCA_NAMESPACE::gpu; diff --git a/GPU/GPUTracking/display/GPUDisplayShaders.h b/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h similarity index 100% rename from GPU/GPUTracking/display/GPUDisplayShaders.h rename to GPU/GPUTracking/display/shaders/GPUDisplayShaders.h From 1c287642971ab2d2db0a13efe6f78a9539b390b1 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 13 Sep 2024 15:32:41 +0200 Subject: [PATCH 0249/2205] GPU Display: Split GPUDisplay.cxx in multiple files --- GPU/GPUTracking/display/CMakeLists.txt | 4 + GPU/GPUTracking/display/GPUDisplay.cxx | 1655 +---------------- GPU/GPUTracking/display/GPUDisplay.h | 3 +- .../display/backend/GPUDisplayBackend.h | 4 +- .../backend/GPUDisplayBackendOpenGL.cxx | 4 +- .../backend/GPUDisplayBackendVulkan.cxx | 10 +- .../display/backend/GPUDisplayBackendVulkan.h | 2 +- .../display/frontend/GPUDisplayFrontend.h | 14 +- .../display/helpers/GPUDisplayAnimation.cxx | 197 ++ .../GPUDisplayBackendOpenGLMagneticField.cxx | 2 +- .../display/helpers/GPUDisplayColors.inc | 178 ++ .../display/helpers/GPUDisplayHelpers.cxx | 131 ++ .../display/helpers/GPUDisplayROOT.cxx | 4 + .../display/render/GPUDisplayDraw.cxx | 987 ++++++++++ .../display/render/GPUDisplayImportEvent.cxx | 276 +++ 15 files changed, 1801 insertions(+), 1670 deletions(-) create mode 100644 GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx create mode 100644 GPU/GPUTracking/display/helpers/GPUDisplayColors.inc create mode 100644 GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx create mode 100644 GPU/GPUTracking/display/render/GPUDisplayDraw.cxx create mode 100644 GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx diff --git a/GPU/GPUTracking/display/CMakeLists.txt b/GPU/GPUTracking/display/CMakeLists.txt index d4de5e5fbe835..2c1814a1a26a0 100644 --- a/GPU/GPUTracking/display/CMakeLists.txt +++ b/GPU/GPUTracking/display/CMakeLists.txt @@ -58,6 +58,10 @@ set(SRCS ../utils/qsem.cxx backend/GPUDisplayBackendOpenGL.cxx) set(SRCS_NO_H helpers/GPUDisplayLoader.cxx + render/GPUDisplayDraw.cxx + render/GPUDisplayImportEvent.cxx + helpers/GPUDisplayHelpers.cxx + helpers/GPUDisplayAnimation.cxx helpers/GPUDisplayBackendOpenGLMagneticField.cxx helpers/GPUDisplayQuaternion.cxx helpers/GPUDisplayInterpolation.cxx diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 8881d1fc05cbe..59d6d978c3eaf 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -12,77 +12,40 @@ /// \file GPUDisplay.cxx /// \author David Rohr -#ifndef GPUCA_NO_ROOT -#include "Rtypes.h" // Include ROOT header first, to use ROOT and disable replacements -#endif - #include "GPUDisplay.h" #include "GPUTPCDef.h" #include -#include -#include #include #include #include -#include #ifndef _WIN32 -#include "helpers/bitmapfile.h" #include "../utils/linux_helpers.h" #endif #ifdef WITH_OPENMP #include #endif -#include "GPUTPCMCInfo.h" #include "GPUChainTracking.h" #include "GPUQA.h" #include "GPUTPCSliceData.h" #include "GPUChainTracking.h" #include "GPUTPCTrack.h" #include "GPUTPCTracker.h" -#include "GPUTRDTracker.h" #include "GPUTPCGMMergedTrack.h" -#include "GPUTPCGMPropagator.h" -#include "GPUTPCClusterData.h" -#include "GPUTRDTrackletWord.h" -#include "GPUTRDGeometry.h" #include "GPUO2DataTypes.h" -#include "GPUParam.inc" -#include "GPUTPCConvertImpl.h" #include "utils/qconfig.h" -#ifdef GPUCA_HAVE_O2HEADERS -#include "GPUTrackParamConvert.h" -#include "DataFormatsITSMFT/ROFRecord.h" -#include "DataFormatsITS/TrackITS.h" -#include "DataFormatsTPC/TrackTPC.h" -#include "DataFormatsTOF/Cluster.h" -#include "TOFBase/Geo.h" -#include "ITSBase/GeometryTGeo.h" -#include "SimulationDataFormat/MCCompLabel.h" -#include "SimulationDataFormat/ConstMCTruthContainer.h" -#endif -#ifdef GPUCA_O2_LIB -#include "ITSMFTBase/DPLAlpideParam.h" -#endif - #include "frontend/GPUDisplayFrontend.h" #include "backend/GPUDisplayBackend.h" +#include "helpers/GPUDisplayColors.inc" constexpr hmm_mat4 MY_HMM_IDENTITY = {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; -constexpr hmm_mat4 MY_HMM_FROM(float (&v)[16]) { return {{{v[0], v[1], v[2], v[3]}, {v[4], v[5], v[6], v[7]}, {v[8], v[9], v[10], v[11]}, {v[12], v[13], v[14], v[15]}}}; } using namespace GPUCA_NAMESPACE::gpu; -#define GL_SCALE_FACTOR (1.f / 100.f) - -#define SEPERATE_GLOBAL_TRACKS_LIMIT (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT) - -#define GET_CID(slice, i) (mParam->par.earlyTpcTransform ? mIOPtrs->clusterData[slice][i].id : (mIOPtrs->clustersNative->clusterOffset[slice][0] + i)) - static const GPUSettingsDisplay& GPUDisplay_GetConfig(GPUChainTracking* chain) { static GPUSettingsDisplay defaultConfig; @@ -110,52 +73,6 @@ GPUDisplay::GPUDisplay(GPUDisplayFrontend* frontend, GPUChainTracking* chain, GP mCfgR.openGLCore = mBackend->CoreProfile(); } -inline const GPUTRDGeometry* GPUDisplay::trdGeometry() { return (GPUTRDGeometry*)mCalib->trdGeometry; } -const GPUTPCTracker& GPUDisplay::sliceTracker(int iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } -const GPUTRDTrackerGPU& GPUDisplay::trdTracker() { return *mChain->GetTRDTrackerGPU(); } -inline int GPUDisplay::getNumThreads() -{ - if (mChain) { - return mChain->GetProcessingSettings().ompThreads; - } else { -#ifdef WITH_OPENMP - return omp_get_max_threads(); -#else - return 1; -#endif - } -} - -void GPUDisplay::disableUnsupportedOptions() -{ - if (!mIOPtrs->mergedTrackHitAttachment) { - mCfgH.markAdjacentClusters = 0; - } - if (!mQA) { - mCfgH.markFakeClusters = 0; - } - if (!mChain) { - mCfgL.excludeClusters = mCfgL.drawInitLinks = mCfgL.drawLinks = mCfgL.drawSeeds = mCfgL.drawTracklets = mCfgL.drawTracks = mCfgL.drawGlobalTracks = 0; - } - if (mConfig.showTPCTracksFromO2Format && mParam->par.earlyTpcTransform) { - throw std::runtime_error("Cannot run GPU display with early Transform when input is O2 tracks"); - } -} - -inline void GPUDisplay::insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last) -{ - if (first == last) { - return; - } - vBuf.first->emplace_back(first); - vBuf.second->emplace_back(last - first); -} -inline void GPUDisplay::insertVertexList(int iSlice, size_t first, size_t last) -{ - std::pair*, vecpod*> vBuf(mVertexBufferStart + iSlice, mVertexBufferCount + iSlice); - insertVertexList(vBuf, first, last); -} - void GPUDisplay::calcXYZ(const float* matrix) { mXYZ[0] = -(matrix[0] * matrix[12] + matrix[1] * matrix[13] + matrix[2] * matrix[14]); @@ -216,246 +133,6 @@ void GPUDisplay::mAnimateCloseQuaternion(float* v, float lastx, float lasty, flo } } } -void GPUDisplay::setAnimationPoint() -{ - if (mCfgL.animationMode & 4) // Spherical - { - float rxy = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[2] * mXYZ[2]); - float anglePhi = atan2f(mXYZ[0], mXYZ[2]); - float angleTheta = atan2f(mXYZ[1], rxy); - if (mAnimateVectors[0].size()) { - mAnimationCloseAngle(anglePhi, mAnimateVectors[2].back()); - } - if (mAnimateVectors[0].size()) { - mAnimationCloseAngle(angleTheta, mAnimateVectors[3].back()); - } - mAnimateVectors[1].emplace_back(0); - mAnimateVectors[2].emplace_back(anglePhi); - mAnimateVectors[3].emplace_back(angleTheta); - } else { - for (int i = 0; i < 3; i++) { - mAnimateVectors[i + 1].emplace_back(mXYZ[i]); - } - // Cartesian - } - float r = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[1] * mXYZ[1] + mXYZ[2] * mXYZ[2]); - mAnimateVectors[4].emplace_back(r); - if (mCfgL.animationMode & 1) // Euler-angles - { - for (int i = 0; i < 3; i++) { - float newangle = mAngle[i]; - if (mAnimateVectors[0].size()) { - mAnimationCloseAngle(newangle, mAnimateVectors[i + 5].back()); - } - mAnimateVectors[i + 5].emplace_back(newangle); - } - mAnimateVectors[8].emplace_back(0); - } else { // Quaternions - float v[4]; - createQuaternionFromMatrix(v, mViewMatrixP); - if (mAnimateVectors[0].size()) { - mAnimateCloseQuaternion(v, mAnimateVectors[5].back(), mAnimateVectors[6].back(), mAnimateVectors[7].back(), mAnimateVectors[8].back()); - } - for (int i = 0; i < 4; i++) { - mAnimateVectors[i + 5].emplace_back(v[i]); - } - } - float delay = 0.f; - if (mAnimateVectors[0].size()) { - delay = mAnimateVectors[0].back() + ((int)(mAnimationDelay * 20)) / 20.f; - } - mAnimateVectors[0].emplace_back(delay); - mAnimateConfig.emplace_back(mCfgL); -} -void GPUDisplay::resetAnimation() -{ - for (int i = 0; i < 9; i++) { - mAnimateVectors[i].clear(); - } - mAnimateConfig.clear(); - mAnimate = 0; -} -void GPUDisplay::removeAnimationPoint() -{ - if (mAnimateVectors[0].size() == 0) { - return; - } - for (int i = 0; i < 9; i++) { - mAnimateVectors[i].pop_back(); - } - mAnimateConfig.pop_back(); -} -void GPUDisplay::startAnimation() -{ - for (int i = 0; i < 8; i++) { - mAnimationSplines[i].create(mAnimateVectors[0], mAnimateVectors[i + 1]); - } - mAnimationTimer.ResetStart(); - mAnimationFrame = 0; - mAnimate = 1; - mAnimationLastBase = 0; -} - -inline void GPUDisplay::ActivateColor() -{ - mBackend->ActivateColor(mDrawColor); -} - -inline void GPUDisplay::SetColorClusters() -{ - if (mCfgL.colorCollisions) { - return; - } - if (mCfgL.invertColors) { - mDrawColor = {0, 0.3, 0.7, 1.f}; - } else { - mDrawColor = {0, 0.7, 1.0, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorTRD() -{ - if (mCfgL.colorCollisions) { - return; - } - if (mCfgL.invertColors) { - mDrawColor = {0.7, 0.3, 0, 1.f}; - } else { - mDrawColor = {1.0, 0.7, 0, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorITS() -{ - if (mCfgL.colorCollisions) { - return; - } - if (mCfgL.invertColors) { - mDrawColor = {1.00, 0.1, 0.1, 1.f}; - } else { - mDrawColor = {1.00, 0.3, 0.3, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorTOF() -{ - if (mCfgL.colorCollisions) { - return; - } - if (mCfgL.invertColors) { - mDrawColor = {0.1, 1.0, 0.1, 1.f}; - } else { - mDrawColor = {0.5, 1.0, 0.5, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorInitLinks() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.42, 0.4, 0.1, 1.f}; - } else { - mDrawColor = {0.42, 0.4, 0.1, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorLinks() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.6, 0.1, 0.1, 1.f}; - } else { - mDrawColor = {0.8, 0.2, 0.2, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorSeeds() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.6, 0.0, 0.65, 1.f}; - } else { - mDrawColor = {0.8, 0.1, 0.85, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorTracklets() -{ - if (mCfgL.invertColors) { - mDrawColor = {0, 0, 0, 1.f}; - } else { - mDrawColor = {1, 1, 1, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorTracks() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.6, 0, 0.1, 1.f}; - } else { - mDrawColor = {0.8, 1., 0.15, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorGlobalTracks() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.8, 0.2, 0, 1.f}; - } else { - mDrawColor = {1.0, 0.4, 0, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorFinal() -{ - if (mCfgL.colorCollisions) { - return; - } - if (mCfgL.invertColors) { - mDrawColor = {0, 0.6, 0.1, 1.f}; - } else { - mDrawColor = {0, 0.7, 0.2, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorGrid() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.5, 0.5, 0.0, 1.f}; - } else { - mDrawColor = {0.7, 0.7, 0.0, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorGridTRD() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.5, 0.5, 0.5, 1.f}; - } else { - mDrawColor = {0.7, 0.7, 0.5, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetColorMarked() -{ - if (mCfgL.invertColors) { - mDrawColor = {0.8, 0, 0, 1.f}; - } else { - mDrawColor = {1.0, 0.0, 0.0, 1.f}; - } - ActivateColor(); -} -inline void GPUDisplay::SetCollisionColor(int col) -{ - int red = (col * 2) % 5; - int blue = (2 + col * 3) % 7; - int green = (4 + col * 5) % 6; - if (mCfgL.invertColors && red == 4 && blue == 5 && green == 6) { - red = 0; - } - if (!mCfgL.invertColors && red == 0 && blue == 0 && green == 0) { - red = 4; - } - mDrawColor = {red / 4.f, green / 5.f, blue / 6.f, 1.f}; - ActivateColor(); -} void GPUDisplay::ResizeScene(int width, int height, bool init) { @@ -522,692 +199,6 @@ void GPUDisplay::ExitDisplay() mBackend->ExitBackend(); } -inline void GPUDisplay::drawPointLinestrip(int iSlice, int cid, int id, int id_limit) -{ - mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); - if (mGlobalPos[cid].w < id_limit) { - mGlobalPos[cid].w = id; - } -} - -GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int iSlice, int select, int iCol) -{ - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - - if (iCol == 0) { - for (unsigned int i = 0; i < mIOPtrs->nTRDTracklets; i++) { - int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); - bool draw = iSlice == iSec && mGlobalPosTRD[i].w == select; - if (draw) { - mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD[i].x, mGlobalPosTRD[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[i].z); - mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD2[i].x, mGlobalPosTRD2[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[i].z); - } - } - } - - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int iSlice, int select, int iCol) -{ - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - - if (iCol == 0 && iSlice == 0) { - for (unsigned int i = 0; i < mIOPtrs->nTOFClusters; i++) { - mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[i].x, mGlobalPosTOF[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[i].z); - } - } - - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int iSlice, int select, int iCol) -{ - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - - if (iCol == 0 && iSlice == 0 && mIOPtrs->itsClusters) { - for (unsigned int i = 0; i < mIOPtrs->nItsClusters; i++) { - mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[i].x, mGlobalPosITS[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[i].z); - } - } - - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned int iCol) -{ - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - if (mOverlayTFClusters.size() > 0 || iCol == 0 || mNCollissions) { - const int firstCluster = (mOverlayTFClusters.size() > 1 && iCol > 0) ? mOverlayTFClusters[iCol - 1][iSlice] : 0; - const int lastCluster = (mOverlayTFClusters.size() > 1 && iCol + 1 < mOverlayTFClusters.size()) ? mOverlayTFClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); - const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth; - for (int cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { - const int cid = GET_CID(iSlice, cidInSlice); -#ifdef GPUCA_TPC_GEOMETRY_O2 - if (checkClusterCollision) { - const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid); - if (labels.size() ? (iCol != mQA->GetMCLabelCol(labels[0])) : (iCol != 0)) { - continue; - } - } -#else - (void)checkClusterCollision; -#endif - if (mCfgH.hideUnmatchedClusters && mQA && mQA->SuppressHit(cid)) { - continue; - } - bool draw = mGlobalPos[cid].w == select; - - if (mCfgH.markAdjacentClusters) { - const int attach = mIOPtrs->mergedTrackHitAttachment[cid]; - if (attach) { - if (mCfgH.markAdjacentClusters >= 32) { - if (mQA && mQA->clusterRemovable(attach, mCfgH.markAdjacentClusters == 33)) { - draw = select == tMARKED; - } - } else if ((mCfgH.markAdjacentClusters & 2) && (attach & gputpcgmmergertypes::attachTube)) { - draw = select == tMARKED; - } else if ((mCfgH.markAdjacentClusters & 1) && (attach & (gputpcgmmergertypes::attachGood | gputpcgmmergertypes::attachTube)) == 0) { - draw = select == tMARKED; - } else if ((mCfgH.markAdjacentClusters & 4) && (attach & gputpcgmmergertypes::attachGoodLeg) == 0) { - draw = select == tMARKED; - } else if ((mCfgH.markAdjacentClusters & 16) && (attach & gputpcgmmergertypes::attachHighIncl)) { - draw = select == tMARKED; - } else if (mCfgH.markAdjacentClusters & 8) { - if (fabsf(mIOPtrs->mergedTracks[attach & gputpcgmmergertypes::attachTrackMask].GetParam().GetQPt()) > 20.f) { - draw = select == tMARKED; - } - } - } - } else if (mCfgH.markClusters) { - short flags; - if (mParam->par.earlyTpcTransform) { - flags = mIOPtrs->clusterData[iSlice][cidInSlice].flags; - } else { - flags = mIOPtrs->clustersNative->clustersLinear[cid].getFlags(); - } - const bool match = flags & mCfgH.markClusters; - draw = (select == tMARKED) ? (match) : (draw && !match); - } else if (mCfgH.markFakeClusters) { - const bool fake = (mQA->HitAttachStatus(cid)); - draw = (select == tMARKED) ? (fake) : (draw && !fake); - } - if (draw) { - mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); - } - } - } - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int id, bool dodown) -{ - int iSlice = tracker.ISlice(); - if (mCfgH.clustersOnly) { - return (vboList(0, 0, iSlice)); - } - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { - const GPUTPCRow& row = tracker.Data().Row(i); - - if (i < GPUCA_ROW_COUNT - 2) { - const GPUTPCRow& rowUp = tracker.Data().Row(i + 2); - for (int j = 0; j < row.NHits(); j++) { - if (tracker.Data().HitLinkUpData(row, j) != CALINK_INVAL) { - const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); - const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowUp, tracker.Data().HitLinkUpData(row, j))); - drawPointLinestrip(iSlice, cid1, id); - drawPointLinestrip(iSlice, cid2, id); - } - } - } - - if (dodown && i >= 2) { - const GPUTPCRow& rowDown = tracker.Data().Row(i - 2); - for (int j = 0; j < row.NHits(); j++) { - if (tracker.Data().HitLinkDownData(row, j) != CALINK_INVAL) { - const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); - const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowDown, tracker.Data().HitLinkDownData(row, j))); - drawPointLinestrip(iSlice, cid1, id); - drawPointLinestrip(iSlice, cid2, id); - } - } - } - } - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawSeeds(const GPUTPCTracker& tracker) -{ - int iSlice = tracker.ISlice(); - if (mCfgH.clustersOnly) { - return (vboList(0, 0, iSlice)); - } - size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < *tracker.NStartHits(); i++) { - const GPUTPCHitId& hit = tracker.TrackletStartHit(i); - size_t startCountInner = mVertexBuffer[iSlice].size(); - int ir = hit.RowIndex(); - calink ih = hit.HitIndex(); - do { - const GPUTPCRow& row = tracker.Data().Row(ir); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, ih)); - drawPointLinestrip(iSlice, cid, tSEED); - ir += 2; - ih = tracker.Data().HitLinkUpData(row, ih); - } while (ih != CALINK_INVAL); - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - } - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawTracklets(const GPUTPCTracker& tracker) -{ - int iSlice = tracker.ISlice(); - if (mCfgH.clustersOnly) { - return (vboList(0, 0, iSlice)); - } - size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < *tracker.NTracklets(); i++) { - const GPUTPCTracklet& tracklet = tracker.Tracklet(i); - size_t startCountInner = mVertexBuffer[iSlice].size(); - float4 oldpos; - for (int j = tracklet.FirstRow(); j <= tracklet.LastRow(); j++) { - const calink rowHit = tracker.TrackletRowHits()[tracklet.FirstHit() + (j - tracklet.FirstRow())]; - if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) { - const GPUTPCRow& row = tracker.Data().Row(j); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, rowHit)); - oldpos = mGlobalPos[cid]; - drawPointLinestrip(iSlice, cid, tTRACKLET); - } - } - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - } - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int global) -{ - int iSlice = tracker.ISlice(); - if (mCfgH.clustersOnly) { - return (vboList(0, 0, iSlice)); - } - size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = (global ? tracker.CommonMemory()->nLocalTracks : 0); i < (global ? *tracker.NTracks() : tracker.CommonMemory()->nLocalTracks); i++) { - GPUTPCTrack& track = tracker.Tracks()[i]; - size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int j = 0; j < track.NHits(); j++) { - const GPUTPCHitId& hit = tracker.TrackHits()[track.FirstHitID() + j]; - const GPUTPCRow& row = tracker.Data().Row(hit.RowIndex()); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, hit.HitIndex())); - drawPointLinestrip(iSlice, cid, tSLICETRACK + global); - } - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - } - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -void GPUDisplay::DrawTrackITS(int trackId, int iSlice) -{ -#ifdef GPUCA_HAVE_O2HEADERS - const auto& trk = mIOPtrs->itsTracks[trackId]; - for (int k = 0; k < trk.getNClusters(); k++) { - int cid = mIOPtrs->itsTrackClusIdx[trk.getFirstClusterEntry() + k]; - mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[cid].x, mGlobalPosITS[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[cid].z); - mGlobalPosITS[cid].w = tITSATTACHED; - } -#endif -} - -GPUDisplay::vboList GPUDisplay::DrawFinalITS() -{ - const int iSlice = 0; - size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < mIOPtrs->nItsTracks; i++) { - if (mITSStandaloneTracks[i]) { - size_t startCountInner = mVertexBuffer[iSlice].size(); - DrawTrackITS(i, iSlice); - insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); - } - } - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -template -void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer) -{ - auto& vBuf = threadBuffer.vBuf; - auto& buffer = threadBuffer.buffer; - unsigned int nTracks = std::max(trackList[0].size(), trackList[1].size()); - if (mCfgH.clustersOnly) { - nTracks = 0; - } - for (unsigned int ii = 0; ii < nTracks; ii++) { - int i = 0; - const T* track = nullptr; - int lastCluster = -1; - while (true) { - if (ii >= trackList[0].size()) { - break; - } - i = trackList[0][ii]; - int nClusters; - if constexpr (std::is_same_v) { - track = &mIOPtrs->mergedTracks[i]; - nClusters = track->NClusters(); - } else if constexpr (std::is_same_v) { - track = &mIOPtrs->outputTracksTPCO2[i]; - nClusters = track->getNClusters(); - if (!mIOPtrs->clustersNative) { - break; - } - } else { - throw std::runtime_error("invalid type"); - } - - size_t startCountInner = mVertexBuffer[iSlice].size(); - bool drawing = false; - - if constexpr (std::is_same_v) { - if (!mCfgH.drawTracksAndFilter && !(mCfgH.drawTPCTracks || (mCfgH.drawITSTracks && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) || (mCfgH.drawTRDTracks && mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1) || (mCfgH.drawTOFTracks && mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1))) { - break; - } - if (mCfgH.drawTracksAndFilter && ((mCfgH.drawITSTracks && !(mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1)) || (mCfgH.drawTRDTracks && !(mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1)) || (mCfgH.drawTOFTracks && !(mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1)))) { - break; - } - } - - if (mCfgH.trackFilter && !mTrackFilter[i]) { - break; - } - - // Print TOF part of track - if constexpr (std::is_same_v) { - if (mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1 && mIOPtrs->nTOFClusters) { - int cid = mIOPtrs->tpcLinkTOF[i]; - drawing = true; - mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[cid].x, mGlobalPosTOF[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[cid].z); - mGlobalPosTOF[cid].w = tTOFATTACHED; - } - } - - // Print TRD part of track - auto tmpDoTRDTracklets = [&](const auto& trk) { - for (int k = 5; k >= 0; k--) { - int cid = trk.getTrackletIndex(k); - if (cid < 0) { - continue; - } - drawing = true; - mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD2[cid].x, mGlobalPosTRD2[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[cid].z); - mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD[cid].x, mGlobalPosTRD[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[cid].z); - mGlobalPosTRD[cid].w = tTRDATTACHED; - } - }; - if (std::is_same_v || (!mIOPtrs->tpcLinkTRD && mIOPtrs->trdTracksO2)) { - if (mChain && ((int)mConfig.showTPCTracksFromO2Format == (int)mChain->GetProcessingSettings().trdTrackModelO2) && mTRDTrackIds[i] != -1 && mIOPtrs->nTRDTracklets) { - if (mIOPtrs->trdTracksO2) { -#ifdef GPUCA_HAVE_O2HEADERS - tmpDoTRDTracklets(mIOPtrs->trdTracksO2[mTRDTrackIds[i]]); -#endif - } else { - tmpDoTRDTracklets(mIOPtrs->trdTracks[mTRDTrackIds[i]]); - } - } - } else if constexpr (std::is_same_v) { - if (mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1 && mIOPtrs->nTRDTracklets) { - if ((mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->nTRDTracksITSTPCTRD : mIOPtrs->nTRDTracksTPCTRD) { - const auto* container = (mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->trdTracksITSTPCTRD : mIOPtrs->trdTracksTPCTRD; - const auto& trk = container[mIOPtrs->tpcLinkTRD[i] & 0x3FFFFFFF]; - tmpDoTRDTracklets(trk); - } - } - } - - // Print TPC part of track - for (int k = 0; k < nClusters; k++) { - if constexpr (std::is_same_v) { - if (mCfgH.hideRejectedClusters && (mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject)) { - continue; - } - } - int cid; - if constexpr (std::is_same_v) { - cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].num; - } else { - cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, k, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; - } - int w = mGlobalPos[cid].w; - if (drawing) { - drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); - } - if (w == SEPERATE_GLOBAL_TRACKS_LIMIT) { - if (drawing) { - insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); - } - drawing = false; - } else { - if (!drawing) { - startCountInner = mVertexBuffer[iSlice].size(); - } - if (!drawing) { - drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); - } - if (!drawing && lastCluster != -1) { - if constexpr (std::is_same_v) { - cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster].num; - } else { - cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; - } - drawPointLinestrip(iSlice, cid, 7, SEPERATE_GLOBAL_TRACKS_LIMIT); - } - drawing = true; - } - lastCluster = k; - } - - // Print ITS part of track - if constexpr (std::is_same_v) { - if (mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1 && mIOPtrs->nItsTracks && mIOPtrs->nItsClusters) { - DrawTrackITS(mIOPtrs->tpcLinkITS[i], iSlice); - } - } - insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); - break; - } - - if (!mIOPtrs->clustersNative) { - continue; - } - - // Propagate track paramters / plot MC tracks - for (int iMC = 0; iMC < 2; iMC++) { - if (iMC) { - if (ii >= trackList[1].size()) { - continue; - } - i = trackList[1][ii]; - } else { - if (track == nullptr) { - continue; - } - if (lastCluster == -1) { - continue; - } - } - - size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int inFlyDirection = 0; inFlyDirection < 2; inFlyDirection++) { - GPUTPCGMPhysicalTrackModel trkParam; - float ZOffset = 0; - float x = 0; - float alphaOrg = 0; - if (iMC == 0) { - if (!inFlyDirection && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) { - continue; - } - if constexpr (std::is_same_v) { - trkParam.Set(track->GetParam()); - alphaOrg = mParam->Alpha(iSlice); - } else { - GPUTPCGMTrackParam t; - convertTrackParam(t, *track); - alphaOrg = track->getAlpha(); - trkParam.Set(t); - } - - if (mParam->par.earlyTpcTransform) { - if constexpr (std::is_same_v) { - x = mIOPtrs->mergedTrackHitsXYZ[track->FirstClusterRef() + lastCluster].x; - ZOffset = track->GetParam().GetTZOffset(); - } - } else { - float y, z; - if constexpr (std::is_same_v) { - auto cl = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster]; - const auto& cln = mIOPtrs->clustersNative->clustersLinear[cl.num]; - GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, cl.slice, cl.row, cln.getPad(), cln.getTime(), x, y, z); - ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(iSlice, track->GetParam().GetTZOffset(), mParam->par.continuousMaxTimeBin); - } else { - uint8_t sector, row; - auto cln = track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative, sector, row); - GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, sector, row, cln.getPad(), cln.getTime(), x, y, z); - ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(sector, track->getTime0(), mParam->par.continuousMaxTimeBin); - } - } - } else { - const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i]; - if (mc.charge == 0.f) { - break; - } - if (mc.pid < 0) { - break; - } - - alphaOrg = mParam->Alpha(iSlice); - float c = cosf(alphaOrg); - float s = sinf(alphaOrg); - float mclocal[4]; - x = mc.x; - float y = mc.y; - mclocal[0] = x * c + y * s; - mclocal[1] = -x * s + y * c; - float px = mc.pX; - float py = mc.pY; - mclocal[2] = px * c + py * s; - mclocal[3] = -px * s + py * c; - float charge = mc.charge > 0 ? 1.f : -1.f; - - x = mclocal[0]; -#ifdef GPUCA_TPC_GEOMETRY_O2 - trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, -charge); // TODO: DR: unclear to me why we need -charge here - if (mParam->par.continuousTracking) { - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, mc.t0, mParam->par.continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1); - } -#else - if (fabsf(mc.z) > GPUTPCGeometry::TPCLength()) { - ZOffset = mc.z > 0 ? (mc.z - GPUTPCGeometry::TPCLength()) : (mc.z + GPUTPCGeometry::TPCLength()); - } - trkParam.Set(mclocal[0], mclocal[1], mc.z - ZOffset, mclocal[2], mclocal[3], mc.pZ, charge); -#endif - } - float z0 = trkParam.Z(); - if (iMC && inFlyDirection == 0) { - buffer.clear(); - } - if (x < 1) { - break; - } - if (fabsf(trkParam.SinPhi()) > 1) { - break; - } - float alpha = alphaOrg; - vecpod& useBuffer = iMC && inFlyDirection == 0 ? buffer : mVertexBuffer[iSlice]; - int nPoints = 0; - - while (nPoints++ < 5000) { - if ((inFlyDirection == 0 && x < 0) || (inFlyDirection && x * x + trkParam.Y() * trkParam.Y() > (iMC ? (450 * 450) : (300 * 300)))) { - break; - } - if (fabsf(trkParam.Z() + ZOffset) > mMaxClusterZ + (iMC ? 0 : 0)) { - break; - } - if (fabsf(trkParam.Z() - z0) > (iMC ? GPUTPCGeometry::TPCLength() : GPUTPCGeometry::TPCLength())) { - break; - } - if (inFlyDirection) { - if (fabsf(trkParam.SinPhi()) > 0.4f) { - float dalpha = asinf(trkParam.SinPhi()); - trkParam.Rotate(dalpha); - alpha += dalpha; - } - x = trkParam.X() + 1.f; - if (!mCfgH.propagateLoopers) { - float diff = fabsf(alpha - alphaOrg) / (2.f * CAMath::Pi()); - diff -= floor(diff); - if (diff > 0.25f && diff < 0.75f) { - break; - } - } - } - float B[3]; - prop->GetBxByBz(alpha, trkParam.GetX(), trkParam.GetY(), trkParam.GetZ(), B); - float dLp = 0; - if (trkParam.PropagateToXBxByBz(x, B[0], B[1], B[2], dLp)) { - break; - } - if (fabsf(trkParam.SinPhi()) > 0.9f) { - break; - } - float sa = sinf(alpha), ca = cosf(alpha); - float drawX = trkParam.X() + mCfgH.xAdd; - useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) * GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor * GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) * GL_SCALE_FACTOR); - x += inFlyDirection ? 1 : -1; - } - - if (inFlyDirection == 0) { - if (iMC) { - for (int k = (int)buffer.size() - 1; k >= 0; k--) { - mVertexBuffer[iSlice].emplace_back(buffer[k]); - } - } else { - insertVertexList(vBuf[1], startCountInner, mVertexBuffer[iSlice].size()); - startCountInner = mVertexBuffer[iSlice].size(); - } - } - } - insertVertexList(vBuf[iMC ? 3 : 2], startCountInner, mVertexBuffer[iSlice].size()); - } - } -} - -GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) -{ - int iSlice = tracker.ISlice(); - size_t startCount = mVertexBufferStart[iSlice].size(); - size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { - const GPUTPCRow& row = tracker.Data().Row(i); - for (int j = 0; j <= (signed)row.Grid().Ny(); j++) { - float z1 = row.Grid().ZMin(); - float z2 = row.Grid().ZMax(); - float x = row.X() + mCfgH.xAdd; - float y = row.Grid().YMin() + (float)j / row.Grid().StepYInv(); - float zz1, zz2, yy1, yy2, xx1, xx2; - mParam->Slice2Global(tracker.ISlice(), x, y, z1, &xx1, &yy1, &zz1); - mParam->Slice2Global(tracker.ISlice(), x, y, z2, &xx2, &yy2, &zz2); - if (iSlice < 18) { - zz1 += mCfgH.zAdd; - zz2 += mCfgH.zAdd; - } else { - zz1 -= mCfgH.zAdd; - zz2 -= mCfgH.zAdd; - } - mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); - mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); - } - for (int j = 0; j <= (signed)row.Grid().Nz(); j++) { - float y1 = row.Grid().YMin(); - float y2 = row.Grid().YMax(); - float x = row.X() + mCfgH.xAdd; - float z = row.Grid().ZMin() + (float)j / row.Grid().StepZInv(); - float zz1, zz2, yy1, yy2, xx1, xx2; - mParam->Slice2Global(tracker.ISlice(), x, y1, z, &xx1, &yy1, &zz1); - mParam->Slice2Global(tracker.ISlice(), x, y2, z, &xx2, &yy2, &zz2); - if (iSlice < 18) { - zz1 += mCfgH.zAdd; - zz2 += mCfgH.zAdd; - } else { - zz1 -= mCfgH.zAdd; - zz2 -= mCfgH.zAdd; - } - mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); - mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); - } - } - insertVertexList(tracker.ISlice(), startCountInner, mVertexBuffer[iSlice].size()); - return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); -} - -GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) -{ - // TODO: tilted pads ignored at the moment - size_t startCount = mVertexBufferStart[sector].size(); - size_t startCountInner = mVertexBuffer[sector].size(); -#ifdef GPUCA_HAVE_O2HEADERS - auto* geo = trdGeometry(); - if (geo) { - int trdsector = NSLICES / 2 - 1 - sector; - float alpha = geo->GetAlpha() / 2.f + geo->GetAlpha() * trdsector; - if (trdsector >= 9) { - alpha -= 2 * CAMath::Pi(); - } - for (int iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; ++iLy) { - for (int iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; ++iStack) { - int iDet = geo->GetDetector(iLy, iStack, trdsector); - auto matrix = geo->GetClusterMatrix(iDet); - if (!matrix) { - continue; - } - auto pp = geo->GetPadPlane(iDet); - for (int i = 0; i < pp->GetNrows(); ++i) { - float xyzLoc1[3]; - float xyzLoc2[3]; - float xyzGlb1[3]; - float xyzGlb2[3]; - xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos(); - xyzLoc1[1] = pp->GetCol0(); - xyzLoc2[1] = pp->GetColEnd(); - xyzLoc1[2] = xyzLoc2[2] = pp->GetRowPos(i) - pp->GetRowPos(pp->GetNrows() / 2); - matrix->LocalToMaster(xyzLoc1, xyzGlb1); - matrix->LocalToMaster(xyzLoc2, xyzGlb2); - float x1Tmp = xyzGlb1[0]; - xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha); - xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha); - float x2Tmp = xyzGlb2[0]; - xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); - xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); - mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); - mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); - } - for (int j = 0; j < pp->GetNcols(); ++j) { - float xyzLoc1[3]; - float xyzLoc2[3]; - float xyzGlb1[3]; - float xyzGlb2[3]; - xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos(); - xyzLoc1[1] = xyzLoc2[1] = pp->GetColPos(j) + pp->GetColSize(j) / 2.f; - xyzLoc1[2] = pp->GetRow0() - pp->GetRowPos(pp->GetNrows() / 2); - xyzLoc2[2] = pp->GetRowEnd() - pp->GetRowPos(pp->GetNrows() / 2); - matrix->LocalToMaster(xyzLoc1, xyzGlb1); - matrix->LocalToMaster(xyzLoc2, xyzGlb2); - float x1Tmp = xyzGlb1[0]; - xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha); - xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha); - float x2Tmp = xyzGlb2[0]; - xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); - xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); - mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); - mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); - } - } - } - } -#endif - insertVertexList(sector, startCountInner, mVertexBuffer[sector].size()); - return (vboList(startCount, mVertexBufferStart[sector].size() - startCount, sector)); -} - int GPUDisplay::DrawGLScene() { // Make sure event gets not overwritten during display @@ -1234,244 +225,6 @@ int GPUDisplay::DrawGLScene() return retVal; } -void GPUDisplay::DrawGLScene_updateEventData() -{ - mTimerDraw.ResetStart(); - if (mIOPtrs->clustersNative) { - mCurrentClusters = mIOPtrs->clustersNative->nClustersTotal; - } else { - mCurrentClusters = 0; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - mCurrentClusters += mIOPtrs->nClusterData[iSlice]; - } - } - if (mNMaxClusters < mCurrentClusters) { - mNMaxClusters = mCurrentClusters; - mGlobalPosPtr.reset(new float4[mNMaxClusters]); - mGlobalPos = mGlobalPosPtr.get(); - } - - mCurrentSpacePointsTRD = mIOPtrs->nTRDTracklets; - if (mCurrentSpacePointsTRD > mNMaxSpacePointsTRD) { - mNMaxSpacePointsTRD = mCurrentSpacePointsTRD; - mGlobalPosPtrTRD.reset(new float4[mNMaxSpacePointsTRD]); - mGlobalPosPtrTRD2.reset(new float4[mNMaxSpacePointsTRD]); - mGlobalPosTRD = mGlobalPosPtrTRD.get(); - mGlobalPosTRD2 = mGlobalPosPtrTRD2.get(); - } - - mCurrentClustersITS = mIOPtrs->itsClusters ? mIOPtrs->nItsClusters : 0; - if (mNMaxClustersITS < mCurrentClustersITS) { - mNMaxClustersITS = mCurrentClustersITS; - mGlobalPosPtrITS.reset(new float4[mNMaxClustersITS]); - mGlobalPosITS = mGlobalPosPtrITS.get(); - } - - mCurrentClustersTOF = mIOPtrs->nTOFClusters; - if (mNMaxClustersTOF < mCurrentClustersTOF) { - mNMaxClustersTOF = mCurrentClustersTOF; - mGlobalPosPtrTOF.reset(new float4[mNMaxClustersTOF]); - mGlobalPosTOF = mGlobalPosPtrTOF.get(); - } - - unsigned int nTpcMergedTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; - if ((size_t)nTpcMergedTracks > mTRDTrackIds.size()) { - mTRDTrackIds.resize(nTpcMergedTracks); - } - if (mIOPtrs->nItsTracks > mITSStandaloneTracks.size()) { - mITSStandaloneTracks.resize(mIOPtrs->nItsTracks); - } - for (unsigned int i = 0; i < nTpcMergedTracks; i++) { - mTRDTrackIds[i] = -1; - } - auto tmpDoTRDTracklets = [&](auto* trdTracks) { - for (unsigned int i = 0; i < mIOPtrs->nTRDTracks; i++) { - if (trdTracks[i].getNtracklets()) { - mTRDTrackIds[trdTracks[i].getRefGlobalTrackIdRaw()] = i; - } - } - }; - if (mIOPtrs->trdTracksO2) { -#ifdef GPUCA_HAVE_O2HEADERS - tmpDoTRDTracklets(mIOPtrs->trdTracksO2); -#endif - } else { - tmpDoTRDTracklets(mIOPtrs->trdTracks); - } - if (mIOPtrs->nItsTracks) { - std::fill(mITSStandaloneTracks.begin(), mITSStandaloneTracks.end(), true); - if (mIOPtrs->tpcLinkITS) { - for (unsigned int i = 0; i < nTpcMergedTracks; i++) { - if (mIOPtrs->tpcLinkITS[i] != -1) { - mITSStandaloneTracks[mIOPtrs->tpcLinkITS[i]] = false; - } - } - } - } - - if (mCfgH.trackFilter) { - unsigned int nTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; - mTrackFilter.resize(nTracks); - std::fill(mTrackFilter.begin(), mTrackFilter.end(), true); - if (buildTrackFilter()) { - SetInfo("Error running track filter from %s", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str()); - } else { - unsigned int nFiltered = 0; - for (unsigned int i = 0; i < mTrackFilter.size(); i++) { - nFiltered += !mTrackFilter[i]; - } - if (mUpdateTrackFilter) { - SetInfo("Applied track filter %s - filtered %u / %u", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str(), nFiltered, (unsigned int)mTrackFilter.size()); - } - } - } - mUpdateTrackFilter = false; - - mMaxClusterZ = 0; - GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - int row = 0; - unsigned int nCls = mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] - : 0; - for (unsigned int i = 0; i < nCls; i++) { - int cid; - if (mParam->par.earlyTpcTransform) { - const auto& cl = mIOPtrs->clusterData[iSlice][i]; - cid = cl.id; - row = cl.row; - } else { - cid = mIOPtrs->clustersNative->clusterOffset[iSlice][0] + i; - while (row < GPUCA_ROW_COUNT - 1 && mIOPtrs->clustersNative->clusterOffset[iSlice][row + 1] <= (unsigned int)cid) { - row++; - } - } - if (cid >= mNMaxClusters) { - throw std::runtime_error("Cluster Buffer Size exceeded"); - } - float4* ptr = &mGlobalPos[cid]; - if (mParam->par.earlyTpcTransform) { - const auto& cl = mIOPtrs->clusterData[iSlice][i]; - mParam->Slice2Global(iSlice, (mCfgH.clustersOnNominalRow ? mParam->tpcGeometry.Row2X(row) : cl.x) + mCfgH.xAdd, cl.y, cl.z, &ptr->x, &ptr->y, &ptr->z); - } else { - float x, y, z; - const auto& cln = mIOPtrs->clustersNative->clusters[iSlice][0][i]; - GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, iSlice, row, cln.getPad(), cln.getTime(), x, y, z); - if (mCfgH.clustersOnNominalRow) { - x = mParam->tpcGeometry.Row2X(row); - } - mParam->Slice2Global(iSlice, x + mCfgH.xAdd, y, z, &ptr->x, &ptr->y, &ptr->z); - } - - if (fabsf(ptr->z) > mMaxClusterZ) { - mMaxClusterZ = fabsf(ptr->z); - } - ptr->z += iSlice < 18 ? mCfgH.zAdd : -mCfgH.zAdd; - ptr->x *= GL_SCALE_FACTOR; - ptr->y *= GL_SCALE_FACTOR; - ptr->z *= GL_SCALE_FACTOR; - ptr->w = tCLUSTER; - } - } - - int trdTriggerRecord = -1; - float trdZoffset = 0; - GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ) firstprivate(trdTriggerRecord, trdZoffset)) - for (int i = 0; i < mCurrentSpacePointsTRD; i++) { - while (mParam->par.continuousTracking && trdTriggerRecord < (int)mIOPtrs->nTRDTriggerRecords - 1 && mIOPtrs->trdTrackletIdxFirst[trdTriggerRecord + 1] <= i) { - trdTriggerRecord++; -#ifdef GPUCA_HAVE_O2HEADERS - float trdTime = mIOPtrs->trdTriggerTimes[trdTriggerRecord] * 1e3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; - trdZoffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, trdTime, mParam->par.continuousMaxTimeBin)); -#endif - } - const auto& sp = mIOPtrs->trdSpacePoints[i]; - int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); - float4* ptr = &mGlobalPosTRD[i]; - mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd, sp.getY(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); - ptr->z += ptr->z > 0 ? trdZoffset : -trdZoffset; - if (fabsf(ptr->z) > mMaxClusterZ) { - mMaxClusterZ = fabsf(ptr->z); - } - ptr->x *= GL_SCALE_FACTOR; - ptr->y *= GL_SCALE_FACTOR; - ptr->z *= GL_SCALE_FACTOR; - ptr->w = tTRDCLUSTER; - ptr = &mGlobalPosTRD2[i]; - mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd + 4.5f, sp.getY() + 1.5f * sp.getDy(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); - ptr->z += ptr->z > 0 ? trdZoffset : -trdZoffset; - if (fabsf(ptr->z) > mMaxClusterZ) { - mMaxClusterZ = fabsf(ptr->z); - } - ptr->x *= GL_SCALE_FACTOR; - ptr->y *= GL_SCALE_FACTOR; - ptr->z *= GL_SCALE_FACTOR; - ptr->w = tTRDCLUSTER; - } - - GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) - for (int i = 0; i < mCurrentClustersTOF; i++) { -#ifdef GPUCA_HAVE_O2HEADERS - float4* ptr = &mGlobalPosTOF[i]; - mParam->Slice2Global(mIOPtrs->tofClusters[i].getSector(), mIOPtrs->tofClusters[i].getX() + mCfgH.xAdd, mIOPtrs->tofClusters[i].getY(), mIOPtrs->tofClusters[i].getZ(), &ptr->x, &ptr->y, &ptr->z); - float ZOffset = 0; - if (mParam->par.continuousTracking) { - float tofTime = mIOPtrs->tofClusters[i].getTime() * 1e-3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, tofTime, mParam->par.continuousMaxTimeBin)); - ptr->z += ptr->z > 0 ? ZOffset : -ZOffset; - } - if (fabsf(ptr->z) > mMaxClusterZ) { - mMaxClusterZ = fabsf(ptr->z); - } - ptr->x *= GL_SCALE_FACTOR; - ptr->y *= GL_SCALE_FACTOR; - ptr->z *= GL_SCALE_FACTOR; - ptr->w = tTOFCLUSTER; -#endif - } - - if (mCurrentClustersITS) { -#ifdef GPUCA_HAVE_O2HEADERS - float itsROFhalfLen = 0; -#ifdef GPUCA_O2_LIB // Not available in standalone benchmark - if (mParam->par.continuousTracking) { - const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); - itsROFhalfLen = alpParams.roFrameLengthInBC / (float)o2::tpc::constants::LHCBCPERTIMEBIN / 2; - } -#endif - int i = 0; - for (unsigned int j = 0; j < mIOPtrs->nItsClusterROF; j++) { - float ZOffset = 0; - if (mParam->par.continuousTracking) { - o2::InteractionRecord startIR = o2::InteractionRecord(0, mIOPtrs->settingsTF && mIOPtrs->settingsTF->hasTfStartOrbit ? mIOPtrs->settingsTF->tfStartOrbit : 0); - float itsROFtime = mIOPtrs->itsClusterROF[j].getBCData().differenceInBC(startIR) / (float)o2::tpc::constants::LHCBCPERTIMEBIN; - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, itsROFtime + itsROFhalfLen, mParam->par.continuousMaxTimeBin)); - } - if (i != mIOPtrs->itsClusterROF[j].getFirstEntry()) { - throw std::runtime_error("Inconsistent ITS data, number of clusters does not match ROF content"); - } - for (int k = 0; k < mIOPtrs->itsClusterROF[j].getNEntries(); k++) { - float4* ptr = &mGlobalPosITS[i]; - const auto& cl = mIOPtrs->itsClusters[i]; - auto* itsGeo = o2::its::GeometryTGeo::Instance(); - auto p = cl.getXYZGlo(*itsGeo); - ptr->x = p.X(); - ptr->y = p.Y(); - ptr->z = p.Z(); - ptr->z += ptr->z > 0 ? ZOffset : -ZOffset; - if (fabsf(ptr->z) > mMaxClusterZ) { - mMaxClusterZ = fabsf(ptr->z); - } - ptr->x *= GL_SCALE_FACTOR; - ptr->y *= GL_SCALE_FACTOR; - ptr->z *= GL_SCALE_FACTOR; - ptr->w = tITSCLUSTER; - i++; - } - } -#endif - } -} - void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix) { int mMouseWheelTmp = mFrontend->mMouseWheel; @@ -1496,95 +249,10 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla } scalefactor *= sqrdist; - float time = animateTime; - if (mAnimate && time < 0) { - if (mAnimateScreenshot) { - time = mAnimationFrame / 30.f; - } else { - time = mAnimationTimer.GetCurrentElapsedTime(); - } - - float maxTime = mAnimateVectors[0].back(); - if (time >= maxTime) { - time = maxTime; - mAnimate = mAnimateScreenshot = 0; - SetInfo("Animation finished. (%1.2f seconds, %d frames)", time, mAnimationFrame); - } else { - SetInfo("Running mAnimation: time %1.2f/%1.2f, frames %d", time, maxTime, mAnimationFrame); - } - mAnimationFrame++; - } - // Perform new rotation / translation - if (mAnimate) { - float vals[8]; - for (int i = 0; i < 8; i++) { - vals[i] = mAnimationSplines[i].evaluate(time); - } - if (mAnimationChangeConfig && animateTime < 0) { - int base = 0; - int k = mAnimateVectors[0].size() - 1; - while (base < k && time > mAnimateVectors[0][base]) { - base++; - } - if (base > mAnimationLastBase + 1) { - mAnimationLastBase = base - 1; - } - - if (base != mAnimationLastBase && mAnimateVectors[0][mAnimationLastBase] != mAnimateVectors[0][base] && memcmp(&mAnimateConfig[base], &mAnimateConfig[mAnimationLastBase], sizeof(mAnimateConfig[base]))) { - mixSlaveImage = 1.f - (time - mAnimateVectors[0][mAnimationLastBase]) / (mAnimateVectors[0][base] - mAnimateVectors[0][mAnimationLastBase]); - if (mixSlaveImage > 0) { - mCfgL = mAnimateConfig[mAnimationLastBase]; - updateConfig(); - DrawGLScene_internal(time, true); - } - } - - if (memcmp(&mAnimateConfig[base], &mCfgL, sizeof(mCfgL))) { - mCfgL = mAnimateConfig[base]; - updateConfig(); - } - } + // Perform new rotation / translation / animation - if (mCfgL.animationMode != 6) { - if (mCfgL.animationMode & 1) // Rotation from euler angles - { - nextViewMatrix = nextViewMatrix * HMM_Rotate(-vals[4] * 180.f / CAMath::Pi(), {{1, 0, 0}}) * HMM_Rotate(vals[5] * 180.f / CAMath::Pi(), {{0, 1, 0}}) * HMM_Rotate(-vals[6] * 180.f / CAMath::Pi(), {{0, 0, 1}}); - } else { // Rotation from quaternion - const float mag = sqrtf(vals[4] * vals[4] + vals[5] * vals[5] + vals[6] * vals[6] + vals[7] * vals[7]); - if (mag < 0.0001f) { - vals[7] = 1; - } else { - for (int i = 0; i < 4; i++) { - vals[4 + i] /= mag; - } - } - - float xx = vals[4] * vals[4], xy = vals[4] * vals[5], xz = vals[4] * vals[6], xw = vals[4] * vals[7], yy = vals[5] * vals[5], yz = vals[5] * vals[6], yw = vals[5] * vals[7], zz = vals[6] * vals[6], zw = vals[6] * vals[7]; - float mat[16] = {1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0, 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0, 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0, 0, 0, 0, 1}; - nextViewMatrix = nextViewMatrix * MY_HMM_FROM(mat); - } - } - if (mCfgL.animationMode & 4) // Compute cartesian translation from sperical coordinates (euler angles) - { - const float r = vals[3], phi = vals[1], theta = vals[2]; - vals[2] = r * cosf(phi) * cosf(theta); - vals[0] = r * sinf(phi) * cosf(theta); - vals[1] = r * sinf(theta); - } else if (mCfgL.animationMode & 2) { // Scale cartesion translation to interpolated radius - float r = sqrtf(vals[0] * vals[0] + vals[1] * vals[1] + vals[2] * vals[2]); - if (fabsf(r) < 0.0001f) { - r = 1; - } - r = vals[3] / r; - for (int i = 0; i < 3; i++) { - vals[i] *= r; - } - } - if (mCfgL.animationMode == 6) { - nextViewMatrix = HMM_LookAt({{vals[0], vals[1], vals[2]}}, {{0, 0, 0}}, {{0, 1, 0}}); - } else { - nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}}); - } + if (animateCamera(animateTime, mixSlaveImage, nextViewMatrix)) { + // Do nothing else } else if (mResetScene) { const float initialZpos = mCfgH.projectXY ? 16 : (mParam->par.continuousTracking ? (mMaxClusterZ * GL_SCALE_FACTOR + 8) : 8); nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, -initialZpos}}); @@ -1744,243 +412,6 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla } } -size_t GPUDisplay::DrawGLScene_updateVertexList() -{ - for (int i = 0; i < NSLICES; i++) { - mVertexBuffer[i].clear(); - mVertexBufferStart[i].clear(); - mVertexBufferCount[i].clear(); - } - - for (int i = 0; i < mCurrentClusters; i++) { - mGlobalPos[i].w = tCLUSTER; - } - for (int i = 0; i < mCurrentSpacePointsTRD; i++) { - mGlobalPosTRD[i].w = tTRDCLUSTER; - } - - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = 0; i < N_POINTS_TYPE; i++) { - mGlDLPoints[iSlice][i].resize(mNCollissions); - } - for (int i = 0; i < N_FINAL_TYPE; i++) { - mGlDLFinal[iSlice].resize(mNCollissions); - } - } - GPUCA_OPENMP(parallel num_threads(getNumThreads())) - { -#ifdef WITH_OPENMP - int numThread = omp_get_thread_num(); - int numThreads = omp_get_num_threads(); -#else - int numThread = 0, numThreads = 1; -#endif - if (mChain && (mChain->GetRecoSteps() & GPUDataTypes::RecoStep::TPCSliceTracking)) { - GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - GPUTPCTracker& tracker = (GPUTPCTracker&)sliceTracker(iSlice); - tracker.SetPointersDataLinks(tracker.LinkTmpMemory()); - mGlDLLines[iSlice][tINITLINK] = DrawLinks(tracker, tINITLINK, true); - tracker.SetPointersDataLinks(mChain->rec()->Res(tracker.MemoryResLinks()).Ptr()); - } - GPUCA_OPENMP(barrier) - - GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - const GPUTPCTracker& tracker = sliceTracker(iSlice); - - mGlDLLines[iSlice][tLINK] = DrawLinks(tracker, tLINK); - mGlDLLines[iSlice][tSEED] = DrawSeeds(tracker); - mGlDLLines[iSlice][tTRACKLET] = DrawTracklets(tracker); - mGlDLLines[iSlice][tSLICETRACK] = DrawTracks(tracker, 0); - mGlDLGrid[iSlice] = DrawGrid(tracker); - if (iSlice < NSLICES / 2) { - mGlDLGridTRD[iSlice] = DrawGridTRD(iSlice); - } - } - GPUCA_OPENMP(barrier) - - GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - const GPUTPCTracker& tracker = sliceTracker(iSlice); - mGlDLLines[iSlice][tGLOBALTRACK] = DrawTracks(tracker, 1); - } - GPUCA_OPENMP(barrier) - } - mThreadTracks[numThread].resize(mNCollissions); - for (int i = 0; i < mNCollissions; i++) { - for (int j = 0; j < NSLICES; j++) { - for (int k = 0; k < 2; k++) { - mThreadTracks[numThread][i][j][k].clear(); - } - } - } - if (mConfig.showTPCTracksFromO2Format) { -#ifdef GPUCA_TPC_GEOMETRY_O2 - unsigned int col = 0; - GPUCA_OPENMP(for) - for (unsigned int i = 0; i < mIOPtrs->nOutputTracksTPCO2; i++) { - uint8_t sector, row; - if (mIOPtrs->clustersNative) { - mIOPtrs->outputTracksTPCO2[i].getCluster(mIOPtrs->outputClusRefsTPCO2, 0, *mIOPtrs->clustersNative, sector, row); - } else { - sector = 0; - } - if (mQA && mIOPtrs->outputTracksTPCO2MC) { - col = mQA->GetMCLabelCol(mIOPtrs->outputTracksTPCO2MC[i]); - } - mThreadTracks[numThread][col][sector][0].emplace_back(i); - } -#endif - } else { - GPUCA_OPENMP(for) - for (unsigned int i = 0; i < mIOPtrs->nMergedTracks; i++) { - const GPUTPCGMMergedTrack* track = &mIOPtrs->mergedTracks[i]; - if (track->NClusters() == 0) { - continue; - } - if (mCfgH.hideRejectedTracks && !track->OK()) { - continue; - } - int slice = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].slice; - unsigned int col = 0; - if (mQA) { - const auto& label = mQA->GetMCTrackLabel(i); -#ifdef GPUCA_TPC_GEOMETRY_O2 - col = mQA->GetMCLabelCol(label); -#else - while (label.isValid() && col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSLICES] < label.track) { - col++; - } -#endif - } - mThreadTracks[numThread][col][slice][0].emplace_back(i); - } - } - for (unsigned int col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) { - GPUCA_OPENMP(for) - for (unsigned int i = mIOPtrs->mcInfosTPCCol[col].first; i < mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num; i++) { - const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i]; - if (mc.charge == 0.f) { - continue; - } - if (mc.pid < 0) { - continue; - } - - float alpha = atan2f(mc.y, mc.x); - if (alpha < 0) { - alpha += 2 * CAMath::Pi(); - } - int slice = alpha / (2 * CAMath::Pi()) * 18; - if (mc.z < 0) { - slice += 18; - } - mThreadTracks[numThread][col][slice][1].emplace_back(i); - } - } - GPUCA_OPENMP(barrier) - - GPUTPCGMPropagator prop; - prop.SetMaxSinPhi(.999); - prop.SetMaterialTPC(); - prop.SetPolynomialField(&mParam->polynomialField); - - GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { - mThreadBuffers[numThread].clear(); - for (int iSet = 0; iSet < numThreads; iSet++) { -#ifdef GPUCA_HAVE_O2HEADERS - if (mConfig.showTPCTracksFromO2Format) { - DrawFinal(iSlice, iCol, &prop, mThreadTracks[iSet][iCol][iSlice], mThreadBuffers[numThread]); - } else -#endif - { - DrawFinal(iSlice, iCol, &prop, mThreadTracks[iSet][iCol][iSlice], mThreadBuffers[numThread]); - } - } - vboList* list = &mGlDLFinal[iSlice][iCol][0]; - for (int i = 0; i < N_FINAL_TYPE; i++) { - size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) { - mVertexBufferStart[iSlice].emplace_back(mThreadBuffers[numThread].start[i][j]); - mVertexBufferCount[iSlice].emplace_back(mThreadBuffers[numThread].count[i][j]); - } - list[i] = vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice); - } - } - } - - GPUCA_OPENMP(barrier) - GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = 0; i < N_POINTS_TYPE_TPC; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { - mGlDLPoints[iSlice][i][iCol] = DrawClusters(iSlice, i, iCol); - } - } - } - } - // End omp parallel - - mGlDLFinalITS = DrawFinalITS(); - - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { - mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTRD(iSlice, i, iCol); - } - } - } - - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { - mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTOF(iSlice, i, iCol); - } - } - break; // TODO: Only slice 0 filled for now - } - - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF + N_POINTS_TYPE_ITS; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { - mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsITS(iSlice, i, iCol); - } - } - break; // TODO: Only slice 0 filled for now - } - - mUpdateVertexLists = 0; - size_t totalVertizes = 0; - for (int i = 0; i < NSLICES; i++) { - totalVertizes += mVertexBuffer[i].size(); - } - if (totalVertizes > 0xFFFFFFFF) { - throw std::runtime_error("Display vertex count exceeds 32bit uint counter"); - } - size_t needMultiVBOSize = mBackend->needMultiVBO(); - mUseMultiVBO = needMultiVBOSize && (totalVertizes * sizeof(mVertexBuffer[0][0]) >= needMultiVBOSize); - if (!mUseMultiVBO) { - size_t totalYet = mVertexBuffer[0].size(); - mVertexBuffer[0].resize(totalVertizes); - for (int i = 1; i < GPUCA_NSLICES; i++) { - for (unsigned int j = 0; j < mVertexBufferStart[i].size(); j++) { - mVertexBufferStart[i][j] += totalYet; - } - memcpy(&mVertexBuffer[0][totalYet], &mVertexBuffer[i][0], mVertexBuffer[i].size() * sizeof(mVertexBuffer[i][0])); - totalYet += mVertexBuffer[i].size(); - mVertexBuffer[i].clear(); - } - } - mBackend->loadDataToGPU(totalVertizes); - for (int i = 0; i < (mUseMultiVBO ? GPUCA_NSLICES : 1); i++) { - mVertexBuffer[i].clear(); - } - return totalVertizes; -} - void GPUDisplay::DrawGLScene_drawCommands() { #define LOOP_SLICE for (int iSlice = (mCfgL.drawSlice == -1 ? 0 : mCfgL.drawRelatedSlices ? (mCfgL.drawSlice % (NSLICES / 4)) : mCfgL.drawSlice); iSlice < NSLICES; iSlice += (mCfgL.drawSlice == -1 ? 1 : mCfgL.drawRelatedSlices ? (NSLICES / 4) : NSLICES)) @@ -2268,71 +699,6 @@ void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) } } -void GPUDisplay::DoScreenshot(const char* filename, std::vector& pixels, float animateTime) -{ - size_t screenshot_x = mBackend->mScreenWidth * mCfgR.screenshotScaleFactor; - size_t screenshot_y = mBackend->mScreenHeight * mCfgR.screenshotScaleFactor; - size_t size = 4 * screenshot_x * screenshot_y; - if (size != pixels.size()) { - GPUError("Pixel array of incorrect size obtained"); - filename = nullptr; - } - - if (filename) { - FILE* fp = fopen(filename, "w+b"); - if (fp == nullptr) { - GPUError("Error opening screenshot file %s", filename); - return; - } - - BITMAPFILEHEADER bmpFH; - BITMAPINFOHEADER bmpIH; - memset(&bmpFH, 0, sizeof(bmpFH)); - memset(&bmpIH, 0, sizeof(bmpIH)); - - bmpFH.bfType = 19778; //"BM" - bmpFH.bfSize = sizeof(bmpFH) + sizeof(bmpIH) + size; - bmpFH.bfOffBits = sizeof(bmpFH) + sizeof(bmpIH); - - bmpIH.biSize = sizeof(bmpIH); - bmpIH.biWidth = screenshot_x; - bmpIH.biHeight = screenshot_y; - bmpIH.biPlanes = 1; - bmpIH.biBitCount = 32; - bmpIH.biCompression = BI_RGB; - bmpIH.biSizeImage = size; - bmpIH.biXPelsPerMeter = 5670; - bmpIH.biYPelsPerMeter = 5670; - - fwrite(&bmpFH, 1, sizeof(bmpFH), fp); - fwrite(&bmpIH, 1, sizeof(bmpIH), fp); - fwrite(pixels.data(), 1, size, fp); - fclose(fp); - } -} - -void GPUDisplay::showInfo(const char* info) -{ - mBackend->prepareText(); - float colorValue = mCfgL.invertColors ? 0.f : 1.f; - OpenGLPrint(info, 40.f, 20.f + std::max(20, mDrawTextFontSize + 4), colorValue, colorValue, colorValue, 1); - if (mInfoText2Timer.IsRunning()) { - if (mInfoText2Timer.GetCurrentElapsedTime() >= 6) { - mInfoText2Timer.Reset(); - } else { - OpenGLPrint(mInfoText2, 40.f, 20.f, colorValue, colorValue, colorValue, 6 - mInfoText2Timer.GetCurrentElapsedTime()); - } - } - if (mInfoHelpTimer.IsRunning() || mPrintInfoTextAlways) { - if (mInfoHelpTimer.GetCurrentElapsedTime() >= 6) { - mInfoHelpTimer.Reset(); - } else { - PrintGLHelpText(colorValue); - } - } - mBackend->finishText(); -} - void GPUDisplay::ShowNextEvent(const GPUTrackingInOutPointers* ptrs) { if (ptrs) { @@ -2358,16 +724,3 @@ int GPUDisplay::StartDisplay() } return (mInitResult != 1); } - -void GPUDisplay::OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton) -{ - if (mBackend->mFreetypeInitialized) { - if (!fromBotton) { - y = mBackend->mScreenHeight - y; - } - float color[4] = {r, g, b, a}; - mBackend->OpenGLPrint(s, x, y, color, 1.0f); - } else if (mFrontend->mCanDrawText) { - mFrontend->OpenGLPrint(s, x, y, r, g, b, a, fromBotton); - } -} diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index 33624aa33fa4d..78638bfaca4a6 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -80,6 +80,7 @@ class GPUDisplay : public GPUDisplayInterface private: static constexpr int NSLICES = GPUChainTracking::NSLICES; + static constexpr float GL_SCALE_FACTOR = (1.f / 100.f); static constexpr const int N_POINTS_TYPE = 15; static constexpr const int N_POINTS_TYPE_TPC = 9; @@ -152,7 +153,6 @@ class GPUDisplay : public GPUDisplayInterface void disableUnsupportedOptions(); int buildTrackFilter(); const GPUTPCTracker& sliceTracker(int iSlice); - const GPUTRDTrackerGPU& trdTracker(); const GPUTRDGeometry* trdGeometry(); const GPUTrackingInOutPointers* mIOPtrs = nullptr; void insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last); @@ -175,6 +175,7 @@ class GPUDisplay : public GPUDisplayInterface void resetAnimation(); void removeAnimationPoint(); void startAnimation(); + int animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix); void showInfo(const char* info); void ActivateColor(); void SetColorTRD(); diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackend.h b/GPU/GPUTracking/display/backend/GPUDisplayBackend.h index 978da7c805517..1ce279f6f9bb7 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackend.h +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackend.h @@ -78,8 +78,8 @@ class GPUDisplayBackend virtual unsigned int drawVertices(const vboList& v, const drawType t) = 0; virtual unsigned int drawField() { return 0; } virtual void ActivateColor(std::array& color) = 0; - virtual void setQuality(){}; - virtual void SetVSync(bool enable){}; + virtual void setQuality() {}; + virtual void SetVSync(bool enable) {}; virtual bool backendNeedRedraw() { return true; } virtual void setDepthBuffer() = 0; virtual int InitBackendA() = 0; diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx index 20943f609c4aa..c25fbede428ca 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx @@ -42,7 +42,7 @@ QGET_LD_BINARY_SYMBOLS(shaders_shaders_fragmentUniform_frag_spv); #define GPUCA_BUILD_EVENT_DISPLAY_OPENGL #if !defined(GL_VERSION_4_5) || GL_VERSION_4_5 != 1 #ifdef GPUCA_STANDALONE -//#error Unsupported OpenGL version < 4.5 +// #error Unsupported OpenGL version < 4.5 #elif defined(GPUCA_O2_LIB) #pragma message "Unsupported OpenGL version < 4.5, disabling standalone event display" #else @@ -82,7 +82,7 @@ bool GPUDisplayBackendOpenGL::CoreProfile() } #endif -//#define CHKERR(cmd) {cmd;} +// #define CHKERR(cmd) {cmd;} #define CHKERR(cmd) \ do { \ (cmd); \ diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx index 4d256d69eb0da..a6920942b9990 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx @@ -31,7 +31,7 @@ QGET_LD_BINARY_SYMBOLS(shaders_shaders_vertexTexture_vert_spv); QGET_LD_BINARY_SYMBOLS(shaders_shaders_fragmentTexture_frag_spv); QGET_LD_BINARY_SYMBOLS(shaders_shaders_fragmentText_frag_spv); -//#define CHKERR(cmd) {cmd;} +// #define CHKERR(cmd) {cmd;} #define CHKERR(cmd) \ do { \ auto tmp_internal_retVal = cmd; \ @@ -1083,10 +1083,10 @@ void GPUDisplayBackendVulkan::createPipeline() vk::PipelineMultisampleStateCreateInfo multisampling{}; multisampling.sampleShadingEnable = false; // multisampling.rasterizationSamples // below - multisampling.minSampleShading = 1.0f; // Optional - multisampling.pSampleMask = nullptr; // Optional - multisampling.alphaToCoverageEnable = false; // Optional - multisampling.alphaToOneEnable = false; // Optional + multisampling.minSampleShading = 1.0f; // Optional + multisampling.pSampleMask = nullptr; // Optional + multisampling.alphaToCoverageEnable = false; // Optional + multisampling.alphaToOneEnable = false; // Optional vk::PipelineColorBlendAttachmentState colorBlendAttachment{}; colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h index 3b73fada68b4f..480dd321dbfdb 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h @@ -65,7 +65,7 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend unsigned int drawVertices(const vboList& v, const drawType t) override; void ActivateColor(std::array& color) override; void SetVSync(bool enable) override { mMustUpdateSwapChain = true; }; - void setDepthBuffer() override{}; + void setDepthBuffer() override {}; bool backendNeedRedraw() override; int InitBackendA() override; void ExitBackendA() override; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h index 146cf42b9eb17..c1e41eac81bb7 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h @@ -83,7 +83,7 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface virtual int FrontendMain() = 0; static void* FrontendThreadWrapper(void*); - static constexpr int INIT_WIDTH = 1024, INIT_HEIGHT = 768; // Initial window size, before maximizing + static constexpr int INIT_WIDTH = 1024, INIT_HEIGHT = 768; // Initial window size, before maximizing static constexpr const char* DISPLAY_WINDOW_NAME = "GPU CA Standalone Event Display"; // Title of event display set by backend // Constant key codes for special mKeys (to unify different treatment in X11 / Windows / GLUT / etc.) static constexpr int KEY_UP = 1; @@ -138,12 +138,12 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface std::unique_ptr mGUI; - void HandleKey(unsigned char key); // Callback for handling key presses - int DrawGLScene(); // Callback to draw the GL scene - void HandleSendKey(); // Optional callback to handle key press from external source (e.g. stdin by default) - void ResizeScene(int width, int height); // Callback when GL window is resized - int InitDisplay(bool initFailure = false); // Callback to initialize the GL Display (to be called in StartDisplay) - void ExitDisplay(); // Callback to clean up the GL Display + void HandleKey(unsigned char key); // Callback for handling key presses + int DrawGLScene(); // Callback to draw the GL scene + void HandleSendKey(); // Optional callback to handle key press from external source (e.g. stdin by default) + void ResizeScene(int width, int height); // Callback when GL window is resized + int InitDisplay(bool initFailure = false); // Callback to initialize the GL Display (to be called in StartDisplay) + void ExitDisplay(); // Callback to clean up the GL Display int& drawTextFontSize(); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx new file mode 100644 index 0000000000000..8d023fb70cb16 --- /dev/null +++ b/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx @@ -0,0 +1,197 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUDisplayAnimation.cxx +/// \author David Rohr + +#include "GPUDisplay.h" + +using namespace GPUCA_NAMESPACE::gpu; + +constexpr hmm_mat4 MY_HMM_FROM(float (&v)[16]) { return {{{v[0], v[1], v[2], v[3]}, {v[4], v[5], v[6], v[7]}, {v[8], v[9], v[10], v[11]}, {v[12], v[13], v[14], v[15]}}}; } + +void GPUDisplay::setAnimationPoint() +{ + if (mCfgL.animationMode & 4) // Spherical + { + float rxy = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[2] * mXYZ[2]); + float anglePhi = atan2f(mXYZ[0], mXYZ[2]); + float angleTheta = atan2f(mXYZ[1], rxy); + if (mAnimateVectors[0].size()) { + mAnimationCloseAngle(anglePhi, mAnimateVectors[2].back()); + } + if (mAnimateVectors[0].size()) { + mAnimationCloseAngle(angleTheta, mAnimateVectors[3].back()); + } + mAnimateVectors[1].emplace_back(0); + mAnimateVectors[2].emplace_back(anglePhi); + mAnimateVectors[3].emplace_back(angleTheta); + } else { + for (int i = 0; i < 3; i++) { + mAnimateVectors[i + 1].emplace_back(mXYZ[i]); + } + // Cartesian + } + float r = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[1] * mXYZ[1] + mXYZ[2] * mXYZ[2]); + mAnimateVectors[4].emplace_back(r); + if (mCfgL.animationMode & 1) // Euler-angles + { + for (int i = 0; i < 3; i++) { + float newangle = mAngle[i]; + if (mAnimateVectors[0].size()) { + mAnimationCloseAngle(newangle, mAnimateVectors[i + 5].back()); + } + mAnimateVectors[i + 5].emplace_back(newangle); + } + mAnimateVectors[8].emplace_back(0); + } else { // Quaternions + float v[4]; + createQuaternionFromMatrix(v, mViewMatrixP); + if (mAnimateVectors[0].size()) { + mAnimateCloseQuaternion(v, mAnimateVectors[5].back(), mAnimateVectors[6].back(), mAnimateVectors[7].back(), mAnimateVectors[8].back()); + } + for (int i = 0; i < 4; i++) { + mAnimateVectors[i + 5].emplace_back(v[i]); + } + } + float delay = 0.f; + if (mAnimateVectors[0].size()) { + delay = mAnimateVectors[0].back() + ((int)(mAnimationDelay * 20)) / 20.f; + } + mAnimateVectors[0].emplace_back(delay); + mAnimateConfig.emplace_back(mCfgL); +} + +void GPUDisplay::resetAnimation() +{ + for (int i = 0; i < 9; i++) { + mAnimateVectors[i].clear(); + } + mAnimateConfig.clear(); + mAnimate = 0; +} + +void GPUDisplay::removeAnimationPoint() +{ + if (mAnimateVectors[0].size() == 0) { + return; + } + for (int i = 0; i < 9; i++) { + mAnimateVectors[i].pop_back(); + } + mAnimateConfig.pop_back(); +} + +void GPUDisplay::startAnimation() +{ + for (int i = 0; i < 8; i++) { + mAnimationSplines[i].create(mAnimateVectors[0], mAnimateVectors[i + 1]); + } + mAnimationTimer.ResetStart(); + mAnimationFrame = 0; + mAnimate = 1; + mAnimationLastBase = 0; +} + +int GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix) +{ + float time = animateTime; + if (mAnimate && time < 0) { + if (mAnimateScreenshot) { + time = mAnimationFrame / 30.f; + } else { + time = mAnimationTimer.GetCurrentElapsedTime(); + } + + float maxTime = mAnimateVectors[0].back(); + if (time >= maxTime) { + time = maxTime; + mAnimate = mAnimateScreenshot = 0; + SetInfo("Animation finished. (%1.2f seconds, %d frames)", time, mAnimationFrame); + } else { + SetInfo("Running mAnimation: time %1.2f/%1.2f, frames %d", time, maxTime, mAnimationFrame); + } + mAnimationFrame++; + } + if (!mAnimate) { + return 0; + } + float vals[8]; + for (int i = 0; i < 8; i++) { + vals[i] = mAnimationSplines[i].evaluate(time); + } + if (mAnimationChangeConfig && animateTime < 0) { + int base = 0; + int k = mAnimateVectors[0].size() - 1; + while (base < k && time > mAnimateVectors[0][base]) { + base++; + } + if (base > mAnimationLastBase + 1) { + mAnimationLastBase = base - 1; + } + + if (base != mAnimationLastBase && mAnimateVectors[0][mAnimationLastBase] != mAnimateVectors[0][base] && memcmp(&mAnimateConfig[base], &mAnimateConfig[mAnimationLastBase], sizeof(mAnimateConfig[base]))) { + mixSlaveImage = 1.f - (time - mAnimateVectors[0][mAnimationLastBase]) / (mAnimateVectors[0][base] - mAnimateVectors[0][mAnimationLastBase]); + if (mixSlaveImage > 0) { + mCfgL = mAnimateConfig[mAnimationLastBase]; + updateConfig(); + DrawGLScene_internal(time, true); + } + } + + if (memcmp(&mAnimateConfig[base], &mCfgL, sizeof(mCfgL))) { + mCfgL = mAnimateConfig[base]; + updateConfig(); + } + } + + if (mCfgL.animationMode != 6) { + if (mCfgL.animationMode & 1) // Rotation from euler angles + { + nextViewMatrix = nextViewMatrix * HMM_Rotate(-vals[4] * 180.f / CAMath::Pi(), {{1, 0, 0}}) * HMM_Rotate(vals[5] * 180.f / CAMath::Pi(), {{0, 1, 0}}) * HMM_Rotate(-vals[6] * 180.f / CAMath::Pi(), {{0, 0, 1}}); + } else { // Rotation from quaternion + const float mag = sqrtf(vals[4] * vals[4] + vals[5] * vals[5] + vals[6] * vals[6] + vals[7] * vals[7]); + if (mag < 0.0001f) { + vals[7] = 1; + } else { + for (int i = 0; i < 4; i++) { + vals[4 + i] /= mag; + } + } + + float xx = vals[4] * vals[4], xy = vals[4] * vals[5], xz = vals[4] * vals[6], xw = vals[4] * vals[7], yy = vals[5] * vals[5], yz = vals[5] * vals[6], yw = vals[5] * vals[7], zz = vals[6] * vals[6], zw = vals[6] * vals[7]; + float mat[16] = {1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0, 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0, 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0, 0, 0, 0, 1}; + nextViewMatrix = nextViewMatrix * MY_HMM_FROM(mat); + } + } + if (mCfgL.animationMode & 4) // Compute cartesian translation from sperical coordinates (euler angles) + { + const float r = vals[3], phi = vals[1], theta = vals[2]; + vals[2] = r * cosf(phi) * cosf(theta); + vals[0] = r * sinf(phi) * cosf(theta); + vals[1] = r * sinf(theta); + } else if (mCfgL.animationMode & 2) { // Scale cartesion translation to interpolated radius + float r = sqrtf(vals[0] * vals[0] + vals[1] * vals[1] + vals[2] * vals[2]); + if (fabsf(r) < 0.0001f) { + r = 1; + } + r = vals[3] / r; + for (int i = 0; i < 3; i++) { + vals[i] *= r; + } + } + if (mCfgL.animationMode == 6) { + nextViewMatrix = HMM_LookAt({{vals[0], vals[1], vals[2]}}, {{0, 0, 0}}, {{0, 1, 0}}); + } else { + nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}}); + } + return 1; +} diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx index d3fe6e71a91b2..ad1fd33cab686 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx @@ -38,7 +38,7 @@ using namespace GPUCA_NAMESPACE::gpu; #define GPUCA_BUILD_EVENT_DISPLAY_OPENGL #if !defined(GL_VERSION_4_5) || GL_VERSION_4_5 != 1 #ifdef GPUCA_STANDALONE -//#error Unsupported OpenGL version < 4.5 +// #error Unsupported OpenGL version < 4.5 #elif defined(GPUCA_O2_LIB) #pragma message "Unsupported OpenGL version < 4.5, disabling standalone event display" #else diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc b/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc new file mode 100644 index 0000000000000..75093ab191804 --- /dev/null +++ b/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc @@ -0,0 +1,178 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUDisplayColors.cxx +/// \author David Rohr + +#include "GPUDisplay.h" + +using namespace GPUCA_NAMESPACE::gpu; + +inline void GPUDisplay::ActivateColor() +{ + mBackend->ActivateColor(mDrawColor); +} + +inline void GPUDisplay::SetColorClusters() +{ + if (mCfgL.colorCollisions) { + return; + } + if (mCfgL.invertColors) { + mDrawColor = {0, 0.3, 0.7, 1.f}; + } else { + mDrawColor = {0, 0.7, 1.0, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorTRD() +{ + if (mCfgL.colorCollisions) { + return; + } + if (mCfgL.invertColors) { + mDrawColor = {0.7, 0.3, 0, 1.f}; + } else { + mDrawColor = {1.0, 0.7, 0, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorITS() +{ + if (mCfgL.colorCollisions) { + return; + } + if (mCfgL.invertColors) { + mDrawColor = {1.00, 0.1, 0.1, 1.f}; + } else { + mDrawColor = {1.00, 0.3, 0.3, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorTOF() +{ + if (mCfgL.colorCollisions) { + return; + } + if (mCfgL.invertColors) { + mDrawColor = {0.1, 1.0, 0.1, 1.f}; + } else { + mDrawColor = {0.5, 1.0, 0.5, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorInitLinks() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.42, 0.4, 0.1, 1.f}; + } else { + mDrawColor = {0.42, 0.4, 0.1, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorLinks() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.6, 0.1, 0.1, 1.f}; + } else { + mDrawColor = {0.8, 0.2, 0.2, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorSeeds() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.6, 0.0, 0.65, 1.f}; + } else { + mDrawColor = {0.8, 0.1, 0.85, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorTracklets() +{ + if (mCfgL.invertColors) { + mDrawColor = {0, 0, 0, 1.f}; + } else { + mDrawColor = {1, 1, 1, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorTracks() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.6, 0, 0.1, 1.f}; + } else { + mDrawColor = {0.8, 1., 0.15, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorGlobalTracks() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.8, 0.2, 0, 1.f}; + } else { + mDrawColor = {1.0, 0.4, 0, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorFinal() +{ + if (mCfgL.colorCollisions) { + return; + } + if (mCfgL.invertColors) { + mDrawColor = {0, 0.6, 0.1, 1.f}; + } else { + mDrawColor = {0, 0.7, 0.2, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorGrid() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.5, 0.5, 0.0, 1.f}; + } else { + mDrawColor = {0.7, 0.7, 0.0, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorGridTRD() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.5, 0.5, 0.5, 1.f}; + } else { + mDrawColor = {0.7, 0.7, 0.5, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetColorMarked() +{ + if (mCfgL.invertColors) { + mDrawColor = {0.8, 0, 0, 1.f}; + } else { + mDrawColor = {1.0, 0.0, 0.0, 1.f}; + } + ActivateColor(); +} +inline void GPUDisplay::SetCollisionColor(int col) +{ + int red = (col * 2) % 5; + int blue = (2 + col * 3) % 7; + int green = (4 + col * 5) % 6; + if (mCfgL.invertColors && red == 4 && blue == 5 && green == 6) { + red = 0; + } + if (!mCfgL.invertColors && red == 0 && blue == 0 && green == 0) { + red = 4; + } + mDrawColor = {red / 4.f, green / 5.f, blue / 6.f, 1.f}; + ActivateColor(); +} diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx new file mode 100644 index 0000000000000..a41be9d9e278a --- /dev/null +++ b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx @@ -0,0 +1,131 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUDisplayHelpers.cxx +/// \author David Rohr + +#include "GPUDisplay.h" + +#ifdef WITH_OPENMP +#include +#endif +#ifndef _WIN32 +#include "bitmapfile.h" +#endif + +using namespace GPUCA_NAMESPACE::gpu; + +int GPUDisplay::getNumThreads() +{ + if (mChain) { + return mChain->GetProcessingSettings().ompThreads; + } else { +#ifdef WITH_OPENMP + return omp_get_max_threads(); +#else + return 1; +#endif + } +} + +void GPUDisplay::disableUnsupportedOptions() +{ + if (!mIOPtrs->mergedTrackHitAttachment) { + mCfgH.markAdjacentClusters = 0; + } + if (!mQA) { + mCfgH.markFakeClusters = 0; + } + if (!mChain) { + mCfgL.excludeClusters = mCfgL.drawInitLinks = mCfgL.drawLinks = mCfgL.drawSeeds = mCfgL.drawTracklets = mCfgL.drawTracks = mCfgL.drawGlobalTracks = 0; + } + if (mConfig.showTPCTracksFromO2Format && mParam->par.earlyTpcTransform) { + throw std::runtime_error("Cannot run GPU display with early Transform when input is O2 tracks"); + } +} + +void GPUDisplay::DoScreenshot(const char* filename, std::vector& pixels, float animateTime) +{ + size_t screenshot_x = mBackend->mScreenWidth * mCfgR.screenshotScaleFactor; + size_t screenshot_y = mBackend->mScreenHeight * mCfgR.screenshotScaleFactor; + size_t size = 4 * screenshot_x * screenshot_y; + if (size != pixels.size()) { + GPUError("Pixel array of incorrect size obtained"); + filename = nullptr; + } + + if (filename) { + FILE* fp = fopen(filename, "w+b"); + if (fp == nullptr) { + GPUError("Error opening screenshot file %s", filename); + return; + } + + BITMAPFILEHEADER bmpFH; + BITMAPINFOHEADER bmpIH; + memset(&bmpFH, 0, sizeof(bmpFH)); + memset(&bmpIH, 0, sizeof(bmpIH)); + + bmpFH.bfType = 19778; //"BM" + bmpFH.bfSize = sizeof(bmpFH) + sizeof(bmpIH) + size; + bmpFH.bfOffBits = sizeof(bmpFH) + sizeof(bmpIH); + + bmpIH.biSize = sizeof(bmpIH); + bmpIH.biWidth = screenshot_x; + bmpIH.biHeight = screenshot_y; + bmpIH.biPlanes = 1; + bmpIH.biBitCount = 32; + bmpIH.biCompression = BI_RGB; + bmpIH.biSizeImage = size; + bmpIH.biXPelsPerMeter = 5670; + bmpIH.biYPelsPerMeter = 5670; + + fwrite(&bmpFH, 1, sizeof(bmpFH), fp); + fwrite(&bmpIH, 1, sizeof(bmpIH), fp); + fwrite(pixels.data(), 1, size, fp); + fclose(fp); + } +} + +void GPUDisplay::showInfo(const char* info) +{ + mBackend->prepareText(); + float colorValue = mCfgL.invertColors ? 0.f : 1.f; + OpenGLPrint(info, 40.f, 20.f + std::max(20, mDrawTextFontSize + 4), colorValue, colorValue, colorValue, 1); + if (mInfoText2Timer.IsRunning()) { + if (mInfoText2Timer.GetCurrentElapsedTime() >= 6) { + mInfoText2Timer.Reset(); + } else { + OpenGLPrint(mInfoText2, 40.f, 20.f, colorValue, colorValue, colorValue, 6 - mInfoText2Timer.GetCurrentElapsedTime()); + } + } + if (mInfoHelpTimer.IsRunning() || mPrintInfoTextAlways) { + if (mInfoHelpTimer.GetCurrentElapsedTime() >= 6) { + mInfoHelpTimer.Reset(); + } else { + PrintGLHelpText(colorValue); + } + } + mBackend->finishText(); +} + +void GPUDisplay::OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton) +{ + if (mBackend->mFreetypeInitialized) { + if (!fromBotton) { + y = mBackend->mScreenHeight - y; + } + float color[4] = {r, g, b, a}; + mBackend->OpenGLPrint(s, x, y, color, 1.0f); + } else if (mFrontend->mCanDrawText) { + mFrontend->OpenGLPrint(s, x, y, r, g, b, a, fromBotton); + } +} diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx index 30eaa2c3863aa..cb81b485bc6dd 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx @@ -12,6 +12,10 @@ /// \file GPUDisplayROOT.cxx /// \author David Rohr +#ifndef GPUCA_NO_ROOT +#include "Rtypes.h" // Include ROOT header first, to use ROOT and disable replacements +#endif + #include "GPUDisplay.h" using namespace GPUCA_NAMESPACE::gpu; diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx new file mode 100644 index 0000000000000..8adfb8441eee2 --- /dev/null +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -0,0 +1,987 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUDisplayDraw.cxx +/// \author David Rohr + +#ifndef GPUCA_NO_ROOT +#include "Rtypes.h" // Include ROOT header first, to use ROOT and disable replacements +#endif + +#include "GPUDisplay.h" +#include "GPUTRDGeometry.h" +#include "GPUO2DataTypes.h" +#include "GPUTRDTracker.h" +#include "GPUTRDTrackletWord.h" +#include "GPUQA.h" +#include "GPUTPCClusterData.h" +#include "GPUTPCConvertImpl.h" +#include "GPUTPCGMPropagator.h" +#include "GPUTPCMCInfo.h" +#include "GPUParam.inc" + +#include + +#ifdef GPUCA_HAVE_O2HEADERS +#include "DataFormatsITS/TrackITS.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/ConstMCTruthContainer.h" +#include "GPUTrackParamConvert.h" +#endif + +#ifdef WITH_OPENMP +#include +#endif + +using namespace GPUCA_NAMESPACE::gpu; + +#define GET_CID(slice, i) (mParam->par.earlyTpcTransform ? mIOPtrs->clusterData[slice][i].id : (mIOPtrs->clustersNative->clusterOffset[slice][0] + i)) +#define SEPERATE_GLOBAL_TRACKS_LIMIT (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT) + +const GPUTRDGeometry* GPUDisplay::trdGeometry() { return (GPUTRDGeometry*)mCalib->trdGeometry; } +const GPUTPCTracker& GPUDisplay::sliceTracker(int iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } + +inline void GPUDisplay::insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last) +{ + if (first == last) { + return; + } + vBuf.first->emplace_back(first); + vBuf.second->emplace_back(last - first); +} +inline void GPUDisplay::insertVertexList(int iSlice, size_t first, size_t last) +{ + std::pair*, vecpod*> vBuf(mVertexBufferStart + iSlice, mVertexBufferCount + iSlice); + insertVertexList(vBuf, first, last); +} + +inline void GPUDisplay::drawPointLinestrip(int iSlice, int cid, int id, int id_limit) +{ + mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); + if (mGlobalPos[cid].w < id_limit) { + mGlobalPos[cid].w = id; + } +} + +GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int iSlice, int select, int iCol) +{ + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + + if (iCol == 0) { + for (unsigned int i = 0; i < mIOPtrs->nTRDTracklets; i++) { + int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); + bool draw = iSlice == iSec && mGlobalPosTRD[i].w == select; + if (draw) { + mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD[i].x, mGlobalPosTRD[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[i].z); + mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD2[i].x, mGlobalPosTRD2[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[i].z); + } + } + } + + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int iSlice, int select, int iCol) +{ + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + + if (iCol == 0 && iSlice == 0) { + for (unsigned int i = 0; i < mIOPtrs->nTOFClusters; i++) { + mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[i].x, mGlobalPosTOF[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[i].z); + } + } + + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int iSlice, int select, int iCol) +{ + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + + if (iCol == 0 && iSlice == 0 && mIOPtrs->itsClusters) { + for (unsigned int i = 0; i < mIOPtrs->nItsClusters; i++) { + mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[i].x, mGlobalPosITS[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[i].z); + } + } + + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned int iCol) +{ + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + if (mOverlayTFClusters.size() > 0 || iCol == 0 || mNCollissions) { + const int firstCluster = (mOverlayTFClusters.size() > 1 && iCol > 0) ? mOverlayTFClusters[iCol - 1][iSlice] : 0; + const int lastCluster = (mOverlayTFClusters.size() > 1 && iCol + 1 < mOverlayTFClusters.size()) ? mOverlayTFClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); + const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth; + for (int cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { + const int cid = GET_CID(iSlice, cidInSlice); +#ifdef GPUCA_TPC_GEOMETRY_O2 + if (checkClusterCollision) { + const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid); + if (labels.size() ? (iCol != mQA->GetMCLabelCol(labels[0])) : (iCol != 0)) { + continue; + } + } +#else + (void)checkClusterCollision; +#endif + if (mCfgH.hideUnmatchedClusters && mQA && mQA->SuppressHit(cid)) { + continue; + } + bool draw = mGlobalPos[cid].w == select; + + if (mCfgH.markAdjacentClusters) { + const int attach = mIOPtrs->mergedTrackHitAttachment[cid]; + if (attach) { + if (mCfgH.markAdjacentClusters >= 32) { + if (mQA && mQA->clusterRemovable(attach, mCfgH.markAdjacentClusters == 33)) { + draw = select == tMARKED; + } + } else if ((mCfgH.markAdjacentClusters & 2) && (attach & gputpcgmmergertypes::attachTube)) { + draw = select == tMARKED; + } else if ((mCfgH.markAdjacentClusters & 1) && (attach & (gputpcgmmergertypes::attachGood | gputpcgmmergertypes::attachTube)) == 0) { + draw = select == tMARKED; + } else if ((mCfgH.markAdjacentClusters & 4) && (attach & gputpcgmmergertypes::attachGoodLeg) == 0) { + draw = select == tMARKED; + } else if ((mCfgH.markAdjacentClusters & 16) && (attach & gputpcgmmergertypes::attachHighIncl)) { + draw = select == tMARKED; + } else if (mCfgH.markAdjacentClusters & 8) { + if (fabsf(mIOPtrs->mergedTracks[attach & gputpcgmmergertypes::attachTrackMask].GetParam().GetQPt()) > 20.f) { + draw = select == tMARKED; + } + } + } + } else if (mCfgH.markClusters) { + short flags; + if (mParam->par.earlyTpcTransform) { + flags = mIOPtrs->clusterData[iSlice][cidInSlice].flags; + } else { + flags = mIOPtrs->clustersNative->clustersLinear[cid].getFlags(); + } + const bool match = flags & mCfgH.markClusters; + draw = (select == tMARKED) ? (match) : (draw && !match); + } else if (mCfgH.markFakeClusters) { + const bool fake = (mQA->HitAttachStatus(cid)); + draw = (select == tMARKED) ? (fake) : (draw && !fake); + } + if (draw) { + mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); + } + } + } + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int id, bool dodown) +{ + int iSlice = tracker.ISlice(); + if (mCfgH.clustersOnly) { + return (vboList(0, 0, iSlice)); + } + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + const GPUTPCRow& row = tracker.Data().Row(i); + + if (i < GPUCA_ROW_COUNT - 2) { + const GPUTPCRow& rowUp = tracker.Data().Row(i + 2); + for (int j = 0; j < row.NHits(); j++) { + if (tracker.Data().HitLinkUpData(row, j) != CALINK_INVAL) { + const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); + const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowUp, tracker.Data().HitLinkUpData(row, j))); + drawPointLinestrip(iSlice, cid1, id); + drawPointLinestrip(iSlice, cid2, id); + } + } + } + + if (dodown && i >= 2) { + const GPUTPCRow& rowDown = tracker.Data().Row(i - 2); + for (int j = 0; j < row.NHits(); j++) { + if (tracker.Data().HitLinkDownData(row, j) != CALINK_INVAL) { + const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); + const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowDown, tracker.Data().HitLinkDownData(row, j))); + drawPointLinestrip(iSlice, cid1, id); + drawPointLinestrip(iSlice, cid2, id); + } + } + } + } + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawSeeds(const GPUTPCTracker& tracker) +{ + int iSlice = tracker.ISlice(); + if (mCfgH.clustersOnly) { + return (vboList(0, 0, iSlice)); + } + size_t startCount = mVertexBufferStart[iSlice].size(); + for (unsigned int i = 0; i < *tracker.NStartHits(); i++) { + const GPUTPCHitId& hit = tracker.TrackletStartHit(i); + size_t startCountInner = mVertexBuffer[iSlice].size(); + int ir = hit.RowIndex(); + calink ih = hit.HitIndex(); + do { + const GPUTPCRow& row = tracker.Data().Row(ir); + const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, ih)); + drawPointLinestrip(iSlice, cid, tSEED); + ir += 2; + ih = tracker.Data().HitLinkUpData(row, ih); + } while (ih != CALINK_INVAL); + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + } + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawTracklets(const GPUTPCTracker& tracker) +{ + int iSlice = tracker.ISlice(); + if (mCfgH.clustersOnly) { + return (vboList(0, 0, iSlice)); + } + size_t startCount = mVertexBufferStart[iSlice].size(); + for (unsigned int i = 0; i < *tracker.NTracklets(); i++) { + const GPUTPCTracklet& tracklet = tracker.Tracklet(i); + size_t startCountInner = mVertexBuffer[iSlice].size(); + float4 oldpos; + for (int j = tracklet.FirstRow(); j <= tracklet.LastRow(); j++) { + const calink rowHit = tracker.TrackletRowHits()[tracklet.FirstHit() + (j - tracklet.FirstRow())]; + if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) { + const GPUTPCRow& row = tracker.Data().Row(j); + const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, rowHit)); + oldpos = mGlobalPos[cid]; + drawPointLinestrip(iSlice, cid, tTRACKLET); + } + } + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + } + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int global) +{ + int iSlice = tracker.ISlice(); + if (mCfgH.clustersOnly) { + return (vboList(0, 0, iSlice)); + } + size_t startCount = mVertexBufferStart[iSlice].size(); + for (unsigned int i = (global ? tracker.CommonMemory()->nLocalTracks : 0); i < (global ? *tracker.NTracks() : tracker.CommonMemory()->nLocalTracks); i++) { + GPUTPCTrack& track = tracker.Tracks()[i]; + size_t startCountInner = mVertexBuffer[iSlice].size(); + for (int j = 0; j < track.NHits(); j++) { + const GPUTPCHitId& hit = tracker.TrackHits()[track.FirstHitID() + j]; + const GPUTPCRow& row = tracker.Data().Row(hit.RowIndex()); + const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, hit.HitIndex())); + drawPointLinestrip(iSlice, cid, tSLICETRACK + global); + } + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + } + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +void GPUDisplay::DrawTrackITS(int trackId, int iSlice) +{ +#ifdef GPUCA_HAVE_O2HEADERS + const auto& trk = mIOPtrs->itsTracks[trackId]; + for (int k = 0; k < trk.getNClusters(); k++) { + int cid = mIOPtrs->itsTrackClusIdx[trk.getFirstClusterEntry() + k]; + mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[cid].x, mGlobalPosITS[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[cid].z); + mGlobalPosITS[cid].w = tITSATTACHED; + } +#endif +} + +GPUDisplay::vboList GPUDisplay::DrawFinalITS() +{ + const int iSlice = 0; + size_t startCount = mVertexBufferStart[iSlice].size(); + for (unsigned int i = 0; i < mIOPtrs->nItsTracks; i++) { + if (mITSStandaloneTracks[i]) { + size_t startCountInner = mVertexBuffer[iSlice].size(); + DrawTrackITS(i, iSlice); + insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); + } + } + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +template +void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer) +{ + auto& vBuf = threadBuffer.vBuf; + auto& buffer = threadBuffer.buffer; + unsigned int nTracks = std::max(trackList[0].size(), trackList[1].size()); + if (mCfgH.clustersOnly) { + nTracks = 0; + } + for (unsigned int ii = 0; ii < nTracks; ii++) { + int i = 0; + const T* track = nullptr; + int lastCluster = -1; + while (true) { + if (ii >= trackList[0].size()) { + break; + } + i = trackList[0][ii]; + int nClusters; + if constexpr (std::is_same_v) { + track = &mIOPtrs->mergedTracks[i]; + nClusters = track->NClusters(); + } else if constexpr (std::is_same_v) { + track = &mIOPtrs->outputTracksTPCO2[i]; + nClusters = track->getNClusters(); + if (!mIOPtrs->clustersNative) { + break; + } + } else { + throw std::runtime_error("invalid type"); + } + + size_t startCountInner = mVertexBuffer[iSlice].size(); + bool drawing = false; + + if constexpr (std::is_same_v) { + if (!mCfgH.drawTracksAndFilter && !(mCfgH.drawTPCTracks || (mCfgH.drawITSTracks && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) || (mCfgH.drawTRDTracks && mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1) || (mCfgH.drawTOFTracks && mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1))) { + break; + } + if (mCfgH.drawTracksAndFilter && ((mCfgH.drawITSTracks && !(mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1)) || (mCfgH.drawTRDTracks && !(mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1)) || (mCfgH.drawTOFTracks && !(mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1)))) { + break; + } + } + + if (mCfgH.trackFilter && !mTrackFilter[i]) { + break; + } + + // Print TOF part of track + if constexpr (std::is_same_v) { + if (mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1 && mIOPtrs->nTOFClusters) { + int cid = mIOPtrs->tpcLinkTOF[i]; + drawing = true; + mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[cid].x, mGlobalPosTOF[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[cid].z); + mGlobalPosTOF[cid].w = tTOFATTACHED; + } + } + + // Print TRD part of track + auto tmpDoTRDTracklets = [&](const auto& trk) { + for (int k = 5; k >= 0; k--) { + int cid = trk.getTrackletIndex(k); + if (cid < 0) { + continue; + } + drawing = true; + mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD2[cid].x, mGlobalPosTRD2[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[cid].z); + mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD[cid].x, mGlobalPosTRD[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[cid].z); + mGlobalPosTRD[cid].w = tTRDATTACHED; + } + }; + if (std::is_same_v || (!mIOPtrs->tpcLinkTRD && mIOPtrs->trdTracksO2)) { + if (mChain && ((int)mConfig.showTPCTracksFromO2Format == (int)mChain->GetProcessingSettings().trdTrackModelO2) && mTRDTrackIds[i] != -1 && mIOPtrs->nTRDTracklets) { + if (mIOPtrs->trdTracksO2) { +#ifdef GPUCA_HAVE_O2HEADERS + tmpDoTRDTracklets(mIOPtrs->trdTracksO2[mTRDTrackIds[i]]); +#endif + } else { + tmpDoTRDTracklets(mIOPtrs->trdTracks[mTRDTrackIds[i]]); + } + } + } else if constexpr (std::is_same_v) { + if (mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1 && mIOPtrs->nTRDTracklets) { + if ((mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->nTRDTracksITSTPCTRD : mIOPtrs->nTRDTracksTPCTRD) { + const auto* container = (mIOPtrs->tpcLinkTRD[i] & 0x40000000) ? mIOPtrs->trdTracksITSTPCTRD : mIOPtrs->trdTracksTPCTRD; + const auto& trk = container[mIOPtrs->tpcLinkTRD[i] & 0x3FFFFFFF]; + tmpDoTRDTracklets(trk); + } + } + } + + // Print TPC part of track + for (int k = 0; k < nClusters; k++) { + if constexpr (std::is_same_v) { + if (mCfgH.hideRejectedClusters && (mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject)) { + continue; + } + } + int cid; + if constexpr (std::is_same_v) { + cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].num; + } else { + cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, k, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; + } + int w = mGlobalPos[cid].w; + if (drawing) { + drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); + } + if (w == SEPERATE_GLOBAL_TRACKS_LIMIT) { + if (drawing) { + insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); + } + drawing = false; + } else { + if (!drawing) { + startCountInner = mVertexBuffer[iSlice].size(); + } + if (!drawing) { + drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); + } + if (!drawing && lastCluster != -1) { + if constexpr (std::is_same_v) { + cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster].num; + } else { + cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; + } + drawPointLinestrip(iSlice, cid, 7, SEPERATE_GLOBAL_TRACKS_LIMIT); + } + drawing = true; + } + lastCluster = k; + } + + // Print ITS part of track + if constexpr (std::is_same_v) { + if (mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1 && mIOPtrs->nItsTracks && mIOPtrs->nItsClusters) { + DrawTrackITS(mIOPtrs->tpcLinkITS[i], iSlice); + } + } + insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); + break; + } + + if (!mIOPtrs->clustersNative) { + continue; + } + + // Propagate track paramters / plot MC tracks + for (int iMC = 0; iMC < 2; iMC++) { + if (iMC) { + if (ii >= trackList[1].size()) { + continue; + } + i = trackList[1][ii]; + } else { + if (track == nullptr) { + continue; + } + if (lastCluster == -1) { + continue; + } + } + + size_t startCountInner = mVertexBuffer[iSlice].size(); + for (int inFlyDirection = 0; inFlyDirection < 2; inFlyDirection++) { + GPUTPCGMPhysicalTrackModel trkParam; + float ZOffset = 0; + float x = 0; + float alphaOrg = 0; + if (iMC == 0) { + if (!inFlyDirection && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) { + continue; + } + if constexpr (std::is_same_v) { + trkParam.Set(track->GetParam()); + alphaOrg = mParam->Alpha(iSlice); + } else { + GPUTPCGMTrackParam t; + convertTrackParam(t, *track); + alphaOrg = track->getAlpha(); + trkParam.Set(t); + } + + if (mParam->par.earlyTpcTransform) { + if constexpr (std::is_same_v) { + x = mIOPtrs->mergedTrackHitsXYZ[track->FirstClusterRef() + lastCluster].x; + ZOffset = track->GetParam().GetTZOffset(); + } + } else { + float y, z; + if constexpr (std::is_same_v) { + auto cl = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster]; + const auto& cln = mIOPtrs->clustersNative->clustersLinear[cl.num]; + GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, cl.slice, cl.row, cln.getPad(), cln.getTime(), x, y, z); + ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(iSlice, track->GetParam().GetTZOffset(), mParam->par.continuousMaxTimeBin); + } else { + uint8_t sector, row; + auto cln = track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative, sector, row); + GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, sector, row, cln.getPad(), cln.getTime(), x, y, z); + ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(sector, track->getTime0(), mParam->par.continuousMaxTimeBin); + } + } + } else { + const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i]; + if (mc.charge == 0.f) { + break; + } + if (mc.pid < 0) { + break; + } + + alphaOrg = mParam->Alpha(iSlice); + float c = cosf(alphaOrg); + float s = sinf(alphaOrg); + float mclocal[4]; + x = mc.x; + float y = mc.y; + mclocal[0] = x * c + y * s; + mclocal[1] = -x * s + y * c; + float px = mc.pX; + float py = mc.pY; + mclocal[2] = px * c + py * s; + mclocal[3] = -px * s + py * c; + float charge = mc.charge > 0 ? 1.f : -1.f; + + x = mclocal[0]; +#ifdef GPUCA_TPC_GEOMETRY_O2 + trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, -charge); // TODO: DR: unclear to me why we need -charge here + if (mParam->par.continuousTracking) { + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, mc.t0, mParam->par.continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1); + } +#else + if (fabsf(mc.z) > GPUTPCGeometry::TPCLength()) { + ZOffset = mc.z > 0 ? (mc.z - GPUTPCGeometry::TPCLength()) : (mc.z + GPUTPCGeometry::TPCLength()); + } + trkParam.Set(mclocal[0], mclocal[1], mc.z - ZOffset, mclocal[2], mclocal[3], mc.pZ, charge); +#endif + } + float z0 = trkParam.Z(); + if (iMC && inFlyDirection == 0) { + buffer.clear(); + } + if (x < 1) { + break; + } + if (fabsf(trkParam.SinPhi()) > 1) { + break; + } + float alpha = alphaOrg; + vecpod& useBuffer = iMC && inFlyDirection == 0 ? buffer : mVertexBuffer[iSlice]; + int nPoints = 0; + + while (nPoints++ < 5000) { + if ((inFlyDirection == 0 && x < 0) || (inFlyDirection && x * x + trkParam.Y() * trkParam.Y() > (iMC ? (450 * 450) : (300 * 300)))) { + break; + } + if (fabsf(trkParam.Z() + ZOffset) > mMaxClusterZ + (iMC ? 0 : 0)) { + break; + } + if (fabsf(trkParam.Z() - z0) > (iMC ? GPUTPCGeometry::TPCLength() : GPUTPCGeometry::TPCLength())) { + break; + } + if (inFlyDirection) { + if (fabsf(trkParam.SinPhi()) > 0.4f) { + float dalpha = asinf(trkParam.SinPhi()); + trkParam.Rotate(dalpha); + alpha += dalpha; + } + x = trkParam.X() + 1.f; + if (!mCfgH.propagateLoopers) { + float diff = fabsf(alpha - alphaOrg) / (2.f * CAMath::Pi()); + diff -= floor(diff); + if (diff > 0.25f && diff < 0.75f) { + break; + } + } + } + float B[3]; + prop->GetBxByBz(alpha, trkParam.GetX(), trkParam.GetY(), trkParam.GetZ(), B); + float dLp = 0; + if (trkParam.PropagateToXBxByBz(x, B[0], B[1], B[2], dLp)) { + break; + } + if (fabsf(trkParam.SinPhi()) > 0.9f) { + break; + } + float sa = sinf(alpha), ca = cosf(alpha); + float drawX = trkParam.X() + mCfgH.xAdd; + useBuffer.emplace_back((ca * drawX - sa * trkParam.Y()) * GL_SCALE_FACTOR, (ca * trkParam.Y() + sa * drawX) * mYFactor * GL_SCALE_FACTOR, mCfgH.projectXY ? 0 : (trkParam.Z() + ZOffset) * GL_SCALE_FACTOR); + x += inFlyDirection ? 1 : -1; + } + + if (inFlyDirection == 0) { + if (iMC) { + for (int k = (int)buffer.size() - 1; k >= 0; k--) { + mVertexBuffer[iSlice].emplace_back(buffer[k]); + } + } else { + insertVertexList(vBuf[1], startCountInner, mVertexBuffer[iSlice].size()); + startCountInner = mVertexBuffer[iSlice].size(); + } + } + } + insertVertexList(vBuf[iMC ? 3 : 2], startCountInner, mVertexBuffer[iSlice].size()); + } + } +} + +GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) +{ + int iSlice = tracker.ISlice(); + size_t startCount = mVertexBufferStart[iSlice].size(); + size_t startCountInner = mVertexBuffer[iSlice].size(); + for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + const GPUTPCRow& row = tracker.Data().Row(i); + for (int j = 0; j <= (signed)row.Grid().Ny(); j++) { + float z1 = row.Grid().ZMin(); + float z2 = row.Grid().ZMax(); + float x = row.X() + mCfgH.xAdd; + float y = row.Grid().YMin() + (float)j / row.Grid().StepYInv(); + float zz1, zz2, yy1, yy2, xx1, xx2; + mParam->Slice2Global(tracker.ISlice(), x, y, z1, &xx1, &yy1, &zz1); + mParam->Slice2Global(tracker.ISlice(), x, y, z2, &xx2, &yy2, &zz2); + if (iSlice < 18) { + zz1 += mCfgH.zAdd; + zz2 += mCfgH.zAdd; + } else { + zz1 -= mCfgH.zAdd; + zz2 -= mCfgH.zAdd; + } + mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); + } + for (int j = 0; j <= (signed)row.Grid().Nz(); j++) { + float y1 = row.Grid().YMin(); + float y2 = row.Grid().YMax(); + float x = row.X() + mCfgH.xAdd; + float z = row.Grid().ZMin() + (float)j / row.Grid().StepZInv(); + float zz1, zz2, yy1, yy2, xx1, xx2; + mParam->Slice2Global(tracker.ISlice(), x, y1, z, &xx1, &yy1, &zz1); + mParam->Slice2Global(tracker.ISlice(), x, y2, z, &xx2, &yy2, &zz2); + if (iSlice < 18) { + zz1 += mCfgH.zAdd; + zz2 += mCfgH.zAdd; + } else { + zz1 -= mCfgH.zAdd; + zz2 -= mCfgH.zAdd; + } + mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); + mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); + } + } + insertVertexList(tracker.ISlice(), startCountInner, mVertexBuffer[iSlice].size()); + return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); +} + +GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) +{ + // TODO: tilted pads ignored at the moment + size_t startCount = mVertexBufferStart[sector].size(); + size_t startCountInner = mVertexBuffer[sector].size(); +#ifdef GPUCA_HAVE_O2HEADERS + auto* geo = trdGeometry(); + if (geo) { + int trdsector = NSLICES / 2 - 1 - sector; + float alpha = geo->GetAlpha() / 2.f + geo->GetAlpha() * trdsector; + if (trdsector >= 9) { + alpha -= 2 * CAMath::Pi(); + } + for (int iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; ++iLy) { + for (int iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; ++iStack) { + int iDet = geo->GetDetector(iLy, iStack, trdsector); + auto matrix = geo->GetClusterMatrix(iDet); + if (!matrix) { + continue; + } + auto pp = geo->GetPadPlane(iDet); + for (int i = 0; i < pp->GetNrows(); ++i) { + float xyzLoc1[3]; + float xyzLoc2[3]; + float xyzGlb1[3]; + float xyzGlb2[3]; + xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos(); + xyzLoc1[1] = pp->GetCol0(); + xyzLoc2[1] = pp->GetColEnd(); + xyzLoc1[2] = xyzLoc2[2] = pp->GetRowPos(i) - pp->GetRowPos(pp->GetNrows() / 2); + matrix->LocalToMaster(xyzLoc1, xyzGlb1); + matrix->LocalToMaster(xyzLoc2, xyzGlb2); + float x1Tmp = xyzGlb1[0]; + xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha); + xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha); + float x2Tmp = xyzGlb2[0]; + xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); + xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); + mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); + } + for (int j = 0; j < pp->GetNcols(); ++j) { + float xyzLoc1[3]; + float xyzLoc2[3]; + float xyzGlb1[3]; + float xyzGlb2[3]; + xyzLoc1[0] = xyzLoc2[0] = geo->AnodePos(); + xyzLoc1[1] = xyzLoc2[1] = pp->GetColPos(j) + pp->GetColSize(j) / 2.f; + xyzLoc1[2] = pp->GetRow0() - pp->GetRowPos(pp->GetNrows() / 2); + xyzLoc2[2] = pp->GetRowEnd() - pp->GetRowPos(pp->GetNrows() / 2); + matrix->LocalToMaster(xyzLoc1, xyzGlb1); + matrix->LocalToMaster(xyzLoc2, xyzGlb2); + float x1Tmp = xyzGlb1[0]; + xyzGlb1[0] = xyzGlb1[0] * cosf(alpha) + xyzGlb1[1] * sinf(alpha); + xyzGlb1[1] = -x1Tmp * sinf(alpha) + xyzGlb1[1] * cosf(alpha); + float x2Tmp = xyzGlb2[0]; + xyzGlb2[0] = xyzGlb2[0] * cosf(alpha) + xyzGlb2[1] * sinf(alpha); + xyzGlb2[1] = -x2Tmp * sinf(alpha) + xyzGlb2[1] * cosf(alpha); + mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); + mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); + } + } + } + } +#endif + insertVertexList(sector, startCountInner, mVertexBuffer[sector].size()); + return (vboList(startCount, mVertexBufferStart[sector].size() - startCount, sector)); +} + +size_t GPUDisplay::DrawGLScene_updateVertexList() +{ + for (int i = 0; i < NSLICES; i++) { + mVertexBuffer[i].clear(); + mVertexBufferStart[i].clear(); + mVertexBufferCount[i].clear(); + } + + for (int i = 0; i < mCurrentClusters; i++) { + mGlobalPos[i].w = tCLUSTER; + } + for (int i = 0; i < mCurrentSpacePointsTRD; i++) { + mGlobalPosTRD[i].w = tTRDCLUSTER; + } + + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int i = 0; i < N_POINTS_TYPE; i++) { + mGlDLPoints[iSlice][i].resize(mNCollissions); + } + for (int i = 0; i < N_FINAL_TYPE; i++) { + mGlDLFinal[iSlice].resize(mNCollissions); + } + } + GPUCA_OPENMP(parallel num_threads(getNumThreads())) + { +#ifdef WITH_OPENMP + int numThread = omp_get_thread_num(); + int numThreads = omp_get_num_threads(); +#else + int numThread = 0, numThreads = 1; +#endif + if (mChain && (mChain->GetRecoSteps() & GPUDataTypes::RecoStep::TPCSliceTracking)) { + GPUCA_OPENMP(for) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + GPUTPCTracker& tracker = (GPUTPCTracker&)sliceTracker(iSlice); + tracker.SetPointersDataLinks(tracker.LinkTmpMemory()); + mGlDLLines[iSlice][tINITLINK] = DrawLinks(tracker, tINITLINK, true); + tracker.SetPointersDataLinks(mChain->rec()->Res(tracker.MemoryResLinks()).Ptr()); + } + GPUCA_OPENMP(barrier) + + GPUCA_OPENMP(for) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + const GPUTPCTracker& tracker = sliceTracker(iSlice); + + mGlDLLines[iSlice][tLINK] = DrawLinks(tracker, tLINK); + mGlDLLines[iSlice][tSEED] = DrawSeeds(tracker); + mGlDLLines[iSlice][tTRACKLET] = DrawTracklets(tracker); + mGlDLLines[iSlice][tSLICETRACK] = DrawTracks(tracker, 0); + mGlDLGrid[iSlice] = DrawGrid(tracker); + if (iSlice < NSLICES / 2) { + mGlDLGridTRD[iSlice] = DrawGridTRD(iSlice); + } + } + GPUCA_OPENMP(barrier) + + GPUCA_OPENMP(for) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + const GPUTPCTracker& tracker = sliceTracker(iSlice); + mGlDLLines[iSlice][tGLOBALTRACK] = DrawTracks(tracker, 1); + } + GPUCA_OPENMP(barrier) + } + mThreadTracks[numThread].resize(mNCollissions); + for (int i = 0; i < mNCollissions; i++) { + for (int j = 0; j < NSLICES; j++) { + for (int k = 0; k < 2; k++) { + mThreadTracks[numThread][i][j][k].clear(); + } + } + } + if (mConfig.showTPCTracksFromO2Format) { +#ifdef GPUCA_TPC_GEOMETRY_O2 + unsigned int col = 0; + GPUCA_OPENMP(for) + for (unsigned int i = 0; i < mIOPtrs->nOutputTracksTPCO2; i++) { + uint8_t sector, row; + if (mIOPtrs->clustersNative) { + mIOPtrs->outputTracksTPCO2[i].getCluster(mIOPtrs->outputClusRefsTPCO2, 0, *mIOPtrs->clustersNative, sector, row); + } else { + sector = 0; + } + if (mQA && mIOPtrs->outputTracksTPCO2MC) { + col = mQA->GetMCLabelCol(mIOPtrs->outputTracksTPCO2MC[i]); + } + mThreadTracks[numThread][col][sector][0].emplace_back(i); + } +#endif + } else { + GPUCA_OPENMP(for) + for (unsigned int i = 0; i < mIOPtrs->nMergedTracks; i++) { + const GPUTPCGMMergedTrack* track = &mIOPtrs->mergedTracks[i]; + if (track->NClusters() == 0) { + continue; + } + if (mCfgH.hideRejectedTracks && !track->OK()) { + continue; + } + int slice = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].slice; + unsigned int col = 0; + if (mQA) { + const auto& label = mQA->GetMCTrackLabel(i); +#ifdef GPUCA_TPC_GEOMETRY_O2 + col = mQA->GetMCLabelCol(label); +#else + while (label.isValid() && col < mOverlayTFClusters.size() && mOverlayTFClusters[col][NSLICES] < label.track) { + col++; + } +#endif + } + mThreadTracks[numThread][col][slice][0].emplace_back(i); + } + } + for (unsigned int col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) { + GPUCA_OPENMP(for) + for (unsigned int i = mIOPtrs->mcInfosTPCCol[col].first; i < mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num; i++) { + const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i]; + if (mc.charge == 0.f) { + continue; + } + if (mc.pid < 0) { + continue; + } + + float alpha = atan2f(mc.y, mc.x); + if (alpha < 0) { + alpha += 2 * CAMath::Pi(); + } + int slice = alpha / (2 * CAMath::Pi()) * 18; + if (mc.z < 0) { + slice += 18; + } + mThreadTracks[numThread][col][slice][1].emplace_back(i); + } + } + GPUCA_OPENMP(barrier) + + GPUTPCGMPropagator prop; + prop.SetMaxSinPhi(.999); + prop.SetMaterialTPC(); + prop.SetPolynomialField(&mParam->polynomialField); + + GPUCA_OPENMP(for) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int iCol = 0; iCol < mNCollissions; iCol++) { + mThreadBuffers[numThread].clear(); + for (int iSet = 0; iSet < numThreads; iSet++) { +#ifdef GPUCA_HAVE_O2HEADERS + if (mConfig.showTPCTracksFromO2Format) { + DrawFinal(iSlice, iCol, &prop, mThreadTracks[iSet][iCol][iSlice], mThreadBuffers[numThread]); + } else +#endif + { + DrawFinal(iSlice, iCol, &prop, mThreadTracks[iSet][iCol][iSlice], mThreadBuffers[numThread]); + } + } + vboList* list = &mGlDLFinal[iSlice][iCol][0]; + for (int i = 0; i < N_FINAL_TYPE; i++) { + size_t startCount = mVertexBufferStart[iSlice].size(); + for (unsigned int j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) { + mVertexBufferStart[iSlice].emplace_back(mThreadBuffers[numThread].start[i][j]); + mVertexBufferCount[iSlice].emplace_back(mThreadBuffers[numThread].count[i][j]); + } + list[i] = vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice); + } + } + } + + GPUCA_OPENMP(barrier) + GPUCA_OPENMP(for) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int i = 0; i < N_POINTS_TYPE_TPC; i++) { + for (int iCol = 0; iCol < mNCollissions; iCol++) { + mGlDLPoints[iSlice][i][iCol] = DrawClusters(iSlice, i, iCol); + } + } + } + } + // End omp parallel + + mGlDLFinalITS = DrawFinalITS(); + + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int i = N_POINTS_TYPE_TPC; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i++) { + for (int iCol = 0; iCol < mNCollissions; iCol++) { + mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTRD(iSlice, i, iCol); + } + } + } + + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i++) { + for (int iCol = 0; iCol < mNCollissions; iCol++) { + mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTOF(iSlice, i, iCol); + } + } + break; // TODO: Only slice 0 filled for now + } + + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF + N_POINTS_TYPE_ITS; i++) { + for (int iCol = 0; iCol < mNCollissions; iCol++) { + mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsITS(iSlice, i, iCol); + } + } + break; // TODO: Only slice 0 filled for now + } + + mUpdateVertexLists = 0; + size_t totalVertizes = 0; + for (int i = 0; i < NSLICES; i++) { + totalVertizes += mVertexBuffer[i].size(); + } + if (totalVertizes > 0xFFFFFFFF) { + throw std::runtime_error("Display vertex count exceeds 32bit uint counter"); + } + size_t needMultiVBOSize = mBackend->needMultiVBO(); + mUseMultiVBO = needMultiVBOSize && (totalVertizes * sizeof(mVertexBuffer[0][0]) >= needMultiVBOSize); + if (!mUseMultiVBO) { + size_t totalYet = mVertexBuffer[0].size(); + mVertexBuffer[0].resize(totalVertizes); + for (int i = 1; i < GPUCA_NSLICES; i++) { + for (unsigned int j = 0; j < mVertexBufferStart[i].size(); j++) { + mVertexBufferStart[i][j] += totalYet; + } + memcpy(&mVertexBuffer[0][totalYet], &mVertexBuffer[i][0], mVertexBuffer[i].size() * sizeof(mVertexBuffer[i][0])); + totalYet += mVertexBuffer[i].size(); + mVertexBuffer[i].clear(); + } + } + mBackend->loadDataToGPU(totalVertizes); + for (int i = 0; i < (mUseMultiVBO ? GPUCA_NSLICES : 1); i++) { + mVertexBuffer[i].clear(); + } + return totalVertizes; +} diff --git a/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx new file mode 100644 index 0000000000000..2b7baec173b61 --- /dev/null +++ b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx @@ -0,0 +1,276 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUDisplay.cxx +/// \author David Rohr + +#ifndef GPUCA_NO_ROOT +#include "Rtypes.h" // Include ROOT header first, to use ROOT and disable replacements +#endif + +#include "GPUDisplay.h" +#include "GPUO2DataTypes.h" +#include "GPUTPCClusterData.h" +#include "GPUTPCConvertImpl.h" +#include "GPUTRDGeometry.h" +#include "GPUTRDTrackletWord.h" +#include "GPUParam.inc" + +#ifdef GPUCA_HAVE_O2HEADERS +#include "DataFormatsTOF/Cluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTPC/TrackTPC.h" +#include "TOFBase/Geo.h" +#include "ITSBase/GeometryTGeo.h" +#endif +#ifdef GPUCA_O2_LIB +#include "ITSMFTBase/DPLAlpideParam.h" +#endif + +using namespace GPUCA_NAMESPACE::gpu; + +void GPUDisplay::DrawGLScene_updateEventData() +{ + mTimerDraw.ResetStart(); + if (mIOPtrs->clustersNative) { + mCurrentClusters = mIOPtrs->clustersNative->nClustersTotal; + } else { + mCurrentClusters = 0; + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + mCurrentClusters += mIOPtrs->nClusterData[iSlice]; + } + } + if (mNMaxClusters < mCurrentClusters) { + mNMaxClusters = mCurrentClusters; + mGlobalPosPtr.reset(new float4[mNMaxClusters]); + mGlobalPos = mGlobalPosPtr.get(); + } + + mCurrentSpacePointsTRD = mIOPtrs->nTRDTracklets; + if (mCurrentSpacePointsTRD > mNMaxSpacePointsTRD) { + mNMaxSpacePointsTRD = mCurrentSpacePointsTRD; + mGlobalPosPtrTRD.reset(new float4[mNMaxSpacePointsTRD]); + mGlobalPosPtrTRD2.reset(new float4[mNMaxSpacePointsTRD]); + mGlobalPosTRD = mGlobalPosPtrTRD.get(); + mGlobalPosTRD2 = mGlobalPosPtrTRD2.get(); + } + + mCurrentClustersITS = mIOPtrs->itsClusters ? mIOPtrs->nItsClusters : 0; + if (mNMaxClustersITS < mCurrentClustersITS) { + mNMaxClustersITS = mCurrentClustersITS; + mGlobalPosPtrITS.reset(new float4[mNMaxClustersITS]); + mGlobalPosITS = mGlobalPosPtrITS.get(); + } + + mCurrentClustersTOF = mIOPtrs->nTOFClusters; + if (mNMaxClustersTOF < mCurrentClustersTOF) { + mNMaxClustersTOF = mCurrentClustersTOF; + mGlobalPosPtrTOF.reset(new float4[mNMaxClustersTOF]); + mGlobalPosTOF = mGlobalPosPtrTOF.get(); + } + + unsigned int nTpcMergedTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; + if ((size_t)nTpcMergedTracks > mTRDTrackIds.size()) { + mTRDTrackIds.resize(nTpcMergedTracks); + } + if (mIOPtrs->nItsTracks > mITSStandaloneTracks.size()) { + mITSStandaloneTracks.resize(mIOPtrs->nItsTracks); + } + for (unsigned int i = 0; i < nTpcMergedTracks; i++) { + mTRDTrackIds[i] = -1; + } + auto tmpDoTRDTracklets = [&](auto* trdTracks) { + for (unsigned int i = 0; i < mIOPtrs->nTRDTracks; i++) { + if (trdTracks[i].getNtracklets()) { + mTRDTrackIds[trdTracks[i].getRefGlobalTrackIdRaw()] = i; + } + } + }; + if (mIOPtrs->trdTracksO2) { +#ifdef GPUCA_HAVE_O2HEADERS + tmpDoTRDTracklets(mIOPtrs->trdTracksO2); +#endif + } else { + tmpDoTRDTracklets(mIOPtrs->trdTracks); + } + if (mIOPtrs->nItsTracks) { + std::fill(mITSStandaloneTracks.begin(), mITSStandaloneTracks.end(), true); + if (mIOPtrs->tpcLinkITS) { + for (unsigned int i = 0; i < nTpcMergedTracks; i++) { + if (mIOPtrs->tpcLinkITS[i] != -1) { + mITSStandaloneTracks[mIOPtrs->tpcLinkITS[i]] = false; + } + } + } + } + + if (mCfgH.trackFilter) { + unsigned int nTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; + mTrackFilter.resize(nTracks); + std::fill(mTrackFilter.begin(), mTrackFilter.end(), true); + if (buildTrackFilter()) { + SetInfo("Error running track filter from %s", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str()); + } else { + unsigned int nFiltered = 0; + for (unsigned int i = 0; i < mTrackFilter.size(); i++) { + nFiltered += !mTrackFilter[i]; + } + if (mUpdateTrackFilter) { + SetInfo("Applied track filter %s - filtered %u / %u", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str(), nFiltered, (unsigned int)mTrackFilter.size()); + } + } + } + mUpdateTrackFilter = false; + + mMaxClusterZ = 0; + GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) + for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + int row = 0; + unsigned int nCls = mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] + : 0; + for (unsigned int i = 0; i < nCls; i++) { + int cid; + if (mParam->par.earlyTpcTransform) { + const auto& cl = mIOPtrs->clusterData[iSlice][i]; + cid = cl.id; + row = cl.row; + } else { + cid = mIOPtrs->clustersNative->clusterOffset[iSlice][0] + i; + while (row < GPUCA_ROW_COUNT - 1 && mIOPtrs->clustersNative->clusterOffset[iSlice][row + 1] <= (unsigned int)cid) { + row++; + } + } + if (cid >= mNMaxClusters) { + throw std::runtime_error("Cluster Buffer Size exceeded"); + } + float4* ptr = &mGlobalPos[cid]; + if (mParam->par.earlyTpcTransform) { + const auto& cl = mIOPtrs->clusterData[iSlice][i]; + mParam->Slice2Global(iSlice, (mCfgH.clustersOnNominalRow ? mParam->tpcGeometry.Row2X(row) : cl.x) + mCfgH.xAdd, cl.y, cl.z, &ptr->x, &ptr->y, &ptr->z); + } else { + float x, y, z; + const auto& cln = mIOPtrs->clustersNative->clusters[iSlice][0][i]; + GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, iSlice, row, cln.getPad(), cln.getTime(), x, y, z); + if (mCfgH.clustersOnNominalRow) { + x = mParam->tpcGeometry.Row2X(row); + } + mParam->Slice2Global(iSlice, x + mCfgH.xAdd, y, z, &ptr->x, &ptr->y, &ptr->z); + } + + if (fabsf(ptr->z) > mMaxClusterZ) { + mMaxClusterZ = fabsf(ptr->z); + } + ptr->z += iSlice < 18 ? mCfgH.zAdd : -mCfgH.zAdd; + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; + ptr->w = tCLUSTER; + } + } + + int trdTriggerRecord = -1; + float trdZoffset = 0; + GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ) firstprivate(trdTriggerRecord, trdZoffset)) + for (int i = 0; i < mCurrentSpacePointsTRD; i++) { + while (mParam->par.continuousTracking && trdTriggerRecord < (int)mIOPtrs->nTRDTriggerRecords - 1 && mIOPtrs->trdTrackletIdxFirst[trdTriggerRecord + 1] <= i) { + trdTriggerRecord++; +#ifdef GPUCA_HAVE_O2HEADERS + float trdTime = mIOPtrs->trdTriggerTimes[trdTriggerRecord] * 1e3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; + trdZoffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, trdTime, mParam->par.continuousMaxTimeBin)); +#endif + } + const auto& sp = mIOPtrs->trdSpacePoints[i]; + int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); + float4* ptr = &mGlobalPosTRD[i]; + mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd, sp.getY(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); + ptr->z += ptr->z > 0 ? trdZoffset : -trdZoffset; + if (fabsf(ptr->z) > mMaxClusterZ) { + mMaxClusterZ = fabsf(ptr->z); + } + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; + ptr->w = tTRDCLUSTER; + ptr = &mGlobalPosTRD2[i]; + mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd + 4.5f, sp.getY() + 1.5f * sp.getDy(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); + ptr->z += ptr->z > 0 ? trdZoffset : -trdZoffset; + if (fabsf(ptr->z) > mMaxClusterZ) { + mMaxClusterZ = fabsf(ptr->z); + } + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; + ptr->w = tTRDCLUSTER; + } + + GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) + for (int i = 0; i < mCurrentClustersTOF; i++) { +#ifdef GPUCA_HAVE_O2HEADERS + float4* ptr = &mGlobalPosTOF[i]; + mParam->Slice2Global(mIOPtrs->tofClusters[i].getSector(), mIOPtrs->tofClusters[i].getX() + mCfgH.xAdd, mIOPtrs->tofClusters[i].getY(), mIOPtrs->tofClusters[i].getZ(), &ptr->x, &ptr->y, &ptr->z); + float ZOffset = 0; + if (mParam->par.continuousTracking) { + float tofTime = mIOPtrs->tofClusters[i].getTime() * 1e-3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, tofTime, mParam->par.continuousMaxTimeBin)); + ptr->z += ptr->z > 0 ? ZOffset : -ZOffset; + } + if (fabsf(ptr->z) > mMaxClusterZ) { + mMaxClusterZ = fabsf(ptr->z); + } + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; + ptr->w = tTOFCLUSTER; +#endif + } + + if (mCurrentClustersITS) { +#ifdef GPUCA_HAVE_O2HEADERS + float itsROFhalfLen = 0; +#ifdef GPUCA_O2_LIB // Not available in standalone benchmark + if (mParam->par.continuousTracking) { + const auto& alpParams = o2::itsmft::DPLAlpideParam::Instance(); + itsROFhalfLen = alpParams.roFrameLengthInBC / (float)o2::tpc::constants::LHCBCPERTIMEBIN / 2; + } +#endif + int i = 0; + for (unsigned int j = 0; j < mIOPtrs->nItsClusterROF; j++) { + float ZOffset = 0; + if (mParam->par.continuousTracking) { + o2::InteractionRecord startIR = o2::InteractionRecord(0, mIOPtrs->settingsTF && mIOPtrs->settingsTF->hasTfStartOrbit ? mIOPtrs->settingsTF->tfStartOrbit : 0); + float itsROFtime = mIOPtrs->itsClusterROF[j].getBCData().differenceInBC(startIR) / (float)o2::tpc::constants::LHCBCPERTIMEBIN; + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, itsROFtime + itsROFhalfLen, mParam->par.continuousMaxTimeBin)); + } + if (i != mIOPtrs->itsClusterROF[j].getFirstEntry()) { + throw std::runtime_error("Inconsistent ITS data, number of clusters does not match ROF content"); + } + for (int k = 0; k < mIOPtrs->itsClusterROF[j].getNEntries(); k++) { + float4* ptr = &mGlobalPosITS[i]; + const auto& cl = mIOPtrs->itsClusters[i]; + auto* itsGeo = o2::its::GeometryTGeo::Instance(); + auto p = cl.getXYZGlo(*itsGeo); + ptr->x = p.X(); + ptr->y = p.Y(); + ptr->z = p.Z(); + ptr->z += ptr->z > 0 ? ZOffset : -ZOffset; + if (fabsf(ptr->z) > mMaxClusterZ) { + mMaxClusterZ = fabsf(ptr->z); + } + ptr->x *= GL_SCALE_FACTOR; + ptr->y *= GL_SCALE_FACTOR; + ptr->z *= GL_SCALE_FACTOR; + ptr->w = tITSCLUSTER; + i++; + } + } +#endif + } +} From 1c282ce55624bd9dc7a55dd66d1a3bf50ef8ea31 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 14 Sep 2024 09:45:41 +0200 Subject: [PATCH 0250/2205] dpl-workflow: more protection and explanation that this is due to bogus stdin file descriptors --- prodtests/full-system-test/aggregator-workflow.sh | 1 + prodtests/full-system-test/dpl-workflow.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index 4bd093b5a7fc6..6c4efc0e1e24e 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -125,6 +125,7 @@ if [[ "${CALIB_TPC_SCDCALIB_SENDTRKDATA:-}" == "1" ]]; then ENABLE_TRACK_INPUT=" # Calibration workflows if ! workflow_has_parameter CALIB_LOCAL_INTEGRATED_AGGREGATOR; then WORKFLOW= + [[ "${GEN_TOPO_ONTHEFLY:-}" == "1" ]] && WORKFLOW="echo '{}' | " # When running in a pseudo terminal / with ODC, sometimes we have bogus stdin file descriptors else : ${AGGREGATOR_TASKS:=ALL} fi diff --git a/prodtests/full-system-test/dpl-workflow.sh b/prodtests/full-system-test/dpl-workflow.sh index 87c50bab10079..de812ecbf6ca0 100755 --- a/prodtests/full-system-test/dpl-workflow.sh +++ b/prodtests/full-system-test/dpl-workflow.sh @@ -360,7 +360,7 @@ fi # Start of workflow command generation WORKFLOW= # Make sure we start with an empty workflow -[[ "${GEN_TOPO_ONTHEFLY:-}" == "1" ]] && WORKFLOW="echo '{}' | " +[[ "${GEN_TOPO_ONTHEFLY:-}" == "1" ]] && WORKFLOW="echo '{}' | " # When running in a pseudo terminal / with ODC, sometimes we have bogus stdin file descriptors # --------------------------------------------------------------------------------------------------------------------- # Input workflow From 18b692ecf4243d08a0c4d9101e498f1fd8cd872a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 14 Sep 2024 10:07:11 +0200 Subject: [PATCH 0251/2205] GPU: Fix some settings must not be constexpr with RTC since they can change --- .../TPC/workflow/src/EntropyEncoderSpec.cxx | 4 ++-- GPU/GPUTracking/Base/GPUParam.cxx | 8 ++++---- GPU/GPUTracking/Base/GPUParam.h | 3 +++ .../GPUTPCDecompressionKernels.cxx | 8 ++++---- .../TPCClusterDecompressor.cxx | 8 ++++---- .../TPCClusterDecompressor.inc | 2 +- .../DataTypes/GPUTPCClusterOccupancyMap.cxx | 2 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 15 +++++++------- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- .../Global/GPUChainTrackingClusterizer.cxx | 2 +- .../Global/GPUChainTrackingCompression.cxx | 4 ++-- .../Global/GPUChainTrackingMerger.cxx | 2 +- .../Global/GPUChainTrackingTRD.cxx | 2 +- .../Global/GPUChainTrackingTransformation.cxx | 2 +- GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx | 6 +++--- GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx | 6 +++--- GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx | 6 +++--- GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx | 8 ++++---- .../SliceTracker/GPUTPCSliceData.cxx | 2 +- .../tools/GPUExtractPbPbCollision.h | 20 +++++++++---------- .../TPCConvert/GPUTPCConvertImpl.h | 4 ++-- .../display/render/GPUDisplayDraw.cxx | 6 +++--- .../display/render/GPUDisplayImportEvent.cxx | 6 +++--- GPU/GPUTracking/qa/GPUQA.cxx | 2 +- 24 files changed, 66 insertions(+), 64 deletions(-) diff --git a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx index fc707f433c8c5..35b76715cbc28 100644 --- a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx +++ b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx @@ -148,7 +148,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) if (clusters.nTracks && clusters.solenoidBz != -1e6f && clusters.solenoidBz != mParam->bzkG) { throw std::runtime_error("Configured solenoid Bz does not match value used for track model encoding"); } - if (clusters.nTracks && clusters.maxTimeBin != -1e6 && clusters.maxTimeBin != mParam->par.continuousMaxTimeBin) { + if (clusters.nTracks && clusters.maxTimeBin != -1e6 && clusters.maxTimeBin != mParam->continuousMaxTimeBin) { throw std::runtime_error("Configured max time bin does not match value used for track model encoding"); } mCTFCoder.setSelectedIRFrames(pc.inputs().get>("selIRFrames")); @@ -162,7 +162,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) const float totalT = std::max(mFastTransform->getMaxDriftTime(0), mFastTransform->getMaxDriftTime(GPUCA_NSLICES / 2)); unsigned int offset = 0, lasti = 0; - const unsigned int maxTime = (mParam->par.continuousMaxTimeBin + 1) * o2::tpc::ClusterNative::scaleTimePacked - 1; + const unsigned int maxTime = (mParam->continuousMaxTimeBin + 1) * o2::tpc::ClusterNative::scaleTimePacked - 1; #ifdef WITH_OPENMP #pragma omp parallel for firstprivate(offset, lasti) num_threads(mNThreads) #endif diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index d9518b903d98f..a0d2f9c297f7c 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -119,7 +119,7 @@ void GPUParam::SetDefaults(float solenoidBz) par.assumeConstantBz = false; par.toyMCEventsFlag = false; par.continuousTracking = false; - par.continuousMaxTimeBin = 0; + continuousMaxTimeBin = 0; par.debugLevel = 0; par.earlyTpcTransform = false; } @@ -131,7 +131,7 @@ void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessi par.assumeConstantBz = g->constBz; par.toyMCEventsFlag = g->homemadeEvents; par.continuousTracking = g->continuousMaxTimeBin != 0; - par.continuousMaxTimeBin = g->continuousMaxTimeBin == -1 ? GPUSettings::TPC_MAX_TF_TIME_BIN : g->continuousMaxTimeBin; + continuousMaxTimeBin = g->continuousMaxTimeBin == -1 ? GPUSettings::TPC_MAX_TF_TIME_BIN : g->continuousMaxTimeBin; } par.earlyTpcTransform = rec.tpc.forceEarlyTransform == -1 ? (!par.continuousTracking) : rec.tpc.forceEarlyTransform; qptB5Scaler = CAMath::Abs(bzkG) > 0.1f ? CAMath::Abs(bzkG) / 5.006680f : 1.f; // Repeat here, since passing in g is optional @@ -140,9 +140,9 @@ void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessi UpdateRun3ClusterErrors(p->param.tpcErrorParamY, p->param.tpcErrorParamZ); } if (w) { - par.dodEdx = w->steps.isSet(GPUDataTypes::RecoStep::TPCdEdx); + par.dodEdx = dodEdxDownscaled = w->steps.isSet(GPUDataTypes::RecoStep::TPCdEdx); if (par.dodEdx && p && p->tpcDownscaledEdx != 0) { - par.dodEdx = (rand() % 100) < p->tpcDownscaledEdx; + dodEdxDownscaled = (rand() % 100) < p->tpcDownscaledEdx; } } } diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h index 852f52bf68862..ef1cccf58cdbf 100644 --- a/GPU/GPUTracking/Base/GPUParam.h +++ b/GPU/GPUTracking/Base/GPUParam.h @@ -57,6 +57,9 @@ struct GPUParam_t { float bzCLight; float qptB5Scaler; + signed char dodEdxDownscaled; + int continuousMaxTimeBin; + GPUTPCGeometry tpcGeometry; // TPC Geometry GPUTPCGMPolynomialField polynomialField; // Polynomial approx. of magnetic field for TPC GM const unsigned int* occupancyMap; // Ptr to TPC occupancy map diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index 7a58cad637514..be3abfbdfa598 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -28,7 +28,7 @@ GPUdii() void GPUTPCDecompressionKernels::Thread 0 && time >= maxTime) { + if (param.continuousMaxTimeBin > 0 && time >= maxTime) { if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) time = 0; } else { @@ -152,8 +152,8 @@ GPUdii() void GPUTPCDecompressionKernels::Thread 0 && t > processors.param.par.continuousMaxTimeBin) { - t = processors.param.par.continuousMaxTimeBin; + if (processors.param.continuousMaxTimeBin > 0 && t > processors.param.continuousMaxTimeBin) { + t = processors.param.continuousMaxTimeBin; } cl.setTime(t); } diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx index 61e3392af0f03..d829dc978c5ef 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx @@ -43,7 +43,7 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres if (clustersCompressed->nTracks && clustersCompressed->solenoidBz != -1e6f && clustersCompressed->solenoidBz != param.bzkG) { throw std::runtime_error("Configured solenoid Bz does not match value used for track model encoding"); } - if (clustersCompressed->nTracks && clustersCompressed->maxTimeBin != -1e6 && clustersCompressed->maxTimeBin != param.par.continuousMaxTimeBin) { + if (clustersCompressed->nTracks && clustersCompressed->maxTimeBin != -1e6 && clustersCompressed->maxTimeBin != param.continuousMaxTimeBin) { throw std::runtime_error("Configured max time bin does not match value used for track model encoding"); } std::vector clusters[NSLICES][GPUCA_ROW_COUNT]; @@ -52,7 +52,7 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres (&locks[0][0])[i].clear(); } unsigned int offset = 0, lasti = 0; - const unsigned int maxTime = param.par.continuousMaxTimeBin > 0 ? ((param.par.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1) : TPC_MAX_TIME_BIN_TRIGGERED; + const unsigned int maxTime = param.continuousMaxTimeBin > 0 ? ((param.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1) : TPC_MAX_TIME_BIN_TRIGGERED; GPUCA_OPENMP(parallel for firstprivate(offset, lasti)) for (unsigned int i = 0; i < clustersCompressed->nTracks; i++) { if (i < lasti) { @@ -99,8 +99,8 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres if (t < 0) { t = 0; } - if (param.par.continuousMaxTimeBin > 0 && t > param.par.continuousMaxTimeBin) { - t = param.par.continuousMaxTimeBin; + if (param.continuousMaxTimeBin > 0 && t > param.continuousMaxTimeBin) { + t = param.continuousMaxTimeBin; } cl.setTime(t); } diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc index f83b539d80cfa..f0cd648e0f49e 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc @@ -101,7 +101,7 @@ inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* cl pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; } } - if (param.par.continuousMaxTimeBin > 0 && time >= maxTime) { + if (param.continuousMaxTimeBin > 0 && time >= maxTime) { if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) time = 0; } else { diff --git a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx index 96c288d86b23d..9b388bb0260e5 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx +++ b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx @@ -22,7 +22,7 @@ GPUd() unsigned int GPUTPCClusterOccupancyMapBin::getNBins(const GPUParam& param if (param.rec.tpc.occupancyMapTimeBins == 0) { return 0; } - unsigned int maxTimeBin = param.par.continuousTracking ? param.par.continuousMaxTimeBin : TPC_MAX_TIME_BIN_TRIGGERED; + unsigned int maxTimeBin = param.par.continuousTracking ? param.continuousMaxTimeBin : TPC_MAX_TIME_BIN_TRIGGERED; return (maxTimeBin + param.rec.tpc.occupancyMapTimeBins) / param.rec.tpc.occupancyMapTimeBins; // Not -1, since maxTimeBin is allowed } diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 610cfe1627b2f..26a6168faecbb 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -565,14 +565,13 @@ EndConfig() // Derrived parameters used in GPUParam BeginHiddenConfig(GPUSettingsParam, param) -AddVariableRTC(dAlpha, float, 0.f) // angular size -AddVariableRTC(assumeConstantBz, signed char, 0) // Assume a constant magnetic field -AddVariableRTC(toyMCEventsFlag, signed char, 0) // events were build with home-made event generator -AddVariableRTC(continuousTracking, signed char, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding -AddVariableRTC(dodEdx, signed char, 0) // Do dEdx computation -AddVariableRTC(earlyTpcTransform, signed char, 0) // do Early TPC transformation -AddVariableRTC(debugLevel, signed char, 0) // Debug level -AddVariableRTC(continuousMaxTimeBin, int, 0) // Max time bin for continuous tracking +AddVariableRTC(dAlpha, float, 0.f) // angular size +AddVariableRTC(assumeConstantBz, signed char, 0) // Assume a constant magnetic field +AddVariableRTC(toyMCEventsFlag, signed char, 0) // events were build with home-made event generator +AddVariableRTC(continuousTracking, signed char, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding +AddVariableRTC(dodEdx, signed char, 0) // Do dEdx computation +AddVariableRTC(earlyTpcTransform, signed char, 0) // do Early TPC transformation +AddVariableRTC(debugLevel, signed char, 0) // Debug level EndConfig() EndNamespace() // gpu diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index fb5c6974e03c3..ba17b3e3ead54 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -285,7 +285,7 @@ bool GPUChainTracking::ValidateSettings() GPUError("OMP Kernels require mergerReadFromTrackerDirectly"); return false; } - if (param().par.continuousMaxTimeBin > (int)GPUSettings::TPC_MAX_TF_TIME_BIN) { + if (param().continuousMaxTimeBin > (int)GPUSettings::TPC_MAX_TF_TIME_BIN) { GPUError("configured max time bin exceeds 256 orbits"); return false; } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index c26968513611a..bcf4310a333f6 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -472,7 +472,7 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) mCFContext.reset(new GPUTPCCFChainContext); } const short maxFragmentLen = GetProcessingSettings().overrideClusterizerFragmentLen; - const unsigned int maxAllowedTimebin = param().par.continuousTracking ? std::max(param().par.continuousMaxTimeBin, maxFragmentLen) : TPC_MAX_TIME_BIN_TRIGGERED; + const unsigned int maxAllowedTimebin = param().par.continuousTracking ? std::max(param().continuousMaxTimeBin, maxFragmentLen) : TPC_MAX_TIME_BIN_TRIGGERED; mCFContext->tpcMaxTimeBin = maxAllowedTimebin; const CfFragment fragmentMax{(tpccf::TPCTime)mCFContext->tpcMaxTimeBin + 1, maxFragmentLen}; mCFContext->prepare(mIOPtrs.tpcZS, fragmentMax); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 3c06bb7a3a3c5..83bcb20ff6e8b 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -68,7 +68,7 @@ int GPUChainTracking::RunTPCCompression() O->nSliceRows = NSLICES * GPUCA_ROW_COUNT; O->nComppressionModes = param().rec.tpc.compressionTypeMask; O->solenoidBz = param().bzkG; - O->maxTimeBin = param().par.continuousMaxTimeBin; + O->maxTimeBin = param().continuousMaxTimeBin; size_t outputSize = AllocateRegisteredMemory(Compressor.mMemoryResOutputHost, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::compressedClusters)]); Compressor.mOutputFlat->set(outputSize, *Compressor.mOutput); char* hostFlatPtr = (char*)Compressor.mOutput->qTotU; // First array as allocated in GPUTPCCompression::SetPointersCompressedClusters @@ -253,7 +253,7 @@ int GPUChainTracking::RunTPCDecompression() inputGPU.nSliceRows = NSLICES * GPUCA_ROW_COUNT; inputGPU.nComppressionModes = param().rec.tpc.compressionTypeMask; inputGPU.solenoidBz = param().bzkG; - inputGPU.maxTimeBin = param().par.continuousMaxTimeBin; + inputGPU.maxTimeBin = param().continuousMaxTimeBin; SetupGPUProcessor(&Decompressor, true); WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx index 185de2f804acf..cd6de46b95c7a 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx @@ -264,7 +264,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) } GPUMemCpy(RecoStep::TPCMerging, Merger.OutputTracks(), MergerShadowAll.OutputTracks(), Merger.NOutputTracks() * sizeof(*Merger.OutputTracks()), outputStream, 0, nullptr, waitEvent); waitEvent = nullptr; - if (param().par.dodEdx) { + if (param().dodEdxDownscaled) { GPUMemCpy(RecoStep::TPCMerging, Merger.OutputTracksdEdx(), MergerShadowAll.OutputTracksdEdx(), Merger.NOutputTracks() * sizeof(*Merger.OutputTracksdEdx()), outputStream, 0); } GPUMemCpy(RecoStep::TPCMerging, Merger.Clusters(), MergerShadowAll.Clusters(), Merger.NOutputTrackClusters() * sizeof(*Merger.Clusters()), outputStream, 0); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx index 39b9492417400..3d16b6693cade 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx @@ -40,7 +40,7 @@ int GPUChainTracking::RunTRDTracking() return 0; } - bool isTriggeredEvent = (param().par.continuousMaxTimeBin == 0); + bool isTriggeredEvent = (param().continuousMaxTimeBin == 0); if (!isTriggeredEvent) { Tracker.SetProcessPerTimeFrame(true); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx b/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx index 7c8b77d9fe36c..84aef65146ca3 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx @@ -91,7 +91,7 @@ void GPUChainTracking::ConvertNativeToClusterDataLegacy() if (tmp != mIOPtrs.clustersNative) { *tmp = *mIOPtrs.clustersNative; } - GPUReconstructionConvert::ConvertNativeToClusterData(mIOMem.clusterNativeAccess.get(), mIOMem.clusterData, mIOPtrs.nClusterData, processors()->calibObjects.fastTransform, param().par.continuousMaxTimeBin); + GPUReconstructionConvert::ConvertNativeToClusterData(mIOMem.clusterNativeAccess.get(), mIOMem.clusterData, mIOPtrs.nClusterData, processors()->calibObjects.fastTransform, param().continuousMaxTimeBin); for (unsigned int i = 0; i < NSLICES; i++) { mIOPtrs.clusterData[i] = mIOMem.clusterData[i].get(); if (GetProcessingSettings().registerStandaloneInputMemory) { diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx index 671ec9a7794a0..379be50b09caf 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx @@ -325,7 +325,7 @@ void* GPUTPCGMMerger::SetPointersRefitScratch2(void* mem) void* GPUTPCGMMerger::SetPointersOutput(void* mem) { computePointerWithAlignment(mem, mOutputTracks, mNMaxTracks); - if (mRec->GetParam().par.dodEdx) { + if (mRec->GetParam().dodEdxDownscaled) { computePointerWithAlignment(mem, mOutputTracksdEdx, mNMaxTracks); } computePointerWithAlignment(mem, mClusters, mNMaxOutputTrackClusters); @@ -463,7 +463,7 @@ GPUd() int GPUTPCGMMerger::RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const trk.SinPhi() = inTrack->Param().GetSinPhi(); trk.DzDs() = inTrack->Param().GetDzDs(); trk.QPt() = inTrack->Param().GetQPt(); - trk.TZOffset() = Param().par.earlyTpcTransform ? inTrack->Param().GetZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convZOffsetToVertexTime(slice, inTrack->Param().GetZOffset(), Param().par.continuousMaxTimeBin); + trk.TZOffset() = Param().par.earlyTpcTransform ? inTrack->Param().GetZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convZOffsetToVertexTime(slice, inTrack->Param().GetZOffset(), Param().continuousMaxTimeBin); trk.ShiftZ(this, slice, sliceTrack.ClusterZT0(), sliceTrack.ClusterZTN(), inTrack->Param().GetX(), inTrack->Param().GetX()); // We do not store the inner / outer cluster X, so we just use the track X instead sliceTrack.SetX2(0.f); for (int way = 0; way < 2; way++) { @@ -2125,7 +2125,7 @@ GPUd() void GPUTPCGMMerger::MergeLoopersInit(int nBlocks, int nThreads, int iBlo const float qptabs = CAMath::Abs(p.GetQPt()); if (trk.NClusters() && qptabs * Param().qptB5Scaler > 5.f && qptabs * Param().qptB5Scaler <= lowPtThresh) { const int slice = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].slice; - const float refz = p.GetZ() + (Param().par.earlyTpcTransform ? p.GetTZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(slice, p.GetTZOffset(), Param().par.continuousMaxTimeBin)) + (trk.CSide() ? -100 : 100); + const float refz = p.GetZ() + (Param().par.earlyTpcTransform ? p.GetTZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(slice, p.GetTZOffset(), Param().continuousMaxTimeBin)) + (trk.CSide() ? -100 : 100); float sinA, cosA; CAMath::SinCos(trk.GetAlpha(), sinA, cosA); float gx = cosA * p.GetX() - sinA * p.GetY(); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx index fe3157bfae3ae..de9b0aa0a2038 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx @@ -44,7 +44,7 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, i constexpr unsigned char flagsReject = getFlagsReject(); const unsigned int flagsRequired = getFlagsRequired(merger.Param().rec); - bool cutOnTrackdEdx = merger.Param().par.dodEdx && merger.Param().rec.tpc.minTrackdEdxMax2Tot > 0.f; + bool cutOnTrackdEdx = merger.Param().par.dodEdx && merger.Param().dodEdxDownscaled && merger.Param().rec.tpc.minTrackdEdxMax2Tot > 0.f; GPUTPCGMMerger::tmpSort* GPUrestrict() trackSort = merger.TrackSortO2(); uint2* GPUrestrict() tmpData = merger.ClusRefTmp(); @@ -146,7 +146,7 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in oTrack.setChi2(tracks[i].GetParam().GetChi2()); auto& outerPar = tracks[i].OuterParam(); - if (merger.Param().par.dodEdx) { + if (merger.Param().par.dodEdx && merger.Param().dodEdxDownscaled) { oTrack.setdEdx(tracksdEdx[i]); } @@ -163,7 +163,7 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in outerPar.C[6], outerPar.C[7], outerPar.C[8], outerPar.C[9], outerPar.C[10], outerPar.C[11], outerPar.C[12], outerPar.C[13], outerPar.C[14]})); - if (merger.Param().par.dodEdx && merger.Param().rec.tpc.enablePID) { + if (merger.Param().par.dodEdx && merger.Param().dodEdxDownscaled && merger.Param().rec.tpc.enablePID) { PIDResponse pidResponse{}; auto pid = pidResponse.getMostProbablePID(oTrack, merger.Param().rec.tpc.PID_EKrangeMin, merger.Param().rec.tpc.PID_EKrangeMax, merger.Param().rec.tpc.PID_EPrangeMin, merger.Param().rec.tpc.PID_EPrangeMax, merger.Param().rec.tpc.PID_EDrangeMin, merger.Param().rec.tpc.PID_EDrangeMax, merger.Param().rec.tpc.PID_ETrangeMin, merger.Param().rec.tpc.PID_ETrangeMax, merger.Param().rec.tpc.PID_useNsigma, merger.Param().rec.tpc.PID_sigma); auto pidRemap = merger.Param().rec.tpc.PID_remap[pid]; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx index b6f2c72a209e0..c452d2f961979 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx @@ -40,7 +40,7 @@ GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMMerger* merger, const GPUTPCTr if (merger->Param().par.earlyTpcTransform) { mTZOffset = t.GetZOffset(); } else { - mTZOffset = merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convZOffsetToVertexTime(slice, t.GetZOffset(), merger->Param().par.continuousMaxTimeBin); + mTZOffset = merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convZOffsetToVertexTime(slice, t.GetZOffset(), merger->Param().continuousMaxTimeBin); } mNClusters = sliceTr->NHits(); } @@ -329,7 +329,7 @@ GPUd() bool GPUTPCGMSliceTrack::TransportToX(GPUTPCGMMerger* merger, float x, fl if (merger->Param().par.earlyTpcTransform) { b.SetZOffsetLinear(mTZOffset); } else { - b.SetZOffsetLinear(merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(mSlice, mTZOffset, merger->Param().par.continuousMaxTimeBin)); + b.SetZOffsetLinear(merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(mSlice, mTZOffset, merger->Param().continuousMaxTimeBin)); } if (!doCov) { @@ -485,7 +485,7 @@ GPUd() bool GPUTPCGMSliceTrack::TransportToXAlpha(GPUTPCGMMerger* merger, float if (merger->Param().par.earlyTpcTransform) { b.SetZOffsetLinear(mTZOffset); } else { - b.SetZOffsetLinear(merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(mSlice, mTZOffset, merger->Param().par.continuousMaxTimeBin)); + b.SetZOffsetLinear(merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(mSlice, mTZOffset, merger->Param().continuousMaxTimeBin)); } b.SetCov(0, c00 + h2 * h2c22 + h4 * h4c44 + 2.f * (h2 * c20ph4c42 + h4 * c40)); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx index 249e99f240ca0..5e1a6a37cb13a 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx @@ -212,7 +212,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT continue; } } else if (allowModification && lastRow != 255 && CAMath::Abs(cluster.row - lastRow) > 1) { - bool dodEdx = merger->Param().par.dodEdx && merger->Param().rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg; + bool dodEdx = merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled && merger->Param().rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg; dodEdx = AttachClustersPropagate(merger, cluster.slice, lastRow, cluster.row, iTrk, cluster.leg == clusters[maxN - 1].leg, prop, inFlyDirection, GPUCA_MAX_SIN_PHI, dodEdx); if (dodEdx) { dEdx.fillSubThreshold(lastRow - 1, param); @@ -362,7 +362,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT CADEBUG(printf("Reinit linearization\n")); prop.SetTrack(this, prop.GetAlpha()); } - if (merger->Param().par.dodEdx && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { + if (merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { float qtot = 0, qmax = 0, pad = 0, relTime = 0; const int clusterCount = (ihit - ihitMergeFirst) * wayDirection + 1; for (int iTmp = ihitMergeFirst; iTmp != ihit + wayDirection; iTmp += wayDirection) { @@ -413,7 +413,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT // TODO: we have looping tracks here with 0 accepted clusters in the primary leg. In that case we should refit the track using only the primary leg. - if (merger->Param().par.dodEdx) { + if (merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled) { dEdx.computedEdx(merger->OutputTracksdEdx()[iTrk], param); } Alpha = prop.GetAlpha(); @@ -574,7 +574,7 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric return -1e6f; } - const float zOffset = Merger->Param().par.earlyTpcTransform ? ((Merger->OutputTracks()[iTrack].CSide() ^ (slice >= 18)) ? -mTZOffset : mTZOffset) : Merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(slice, mTZOffset, Merger->Param().par.continuousMaxTimeBin); + const float zOffset = Merger->Param().par.earlyTpcTransform ? ((Merger->OutputTracks()[iTrack].CSide() ^ (slice >= 18)) ? -mTZOffset : mTZOffset) : Merger->GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(slice, mTZOffset, Merger->Param().continuousMaxTimeBin); const float y0 = row.Grid().YMin(); const float stepY = row.HstepY(); const float z0 = row.Grid().ZMin() - zOffset; // We can use our own ZOffset, since this is only used temporarily anyway diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx index 85275e19c844b..31a2c5828fe7d 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx @@ -112,7 +112,7 @@ void* GPUTPCSliceData::SetPointersRows(void* mem) GPUd() void GPUTPCSliceData::GetMaxNBins(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, GPUTPCRow* GPUrestrict() row, int& maxY, int& maxZ) { maxY = row->mMaxY * 2.f / GPUCA_MIN_BIN_SIZE + 1; - maxZ = (mem->param.par.continuousMaxTimeBin > 0 ? (mem->calibObjects.fastTransformHelper->getCorrMap()->convTimeToZinTimeFrame(0, 0, mem->param.par.continuousMaxTimeBin)) : mem->param.tpcGeometry.TPCLength()) + 50; + maxZ = (mem->param.continuousMaxTimeBin > 0 ? (mem->calibObjects.fastTransformHelper->getCorrMap()->convTimeToZinTimeFrame(0, 0, mem->param.continuousMaxTimeBin)) : mem->param.tpcGeometry.TPCLength()) + 50; maxZ = maxZ / GPUCA_MIN_BIN_SIZE + 1; } diff --git a/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h b/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h index f1946496eef55..e0cd756d32651 100644 --- a/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h +++ b/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h @@ -14,18 +14,18 @@ static void GPUExtractPbPbCollision(GPUParam& param, GPUTrackingInOutPointers& ioPtrs) { - std::vector counts(param.par.continuousMaxTimeBin + 1); - std::vector sums(param.par.continuousMaxTimeBin + 1); - std::vector countsTracks(param.par.continuousMaxTimeBin + 1); - std::vector sumsTracks(param.par.continuousMaxTimeBin + 1); - std::vector mask(param.par.continuousMaxTimeBin + 1); + std::vector counts(param.continuousMaxTimeBin + 1); + std::vector sums(param.continuousMaxTimeBin + 1); + std::vector countsTracks(param.continuousMaxTimeBin + 1); + std::vector sumsTracks(param.continuousMaxTimeBin + 1); + std::vector mask(param.continuousMaxTimeBin + 1); const int driftlength = 520; const bool checkAfterGlow = true; const int afterGlowLength = checkAfterGlow ? 8000 : 0; for (unsigned int i = 0; i < ioPtrs.clustersNative->nClustersTotal; i++) { int time = ioPtrs.clustersNative->clustersLinear[i].getTime(); - if (time < 0 || time > param.par.continuousMaxTimeBin) { - fprintf(stderr, "Invalid time %d > %d\n", time, param.par.continuousMaxTimeBin); + if (time < 0 || time > param.continuousMaxTimeBin) { + fprintf(stderr, "Invalid time %d > %d\n", time, param.continuousMaxTimeBin); throw std::runtime_error("Invalid Time"); } counts[time]++; @@ -35,19 +35,19 @@ static void GPUExtractPbPbCollision(GPUParam& param, GPUTrackingInOutPointers& i continue; } int time = ioPtrs.mergedTracks[i].GetParam().GetTZOffset(); - if (time < 0 || time > param.par.continuousMaxTimeBin) { + if (time < 0 || time > param.continuousMaxTimeBin) { continue; } countsTracks[time]++; } int first = 0, last = 0; - for (int i = driftlength; i < param.par.continuousMaxTimeBin; i++) { + for (int i = driftlength; i < param.continuousMaxTimeBin; i++) { if (counts[i]) { first = i; break; } } - for (int i = param.par.continuousMaxTimeBin + 1 - driftlength; i > 0; i--) { + for (int i = param.continuousMaxTimeBin + 1 - driftlength; i > 0; i--) { if (counts[i - 1]) { last = i; break; diff --git a/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h b/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h index b791a0aa08abe..e8d777a3b23c1 100644 --- a/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h +++ b/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h @@ -31,7 +31,7 @@ class GPUTPCConvertImpl GPUd() static void convert(const GPUConstantMem& GPUrestrict() cm, int slice, int row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) { if (cm.param.par.continuousTracking) { - cm.calibObjects.fastTransformHelper->getCorrMap()->TransformInTimeFrame(slice, row, pad, time, x, y, z, cm.param.par.continuousMaxTimeBin); + cm.calibObjects.fastTransformHelper->getCorrMap()->TransformInTimeFrame(slice, row, pad, time, x, y, z, cm.param.continuousMaxTimeBin); } else { cm.calibObjects.fastTransformHelper->Transform(slice, row, pad, time, x, y, z); } @@ -39,7 +39,7 @@ class GPUTPCConvertImpl GPUd() static void convert(const TPCFastTransform& GPUrestrict() transform, const GPUParam& GPUrestrict() param, int slice, int row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) { if (param.par.continuousTracking) { - transform.TransformInTimeFrame(slice, row, pad, time, x, y, z, param.par.continuousMaxTimeBin); + transform.TransformInTimeFrame(slice, row, pad, time, x, y, z, param.continuousMaxTimeBin); } else { transform.Transform(slice, row, pad, time, x, y, z); } diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx index 8adfb8441eee2..0b0eed697de2d 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -518,12 +518,12 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s auto cl = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster]; const auto& cln = mIOPtrs->clustersNative->clustersLinear[cl.num]; GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, cl.slice, cl.row, cln.getPad(), cln.getTime(), x, y, z); - ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(iSlice, track->GetParam().GetTZOffset(), mParam->par.continuousMaxTimeBin); + ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(iSlice, track->GetParam().GetTZOffset(), mParam->continuousMaxTimeBin); } else { uint8_t sector, row; auto cln = track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative, sector, row); GPUTPCConvertImpl::convert(*mCalib->fastTransform, *mParam, sector, row, cln.getPad(), cln.getTime(), x, y, z); - ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(sector, track->getTime0(), mParam->par.continuousMaxTimeBin); + ZOffset = mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(sector, track->getTime0(), mParam->continuousMaxTimeBin); } } } else { @@ -553,7 +553,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s #ifdef GPUCA_TPC_GEOMETRY_O2 trkParam.Set(mclocal[0], mclocal[1], mc.z, mclocal[2], mclocal[3], mc.pZ, -charge); // TODO: DR: unclear to me why we need -charge here if (mParam->par.continuousTracking) { - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, mc.t0, mParam->par.continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1); + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, mc.t0, mParam->continuousMaxTimeBin)) * (mc.z < 0 ? -1 : 1); } #else if (fabsf(mc.z) > GPUTPCGeometry::TPCLength()) { diff --git a/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx index 2b7baec173b61..b1e6dfe21fb97 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx @@ -184,7 +184,7 @@ void GPUDisplay::DrawGLScene_updateEventData() trdTriggerRecord++; #ifdef GPUCA_HAVE_O2HEADERS float trdTime = mIOPtrs->trdTriggerTimes[trdTriggerRecord] * 1e3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; - trdZoffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, trdTime, mParam->par.continuousMaxTimeBin)); + trdZoffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, trdTime, mParam->continuousMaxTimeBin)); #endif } const auto& sp = mIOPtrs->trdSpacePoints[i]; @@ -219,7 +219,7 @@ void GPUDisplay::DrawGLScene_updateEventData() float ZOffset = 0; if (mParam->par.continuousTracking) { float tofTime = mIOPtrs->tofClusters[i].getTime() * 1e-3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, tofTime, mParam->par.continuousMaxTimeBin)); + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, tofTime, mParam->continuousMaxTimeBin)); ptr->z += ptr->z > 0 ? ZOffset : -ZOffset; } if (fabsf(ptr->z) > mMaxClusterZ) { @@ -247,7 +247,7 @@ void GPUDisplay::DrawGLScene_updateEventData() if (mParam->par.continuousTracking) { o2::InteractionRecord startIR = o2::InteractionRecord(0, mIOPtrs->settingsTF && mIOPtrs->settingsTF->hasTfStartOrbit ? mIOPtrs->settingsTF->tfStartOrbit : 0); float itsROFtime = mIOPtrs->itsClusterROF[j].getBCData().differenceInBC(startIR) / (float)o2::tpc::constants::LHCBCPERTIMEBIN; - ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, itsROFtime + itsROFhalfLen, mParam->par.continuousMaxTimeBin)); + ZOffset = fabsf(mCalib->fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(0, itsROFtime + itsROFhalfLen, mParam->continuousMaxTimeBin)); } if (i != mIOPtrs->itsClusterROF[j].getFirstEntry()) { throw std::runtime_error("Inconsistent ITS data, number of clusters does not match ROF content"); diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 6b505e133f88e..85b0b49305fc9 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -1363,7 +1363,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (tracksExternal) { return param.GetZ(); } - if (!mParam->par.continuousMaxTimeBin) { + if (!mParam->continuousMaxTimeBin) { return param.GetZ() - mc1.z; } #ifdef GPUCA_TPC_GEOMETRY_O2 From 60f0dd412883f86041630e474730e735eb1a3661 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Sun, 15 Sep 2024 10:12:24 +0200 Subject: [PATCH 0252/2205] ctpdev (#13458) * devL ctpRateFetcher copied from O2Physics to O2 * clang * fixes * clang * dev: fixes according to andrea + demo macro * clang * fix: pointer protection * fix: added fetcher to linkdef * fix: ctpRateFetcher renamed to CTPRateFetcher * fix: pointers to ccdb object changed to instances * clang * fix: references instead of copy * clang --- DataFormats/Detectors/CTP/CMakeLists.txt | 2 + .../include/DataFormatsCTP/CTPRateFetcher.h | 52 ++++++ .../CTP/include/DataFormatsCTP/Scalers.h | 20 ++- .../Detectors/CTP/src/CTPRateFetcher.cxx | 152 ++++++++++++++++++ .../Detectors/CTP/src/DataFormatsCTPLinkDef.h | 1 + DataFormats/Detectors/CTP/src/Scalers.cxx | 16 +- Detectors/CTP/macro/CMakeLists.txt | 4 + Detectors/CTP/macro/TestFetcher.C | 46 ++++++ 8 files changed, 278 insertions(+), 15 deletions(-) create mode 100644 DataFormats/Detectors/CTP/include/DataFormatsCTP/CTPRateFetcher.h create mode 100644 DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx create mode 100644 Detectors/CTP/macro/TestFetcher.C diff --git a/DataFormats/Detectors/CTP/CMakeLists.txt b/DataFormats/Detectors/CTP/CMakeLists.txt index d07a4c65a7559..37c5af7b07b6e 100644 --- a/DataFormats/Detectors/CTP/CMakeLists.txt +++ b/DataFormats/Detectors/CTP/CMakeLists.txt @@ -15,6 +15,7 @@ o2_add_library(DataFormatsCTP src/CTF.cxx src/TriggerOffsetsParam.cxx src/LumiInfo.cxx + src/CTPRateFetcher.cxx PUBLIC_LINK_LIBRARIES O2::CommonDataFormat O2::Headers O2::CommonUtils @@ -27,5 +28,6 @@ o2_target_root_dictionary(DataFormatsCTP include/DataFormatsCTP/Configuration.h include/DataFormatsCTP/Scalers.h include/DataFormatsCTP/LumiInfo.h + include/DataFormatsCTP/CTPRateFetcher.h include/DataFormatsCTP/TriggerOffsetsParam.h) diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/CTPRateFetcher.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/CTPRateFetcher.h new file mode 100644 index 0000000000000..89605fbd28e1f --- /dev/null +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/CTPRateFetcher.h @@ -0,0 +1,52 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef COMMON_CCDB_CTPRATEFETCHER_H_ +#define COMMON_CCDB_CTPRATEFETCHER_H_ + +#include + +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "DataFormatsCTP/Configuration.h" +#include "DataFormatsCTP/Scalers.h" + +namespace o2 +{ +namespace ctp +{ + +class CTPRateFetcher +{ + public: + CTPRateFetcher() = default; + double fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, const std::string sourceName); + double fetchNoPuCorr(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, const std::string sourceName); + void setupRun(int runNumber, o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, bool initScalers); + void updateScalers(ctp::CTPRunScalers& scalers); + + private: + double fetchCTPratesInputs(uint64_t timeStamp, int input); + double fetchCTPratesClasses(uint64_t timeStamp, const std::string& className, int inputType = 1); + double fetchCTPratesInputsNoPuCorr(uint64_t timeStamp, int input); + double fetchCTPratesClassesNoPuCorr(uint64_t timeStamp, const std::string& className, int inputType = 1); + + double pileUpCorrection(double rate); + int mRunNumber = -1; + o2::ctp::CTPConfiguration mConfig{}; + o2::ctp::CTPRunScalers mScalers{}; + o2::parameters::GRPLHCIFData mLHCIFdata{}; + ClassDefNV(CTPRateFetcher, 1); +}; +} // namespace ctp +} // namespace o2 + +#endif // COMMON_CCDB_CTPRATEFETCHER_H_ diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h index 4484046bd4cbd..073cd6a78c24f 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h @@ -87,13 +87,21 @@ struct CTPScalerRecordO2 { class CTPRunScalers { public: + // + // static constexpr uint32_t NCOUNTERS = 1052; + // v1 + // static constexpr uint32_t NCOUNTERS = 1070; + // v2 - orbitid added at the end + static constexpr uint32_t NCOUNTERSv2 = 1071; + static constexpr uint32_t NCOUNTERS = 1085; + static std::vector scalerNames; CTPRunScalers() = default; - void printStream(std::ostream& stream) const; void printO2(std::ostream& stream) const; void printFromZero(std::ostream& stream) const; void printClasses(std::ostream& stream) const; std::vector getClassIndexes() const; + uint32_t getRunNumber() { return mRunNumber; }; int getScalerIndexForClass(uint32_t cls) const; std::vector& getScalerRecordO2() { return mScalerRecordO2; }; std::vector& getScalerRecordRaw() { return mScalerRecordRaw; }; @@ -106,7 +114,6 @@ class CTPRunScalers void setDetectorMask(o2::detectors::DetID::mask_t mask) { mDetectorMask = mask; }; void setRunNumber(uint32_t rnumber) { mRunNumber = rnumber; }; void addScalerRacordRaw(CTPScalerRecordRaw& scalerrecordraw) { mScalerRecordRaw.push_back(scalerrecordraw); }; - uint32_t getRunNumber() { return mRunNumber; }; int printRates(); int printIntegrals(); int printInputRateAndIntegral(int inp); @@ -115,16 +122,7 @@ class CTPRunScalers // int addOrbitOffset(uint32_t offset); // - // static constexpr uint32_t NCOUNTERS = 1052; - // v1 - // static constexpr uint32_t NCOUNTERS = 1070; - // v2 - orbitid added at the end - static constexpr uint32_t NCOUNTERSv2 = 1071; - static constexpr uint32_t NCOUNTERS = 1085; - static std::vector scalerNames; - void printLMBRateVsT() const; // prints LMB interaction rate vs time for debugging - // returns the pair of global (levelled) interaction rate, as well as interpolated // rate in Hz at a certain orbit number within the run std::pair getRate(uint32_t orbit, int classindex, int type) const; diff --git a/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx b/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx new file mode 100644 index 0000000000000..d9fc250bdc2ac --- /dev/null +++ b/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx @@ -0,0 +1,152 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "DataFormatsCTP/CTPRateFetcher.h" + +#include +#include +#include "CommonConstants/LHCConstants.h" + +using namespace o2::ctp; +double CTPRateFetcher::fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName) +{ + auto triggerRate = fetchNoPuCorr(ccdb, timeStamp, runNumber, sourceName); + if (triggerRate >= 0) { + return pileUpCorrection(triggerRate); + } + return -1; +} +double CTPRateFetcher::fetchNoPuCorr(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName) +{ + setupRun(runNumber, ccdb, timeStamp, 1); + if (sourceName.find("ZNC") != std::string::npos) { + if (runNumber < 544448) { + return fetchCTPratesInputsNoPuCorr(timeStamp, 25) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.); + } else { + return fetchCTPratesClassesNoPuCorr(timeStamp, "C1ZNC-B-NOPF-CRU", 6) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.); + } + } else if (sourceName == "T0CE") { + return fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVXTCE-B-NOPF"); + } else if (sourceName == "T0SC") { + return fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVXTSC-B-NOPF"); + } else if (sourceName == "T0VTX") { + if (runNumber < 534202) { + return fetchCTPratesClassesNoPuCorr(timeStamp, "minbias_TVX_L0", 3); // 2022 + } else { + double_t ret = fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVX-B-NOPF"); + if (ret == -2.) { + LOG(info) << "Trying different class"; + ret = fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVX-NONE"); + if (ret < 0) { + LOG(fatal) << "None of the classes used for lumi found"; + } + } + return ret; + } + } + LOG(error) << "CTP rate for " << sourceName << " not available"; + return -1.; +} +void CTPRateFetcher::updateScalers(ctp::CTPRunScalers& scalers) +{ + mScalers = scalers; + mScalers.convertRawToO2(); +} +// +double CTPRateFetcher::fetchCTPratesClasses(uint64_t timeStamp, const std::string& className, int inputType) +{ + auto triggerRate = fetchCTPratesClassesNoPuCorr(timeStamp, className, inputType); + if (triggerRate >= 0) { + return pileUpCorrection(triggerRate); + } + return -1; +} +double CTPRateFetcher::fetchCTPratesClassesNoPuCorr(uint64_t timeStamp, const std::string& className, int inputType) +{ + std::vector& ctpcls = mConfig.getCTPClasses(); + std::vector clslist = mConfig.getTriggerClassList(); + int classIndex = -1; + for (size_t i = 0; i < clslist.size(); i++) { + if (ctpcls[i].name.find(className) != std::string::npos) { + classIndex = i; + break; + } + } + if (classIndex == -1) { + LOG(warn) << "Trigger class " << className << " not found in CTPConfiguration"; + return -2.; + } + auto rate{mScalers.getRateGivenT(timeStamp * 1.e-3, classIndex, inputType)}; + return rate.second; +} +double CTPRateFetcher::fetchCTPratesInputs(uint64_t timeStamp, int input) +{ + std::vector& recs = mScalers.getScalerRecordO2(); + if (recs[0].scalersInps.size() == 48) { + return pileUpCorrection(mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7).second); + } else { + LOG(error) << "Inputs not available"; + return -1.; + } +} +double CTPRateFetcher::fetchCTPratesInputsNoPuCorr(uint64_t timeStamp, int input) +{ + std::vector& recs = mScalers.getScalerRecordO2(); + if (recs[0].scalersInps.size() == 48) { + return mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7).second; + } else { + LOG(error) << "Inputs not available"; + return -1.; + } +} + +double CTPRateFetcher::pileUpCorrection(double triggerRate) +{ + if (mLHCIFdata.getFillNumber() == 0) { + LOG(fatal) << "No filling" << std::endl; + } + auto bfilling = mLHCIFdata.getBunchFilling(); + std::vector bcs = bfilling.getFilledBCs(); + double nbc = bcs.size(); + double nTriggersPerFilledBC = triggerRate / nbc / constants::lhc::LHCRevFreq; + double mu = -std::log(1 - nTriggersPerFilledBC); + return mu * nbc * constants::lhc::LHCRevFreq; +} + +void CTPRateFetcher::setupRun(int runNumber, o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, bool initScalers) +{ + if (runNumber == mRunNumber) { + return; + } + mRunNumber = runNumber; + LOG(debug) << "Setting up CTP scalers for run " << mRunNumber; + std::map metadata; + auto ptrLHCIFdata = ccdb->getSpecific("GLO/Config/GRPLHCIF", timeStamp, metadata); + if (ptrLHCIFdata == nullptr) { + LOG(fatal) << "GRPLHCIFData not in database, timestamp:" << timeStamp; + } + mLHCIFdata = *ptrLHCIFdata; + metadata["runNumber"] = std::to_string(mRunNumber); + auto ptrConfig = ccdb->getSpecific("CTP/Config/Config", timeStamp, metadata); + if (ptrConfig == nullptr) { + LOG(fatal) << "CTPRunConfig not in database, timestamp:" << timeStamp; + } + mConfig = *ptrConfig; + if (initScalers) { + auto ptrScalers = ccdb->getSpecific("CTP/Calib/Scalers", timeStamp, metadata); + if (ptrScalers) { + mScalers = *ptrScalers; + mScalers.convertRawToO2(); + } else { + LOG(fatal) << "CTPRunScalers not in database, timestamp:" << timeStamp; + } + } +} diff --git a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h index 5dbabad4db7e7..da21f779723f8 100644 --- a/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h +++ b/DataFormats/Detectors/CTP/src/DataFormatsCTPLinkDef.h @@ -46,6 +46,7 @@ #pragma link C++ class o2::ctp::CTPRunScalers + ; #pragma link C++ class o2::ctp::LumiInfo + ; #pragma link C++ class vector < o2::ctp::LumiInfo> + ; +#pragma link C++ class o2::ctp::CTPRateFetcher + ; #pragma link C++ struct o2::ctp::CTFHeader + ; #pragma link C++ struct o2::ctp::CTF + ; diff --git a/DataFormats/Detectors/CTP/src/Scalers.cxx b/DataFormats/Detectors/CTP/src/Scalers.cxx index 8e5b608df2180..51242829f4f1e 100644 --- a/DataFormats/Detectors/CTP/src/Scalers.cxx +++ b/DataFormats/Detectors/CTP/src/Scalers.cxx @@ -308,6 +308,11 @@ int CTPRunScalers::convertRawToO2() for (uint32_t i = 1; i < mScalerRecordRaw.size(); i++) { //update overflows int ret = updateOverflows(mScalerRecordRaw[i - 1], mScalerRecordRaw[i], overflows); + // for(int k = 0; k < mClassMask.size(); k++) { + // if(mClassMask[k]) { + // LOG(info) << i << " " << k << " " << overflows[k][0] << " " << overflows[k][1] << " " << overflows[k][2] << " " << overflows[k][3] << " " << overflows[k][4] << " " << overflows[k][5]; + // } + // } // if (ret == 0) { CTPScalerRecordO2 o2rec; @@ -396,7 +401,7 @@ int CTPRunScalers::checkConsistency(const CTPScalerO2& scal0, const CTPScalerO2& // LMB >= LMA >= L0B >= L0A >= L1B >= L1A: 5 relations // broken for classes started at L0 // - int64_t difThres = 2; + int64_t difThres = 6; int64_t dif = (scal1.lmAfter - scal0.lmAfter) - (scal1.lmBefore - scal0.lmBefore); if (dif <= difThres) { eCnts.lmBlmAd1++; @@ -432,12 +437,14 @@ int CTPRunScalers::checkConsistency(const CTPScalerO2& scal0, const CTPScalerO2& // ret++; } dif = (scal1.l1Before - scal0.l1Before) - (scal1.l0After - scal0.l0After); + // LOG(info) << "L1B L0A " << dif << " " << scal1.l1Before << " " << scal1.l0After << " " << scal0.l1Before << " " << scal0.l0After; if (dif <= difThres) { eCnts.l0Al1Bd1++; } else if (dif > difThres) { eCnts.l0Al1B++; if (eCnts.l0Al1B < eCnts.MAXPRINT) { - LOG(error) << "L1B > L0A Before error:" << dif; + // LOG(error) << "L1B > L0A Before error:" << dif << " " << scal1.l1Before << " " << scal1.l0After << " " << scal0.l1Before << " " << scal0.l0After; + LOG(warning) << "L1B > L0A Before error:" << dif; } ret++; } @@ -466,10 +473,11 @@ int CTPRunScalers::updateOverflows(const CTPScalerRecordRaw& rec0, const CTPScal } int CTPRunScalers::checkConsistency(const CTPScalerRecordO2& rec0, const CTPScalerRecordO2& rec1, errorCounters& eCnts) const { + int ret = 0; for (uint32_t i = 0; i < rec0.scalers.size(); i++) { - checkConsistency(rec0.scalers[i], rec1.scalers[i], eCnts); + ret += checkConsistency(rec0.scalers[i], rec1.scalers[i], eCnts); } - return 0; + return ret; } int CTPRunScalers::updateOverflows(const CTPScalerRaw& scal0, const CTPScalerRaw& scal1, std::array& overflow) const { diff --git a/Detectors/CTP/macro/CMakeLists.txt b/Detectors/CTP/macro/CMakeLists.txt index b4f1dce887d35..eb78fd89d7aff 100644 --- a/Detectors/CTP/macro/CMakeLists.txt +++ b/Detectors/CTP/macro/CMakeLists.txt @@ -65,4 +65,8 @@ o2_add_test_root_macro(PlotOrbit.C PUBLIC_LINK_LIBRARIES O2::DataFormatsCTP O2::CCDB LABELS ctp) +o2_add_test_root_macro(TestFetcher.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsCTP + O2::CCDB + LABELS ctp) diff --git a/Detectors/CTP/macro/TestFetcher.C b/Detectors/CTP/macro/TestFetcher.C new file mode 100644 index 0000000000000..2d73b83cd174e --- /dev/null +++ b/Detectors/CTP/macro/TestFetcher.C @@ -0,0 +1,46 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include +#endif +using namespace o2::ctp; + +void TestFetcher(int runNumber = 557251) +{ + auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); + std::pair pp = ccdb.getRunDuration(runNumber); + long ts = pp.first + 60; + std::cout << "Run duration:" << pp.first << " " << pp.second << std::endl; + // Opening run + CTPRateFetcher fetcher; + fetcher.setupRun(runNumber, &ccdb, ts, 0); + ccdb.setURL("http://ali-qcdb-gpn.cern.ch:8083/"); + std::string QCDBPathCTPScalers = "qc/CTP/Scalers"; + map metadata; // can be empty + std::string run = std::to_string(runNumber); + metadata["runNumber"] = run; + CTPRunScalers* ctpscalers = ccdb.getSpecific(QCDBPathCTPScalers, ts, metadata); + auto tt = ctpscalers->getTimeLimitFromRaw(); + std::cout << "1st scalers duration:" << tt.first << " " << tt.second << std::endl; + fetcher.updateScalers(*ctpscalers); + auto rate = fetcher.fetchNoPuCorr(&ccdb, ts, runNumber, "T0VTX"); + std::cout << "1st rate:" << rate << std::endl; + // Running on the same run + ts = ts + 5 * 1000 * 3600; + ctpscalers = ccdb.getSpecific(QCDBPathCTPScalers, ts, metadata); + std::cout << "Later scalers duration:" << tt.first << " " << tt.second << std::endl; + fetcher.updateScalers(*ctpscalers); + rate = fetcher.fetchNoPuCorr(&ccdb, ts, runNumber, "T0VTX"); + std::cout << "Later rate:" << rate << std::endl; +} From 1c7fc8498f1f3a9de91366486ad66fbc3dc94bb7 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Mon, 16 Sep 2024 08:06:10 +0200 Subject: [PATCH 0253/2205] Make DCA fitter to work on GPU (#13510) --- Common/DCAFitter/GPU/cuda/DCAFitterN.cu | 77 ++- .../GPU/cuda/test/testDCAFitterNGPU.cxx | 640 +++++++++--------- .../DCAFitter/include/DCAFitter/DCAFitterN.h | 49 +- .../DCAFitter/include/DCAFitter/HelixHelper.h | 10 +- .../MathUtils/include/MathUtils/SMatrixGPU.h | 4 - .../src/TrackParametrization.cxx | 8 +- .../src/TrackParametrizationWithError.cxx | 4 +- 7 files changed, 405 insertions(+), 387 deletions(-) diff --git a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu index f543b7bc7cdd4..74c27796a6ebb 100644 --- a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu +++ b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu @@ -36,28 +36,32 @@ namespace o2::vertexing::device { namespace kernel { -GPUg() void printKernel(o2::vertexing::DCAFitterN<2>* ft) +template +GPUg() void printKernel(Fitter* ft) { if (threadIdx.x == 0) { - printf(" =============== GPU DCA Fitter ================\n"); + printf(" =============== GPU DCA Fitter %d prongs ================\n", Fitter::getNProngs()); ft->print(); - printf(" ===============================================\n"); + printf(" =========================================================\n"); } } -GPUg() void processKernel(o2::vertexing::DCAFitterN<2>* ft, o2::track::TrackParCov* t1, o2::track::TrackParCov* t2, int* res) +template +GPUg() void processKernel(Fitter* ft, int* res, Tr*... tracks) { - *res = ft->process(*t1, *t2); + *res = ft->process(*tracks...); } } // namespace kernel -void print(o2::vertexing::DCAFitterN<2>* ft, - const int nBlocks, - const int nThreads) +/// CPU handlers +template +void print(const int nBlocks, + const int nThreads, + Fitter& ft) { - DCAFitterN<2>* ft_device; - gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(o2::vertexing::DCAFitterN<2>))); - gpuCheckError(cudaMemcpy(ft_device, ft, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyHostToDevice)); + Fitter* ft_device; + gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(Fitter))); + gpuCheckError(cudaMemcpy(ft_device, &ft, sizeof(Fitter), cudaMemcpyHostToDevice)); kernel::printKernel<<>>(ft_device); @@ -65,42 +69,51 @@ void print(o2::vertexing::DCAFitterN<2>* ft, gpuCheckError(cudaDeviceSynchronize()); } -int process(o2::vertexing::DCAFitterN<2>* fitter, - o2::track::TrackParCov& track1, - o2::track::TrackParCov& track2, - const int nBlocks, - const int nThreads) +template +int process(const int nBlocks, + const int nThreads, + Fitter& fitter, + Tr&... args) { - DCAFitterN<2>* ft_device; - o2::track::TrackParCov* t1_device; - o2::track::TrackParCov* t2_device; + Fitter* ft_device; + std::array tracks_device; int result, *result_device; - gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(o2::vertexing::DCAFitterN<2>))); - gpuCheckError(cudaMalloc(reinterpret_cast(&t1_device), sizeof(o2::track::TrackParCov))); - gpuCheckError(cudaMalloc(reinterpret_cast(&t2_device), sizeof(o2::track::TrackParCov))); + gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(Fitter))); gpuCheckError(cudaMalloc(reinterpret_cast(&result_device), sizeof(int))); - gpuCheckError(cudaMemcpy(ft_device, fitter, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyHostToDevice)); - gpuCheckError(cudaMemcpy(t1_device, &track1, sizeof(o2::track::TrackParCov), cudaMemcpyHostToDevice)); - gpuCheckError(cudaMemcpy(t2_device, &track2, sizeof(o2::track::TrackParCov), cudaMemcpyHostToDevice)); + int iArg{0}; + ([&] { + gpuCheckError(cudaMalloc(reinterpret_cast(&(tracks_device[iArg])), sizeof(o2::track::TrackParCov))); + gpuCheckError(cudaMemcpy(tracks_device[iArg], &args, sizeof(o2::track::TrackParCov), cudaMemcpyHostToDevice)); + ++iArg; + }(), + ...); - kernel::processKernel<<>>(ft_device, t1_device, t2_device, result_device); + gpuCheckError(cudaMemcpy(ft_device, &fitter, sizeof(Fitter), cudaMemcpyHostToDevice)); + + std::apply([&](auto&&... args) { kernel::processKernel<<>>(ft_device, result_device, args...); }, tracks_device); gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); gpuCheckError(cudaMemcpy(&result, result_device, sizeof(int), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaMemcpy(fitter, ft_device, sizeof(o2::vertexing::DCAFitterN<2>), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaMemcpy(&track1, t1_device, sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaMemcpy(&track2, t2_device, sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaFree(ft_device)); - gpuCheckError(cudaFree(t1_device)); - gpuCheckError(cudaFree(t2_device)); + gpuCheckError(cudaMemcpy(&fitter, ft_device, sizeof(Fitter), cudaMemcpyDeviceToHost)); + iArg = 0; + ([&] { + gpuCheckError(cudaMemcpy(&args, tracks_device[iArg], sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaFree(tracks_device[iArg])); + ++iArg; + }(), + ...); gpuCheckError(cudaFree(result_device)); return result; } +template int process(const int, const int, o2::vertexing::DCAFitterN<2>&, o2::track::TrackParCov&, o2::track::TrackParCov&); +template int process(const int, const int, o2::vertexing::DCAFitterN<3>&, o2::track::TrackParCov&, o2::track::TrackParCov&, o2::track::TrackParCov&); +template void print(const int, const int, o2::vertexing::DCAFitterN<2>&); +template void print(const int, const int, o2::vertexing::DCAFitterN<3>&); } // namespace o2::vertexing::device \ No newline at end of file diff --git a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx index 829ecb808f5c2..8a2a70f65ac1c 100644 --- a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx +++ b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx @@ -56,7 +56,6 @@ float checkResults(o2::utils::TreeStreamRedirector& outs, std::string& treeName, double dst = TMath::Sqrt(df[0] * df[0] + df[1] * df[1] + df[2] * df[2]); distMin = dst < distMin ? dst : distMin; auto parentTrack = fitter.createParentTrackParCov(ic); - // float genX outs << treeName.c_str() << "cand=" << ic << "ncand=" << nCand << "nIter=" << nIter << "chi2=" << chi2 << "genPart=" << genPar << "recPart=" << moth << "genX=" << vgen[0] << "genY=" << vgen[1] << "genZ=" << vgen[2] @@ -145,6 +144,8 @@ TLorentzVector generate(Vec3D& vtx, std::vector& vctr, f BOOST_AUTO_TEST_CASE(DCAFitterNProngs) { + gRandom->Delete(); + gRandom = new TRandom(42); constexpr int NTest = 10000; o2::utils::TreeStreamRedirector outStream("dcafitterNTest.root"); @@ -185,9 +186,10 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) swW.Stop(); for (int iev = 0; iev < NTest; iev++) { auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + ft.setUseAbsDCA(true); swA.Start(false); - int ncA = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + int ncA = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swA.Stop(); LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); if (ncA) { @@ -199,7 +201,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) ft.setUseAbsDCA(true); ft.setWeightedFinalPCA(true); swAW.Start(false); - int ncAW = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + int ncAW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAW.Stop(); LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); if (ncAW) { @@ -211,7 +213,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) ft.setUseAbsDCA(false); ft.setWeightedFinalPCA(false); swW.Start(false); - int ncW = device::process(&ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + int ncW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swW.Stop(); LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); if (ncW) { @@ -220,8 +222,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); - device::print(&ft, 1, 1); + device::print(1, 1, ft); meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundA ? nfoundA : 1; meanDW /= nfoundW ? nfoundW : 1; @@ -233,321 +234,322 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " GPU time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); - // BOOST_CHECK(nfoundAW > 0.99 * NTest); - // BOOST_CHECK(nfoundW > 0.99 * NTest); - // BOOST_CHECK(meanDA < 0.1); - // BOOST_CHECK(meanDAW < 0.1); - // BOOST_CHECK(meanDW < 0.1); + BOOST_CHECK(nfoundAW > 0.99 * NTest); + BOOST_CHECK(nfoundW > 0.99 * NTest); + BOOST_CHECK(meanDA < 0.1); + BOOST_CHECK(meanDAW < 0.1); + BOOST_CHECK(meanDW < 0.1); + } + + // 2 prongs vertices with collinear tracks (gamma conversion) + { + LOG(info) << "Processing 2-prong Helix - Helix case gamma conversion"; + std::vector forceQ{1, 1}; + + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::string treeName2A = "gpr2a", treeName2AW = "gpr2aw", treeName2W = "gpr2w"; + TStopwatch swA, swAW, swW; + int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + double meanDA = 0, meanDAW = 0, meanDW = 0; + swA.Stop(); + swAW.Stop(); + swW.Stop(); + for (int iev = 0; iev < NTest; iev++) { + auto genParent = generate(vtxGen, vctracks, bz, genPHS, gamma, gammadec, forceQ); + + ft.setUseAbsDCA(true); + swA.Start(false); + int ncA = device::process(1, 1, ft, vctracks[0], vctracks[1]); + swA.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + if (ncA) { + auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, gammadec); + meanDA += minD; + nfoundA++; + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + swAW.Start(false); + int ncAW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAW.Stop(); + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncAW) { + auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, gammadec); + meanDAW += minD; + nfoundAW++; + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + swW.Start(false); + int ncW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swW.Stop(); + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncW) { + auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, gammadec); + meanDW += minD; + nfoundW++; + } + } + + device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundA ? nfoundA : 1; + meanDW /= nfoundW ? nfoundW : 1; + LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + BOOST_CHECK(nfoundA > 0.99 * NTest); + BOOST_CHECK(nfoundAW > 0.99 * NTest); + BOOST_CHECK(nfoundW > 0.99 * NTest); + BOOST_CHECK(meanDA < 2.1); + BOOST_CHECK(meanDAW < 2.1); + BOOST_CHECK(meanDW < 2.1); } - // // 2 prongs vertices with collinear tracks (gamma conversion) - // { - // LOG(info) << "Processing 2-prong Helix - Helix case gamma conversion"; - // std::vector forceQ{1, 1}; - - // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter - // ft.setBz(bz); - // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway - // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway - // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway - // ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway - // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway - // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor - - // std::string treeName2A = "gpr2a", treeName2AW = "gpr2aw", treeName2W = "gpr2w"; - // TStopwatch swA, swAW, swW; - // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; - // double meanDA = 0, meanDAW = 0, meanDW = 0; - // swA.Stop(); - // swAW.Stop(); - // swW.Stop(); - // for (int iev = 0; iev < NTest; iev++) { - // auto genParent = generate(vtxGen, vctracks, bz, genPHS, gamma, gammadec, forceQ); - - // ft.setUseAbsDCA(true); - // swA.Start(false); - // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swA.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncA) { - // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, gammadec); - // meanDA += minD; - // nfoundA++; - // } - - // ft.setUseAbsDCA(true); - // ft.setWeightedFinalPCA(true); - // swAW.Start(false); - // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swAW.Stop(); - // LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncAW) { - // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, gammadec); - // meanDAW += minD; - // nfoundAW++; - // } - - // ft.setUseAbsDCA(false); - // ft.setWeightedFinalPCA(false); - // swW.Start(false); - // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swW.Stop(); - // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncW) { - // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, gammadec); - // meanDW += minD; - // nfoundW++; - // } - // } - // ft.print(); - // meanDA /= nfoundA ? nfoundA : 1; - // meanDAW /= nfoundA ? nfoundA : 1; - // meanDW /= nfoundW ? nfoundW : 1; - // LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; - // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); - // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); - // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); - // BOOST_CHECK(nfoundA > 0.99 * NTest); - // BOOST_CHECK(nfoundAW > 0.99 * NTest); - // BOOST_CHECK(nfoundW > 0.99 * NTest); - // BOOST_CHECK(meanDA < 2.1); - // BOOST_CHECK(meanDAW < 2.1); - // BOOST_CHECK(meanDW < 2.1); - // } - - // // 2 prongs vertices with one of charges set to 0: Helix : Line - // { - // std::vector forceQ{1, 1}; - // LOG(info) << "Processing 2-prong Helix - Line case"; - // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter - // ft.setBz(bz); - // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway - // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway - // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway - // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway - // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor - - // std::string treeName2A = "pr2aHL", treeName2AW = "pr2awHL", treeName2W = "pr2wHL"; - // TStopwatch swA, swAW, swW; - // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; - // double meanDA = 0, meanDAW = 0, meanDW = 0; - // swA.Stop(); - // swAW.Stop(); - // swW.Stop(); - // for (int iev = 0; iev < NTest; iev++) { - // forceQ[iev % 2] = 1; - // forceQ[1 - iev % 2] = 0; - // auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); - - // ft.setUseAbsDCA(true); - // swA.Start(false); - // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swA.Stop(); - // LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncA) { - // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); - // meanDA += minD; - // nfoundA++; - // } - - // ft.setUseAbsDCA(true); - // ft.setWeightedFinalPCA(true); - // swAW.Start(false); - // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swAW.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncAW) { - // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); - // meanDAW += minD; - // nfoundAW++; - // } - - // ft.setUseAbsDCA(false); - // ft.setWeightedFinalPCA(false); - // swW.Start(false); - // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swW.Stop(); - // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncW) { - // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); - // meanDW += minD; - // nfoundW++; - // } - // } - // ft.print(); - // meanDA /= nfoundA ? nfoundA : 1; - // meanDAW /= nfoundAW ? nfoundAW : 1; - // meanDW /= nfoundW ? nfoundW : 1; - // LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; - // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); - // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); - // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); - // BOOST_CHECK(nfoundA > 0.99 * NTest); - // BOOST_CHECK(nfoundAW > 0.99 * NTest); - // BOOST_CHECK(nfoundW > 0.99 * NTest); - // BOOST_CHECK(meanDA < 0.1); - // BOOST_CHECK(meanDAW < 0.1); - // BOOST_CHECK(meanDW < 0.1); - // } - - // // 2 prongs vertices with both of charges set to 0: Line : Line - // { - // std::vector forceQ{0, 0}; - // LOG(info) << "Processing 2-prong Line - Line case"; - // o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter - // ft.setBz(bz); - // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway - // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway - // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway - // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway - // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor - - // std::string treeName2A = "pr2aLL", treeName2AW = "pr2awLL", treeName2W = "pr2wLL"; - // TStopwatch swA, swAW, swW; - // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; - // double meanDA = 0, meanDAW = 0, meanDW = 0; - // swA.Stop(); - // swAW.Stop(); - // swW.Stop(); - // for (int iev = 0; iev < NTest; iev++) { - // forceQ[0] = forceQ[1] = 0; - // auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); - - // ft.setUseAbsDCA(true); - // swA.Start(false); - // int ncA = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swA.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncA) { - // auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); - // meanDA += minD; - // nfoundA++; - // } - - // ft.setUseAbsDCA(true); - // ft.setWeightedFinalPCA(true); - // swAW.Start(false); - // int ncAW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swAW.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncAW) { - // auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); - // meanDAW += minD; - // nfoundAW++; - // } - - // ft.setUseAbsDCA(false); - // ft.setWeightedFinalPCA(false); - // swW.Start(false); - // int ncW = ft.process(vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES - // swW.Stop(); - // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncW) { - // auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); - // meanDW += minD; - // nfoundW++; - // } - // } - // ft.print(); - // meanDA /= nfoundA ? nfoundA : 1; - // meanDAW /= nfoundAW ? nfoundAW : 1; - // meanDW /= nfoundW ? nfoundW : 1; - // LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; - // LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); - // LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); - // LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); - // BOOST_CHECK(nfoundA > 0.99 * NTest); - // BOOST_CHECK(nfoundAW > 0.99 * NTest); - // BOOST_CHECK(nfoundW > 0.99 * NTest); - // BOOST_CHECK(meanDA < 0.1); - // BOOST_CHECK(meanDAW < 0.1); - // BOOST_CHECK(meanDW < 0.1); - // } - - // // 3 prongs vertices - // { - // std::vector forceQ{1, 1, 1}; - - // o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter - // ft.setBz(bz); - // ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway - // ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway - // ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway - // ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway - // ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor - - // std::string treeName3A = "pr3a", treeName3AW = "pr3aw", treeName3W = "pr3w"; - // TStopwatch swA, swAW, swW; - // int nfoundA = 0, nfoundAW = 0, nfoundW = 0; - // double meanDA = 0, meanDAW = 0, meanDW = 0; - // swA.Stop(); - // swAW.Stop(); - // swW.Stop(); - // for (int iev = 0; iev < NTest; iev++) { - // auto genParent = generate(vtxGen, vctracks, bz, genPHS, dch, dchdec, forceQ); - - // ft.setUseAbsDCA(true); - // swA.Start(false); - // int ncA = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES - // swA.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncA) { - // auto minD = checkResults(outStream, treeName3A, ft, vtxGen, genParent, dchdec); - // meanDA += minD; - // nfoundA++; - // } - - // ft.setUseAbsDCA(true); - // ft.setWeightedFinalPCA(true); - // swAW.Start(false); - // int ncAW = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES - // swAW.Stop(); - // LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncAW) { - // auto minD = checkResults(outStream, treeName3AW, ft, vtxGen, genParent, dchdec); - // meanDAW += minD; - // nfoundAW++; - // } - - // ft.setUseAbsDCA(false); - // ft.setWeightedFinalPCA(false); - // swW.Start(false); - // int ncW = ft.process(vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES - // swW.Stop(); - // LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); - // if (ncW) { - // auto minD = checkResults(outStream, treeName3W, ft, vtxGen, genParent, dchdec); - // meanDW += minD; - // nfoundW++; - // } - // } - // ft.print(); - // meanDA /= nfoundA ? nfoundA : 1; - // meanDAW /= nfoundAW ? nfoundAW : 1; - // meanDW /= nfoundW ? nfoundW : 1; - // LOG(info) << "Processed " << NTest << " 3-prong vertices"; - // LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - // << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); - // LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - // << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); - // LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - // << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); - // BOOST_CHECK(nfoundA > 0.99 * NTest); - // BOOST_CHECK(nfoundAW > 0.99 * NTest); - // BOOST_CHECK(nfoundW > 0.99 * NTest); - // BOOST_CHECK(meanDA < 0.1); - // BOOST_CHECK(meanDAW < 0.1); - // BOOST_CHECK(meanDW < 0.1); - // } + // 2 prongs vertices with one of charges set to 0: Helix : Line + { + std::vector forceQ{1, 1}; + LOG(info) << "Processing 2-prong Helix - Line case"; + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::string treeName2A = "pr2aHL", treeName2AW = "pr2awHL", treeName2W = "pr2wHL"; + TStopwatch swA, swAW, swW; + int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + double meanDA = 0, meanDAW = 0, meanDW = 0; + swA.Stop(); + swAW.Stop(); + swW.Stop(); + for (int iev = 0; iev < NTest; iev++) { + forceQ[iev % 2] = 1; + forceQ[1 - iev % 2] = 0; + auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + + ft.setUseAbsDCA(true); + swA.Start(false); + int ncA = device::process(1, 1, ft, vctracks[0], vctracks[1]); + swA.Stop(); + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + if (ncA) { + auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); + meanDA += minD; + nfoundA++; + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + swAW.Start(false); + int ncAW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAW.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncAW) { + auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); + meanDAW += minD; + nfoundAW++; + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + swW.Start(false); + int ncW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swW.Stop(); + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncW) { + auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); + meanDW += minD; + nfoundW++; + } + } + device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundAW : 1; + meanDW /= nfoundW ? nfoundW : 1; + LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + BOOST_CHECK(nfoundA > 0.99 * NTest); + BOOST_CHECK(nfoundAW > 0.99 * NTest); + BOOST_CHECK(nfoundW > 0.99 * NTest); + BOOST_CHECK(meanDA < 0.1); + BOOST_CHECK(meanDAW < 0.1); + BOOST_CHECK(meanDW < 0.1); + } + + // 2 prongs vertices with both of charges set to 0: Line : Line + { + std::vector forceQ{0, 0}; + LOG(info) << "Processing 2-prong Line - Line case"; + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::string treeName2A = "pr2aLL", treeName2AW = "pr2awLL", treeName2W = "pr2wLL"; + TStopwatch swA, swAW, swW; + int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + double meanDA = 0, meanDAW = 0, meanDW = 0; + swA.Stop(); + swAW.Stop(); + swW.Stop(); + for (int iev = 0; iev < NTest; iev++) { + forceQ[0] = forceQ[1] = 0; + auto genParent = generate(vtxGen, vctracks, bz, genPHS, k0, k0dec, forceQ); + + ft.setUseAbsDCA(true); + swA.Start(false); + int ncA = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swA.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + if (ncA) { + auto minD = checkResults(outStream, treeName2A, ft, vtxGen, genParent, k0dec); + meanDA += minD; + nfoundA++; + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + swAW.Start(false); + int ncAW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAW.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncAW) { + auto minD = checkResults(outStream, treeName2AW, ft, vtxGen, genParent, k0dec); + meanDAW += minD; + nfoundAW++; + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + swW.Start(false); + int ncW = device::process(1, 1, ft, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swW.Stop(); + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncW) { + auto minD = checkResults(outStream, treeName2W, ft, vtxGen, genParent, k0dec); + meanDW += minD; + nfoundW++; + } + } + device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundAW : 1; + meanDW /= nfoundW ? nfoundW : 1; + LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + BOOST_CHECK(nfoundA > 0.99 * NTest); + BOOST_CHECK(nfoundAW > 0.99 * NTest); + BOOST_CHECK(nfoundW > 0.99 * NTest); + BOOST_CHECK(meanDA < 0.1); + BOOST_CHECK(meanDAW < 0.1); + BOOST_CHECK(meanDW < 0.1); + } + + // 3 prongs vertices + { + std::vector forceQ{1, 1, 1}; + + o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::string treeName3A = "pr3a", treeName3AW = "pr3aw", treeName3W = "pr3w"; + TStopwatch swA, swAW, swW; + int nfoundA = 0, nfoundAW = 0, nfoundW = 0; + double meanDA = 0, meanDAW = 0, meanDW = 0; + swA.Stop(); + swAW.Stop(); + swW.Stop(); + for (int iev = 0; iev < NTest; iev++) { + auto genParent = generate(vtxGen, vctracks, bz, genPHS, dch, dchdec, forceQ); + + ft.setUseAbsDCA(true); + swA.Start(false); + int ncA = device::process(1, 1, ft, vctracks[0], vctracks[1], vctracks[2]); + swA.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncA << " Chi2: " << (ncA ? ft.getChi2AtPCACandidate(0) : -1); + if (ncA) { + auto minD = checkResults(outStream, treeName3A, ft, vtxGen, genParent, dchdec); + meanDA += minD; + nfoundA++; + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + swAW.Start(false); + int ncAW = device::process(1, 1, ft, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + swAW.Stop(); + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAW << " Chi2: " << (ncAW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncAW) { + auto minD = checkResults(outStream, treeName3AW, ft, vtxGen, genParent, dchdec); + meanDAW += minD; + nfoundAW++; + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + swW.Start(false); + int ncW = device::process(1, 1, ft, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + swW.Stop(); + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncW << " Chi2: " << (ncW ? ft.getChi2AtPCACandidate(0) : -1); + if (ncW) { + auto minD = checkResults(outStream, treeName3W, ft, vtxGen, genParent, dchdec); + meanDW += minD; + nfoundW++; + } + } + device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundAW : 1; + meanDW /= nfoundW ? nfoundW : 1; + LOG(info) << "Processed " << NTest << " 3-prong vertices"; + LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + BOOST_CHECK(nfoundA > 0.99 * NTest); + BOOST_CHECK(nfoundAW > 0.99 * NTest); + BOOST_CHECK(nfoundW > 0.99 * NTest); + BOOST_CHECK(meanDA < 0.1); + BOOST_CHECK(meanDAW < 0.1); + BOOST_CHECK(meanDW < 0.1); + } outStream.Close(); } diff --git a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h index b74fec89d9f37..b063d1f587fe9 100644 --- a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h +++ b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h @@ -50,6 +50,8 @@ struct TrackCovI { } else { #ifndef GPUCA_GPUCODE throw std::runtime_error("invalid track covariance"); +#else + printf("invalid track covariance\n"); #endif } } @@ -107,8 +109,8 @@ class DCAFitterN //========================================================================= ///< return PCA candidate, by default best on is provided (no check for the index validity) - const Vec3D& getPCACandidate(int cand = 0) const { return mPCA[mOrder[cand]]; } - const auto getPCACandidatePos(int cand = 0) const + GPUd() const Vec3D& getPCACandidate(int cand = 0) const { return mPCA[mOrder[cand]]; } + GPUd() const auto getPCACandidatePos(int cand = 0) const { const auto& vd = mPCA[mOrder[cand]]; return o2::gpu::gpustd::array{static_cast(vd[0]), static_cast(vd[1]), static_cast(vd[2])}; @@ -439,7 +441,7 @@ GPUd() bool DCAFitterN::calcPCACoefs() miei[1][0] = taux.s * tcov.sxx; miei[1][1] = taux.c * tcov.syy; miei[1][2] = taux.c * tcov.syz; - // miei[2][0] = 0; + miei[2][0] = 0; miei[2][1] = tcov.syz; miei[2][2] = tcov.szz; mTrCFVT[mCurHyp][i] = mWeightInv * miei; @@ -902,7 +904,11 @@ GPUd() bool DCAFitterN::minimizeChi2() // do Newton-Rapson iteration with corrections = - dchi2/d{x0..xN} * [ d^2chi2/d{x0..xN}^2 ]^-1 if (!mD2Chi2Dx2.Invert()) { +#ifndef GPUCA_GPUCODE_DEVICE LOG(error) << "InversionFailed"; +#else + printf("InversionFailed\n"); +#endif return false; } VecND dx = mD2Chi2Dx2 * mDChi2Dx; @@ -955,7 +961,11 @@ GPUd() bool DCAFitterN::minimizeChi2NoErr() // do Newton-Rapson iteration with corrections = - dchi2/d{x0..xN} * [ d^2chi2/d{x0..xN}^2 ]^-1 if (!mD2Chi2Dx2.Invert()) { +#ifndef GPUCA_GPUCODE_DEVICE LOG(error) << "InversionFailed"; +#else + printf("InversionFailed\n"); +#endif return false; } VecND dx = mD2Chi2Dx2 * mDChi2Dx; @@ -1022,9 +1032,9 @@ GPUd() void DCAFitterN::print() const } else { printf("%d-prong vertex fitter in weighted distance minimization mode\n", N); } - printf("Bz: %f MaxIter: %d MaxChi2: %f\n", mBz, mMaxIter, mMaxChi2); - printf("Stopping condition: Max.param change < %f Rel.Chi2 change > %f\n", mMinParamChange, mMinRelChi2Change); - printf("Discard candidates for : Rvtx > %f DZ between tracks > %f\n", getMaxR(), mMaxDZIni); + printf("Bz: %1.f MaxIter: %3.d MaxChi2: %2.3f\n", mBz, mMaxIter, mMaxChi2); + printf("Stopping condition: Max.param change < %2.3f Rel.Chi2 change > %2.3f\n", mMinParamChange, mMinRelChi2Change); + printf("Discard candidates for : Rvtx > %2.3f DZ between tracks > %2.3f\n", getMaxR(), mMaxDZIni); #endif } @@ -1122,24 +1132,21 @@ GPUdi() bool DCAFitterN::propagateToX(o2::track::TrackParCov& t, flo using DCAFitter2 = DCAFitterN<2, o2::track::TrackParCov>; using DCAFitter3 = DCAFitterN<3, o2::track::TrackParCov>; -#ifdef GPUCA_GPUCODE -namespace gpu::kernel -{ -GPUg() void printKernel(o2::vertexing::DCAFitterN<2>* ft); -GPUg() void processKernel(o2::vertexing::DCAFitterN<2>* ft, o2::track::TrackParCov* t1, o2::track::TrackParCov* t2, int* res); -} // namespace gpu::kernel -#endif + namespace device { -void print(o2::vertexing::DCAFitterN<2>*, - const int nBlocks = 1, - const int nThreads = 1); -int process(o2::vertexing::DCAFitterN<2>*, - o2::track::TrackParCov&, - o2::track::TrackParCov&, - const int nBlocks = 1, - const int nThreads = 1); +template +void print(const int nBlocks, + const int nThreads, + Fitter& ft); + +template +int process(const int nBlocks, + const int nThreads, + Fitter&, + Tr&... args); } // namespace device + } // namespace vertexing } // namespace o2 #endif // _ALICEO2_DCA_FITTERN_ diff --git a/Common/DCAFitter/include/DCAFitter/HelixHelper.h b/Common/DCAFitter/include/DCAFitter/HelixHelper.h index ee6d6838b3ed9..62ef0bbebdac7 100644 --- a/Common/DCAFitter/include/DCAFitter/HelixHelper.h +++ b/Common/DCAFitter/include/DCAFitter/HelixHelper.h @@ -30,15 +30,15 @@ namespace track struct TrackAuxPar : public o2::math_utils::CircleXYf_t { float c, s, cc, ss, cs; // cos ans sin of track alpha and their products - TrackAuxPar() = default; + GPUdDefault() TrackAuxPar() = default; template - TrackAuxPar(const T& trc, float bz) + GPUd() TrackAuxPar(const T& trc, float bz) { set(trc, bz); } - float cosDif(const TrackAuxPar& t) const { return c * t.c + s * t.s; } // cos(alpha_this - alha_t) - float sinDif(const TrackAuxPar& t) const { return s * t.c - c * t.s; } // sin(alpha_this - alha_t) + GPUd() float cosDif(const TrackAuxPar& t) const { return c * t.c + s * t.s; } // cos(alpha_this - alha_t) + GPUd() float sinDif(const TrackAuxPar& t) const { return s * t.c - c * t.s; } // sin(alpha_this - alha_t) template GPUd() void set(const T& trc, float bz) @@ -289,7 +289,7 @@ struct CrossInfo { GPUdDefault() CrossInfo() = default; template - CrossInfo(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) + GPUd() CrossInfo(const TrackAuxPar& trax0, const T& tr0, const TrackAuxPar& trax1, const T& tr1, float maxDistXY = MaxDistXYDef, bool isCollinear = false) { set(trax0, tr0, trax1, tr1, maxDistXY, isCollinear); } diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index 1372b2a861409..ef76c490ddfbd 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -15,10 +15,6 @@ /// Only parts strictly requiring STD library have been changed. /// Also some utilities to have basic checks and printouts working on GPUs have been rewritten. /// -/// Notably only templated implementation of -/// row_offsets_utils::make and row_offsets_utils::do_make -/// has been reworked to support gpustd::array as backend. -/// /// Other than that, the author is not taking any credit on the methodologies implemented /// which have been taken straight from root source code /// diff --git a/DataFormats/Reconstruction/src/TrackParametrization.cxx b/DataFormats/Reconstruction/src/TrackParametrization.cxx index 3f60455bc45f8..4b68ea425bfbd 100644 --- a/DataFormats/Reconstruction/src/TrackParametrization.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrization.cxx @@ -575,7 +575,7 @@ template std::string TrackParametrization::asString() const { // print parameters as string - return fmt::format("X:{:+.4e} Alp:{:+.3e} Par: {:+.4e} {:+.4e} {:+.4e} {:+.4e} {:+.4e} |Q|:{:d} {:s}", + return fmt::format("X:{:+.4e} Alp:{:+.3e} Par: {:+.4e} {:+.4e} {:+.4e} {:+.4e} {:+.4e} |Q|:{:d} {:s}\n", getX(), getAlpha(), getY(), getZ(), getSnp(), getTgl(), getQ2Pt(), getAbsCharge(), getPID().getName()); } @@ -592,7 +592,7 @@ std::string TrackParametrization::asStringHexadecimal() float _Q2Pt = getQ2Pt(); float _AbsCharge = getAbsCharge(); // print parameters as string - return fmt::format("X:{:x} Alp:{:x} Par: {:x} {:x} {:x} {:x} {:x} |Q|:{:x} {:s}", + return fmt::format("X:{:x} Alp:{:x} Par: {:x} {:x} {:x} {:x} {:x} |Q|:{:x} {:s}\n", reinterpret_cast(_X), reinterpret_cast(_Alpha), reinterpret_cast(_Y), @@ -613,7 +613,7 @@ GPUd() void TrackParametrization::printParam() const #ifndef GPUCA_ALIGPUCODE printf("%s\n", asString().c_str()); #elif !defined(GPUCA_GPUCODE_DEVICE) || (!defined(__OPENCL__) && defined(GPUCA_GPU_DEBUG_PRINT)) - printf("X:%+.4e Alp:%+.3e Par: %+.4e %+.4e %+.4e %+.4e %+.4e |Q|:%d %s", + printf("X:%+.4e Alp:%+.3e Par: %+.4e %+.4e %+.4e %+.4e %+.4e |Q|:%d %s\n", getX(), getAlpha(), getY(), getZ(), getSnp(), getTgl(), getQ2Pt(), getAbsCharge(), getPID().getName()); #endif } @@ -626,7 +626,7 @@ GPUd() void TrackParametrization::printParamHexadecimal() #ifndef GPUCA_ALIGPUCODE printf("%s\n", asStringHexadecimal().c_str()); #elif !defined(GPUCA_GPUCODE_DEVICE) || (!defined(__OPENCL__) && defined(GPUCA_GPU_DEBUG_PRINT)) - printf("X:%x Alp:%x Par: %x %x %x %x %x |Q|:%x %s", + printf("X:%x Alp:%x Par: %x %x %x %x %x |Q|:%x %s\n", gpu::CAMath::Float2UIntReint(getX()), gpu::CAMath::Float2UIntReint(getAlpha()), gpu::CAMath::Float2UIntReint(getY()), diff --git a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx index 84b1da5f94a4f..da15aefcf958f 100644 --- a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx @@ -1217,7 +1217,7 @@ GPUd() void TrackParametrizationWithError::print() const #elif !defined(GPUCA_GPUCODE_DEVICE) || (!defined(__OPENCL__) && defined(GPUCA_GPU_DEBUG_PRINT)) TrackParametrization::printParam(); printf( - "\nCov: [%+.3e] [%+.3e %+.3e] [%+.3e %+.3e %+.3e] [%+.3e %+.3e %+.3e %+.3e] [%+.3e %+.3e %+.3e %+.3e %+.3e]", + " Cov: [%+.3e] [%+.3e %+.3e] [%+.3e %+.3e %+.3e] [%+.3e %+.3e %+.3e %+.3e] [%+.3e %+.3e %+.3e %+.3e %+.3e]\n", mC[kSigY2], mC[kSigZY], mC[kSigZ2], mC[kSigSnpY], mC[kSigSnpZ], mC[kSigSnp2], mC[kSigTglY], mC[kSigTglZ], mC[kSigTglSnp], mC[kSigTgl2], mC[kSigQ2PtY], mC[kSigQ2PtZ], mC[kSigQ2PtSnp], mC[kSigQ2PtTgl], mC[kSigQ2Pt2]); @@ -1234,7 +1234,7 @@ GPUd() void TrackParametrizationWithError::printHexadecimal() #elif !defined(GPUCA_GPUCODE_DEVICE) || (!defined(__OPENCL__) && defined(GPUCA_GPU_DEBUG_PRINT)) TrackParametrization::printParamHexadecimal(); printf( - "\nCov: [%x] [%x %x] [%x %x %x] [%x %x %x %x] [%x %x %x %x %x]", + " Cov: [%x] [%x %x] [%x %x %x] [%x %x %x %x] [%x %x %x %x %x]\n", gpu::CAMath::Float2UIntReint(mC[kSigY2]), gpu::CAMath::Float2UIntReint(mC[kSigZY]), gpu::CAMath::Float2UIntReint(mC[kSigZ2]), gpu::CAMath::Float2UIntReint(mC[kSigSnpY]), gpu::CAMath::Float2UIntReint(mC[kSigSnpZ]), gpu::CAMath::Float2UIntReint(mC[kSigSnp2]), From c173371e34fd40e3496c3ae5c8120e409f577891 Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 16 Sep 2024 10:42:00 +0200 Subject: [PATCH 0254/2205] o2-sim: No longer write FairRoot runtime database - we are not using this file - file writing had crashes, which we can simply avoid --- macro/o2sim.C | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/macro/o2sim.C b/macro/o2sim.C index f610be730eeb7..44db30293bb73 100644 --- a/macro/o2sim.C +++ b/macro/o2sim.C @@ -160,22 +160,6 @@ FairRunSim* o2sim_init(bool asservice, bool evalmat = false) // run init run->Init(); - // runtime database - bool kParameterMerged = true; - auto rtdb = run->GetRuntimeDb(); - auto parOut = new FairParRootFileIo(kParameterMerged); - - std::stringstream s2; - s2 << confref.getOutPrefix(); - if (asservice) { - s2 << "_" << pid; - } - s2 << "_par.root"; - std::string parfilename = s2.str(); - parOut->open(parfilename.c_str()); - rtdb->setOutput(parOut); - rtdb->saveOutput(); - rtdb->print(); // add ALICE particles to TDatabasePDG singleton o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance()); From c981ee0c091fb1ad6e85e832708cc0f7cd84df77 Mon Sep 17 00:00:00 2001 From: ehellbar Date: Tue, 17 Sep 2024 07:55:35 +0200 Subject: [PATCH 0255/2205] aggregator-workflow.sh: adding more protection against empty ccdb-populators (#13521) --- prodtests/full-system-test/aggregator-workflow.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index 6c4efc0e1e24e..7640125676ce5 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -401,9 +401,9 @@ if [[ "${GEN_TOPO_VERBOSE:-}" == "1" ]]; then fi fi -if [[ $CCDB_POPULATOR_UPLOAD_PATH != "none" ]] && [[ ! -z $WORKFLOW ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path $CCDB_POPULATOR_UPLOAD_PATH --environment \"DPL_DONT_DROP_OLD_TIMESLICE=1\" --sspec-min $CCDBPRO_SUBSPEC_MIN --sspec-max $CCDBPRO_SUBSPEC_MAX"; fi +if [[ $CCDB_POPULATOR_UPLOAD_PATH != "none" ]] && [[ ! -z $WORKFLOW ]] && [[ $WORKFLOW != "echo '{}' | " ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path $CCDB_POPULATOR_UPLOAD_PATH --environment \"DPL_DONT_DROP_OLD_TIMESLICE=1\" --sspec-min $CCDBPRO_SUBSPEC_MIN --sspec-max $CCDBPRO_SUBSPEC_MAX"; fi -if [[ $CCDB_DCS_POPULATOR_UPLOAD_PATH != "none" ]] && [[ ! -z $WORKFLOW ]] && [[ $NEED_DCS_CCDB_POPULATOR != 0 ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path $CCDB_DCS_POPULATOR_UPLOAD_PATH --environment \"DPL_DONT_DROP_OLD_TIMESLICE=1\" --sspec-min $CCDBDCS_SUBSPEC_MIN --sspec-max $CCDBDCS_SUBSPEC_MAX --name-extention dcs"; fi +if [[ $CCDB_DCS_POPULATOR_UPLOAD_PATH != "none" ]] && [[ ! -z $WORKFLOW ]] && [[ $WORKFLOW != "echo '{}' | " ]] && [[ $NEED_DCS_CCDB_POPULATOR != 0 ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path $CCDB_DCS_POPULATOR_UPLOAD_PATH --environment \"DPL_DONT_DROP_OLD_TIMESLICE=1\" --sspec-min $CCDBDCS_SUBSPEC_MIN --sspec-max $CCDBDCS_SUBSPEC_MAX --name-extention dcs"; fi if ! workflow_has_parameter CALIB_LOCAL_INTEGRATED_AGGREGATOR; then WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" From 397c97f41981d558441afc166d6e02f99029c16c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 17 Sep 2024 14:13:38 +0200 Subject: [PATCH 0256/2205] DPL: Silence another oldestPossible warning after STOP (#13481) * DPL: Silence another oldestPossible warning after STOP * Update Framework/Core/src/CommonServices.cxx --------- Co-authored-by: Giulio Eulisse <10544+ktf@users.noreply.github.com> --- Framework/Core/src/CommonServices.cxx | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index 0e84333afe115..13b02c74839b9 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -590,7 +590,12 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() decongestion->nextTimeslice = std::max(decongestion->nextTimeslice, (int64_t)oldestPossibleOutput.timeslice.value); O2_SIGNPOST_EVENT_EMIT(data_processor_context, cid, "oldest_possible_timeslice", "Next timeslice %" PRIi64, decongestion->nextTimeslice); if (oldNextTimeslice != decongestion->nextTimeslice) { - O2_SIGNPOST_EVENT_EMIT_ERROR(data_processor_context, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + auto& state = ctx.services().get(); + if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { + O2_SIGNPOST_EVENT_EMIT_WARN(data_processor_context, cid, "oldest_possible_timeslice", "Stop transition requested. Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } else { + O2_SIGNPOST_EVENT_EMIT_ERROR(data_processor_context, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } timesliceIndex.rescan(); } } @@ -644,8 +649,9 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() oldestPossibleOutput.timeslice.value, decongestion.lastTimeslice); return; } - auto &queue = services.get(); - auto& spec = services.get(); + auto& queue = services.get(); + const auto& spec = services.get(); + const auto& state = services.get(); auto *device = services.get().device(); /// We use the oldest possible timeslice to debounce, so that only the latest one /// at the end of one iteration is sent. @@ -683,16 +689,20 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() TimesliceId{oldestPossibleTimeslice}, -1); if (decongestion.orderedCompletionPolicyActive) { AsyncQueueHelpers::post( - queue, decongestion.oldestPossibleTimesliceTask, [ref = services, oldestPossibleOutput, &decongestion, &proxy, &spec, device, ×liceIndex](size_t id) { + queue, decongestion.oldestPossibleTimesliceTask, [ref = services, oldestPossibleOutput, &decongestion, &proxy, &spec, &state, device, ×liceIndex](size_t id) { O2_SIGNPOST_ID_GENERATE(cid, async_queue); int64_t oldNextTimeslice = decongestion.nextTimeslice; decongestion.nextTimeslice = std::max(decongestion.nextTimeslice, (int64_t)oldestPossibleOutput.timeslice.value); if (oldNextTimeslice != decongestion.nextTimeslice) { - O2_SIGNPOST_EVENT_EMIT_ERROR(async_queue, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { + O2_SIGNPOST_EVENT_EMIT_WARN(async_queue, cid, "oldest_possible_timeslice", "Stop transition requested. Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } else { + O2_SIGNPOST_EVENT_EMIT_ERROR(async_queue, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } timesliceIndex.rescan(); } - }, - TimesliceId{oldestPossibleOutput.timeslice.value}, -1); + }, + TimesliceId{oldestPossibleOutput.timeslice.value}, -1); } }, .kind = ServiceKind::Serial}; } From c3799d429ead0587a8a4c4058f3b8153e846f1e9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 17 Sep 2024 14:31:44 +0200 Subject: [PATCH 0257/2205] dpl-workflow: more protection in aggregator-workflow.sh --- prodtests/full-system-test/aggregator-workflow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index 7640125676ce5..aedd9f7b3bc2f 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -409,5 +409,5 @@ if ! workflow_has_parameter CALIB_LOCAL_INTEGRATED_AGGREGATOR; then WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" [[ $WORKFLOWMODE != "print" ]] && WORKFLOW+=" --${WORKFLOWMODE} ${WORKFLOWMODE_FILE:-}" [[ $WORKFLOWMODE == "print" || "${PRINT_WORKFLOW:-}" == "1" ]] && echo "#Aggregator Workflow command:\n\n${WORKFLOW}\n" | sed -e "s/\\\\n/\n/g" -e"s/| */| \\\\\n/g" | eval cat $( [[ $WORKFLOWMODE == "dds" ]] && echo '1>&2') - if [[ $WORKFLOWMODE != "print" ]]; then eval $WORKFLOW; else true; fi + if [[ $WORKFLOWMODE != "print" ]] && [[ ! -z $WORKFLOW ]] && [[ $WORKFLOW != "echo '{}' | " ]]; then eval $WORKFLOW; else true; fi fi From 828de21a37d526b29d24742f25dba05e1e8e305d Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 16 Sep 2024 17:28:34 +0200 Subject: [PATCH 0258/2205] update of inputCard --- scripts/datamodel-doc/inputCard.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/datamodel-doc/inputCard.xml b/scripts/datamodel-doc/inputCard.xml index 5282d3c589881..5d0133cab6de4 100644 --- a/scripts/datamodel-doc/inputCard.xml +++ b/scripts/datamodel-doc/inputCard.xml @@ -109,7 +109,7 @@ o2::aod::FV0As, o2::aod::FT0s, o2::aod::FDDs, so2::aod::HMPIDs, o2::aod::Calos, o2::aod::CaloTriggers, o2::aod::Zdcs, o2::aod::FV0Cs, o2::aod::HMPIDs, o2::aod::CPVClusters, o2::aod::HMPID - o2::aod::V0s, o2::aod::TransientV0s, o2::aod::StoredV0s, o2::aod::TrackedV0s, o2::aod::Cascades, o2::aod::TransientCascades, o2::aod::StoredCascades, o2::aod::TrackedCascades, o2::aod::Decay3Bodys, o2::aod::Tracked3Bodys + o2::aod::V0s, o2::aod::TransientV0s, o2::aod::StoredV0s, o2::aod::TrackedV0s, o2::aod::Cascades, o2::aod::TransientCascades, o2::aod::StoredCascades, o2::aod::TrackedCascades, o2::aod::TrackedV0s, o2::aod::Decay3Bodys, o2::aod::Tracked3Bodys o2::aod::Run3MatchedExclusive, o2::aod::Run3MatchedSparse, o2::aod::MatchedBCCollisionsExclusive, o2::aod::MatchedBCCollisionsSparse, o2::aod::Run3MatchedToBCExclusive, o2::aod::Run3MatchedToBCSparse, o2::aod::MatchedBCCollisionsExclusiveMulti, o2::aod::MatchedBCCollisionsSparseMulti @@ -146,7 +146,7 @@ - CMakeLists.txt, PID/CMakeLists.txt + CMakeLists.txt, PID/CMakeLists.txt, Converters/CMakeLists.txt @@ -159,7 +159,7 @@ - *.cxx, PID/*.cxx + *.cxx, PID/*.cxx, Converters/*.cxx @@ -175,7 +175,7 @@ - DataModel/*.h, FemtoUniverse/DataModel/*.h, FemtoWorld/DataModel/*.h, JCorran/DataModel/*.h, TwoParticleCorrelations/DataModel/*.h + DataModel/*.h, Femto3D/DataModel/*.h, FemtoUniverse/DataModel/*.h, FemtoWorld/DataModel/*.h, JCorran/DataModel/*.h, TwoParticleCorrelations/DataModel/*.h @@ -188,7 +188,7 @@ - TableProducer/CMakeLists.txt, FemtoUniverse/TableProducer/CMakeLists.txt, FemtoWorld/TableProducer/CMakeLists.txt, JCorran/TableProducer/CMakeLists.txt, TwoParticleCorrelations/TableProducer/CMakeLists.txt + EbyEFluctuations/Tasks/CMakeLists.txt, Femto3D/TableProducer/CMakeLists.txt, FemtoDream/TableProducer/CMakeLists.txt, FemtoUniverse/TableProducer/CMakeLists.txt, FemtoWorld/TableProducer/CMakeLists.txt, JCorran/TableProducer/CMakeLists.txt, TableProducer/CMakeLists.txt, TwoParticleCorrelations/TableProducer/CMakeLists.txt @@ -201,7 +201,7 @@ - TableProducer/*.cxx, FemtoUniverse/TableProducer/*.cxx, FemtoWorld/TableProducer/*.cxx, JCorran/TableProducer/*.cxx, TwoParticleCorrelations/TableProducer/*.cxx + EbyEFluctuations/Tasks/*.cxx, Femto3D/TableProducer/*.cxx, FemtoDream/TableProducer/*.cxx, FemtoUniverse/TableProducer/*.cxx, FemtoWorld/TableProducer/*.cxx, JCorran/TableProducer/*.cxx, TableProducer/*.cxx, TwoParticleCorrelations/TableProducer/*.cxx @@ -259,7 +259,7 @@ - PhotonMeson/DataModel/*.h + PhotonMeson/DataModel/*.h, Dilepton/DataModel/*.h @@ -272,7 +272,7 @@ - PhotonMeson/TableProducer/CMakeLists.txt + PhotonMeson/TableProducer/CMakeLists.txt, Dilepton/TableProducer/CMakeLists.txt @@ -285,7 +285,7 @@ - PhotonMeson/TableProducer/*.cxx + PhotonMeson/TableProducer/*.cxx, Dilepton/TableProducer/*.cxx @@ -301,7 +301,7 @@ - DataModel/*.h, TableProducer/*.cxx + TableProducer/*.cxx, D2H/DataModel/*.h, DataModel/*.h, HFC/DataModel/*.h @@ -314,7 +314,7 @@ - TableProducer/CMakeLists.txt + TableProducer/CMakeLists.txt, D2H/TableProducer/CMakeLists.txt, HFC/TableProducer/CMakeLists.txt, HFL/TableProducer/CMakeLists.txt @@ -327,7 +327,7 @@ - TableProducer/*.cxx + TableProducer/*.cxx, D2H/TableProducer/*.cxx, HFC/TableProducer/*.cxx, HFL/TableProducer/*.cxx @@ -397,7 +397,7 @@ - TableProducer/CMakeLists.txt + TableProducer/*/CMakeLists.txt @@ -410,7 +410,7 @@ - TableProducer/*.cxx + TableProducer/*/*.cxx From 2d60fa212503f36c633ffe4b3dcb15ebf5902f9b Mon Sep 17 00:00:00 2001 From: Nicolas Strangmann <77485327+nstrangm@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:54:21 +0200 Subject: [PATCH 0259/2205] [EMCal-688] ClusterLabel: Fix bug in label sorting condition (#13523) Co-authored-by: Nicolas Strangmann --- DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx b/DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx index 2d3abd09d0b04..9ad1f9be5459f 100644 --- a/DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx +++ b/DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx @@ -71,5 +71,5 @@ void ClusterLabel::orderLabels() { // Sort the pairs based on values in descending order std::sort(mClusterLabels.begin(), mClusterLabels.end(), - [](const labelWithE& a, const labelWithE& b) { return a.energyFraction >= b.energyFraction; }); + [](const labelWithE& a, const labelWithE& b) { return a.energyFraction > b.energyFraction; }); } From 3066c2550dc3b4ffbe25737a010fb34886a9a963 Mon Sep 17 00:00:00 2001 From: Artur Furs <9881239+afurs@users.noreply.github.com> Date: Wed, 18 Sep 2024 08:06:29 +0300 Subject: [PATCH 0260/2205] AFIT-101: new extended trg word(min bias), update for FT0 time offset collibration (#13514) * FIT: new extended trg word(min bias), update for FT0 time offset functionality(for min bias usage) * adding Detectectors common data format to FIT det data format * turning off common digits for FT0 and FV0 for checking * turning off common digits for FDD * removing commented lines --------- Co-authored-by: flp --- DataFormats/Detectors/FIT/FDD/CMakeLists.txt | 2 + DataFormats/Detectors/FIT/FT0/CMakeLists.txt | 1 + .../FT0/include/DataFormatsFT0/ChannelData.h | 4 +- .../include/DataFormatsFT0/DigitFilterParam.h | 15 +- .../FIT/FT0/src/DataFormatsFT0LinkDef.h | 1 + DataFormats/Detectors/FIT/FV0/CMakeLists.txt | 4 +- .../Detectors/FIT/common/CMakeLists.txt | 4 +- .../include/DataFormatsFIT/ChannelData.h | 70 ++++++++ .../FIT/common/include/DataFormatsFIT/Digit.h | 79 +++++++++ .../common/include/DataFormatsFIT/Triggers.h | 21 ++- .../FIT/common/src/DataFormatsFITLinkDef.h | 13 ++ Detectors/FIT/FT0/CMakeLists.txt | 2 +- Detectors/FIT/FT0/calibration/CMakeLists.txt | 41 +---- .../calibration/files/dispatcherCalib.json | 21 --- .../FT0Calibration/FT0CalibCollector.h | 95 ---------- .../FT0Calibration/FT0CalibTimeSlewing.h | 78 --------- .../FT0TimeOffsetSlotContainer.h | 4 + .../FT0Calibration/GlobalOffsetsContainer.h | 69 -------- .../FT0Calibration/LHCClockCalibrator.h | 89 ---------- .../FT0Calibration/RecoCalibInfoWorkflow.h | 61 ------- .../FIT/FT0/calibration/macros/CMakeLists.txt | 15 -- .../makeChannelOffsetCalibObjectInCCDB.C | 49 ------ .../FT0/calibration/src/FT0CalibCollector.cxx | 164 ------------------ .../calibration/src/FT0CalibTimeSlewing.cxx | 122 ------------- .../calibration/src/FT0CalibrationLinkDef.h | 7 - .../src/GlobalOffsetsContainer.cxx | 91 ---------- .../calibration/src/RecoCalibInfoWorkflow.cxx | 110 ------------ .../FT0CalibCollectorWriterSpec.h | 132 -------------- .../FT0CalibSlewingCollectorSpec.h | 137 --------------- .../FT0SlewingCalibrationWorkflow.cxx | 28 --- .../GlobalOffsetsCalibrationSpec.h | 59 ------- .../GlobalOffsetsCalibrationWorkflow.cxx | 28 --- .../GlobalOffsetsCollectWorkflow.cxx | 64 ------- .../testWorkflow/LHCClockCalibratorSpec.h | 58 ------- .../testWorkflow/RecoCalibInfoWorkflow.cxx | 116 ------------- .../testWorkflow/RecoQAInfoWorkflow.cxx | 116 ------------- .../testWorkflow/calib-global-offsets.cxx | 43 ----- .../ft0-collect-calib-workflow.cxx | 35 ---- .../testWorkflow/lhc-clockphase-workflow.cxx | 32 ---- .../calibration/testWorkflow/slew_upload.cxx | 116 ------------- .../FT0TimeOffsetCalibration-Workflow.cxx | 0 .../FT0TimeSpectraProcessor-Workflow.cxx | 7 +- cmake/O2RootMacroExclusionList.cmake | 1 - 43 files changed, 211 insertions(+), 1993 deletions(-) create mode 100644 DataFormats/Detectors/FIT/common/include/DataFormatsFIT/ChannelData.h create mode 100644 DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Digit.h delete mode 100644 Detectors/FIT/FT0/calibration/files/dispatcherCalib.json delete mode 100644 Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibCollector.h delete mode 100644 Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibTimeSlewing.h delete mode 100644 Detectors/FIT/FT0/calibration/include/FT0Calibration/GlobalOffsetsContainer.h delete mode 100644 Detectors/FIT/FT0/calibration/include/FT0Calibration/LHCClockCalibrator.h delete mode 100644 Detectors/FIT/FT0/calibration/include/FT0Calibration/RecoCalibInfoWorkflow.h delete mode 100644 Detectors/FIT/FT0/calibration/macros/CMakeLists.txt delete mode 100644 Detectors/FIT/FT0/calibration/macros/makeChannelOffsetCalibObjectInCCDB.C delete mode 100644 Detectors/FIT/FT0/calibration/src/FT0CalibCollector.cxx delete mode 100644 Detectors/FIT/FT0/calibration/src/FT0CalibTimeSlewing.cxx delete mode 100644 Detectors/FIT/FT0/calibration/src/GlobalOffsetsContainer.cxx delete mode 100644 Detectors/FIT/FT0/calibration/src/RecoCalibInfoWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibCollectorWriterSpec.h delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibSlewingCollectorSpec.h delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/FT0SlewingCalibrationWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationSpec.h delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCollectWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/LHCClockCalibratorSpec.h delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/RecoCalibInfoWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/RecoQAInfoWorkflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/calib-global-offsets.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/ft0-collect-calib-workflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/lhc-clockphase-workflow.cxx delete mode 100644 Detectors/FIT/FT0/calibration/testWorkflow/slew_upload.cxx rename Detectors/FIT/FT0/calibration/{testWorkflow => workflow}/FT0TimeOffsetCalibration-Workflow.cxx (100%) rename Detectors/FIT/FT0/calibration/{testWorkflow => workflow}/FT0TimeSpectraProcessor-Workflow.cxx (96%) diff --git a/DataFormats/Detectors/FIT/FDD/CMakeLists.txt b/DataFormats/Detectors/FIT/FDD/CMakeLists.txt index b8f002591c6f3..6cf2deb3f988e 100644 --- a/DataFormats/Detectors/FIT/FDD/CMakeLists.txt +++ b/DataFormats/Detectors/FIT/FDD/CMakeLists.txt @@ -17,6 +17,7 @@ o2_add_library(DataFormatsFDD O2::DataFormatsFIT O2::SimulationDataFormat O2::CommonDataFormat + O2::DetectorsCommonDataFormats ) o2_target_root_dictionary(DataFormatsFDD @@ -28,3 +29,4 @@ o2_target_root_dictionary(DataFormatsFDD include/DataFormatsFDD/RawEventData.h include/DataFormatsFDD/LookUpTable.h include/DataFormatsFDD/CTF.h) + diff --git a/DataFormats/Detectors/FIT/FT0/CMakeLists.txt b/DataFormats/Detectors/FIT/FT0/CMakeLists.txt index d7d6615453661..e5331b7b739b2 100644 --- a/DataFormats/Detectors/FIT/FT0/CMakeLists.txt +++ b/DataFormats/Detectors/FIT/FT0/CMakeLists.txt @@ -26,6 +26,7 @@ o2_add_library(DataFormatsFT0 O2::CommonDataFormat O2::Headers O2::CCDB + O2::DetectorsCommonDataFormats ) o2_target_root_dictionary(DataFormatsFT0 diff --git a/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/ChannelData.h b/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/ChannelData.h index 074caf78f66b3..9b3d6ec805604 100644 --- a/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/ChannelData.h +++ b/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/ChannelData.h @@ -13,8 +13,8 @@ /// \brief Class to describe fired and stored channels for the BC and to refer to channel data /// \author Alla.Maevskaya@cern.ch -#ifndef _FT0_CHANNELDATA_H_ -#define _FT0_CHANNELDATA_H_ +#ifndef O2_FT0_CHANNELDATA_H_ +#define O2_FT0_CHANNELDATA_H_ #include #include diff --git a/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/DigitFilterParam.h b/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/DigitFilterParam.h index 11ff50dfeb86b..a00abc013c27d 100644 --- a/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/DigitFilterParam.h +++ b/DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/DigitFilterParam.h @@ -27,9 +27,9 @@ struct DigitFilterParam : o2::conf::ConfigurableParamHelper { uint8_t mPMbitsGood = (1 << ChannelData::EEventDataBit::kIsCFDinADCgate) | (1 << ChannelData::EEventDataBit::kIsEventInTVDC); uint8_t mPMbitsBad = (1 << ChannelData::EEventDataBit::kIsDoubleEvent) | (1 << ChannelData::EEventDataBit::kIsTimeInfoNOTvalid) | (1 << ChannelData::EEventDataBit::kIsTimeInfoLate) | (1 << ChannelData::EEventDataBit::kIsAmpHigh) | (1 << ChannelData::EEventDataBit::kIsTimeInfoLost); uint8_t mPMbitsToCheck = mPMbitsGood | mPMbitsBad; - uint8_t mTrgBitsGood = (1 << Triggers::bitVertex) | (1 << Triggers::bitDataIsValid); - uint8_t mTrgBitsBad = (1 << Triggers::bitOutputsAreBlocked); - uint8_t mTrgBitsToCheck = mTrgBitsGood | mTrgBitsBad; + uint64_t mTrgBitsGood = Triggers::word(Triggers::bitVertex, Triggers::bitDataIsValid); + uint64_t mTrgBitsBad = Triggers::word(Triggers::bitOutputsAreBlocked); + uint64_t mTrgBitsToCheck = mTrgBitsGood | mTrgBitsBad; O2ParamDef(DigitFilterParam, "FT0DigitFilterParam"); }; @@ -41,12 +41,13 @@ struct ChannelFilterParam : o2::conf::ConfigurableParamHelper, std::vector < double>> + ; #pragma link C++ class o2::ft0::SlewingCoef + ; + #endif diff --git a/DataFormats/Detectors/FIT/FV0/CMakeLists.txt b/DataFormats/Detectors/FIT/FV0/CMakeLists.txt index bc21c382ff446..35bc653a8234e 100644 --- a/DataFormats/Detectors/FIT/FV0/CMakeLists.txt +++ b/DataFormats/Detectors/FIT/FV0/CMakeLists.txt @@ -22,6 +22,7 @@ o2_add_library(DataFormatsFV0 O2::SimulationDataFormat O2::CommonDataFormat Microsoft.GSL::GSL + O2::DetectorsCommonDataFormats ) o2_target_root_dictionary(DataFormatsFV0 @@ -34,5 +35,4 @@ o2_target_root_dictionary(DataFormatsFV0 include/DataFormatsFV0/RecPoints.h include/DataFormatsFV0/RawEventData.h include/DataFormatsFV0/LookUpTable.h - include/DataFormatsFV0/CTF.h -) + include/DataFormatsFV0/CTF.h) diff --git a/DataFormats/Detectors/FIT/common/CMakeLists.txt b/DataFormats/Detectors/FIT/common/CMakeLists.txt index 85fe4c76d2faa..fc8d975a34023 100644 --- a/DataFormats/Detectors/FIT/common/CMakeLists.txt +++ b/DataFormats/Detectors/FIT/common/CMakeLists.txt @@ -20,4 +20,6 @@ o2_add_library(DataFormatsFIT o2_target_root_dictionary(DataFormatsFIT HEADERS include/DataFormatsFIT/DCSDPValues.h include/DataFormatsFIT/LookUpTable.h - include/DataFormatsFIT/Triggers.h) + include/DataFormatsFIT/Triggers.h + include/DataFormatsFIT/ChannelData.h + include/DataFormatsFIT/Digit.h) diff --git a/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/ChannelData.h b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/ChannelData.h new file mode 100644 index 0000000000000..452307d05f200 --- /dev/null +++ b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/ChannelData.h @@ -0,0 +1,70 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ChannelData.h +/// \brief Class represents enity with info per channel in given event +/// \author Artur Furs afurs@cern.ch + +#ifndef _FT0_CHANNELDATA_H_ +#define _FT0_CHANNELDATA_H_ + +#include +#include +#include +#include "DetectorsCommonDataFormats/DetID.h" + +namespace o2 +{ +namespace fit +{ + +template +struct ChannelData { + static constexpr o2::detectors::DetID sDetID = o2::detectors::DetID(DetID); + static constexpr uint8_t sDUMMY_CHANNEL_ID = 0xff; + static constexpr uint8_t sDUMMY_PM_WORD = 0xff; + static constexpr int16_t sDUMMY_TIME = -5000; + static constexpr int16_t sDUMMY_AMP = -5000; + uint8_t mChannelID = sDUMMY_CHANNEL_ID; // channel id + uint8_t mWordPM = sDUMMY_PM_WORD; // PM word, based on EBitsPM + int16_t mTime = sDUMMY_TIME; // time in TDC units + int16_t mAmp = sDUMMY_AMP; // amplitude in ADC units + enum EBitsPM { + kNumberADC, + kIsDoubleEvent, + kIsTimeInfoNotValid, + kIsCFDinADCgate, + kIsTimeInfoLate, + kIsAmpNotValid, + kIsVertexEvent, + kIsTimeInfoLost + }; + static const inline std::map sMapBitsPM = { + {EBitsPM::kNumberADC, "NumberADC"}, + {EBitsPM::kIsDoubleEvent, "IsDoubleEvent"}, + {EBitsPM::kIsTimeInfoNotValid, "IsTimeInfoNotValid"}, + {EBitsPM::kIsCFDinADCgate, "IsCFDinADCgate"}, + {EBitsPM::kIsTimeInfoLate, "IsTimeInfoLate"}, + {EBitsPM::kIsAmpNotValid, "IsAmpNotValid"}, + {EBitsPM::kIsVertexEvent, "IsVertexEvent"}, + {EBitsPM::kIsTimeInfoLost, "IsTimeInfoLost"}}; + ChannelData() = default; + ChannelData(uint8_t channelID, uint8_t wordPM, int16_t time, int16_t amp) : mChannelID(channelID), mWordPM(wordPM), mTime(time), mAmp(amp) + { + } + // void print() const; + bool operator<=>(ChannelData const& other) const = default; + bool operator==(ChannelData const& other) const = default; + ClassDefNV(ChannelData, 1); +}; +} // namespace fit +} // namespace o2 +#endif diff --git a/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Digit.h b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Digit.h new file mode 100644 index 0000000000000..adaef4ec8349a --- /dev/null +++ b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Digit.h @@ -0,0 +1,79 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// \file Digit.h +/// \brief FIT event entity +/// \author Artur Furs afurs@cern.ch + +#ifndef O2_FIT_DIGIT_H_ +#define O2_FIT_DIGIT_H_ + +#include "CommonDataFormat/InteractionRecord.h" +#include "CommonDataFormat/RangeReference.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DataFormatsFIT/ChannelData.h" +#include "DataFormatsFIT/Triggers.h" + +#include +#include + +namespace o2 +{ +namespace fit +{ +using Triggers = o2::fit::Triggers; + +template +struct DigitBase { + static constexpr o2::detectors::DetID sDetID = o2::detectors::DetID(DetID); + typedef ChannelData ChannelData_t; // related ChannelData entity + o2::InteractionRecord mIR{}; // Interaction record (orbit, bc) + o2::dataformats::RangeReference mReference{}; + DigitBase() = default; + DigitBase(int first, int nEntries, const o2::InteractionRecord& ir) : mIR(ir) + { + mReference.setFirstEntry(first); + mReference.setEntries(nEntries); + } + uint32_t getOrbit() const { return mIR.orbit; } + uint16_t getBC() const { return mIR.bc; } + const o2::InteractionRecord& getIntRecord() const { return mIR; }; + gsl::span getBunchChannelData(const gsl::span channelData) const + { + return mReference.getEntries() ? gsl::span(&channelData[mReference.getFirstEntry()], mReference.getEntries()) : gsl::span(); + } + ClassDefNV(DigitBase, 1); +}; + +template +struct Digit : public DigitBase { + uint8_t mTriggerWord{}; + Digit() = default; + Digit(int first, int nEntries, const o2::InteractionRecord& ir, uint8_t trgWord) : DigitBase(first, nEntries, ir), mTriggerWord(trgWord) + { + } + ClassDefNV(Digit, 1); +}; + +template +struct DigitExt : public DigitBase { + Triggers mTriggers{}; + DigitExt() = default; + DigitExt(int first, int nEntries, const o2::InteractionRecord& ir, const Triggers& triggers) : DigitBase(first, nEntries, ir), mTriggers(triggers) + { + } + ClassDefNV(DigitExt, 1); +}; + +} // namespace fit +} // namespace o2 + +#endif diff --git a/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Triggers.h b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Triggers.h index dbdf4759c1dce..6a0eee027498e 100644 --- a/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Triggers.h +++ b/DataFormats/Detectors/FIT/common/include/DataFormatsFIT/Triggers.h @@ -25,10 +25,15 @@ namespace o2 { namespace fit { - class Triggers { public: + template + constexpr static uint64_t word(TrgBits&&... trgBits) + { + return ((1ull << std::forward(trgBits)) | ...); + } + enum { bitA = 0, bitC = 1, // alias of bitAOut (FT0/FDD) bitAOut = 1, // alias of bitC (FV0) @@ -40,7 +45,8 @@ class Triggers bitAIn = 4, // alias of bitVertex (FV0) bitLaser = 5, // indicates the laser was triggered in this BC bitOutputsAreBlocked = 6, // indicates that laser-induced pulses should arrive from detector to FEE in this BC (and trigger outputs are blocked) - bitDataIsValid = 7 }; // data is valid for processing + bitDataIsValid = 7, // data is valid for processing + bitMinBias = 8 }; // extra calculated bit, vrt & (cern || semicent) static const int16_t DEFAULT_TIME = -5000; // for average of one side (A or C) static const int16_t DEFAULT_AMP = 0; static const int16_t DEFAULT_ZERO = 0; @@ -56,6 +62,15 @@ class Triggers timeA = atimeA; timeC = atimeC; } + inline static bool checkMinBiasFT0(uint64_t trgWord) + { + return static_cast(trgWord & word(bitVertex)) && static_cast(trgWord & word(bitSCen, bitCen)); + } + static uint64_t makeExtendedTrgWord(uint64_t trgWord) + { + return trgWord | (static_cast(checkMinBiasFT0(trgWord)) << bitMinBias); + } + bool getOrA() const { return (triggersignals & (1 << bitA)) != 0; } bool getOrC() const { return (triggersignals & (1 << bitC)) != 0; } // only used by FT0/FDD (same bit as OrAOut in FV0) bool getOrAOut() const { return (triggersignals & (1 << bitAOut)) != 0; } // only used by FV0 (same bit as OrC in FT0/FDD) @@ -68,6 +83,8 @@ class Triggers bool getLaser() const { return (triggersignals & (1 << bitLaser)) != 0; } bool getOutputsAreBlocked() const { return (triggersignals & (1 << bitOutputsAreBlocked)) != 0; } bool getDataIsValid() const { return (triggersignals & (1 << bitDataIsValid)) != 0; } + bool getMinBiasFT0() const { return checkMinBiasFT0(static_cast(triggersignals)); } + uint64_t getExtendedTrgWordFT0() const { return makeExtendedTrgWord(static_cast(triggersignals)); } uint8_t getTriggersignals() const { return triggersignals; } uint8_t getNChanA() const { return nChanA; } diff --git a/DataFormats/Detectors/FIT/common/src/DataFormatsFITLinkDef.h b/DataFormats/Detectors/FIT/common/src/DataFormatsFITLinkDef.h index 6f41ab93eed79..e005315e2d6a0 100644 --- a/DataFormats/Detectors/FIT/common/src/DataFormatsFITLinkDef.h +++ b/DataFormats/Detectors/FIT/common/src/DataFormatsFITLinkDef.h @@ -25,6 +25,19 @@ #pragma link C++ std::vector < std::pair < uint64_t, int>> + ; #pragma link C++ struct o2::fit::DCSDPValues + ; +/* +#include "DetectorsCommonDataFormats/DetID.h" +#pragma link C++ struct o2::fit::ChannelData + ; +#pragma link C++ struct o2::fit::Digit + ; + +#pragma link C++ struct o2::fit::ChannelData + ; +#pragma link C++ struct o2::fit::Digit + ; + +#pragma link C++ struct o2::fit::ChannelData + ; +#pragma link C++ struct o2::fit::Digit + ; +*/ +// #pragma link C++ struct o2::fit::ChannelData; +// #pragma link C++ struct o2::fit::Digit; // TODO AM: Set this here when unused class warning is solved. // #pragma link C++ class std::unordered_map < o2::dcs::DataPointIdentifier, o2::fit::DCSDPValues> + ; diff --git a/Detectors/FIT/FT0/CMakeLists.txt b/Detectors/FIT/FT0/CMakeLists.txt index cd76f3a24fc28..2fbb4dfbbc332 100644 --- a/Detectors/FIT/FT0/CMakeLists.txt +++ b/Detectors/FIT/FT0/CMakeLists.txt @@ -18,5 +18,5 @@ add_subdirectory(raw) add_subdirectory(reconstruction) add_subdirectory(simulation) add_subdirectory(workflow) -add_subdirectory(calibration) add_subdirectory(macros) +add_subdirectory(calibration) \ No newline at end of file diff --git a/Detectors/FIT/FT0/calibration/CMakeLists.txt b/Detectors/FIT/FT0/calibration/CMakeLists.txt index ac341d1a3db12..d103b4a9a18b6 100644 --- a/Detectors/FIT/FT0/calibration/CMakeLists.txt +++ b/Detectors/FIT/FT0/calibration/CMakeLists.txt @@ -12,61 +12,24 @@ o2_add_library(FT0Calibration SOURCES src/FT0TimeOffsetSlotContainer.cxx - src/GlobalOffsetsContainer.cxx - src/FT0CalibTimeSlewing.cxx - src/FT0CalibCollector.cxx PUBLIC_LINK_LIBRARIES - O2::CCDB - O2::MathUtils O2::DataFormatsFT0 O2::CommonDataFormat O2::DetectorsCalibration - O2::DataFormatsGlobalTracking - ROOT::Minuit - Microsoft.GSL::GSL ) o2_target_root_dictionary(FT0Calibration HEADERS include/FT0Calibration/FT0TimeOffsetSlotContainer.h - include/FT0Calibration/GlobalOffsetsContainer.h - include/FT0Calibration/FT0CalibTimeSlewing.h - include/FT0Calibration/FT0CalibCollector.h ) o2_add_executable(ft0-time-offset-calib COMPONENT_NAME calibration - SOURCES testWorkflow/FT0TimeOffsetCalibration-Workflow.cxx + SOURCES workflow/FT0TimeOffsetCalibration-Workflow.cxx PUBLIC_LINK_LIBRARIES O2::FT0Calibration O2::FITCalibration ) o2_add_executable(ft0-time-spectra-processor COMPONENT_NAME calibration - SOURCES testWorkflow/FT0TimeSpectraProcessor-Workflow.cxx + SOURCES workflow/FT0TimeSpectraProcessor-Workflow.cxx PUBLIC_LINK_LIBRARIES O2::FT0Calibration ) - o2_add_executable(ft0-slew-upload - COMPONENT_NAME calibration - SOURCES testWorkflow/slew_upload.cxx - PUBLIC_LINK_LIBRARIES - O2::FT0Calibration - ) - o2_add_executable(ft0-global-offsets - COMPONENT_NAME calibration - SOURCES testWorkflow/GlobalOffsetsCalibrationWorkflow.cxx - PUBLIC_LINK_LIBRARIES - O2::FT0Calibration O2::FITCalibration - ) - o2_add_executable(ft0-collect-global-offsets-workflow - COMPONENT_NAME calibration - SOURCES testWorkflow/GlobalOffsetsCollectWorkflow.cxx - PUBLIC_LINK_LIBRARIES - O2::FT0Calibration - ) - o2_add_executable(ft0-collect-calib-workflow - COMPONENT_NAME calibration - SOURCES testWorkflow/ft0-collect-calib-workflow.cxx - PUBLIC_LINK_LIBRARIES - O2::FT0Calibration - ) - -o2_data_file(COPY files DESTINATION Detectors/FT0/) diff --git a/Detectors/FIT/FT0/calibration/files/dispatcherCalib.json b/Detectors/FIT/FT0/calibration/files/dispatcherCalib.json deleted file mode 100644 index edaf486043790..0000000000000 --- a/Detectors/FIT/FT0/calibration/files/dispatcherCalib.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "dataSamplingPolicies": [ - { - "id": "sampling1", - "active": "true", - "machines": [ - "localhost" - ], - "query": "digits:FT0/DIGITSBC/0;channels:FT0/DIGITSCH/0", - "outputs": "digits_sampled:FT0/SUB_DIGITSBC/0;channels_sampled:FT0/SUB_DIGITSCH/0", - "samplingConditions": [ - { - "condition": "random", - "fraction": "0.99", - "seed": "1234" - } - ], - "blocking": "false" - } - ] -} diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibCollector.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibCollector.h deleted file mode 100644 index bf6f4ed6c3ad6..0000000000000 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibCollector.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef FT0_CALIB_COLLECTOR_H_ -#define FT0_CALIB_COLLECTOR_H_ - -#include "DetectorsCalibration/TimeSlotCalibration.h" -#include "DetectorsCalibration/TimeSlot.h" -#include "DataFormatsFT0/FT0CalibrationInfoObject.h" -#include "FT0Base/Geometry.h" - -#include - -namespace o2 -{ -namespace ft0 -{ - -class FT0CalibInfoSlot -{ - - using Slot = o2::calibration::TimeSlot; - using Geo = o2::ft0::Geometry; - - public: - static constexpr int NCHANNELS = Geo::Nchannels; - static constexpr int HISTO_RANGE = 200; - - FT0CalibInfoSlot() - { - for (int ch = 0; ch < NCHANNELS; ch++) { - mEntriesSlot[ch] = 0; - } - } - - ~FT0CalibInfoSlot() = default; - - void print() const; - void printEntries() const; - void fill(const gsl::span data); - void merge(const FT0CalibInfoSlot* prev); - - auto& getEntriesPerChannel() const { return mEntriesSlot; } - auto& getEntriesPerChannel() { return mEntriesSlot; } - auto& getCollectedCalibInfoSlot() { return mFT0CollectedCalibInfoSlot; } - auto& getCollectedCalibInfoSlot() const { return mFT0CollectedCalibInfoSlot; } - - private: - std::array mEntriesSlot; // vector containing number of entries per channel - std::vector mFT0CollectedCalibInfoSlot; ///< output FT0 calibration info - - ClassDefNV(FT0CalibInfoSlot, 1); -}; - -class FT0CalibCollector final : public o2::calibration::TimeSlotCalibration -{ - using TFType = o2::calibration::TFType; - using Slot = o2::calibration::TimeSlot; - static constexpr int NCHANNELS = o2::ft0::Geometry::Nchannels; - - public: - FT0CalibCollector(bool TFsendingPolicy, int maxNumOfHits) : mTFsendingPolicy(TFsendingPolicy), mMaxNumOfHits(maxNumOfHits){}; - - ~FT0CalibCollector() final = default; - - bool hasEnoughData(const Slot& slot) const final; - void initOutput() final; - void finalizeSlot(Slot& slot) final; - Slot& emplaceNewSlot(bool front, TFType tstart, TFType tend) final; - auto& getCollectedCalibInfo() const { return mFT0CollectedCalibInfo; } - auto& getEntriesPerChannel() const { return mEntries; } - void setIsMaxNumberOfHitsAbsolute(bool absNumber) { mAbsMaxNumOfHits = absNumber; } - - private: - bool mTFsendingPolicy = false; // whether we will send information at every TF or only when we have a certain statistics - int mMaxNumOfHits = 1000000; // maximum number of hits for one single channel to trigger the sending of the information (if mTFsendingPolicy = false) - bool mAbsMaxNumOfHits = true; // to decide if the mMaxNumOfHits should be multiplied by the number of FT0 channels - std::array mEntries; // vector containing number of entries per channel - std::vector mFT0CollectedCalibInfo; ///< output FT0 calibration info - - ClassDefOverride(FT0CalibCollector, 1); -}; - -} // end namespace ft0 -} // end namespace o2 - -#endif /* FT0 CALIB COLLECTOR */ diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibTimeSlewing.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibTimeSlewing.h deleted file mode 100644 index 41de777557c6a..0000000000000 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0CalibTimeSlewing.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file CalibTimeSlewingParamFT0.h -/// \brief Class to store the output of the matching to FT0 for calibration - -#ifndef ALICEO2_FT0CALIBTIMESLEWING_H -#define ALICEO2_FT0CALIBTIMESLEWING_H - -#include -#include -#include -#include -#include -#include -#include "Rtypes.h" -#include -#include "DataFormatsFT0/FT0CalibrationInfoObject.h" -#include "FT0Base/Geometry.h" -namespace o2::ft0 -{ -static constexpr int NCHANNELS = o2::ft0::Geometry::Nchannels; -class FT0CalibTimeSlewing -{ - public: - static constexpr int HISTOGRAM_RANGE_X = 4000; - static constexpr unsigned int NUMBER_OF_HISTOGRAM_BINS_X = HISTOGRAM_RANGE_X / 4; - static constexpr int HISTOGRAM_RANGE_Y = 200; - static constexpr unsigned int NUMBER_OF_HISTOGRAM_BINS_Y = HISTOGRAM_RANGE_Y; - FT0CalibTimeSlewing(); - - FT0CalibTimeSlewing(const FT0CalibTimeSlewing& source) = default; - - FT0CalibTimeSlewing& operator=(const FT0CalibTimeSlewing& source) = default; - - float getChannelOffset(int channel, int amplitude) const; - - const TGraph getGraph(int channel) const { return mTimeSlewing[channel]; } - std::array getGraphs() const { return mTimeSlewing; } - void fillGraph(int channel, TH2F* histo); - - float getSigmaPeak(int channel) const { return mSigmaPeak[channel]; } - void setSigmaPeak(int channel, float value) { mSigmaPeak[channel] = value; } - - ///< perform all initializations - void init(); - void mergeFilesWithTree(); - void fillHistos(TTree* tr); - TH2F* getTimeAmpHist(int channel) { return mTimeAmpHist[channel]; }; - void setSingleFileName(std::string name) { mSingleFileName = name; } - void setMergedFileName(std::string name) { mMergedFileName = name; } - void setNfiles(int nfiles) { mNfiles = nfiles; }; - - FT0CalibTimeSlewing& operator+=(const FT0CalibTimeSlewing& other); - static constexpr const char* getObjectPath() { return "FT0/Calib/SlewingCorrection"; } - - private: - // FT0 channel calibrations - std::array mTimeSlewing; ///< array of TGraph wirh time -amplitude for each channel - std::array mSigmaPeak; ///< array with the sigma of the peak - TFile* mMergedFile; // file with merged tree - TH2F* mTimeAmpHist[NCHANNELS]; // historgams time vs amplitude - int mNfiles; // number of files with stored Tree with CalibrationInfoObject - std::string mSingleFileName; - std::string mMergedFileName; - - ClassDefNV(FT0CalibTimeSlewing, 1); // class for FT0 time slewing params -}; -} // namespace o2::ft0 -#endif diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0TimeOffsetSlotContainer.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0TimeOffsetSlotContainer.h index 88f820f28ed70..2d7470d94e9e8 100644 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0TimeOffsetSlotContainer.h +++ b/Detectors/FIT/FT0/calibration/include/FT0Calibration/FT0TimeOffsetSlotContainer.h @@ -17,6 +17,8 @@ #include "CommonDataFormat/FlatHisto2D.h" #include "DataFormatsFT0/SpectraInfoObject.h" +#include "DetectorsCalibration/TimeSlotCalibration.h" +#include "DetectorsCalibration/TimeSlot.h" #include "TList.h" @@ -27,6 +29,8 @@ namespace o2::ft0 class FT0TimeOffsetSlotContainer final { static constexpr int sNCHANNELS = o2::ft0::Geometry::Nchannels; + using TimeSlot = o2::calibration::TimeSlot; + using TimeSlotCalibration = o2::calibration::TimeSlotCalibration; public: FT0TimeOffsetSlotContainer(std::size_t minEntries); // constructor is needed due to current version of FITCalibration library, should be removed diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/GlobalOffsetsContainer.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/GlobalOffsetsContainer.h deleted file mode 100644 index c2f4c1b51ca8f..0000000000000 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/GlobalOffsetsContainer.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_GLOBALOFFSETSCONTAINER_H -#define O2_GLOBALOFFSETSCONTAINER_H - -#include "DataFormatsFT0/GlobalOffsetsInfoObject.h" -#include "DataFormatsFT0/GlobalOffsetsCalibrationObject.h" -#include "Rtypes.h" -#include -#include -#include -#include - -namespace o2::ft0 -{ -class GlobalOffsetsContainer final -{ - static constexpr int RANGE = 1000; - static constexpr unsigned int NBINS = 2 * RANGE; - - public: - explicit GlobalOffsetsContainer(std::size_t minEntries) - { - // mHisto.resize(NBINS, 0.); - } - - bool hasEnoughEntries() const; - void fill(const gsl::span& data); - int getMeanGaussianFitValue() const; - void merge(GlobalOffsetsContainer* prev); - void print() const; - GlobalOffsetsCalibrationObject generateCalibrationObject(long, long, const std::string&) const; - void updateFirstCreation(std::uint64_t creation) - { - if (creation < mFirstCreation) { - mFirstCreation = creation; - } - } - void resetFirstCreation() - { - - mFirstCreation = std::numeric_limits::max(); - } - std::uint64_t getFirstCreation() const - { - return mFirstCreation; - } - - private: - std::uint64_t mFirstCreation = std::numeric_limits::max(); - std::size_t mMinEntries; - std::array mHisto{}; - int mEntries = 0; - - ClassDefNV(GlobalOffsetsContainer, 2); -}; - -} // namespace o2::ft0 - -#endif // O2_GLOBALOFFSETCONTAINER_H diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/LHCClockCalibrator.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/LHCClockCalibrator.h deleted file mode 100644 index 42e69c199b946..0000000000000 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/LHCClockCalibrator.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef FT0_LHCPHASE_CALIBRATION_H_ -#define FT0_LHCPHASE_CALIBRATION_H_ - -#include "DetectorsCalibration/TimeSlotCalibration.h" -#include "DetectorsCalibration/TimeSlot.h" -#include "DataFormatsFT0/FT0CalibrationInfoObject.h" -#include "DataFormatsFT0/LHCphaseCalibrationObject.h" -#include "CommonConstants/LHCConstants.h" -#include "CommonUtils/NameConf.h" -#include "CCDB/CcdbObjectInfo.h" -#include - -namespace o2 -{ -namespace ft0 -{ - -struct LHCClockDataHisto { - float range = 1000. * o2::constants::lhc::LHCBunchSpacingNS * 0.5; // BC in PS - int nbins = 1000; - float v2Bin = nbins / (2 * range); - int entries = 0; - std::vector histo{0}; - - LHCClockDataHisto(); - - LHCClockDataHisto(int nb, float r) : nbins(nb), range(r), v2Bin(0) - { - if (r <= 0. || nb < 1) { - throw std::runtime_error("Wrong initialization of the histogram"); - } - v2Bin = nbins / (2 * range); - histo.resize(nbins, 0.); - } - - size_t getEntries() const { return entries; } - void print() const; - void fill(const gsl::span& data); - void merge(const LHCClockDataHisto* prev); - - ClassDefNV(LHCClockDataHisto, 1); -}; - -class LHCClockCalibrator -{ - using TFType = o2::calibration::TFType; - using Slot = o2::calibration::TimeSlot; - using LHCphase = o2::ft0::LHCphaseCalibrationObject; - using CcdbObjectInfo = o2::ccdb::CcdbObjectInfo; - using CcdbObjectInfoVector = std::vector; - using LHCphaseVector = std::vector; - - public: - LHCClockCalibrator(int minEnt = 500, int nb = 1000, float r = 24400, const std::string path = o2::base::NameConf::getCCDBServer()) : mMinEntries(minEnt), mNBins(nb), mRange(r) {} - ~LHCClockCalibrator() = default; - bool hasEnoughData(const Slot& slot) const { return slot.getContainer()->entries >= mMinEntries; } - void initOutput(); - void finalizeSlot(Slot& slot); - Slot& emplaceNewSlot(bool front, TFType tstart, TFType tend); - - const LHCphaseVector& getLHCphaseVector() const { return mLHCphaseVector; } - const CcdbObjectInfoVector& getLHCphaseInfoVector() const { return mInfoVector; } - CcdbObjectInfoVector& getLHCphaseInfoVector() { return mInfoVector; } - - private: - int mMinEntries = 0; - int mNBins = 0; - float mRange = 0.; - CcdbObjectInfoVector mInfoVector; // vector of CCDB Infos , each element is filled with the CCDB description of the accompanying LHCPhase - LHCphaseVector mLHCphaseVector; // vector of LhcPhase, each element is filled in "process" when we finalize one slot (multiple can be finalized during the same "process", which is why we have a vector. Each element is to be considered the output of the device, and will go to the CCDB - - ClassDef(LHCClockCalibrator, 1); -}; - -} // end namespace ft0 -} // end namespace o2 - -#endif /* FT0_LHCPHASE_CALIBRATION_H_ */ diff --git a/Detectors/FIT/FT0/calibration/include/FT0Calibration/RecoCalibInfoWorkflow.h b/Detectors/FIT/FT0/calibration/include/FT0Calibration/RecoCalibInfoWorkflow.h deleted file mode 100644 index b2444ae45f15a..0000000000000 --- a/Detectors/FIT/FT0/calibration/include/FT0Calibration/RecoCalibInfoWorkflow.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file RecoCalibInfoWorkflow.h -///\ brief Collect data for global offsets calibration -/// \author Alla.Maevskaya@cern.ch - -#ifndef O2_RECOCALIBINFO_WORKFLOW -#define O2_RECOCALIBINFO_WORKFLOW - -#include -#include -#include -#include "Framework/DeviceSpec.h" -#include "Framework/WorkflowSpec.h" -#include "Framework/Task.h" -#include "DataFormatsGlobalTracking/RecoContainer.h" -#include "DataFormatsFT0/RecPoints.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "CommonDataFormat/TimeStamp.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "DataFormatsFT0/RecoCalibInfoObject.h" -#include "TStopwatch.h" -#include -#include - -using namespace o2::framework; -using DataRequest = o2::globaltracking::DataRequest; -using GID = o2::dataformats::GlobalTrackID; - -namespace o2::ft0 -{ - -class RecoCalibInfoWorkflow final : public o2::framework::Task -{ - public: - RecoCalibInfoWorkflow() {} - void run(o2::framework::ProcessingContext& pc) final; - void init(InitContext& ic) final; - void endOfStream(framework::EndOfStreamContext& ec) final; - - private: - std::shared_ptr mDataRequest; - const float cSpeed = 0.029979246f; // speed of light in TOF units - GID::mask_t mInputSources; - TStopwatch mTimer; -}; -framework::DataProcessorSpec getRecoCalibInfoWorkflow(bool useMC); - -} // namespace o2::ft0 - -#endif /* O2_RECOCALIBINFO_WORKFLOW */ diff --git a/Detectors/FIT/FT0/calibration/macros/CMakeLists.txt b/Detectors/FIT/FT0/calibration/macros/CMakeLists.txt deleted file mode 100644 index 9125746b3a695..0000000000000 --- a/Detectors/FIT/FT0/calibration/macros/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2019-2020 CERN and copyright holders of ALICE O2. -# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -# All rights not expressly granted are reserved. -# -# This software is distributed under the terms of the GNU General Public -# License v3 (GPL Version 3), copied verbatim in the file "COPYING". -# -# In applying this license CERN does not waive the privileges and immunities -# granted to it by virtue of its status as an Intergovernmental Organization -# or submit itself to any jurisdiction. - -o2_add_test_root_macro( - makeChannelOffsetCalibObjectInCCDB.C - PUBLIC_LINK_LIBRARIES O2::DataFormatsFT0 O2::Framework O2::CCDB O2::DetectorsCalibration - LABELS ft0) diff --git a/Detectors/FIT/FT0/calibration/macros/makeChannelOffsetCalibObjectInCCDB.C b/Detectors/FIT/FT0/calibration/macros/makeChannelOffsetCalibObjectInCCDB.C deleted file mode 100644 index f184989c75bc3..0000000000000 --- a/Detectors/FIT/FT0/calibration/macros/makeChannelOffsetCalibObjectInCCDB.C +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#if !defined(__CLING__) || defined(__ROOTCLING__) -#include -#include "TFile.h" -#include "CCDB/CcdbApi.h" -#include "CCDB/CCDBTimeStampUtils.h" -#include "CCDB/CcdbObjectInfo.h" -#include "CommonUtils/MemFileHelper.h" -#include "CCDB/BasicCCDBManager.h" -#include -#include -#include "DataFormatsFT0/FT0ChannelTimeCalibrationObject.h" -#endif - -int makeChannelOffsetCalibObjectInCCDB(const std::string url = "http://ccdb-test.cern.ch:8080") -{ - using CalibObjWithInfoType = std::pair>>; - std::array offsets; - for (int i = 0; i < 208; i++) { - offsets[i] = 0; - } - o2::ccdb::CcdbApi api; - api.init(url); - // std::map md; - CalibObjWithInfoType result; - o2::ft0::FT0ChannelTimeCalibrationObject calibrationObject; - static std::map metaData; - auto clName = o2::utils::MemFileHelper::getClassName(calibrationObject); - auto flName = o2::ccdb::CcdbApi::generateFileName(clName); - uint64_t starting = 1546300800; // 01.01.2019 - uint64_t stopping = o2::ccdb::CcdbObjectInfo::INFINITE_TIMESTAMP; // 1633046400; // 01.10.2021 - LOG(info) << " clName " << clName << " flName " << flName; - result.first = o2::ccdb::CcdbObjectInfo("FT0/Calib/ChannelTimeOffset", clName, flName, metaData, starting, stopping); - result.second = o2::ccdb::CcdbApi::createObjectImage(&offsets, &result.first); - LOG(info) << " start " << starting << " end " << stopping; - api.storeAsTFileAny(&calibrationObject, "FT0/Calib/ChannelTimeOffset", metaData, starting, stopping); - - return 0; -} diff --git a/Detectors/FIT/FT0/calibration/src/FT0CalibCollector.cxx b/Detectors/FIT/FT0/calibration/src/FT0CalibCollector.cxx deleted file mode 100644 index acff7a13ceabe..0000000000000 --- a/Detectors/FIT/FT0/calibration/src/FT0CalibCollector.cxx +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "FT0Calibration/FT0CalibCollector.h" -#include "Framework/Logger.h" -#include -#include -#include -#include -#include - -namespace o2 -{ -namespace ft0 -{ - -using Slot = o2::calibration::TimeSlot; - -//_____________________________________________ -void FT0CalibInfoSlot::fill(const gsl::span data) -{ - // fill container - // we first order the data that arrived, to improve speed when filling - int nd = data.size(); - LOG(info) << "FT0CalibInfoSlot::fill entries in incoming data = " << nd; - std::vector ord(nd); - std::iota(ord.begin(), ord.end(), 0); - std::sort(ord.begin(), ord.end(), [&data](int i, int j) { return data[i].getChannelIndex() < data[j].getChannelIndex(); }); - int chPrev = 0, offsPrev = 0; - for (int i = 0; i < nd; i++) { - if (std::abs(data[ord[i]].getTime()) > HISTO_RANGE) { - continue; - } - const auto& dti = data[ord[i]]; - auto ch = dti.getChannelIndex(); - auto offset = offsPrev; - if (ch > chPrev) { - offset += std::accumulate(mEntriesSlot.begin() + chPrev, mEntriesSlot.begin() + ch, 0); - } - offsPrev = offset; - chPrev = ch; - auto it = mFT0CollectedCalibInfoSlot.emplace(mFT0CollectedCalibInfoSlot.begin() + offset, data[ord[i]].getChannelIndex(), data[ord[i]].getTime(), data[ord[i]].getAmp(), data[ord[i]].getTimeStamp()); - mEntriesSlot[ch]++; - } -} -//_____________________________________________ -void FT0CalibInfoSlot::merge(const FT0CalibInfoSlot* prev) -{ - // merge data of 2 slots - - LOG(info) << "Merging two slots with entries: current slot -> " << mFT0CollectedCalibInfoSlot.size() << " , previous slot -> " << prev->mFT0CollectedCalibInfoSlot.size(); - - int offset = 0, offsetPrev = 0; - std::vector tmpVector; - for (int ch = 0; ch < NCHANNELS; ch++) { - if (mEntriesSlot[ch] != 0) { - for (int i = offset; i < offset + mEntriesSlot[ch]; i++) { - tmpVector.emplace_back(mFT0CollectedCalibInfoSlot[i]); - } - offset += mEntriesSlot[ch]; - } - if (prev->mEntriesSlot[ch] != 0) { - for (int i = offsetPrev; i < offsetPrev + prev->mEntriesSlot[ch]; i++) { - tmpVector.emplace_back(prev->mFT0CollectedCalibInfoSlot[i]); - } - offsetPrev += prev->mEntriesSlot[ch]; - mEntriesSlot[ch] += prev->mEntriesSlot[ch]; - } - } - mFT0CollectedCalibInfoSlot.swap(tmpVector); - LOG(debug) << "After merging the size is " << mFT0CollectedCalibInfoSlot.size(); - return; -} -//_____________________________________________ -void FT0CalibInfoSlot::print() const -{ - // to print number of entries in the tree and the channel with the max number of entries - - LOG(info) << "Total number of entries " << mFT0CollectedCalibInfoSlot.size(); - auto maxElementIndex = std::max_element(mEntriesSlot.begin(), mEntriesSlot.end()); - auto channelIndex = std::distance(mEntriesSlot.begin(), maxElementIndex); - LOG(info) << "The maximum number of entries per channel in the current mFT0CollectedCalibInfo is " << *maxElementIndex << " for channel " << channelIndex; - return; -} - -//_____________________________________________ -void FT0CalibInfoSlot::printEntries() const -{ - // to print number of entries in the tree and per channel - - LOG(debug) << "Total number of entries " << mFT0CollectedCalibInfoSlot.size(); - for (int i = 0; i < mEntriesSlot.size(); ++i) { - if (mEntriesSlot[i] != 0) { - LOG(info) << "channel " << i << " has " << mEntriesSlot[i] << " entries"; - } - } - return; -} - -//=================================================================== - -//_____________________________________________ -void FT0CalibCollector::initOutput() -{ - // emptying the vectors - - mFT0CollectedCalibInfo.clear(); - for (int ch = 0; ch < NCHANNELS; ch++) { - mEntries[ch] = 0; - } - - return; -} - -//_____________________________________________ -bool FT0CalibCollector::hasEnoughData(const Slot& slot) const -{ - // We define that we have enough data if the tree is big enough. - // each FT0CalibrationInfoObject is composed of two int8 and one int16 --> 32 bytes - // E.g. supposing that we have 500000 entries per channel --> 500 eneries per one amplitude bin - // we can check if we have 500000*o2::ft0::Geometry::NCHANNELS entries in the vector - - const o2::ft0::FT0CalibInfoSlot* c = slot.getContainer(); - LOG(info) << "we have " << c->getCollectedCalibInfoSlot().size() << " entries"; - int maxNumberOfHits = mAbsMaxNumOfHits ? mMaxNumOfHits : mMaxNumOfHits * NCHANNELS; - if (mTFsendingPolicy || c->getCollectedCalibInfoSlot().size() > maxNumberOfHits) { - return true; - } - return false; -} - -//_____________________________________________ -void FT0CalibCollector::finalizeSlot(Slot& slot) -{ - - o2::ft0::FT0CalibInfoSlot* c = slot.getContainer(); - mFT0CollectedCalibInfo = c->getCollectedCalibInfoSlot(); - LOG(info) << "vector of received with size = " << mFT0CollectedCalibInfo.size(); - mEntries = c->getEntriesPerChannel(); - return; -} - -//_____________________________________________ -Slot& FT0CalibCollector::emplaceNewSlot(bool front, TFType tstart, TFType tend) -{ - - LOG(info) << "FIT_CALIBRATOR_TYPE::emplaceNewSlot " - << " start " << tstart << " end " << tend; - auto& cont = getSlots(); - auto& slot = front ? cont.emplace_front(tstart, tend) : cont.emplace_back(tstart, tend); - slot.setContainer(std::make_unique()); - return slot; -} - -} // end namespace ft0 -} // end namespace o2 diff --git a/Detectors/FIT/FT0/calibration/src/FT0CalibTimeSlewing.cxx b/Detectors/FIT/FT0/calibration/src/FT0CalibTimeSlewing.cxx deleted file mode 100644 index 3ea4fcb788a99..0000000000000 --- a/Detectors/FIT/FT0/calibration/src/FT0CalibTimeSlewing.cxx +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// \file FT0CalibTimeSlewing.cxx -/// \brief Class for slewing calibration object -/// -#include -#include -#include -#include -#include -#include -#include -#include "FT0Calibration/FT0CalibTimeSlewing.h" - -using namespace o2::ft0; - -FT0CalibTimeSlewing::FT0CalibTimeSlewing() -{ - for (int iCh = 0; iCh < NCHANNELS; iCh++) { - mSigmaPeak[iCh] = -1.; - mTimeAmpHist[iCh] = new TH2F(Form("hTimeAmpHist%d", iCh), Form("TimeAmp%d", iCh), - NUMBER_OF_HISTOGRAM_BINS_X, 0, HISTOGRAM_RANGE_X, - NUMBER_OF_HISTOGRAM_BINS_Y, -HISTOGRAM_RANGE_Y, HISTOGRAM_RANGE_Y); - } -} - -//______________________________________________ -float FT0CalibTimeSlewing::getChannelOffset(int channel, int amplitude) const -{ - return mTimeSlewing[channel].Eval(amplitude); -} - -//______________________________________________ -void FT0CalibTimeSlewing::fillGraph(int channel, TH2F* histo) -{ - LOG(info) << "FT0CalibTimeSlewing::fillGraph " << channel << " entries " << int(histo->GetEntries()); - double shiftchannel = 0; - TH1D* hist_Proj = histo->ProjectionY(); - TFitResultPtr res = hist_Proj->Fit("gaus", "SQ"); - if ((Int_t)res == 0) { - shiftchannel = res->Parameter(1); - } - Double_t xgr[NUMBER_OF_HISTOGRAM_BINS_X] = {}; - Double_t ygr[NUMBER_OF_HISTOGRAM_BINS_X] = {}; - TH1D* proj = nullptr; - int nbins = 0; - for (int ibin = 1; ibin < NUMBER_OF_HISTOGRAM_BINS_X; ibin++) { - xgr[ibin] = histo->GetXaxis()->GetBinCenter(ibin); - proj = histo->ProjectionY(Form("proj_px%i", ibin), ibin, ibin + 1); - if (proj->GetEntries() < 500) { - ygr[ibin] = 0; - continue; - } - TFitResultPtr r = proj->Fit("gaus", "SQ"); - if ((Int_t)r == 0) { - ygr[ibin] = r->Parameter(1) - shiftchannel; - } - nbins++; - LOG(info) << "channel " << channel << " bin " << ibin << " x " << xgr[ibin] << " y " << ygr[ibin] << " ent " << proj->GetEntries() << " sigma " << r->Parameter(2) << " shiftchannel " << shiftchannel; - } - TGraph* grTimeAmp = new TGraph(nbins + 5, xgr, ygr); - mTimeSlewing[channel] = *grTimeAmp; -} -//______________________________________________ -FT0CalibTimeSlewing& FT0CalibTimeSlewing::operator+=(const FT0CalibTimeSlewing& other) -{ - for (int i = 0; i < NCHANNELS; i++) { - mTimeSlewing[i] = other.mTimeSlewing[i]; - mSigmaPeak[i] = other.mSigmaPeak[i]; - } - return *this; -} - -//______________________________________________ -void FT0CalibTimeSlewing::mergeFilesWithTree() -{ - TFileMerger merger; - merger.OutputFile(mMergedFileName.c_str()); - for (Int_t i = 0; i < mNfiles; i++) { - TFile* file = - TFile::Open(Form("%s_%d.root", mSingleFileName.c_str(), i)); - if (file) { - merger.AddAdoptFile(file); - } - } - if (!merger.Merge()) { - LOG(fatal) << "Could not merge files"; - } - TFile mMergedFile{merger.GetOutputFileName()}; - TTree* tr = (TTree*)mMergedFile.Get("treeCollectedCalibInfo"); - if (!tr) { - LOG(fatal) << "Could not get tree with calib info"; - } - fillHistos(tr); -} - -//______________________________________________ -void FT0CalibTimeSlewing::fillHistos(TTree* tr) -{ - std::vector* localCalibInfoFT0 = nullptr; - if (!tr->GetBranch("FT0CollectedCalibInfo")) { - LOG(fatal) << "Did not find collected FT0 calib info branch in the input tree"; - } - tr->SetBranchAddress("FT0CollectedCalibInfo", &localCalibInfoFT0); - for (Int_t ievent = 0; ievent < tr->GetEntries(); ievent++) { - tr->GetEvent(ievent); - for (auto& info : *localCalibInfoFT0) { - LOG(debug) << " ch " << int(info.getChannelIndex()) << " time " << info.getTime() << " amp " << info.getAmp(); - int iCh = info.getChannelIndex(); - mTimeAmpHist[iCh]->Fill(info.getAmp(), info.getTime()); - } - } - delete localCalibInfoFT0; -} diff --git a/Detectors/FIT/FT0/calibration/src/FT0CalibrationLinkDef.h b/Detectors/FIT/FT0/calibration/src/FT0CalibrationLinkDef.h index 1facc4be739fc..49f72e8cbdfff 100644 --- a/Detectors/FIT/FT0/calibration/src/FT0CalibrationLinkDef.h +++ b/Detectors/FIT/FT0/calibration/src/FT0CalibrationLinkDef.h @@ -16,14 +16,7 @@ #pragma link off all functions; #pragma link C++ class o2::ft0::FT0TimeOffsetSlotContainer + ; -#pragma link C++ class o2::ft0::GlobalOffsetsContainer + ; -#pragma link C++ class o2::ft0::FT0CalibTimeSlewing + ; -#pragma link C++ class o2::ft0::FT0CalibCollector + ; -#pragma link C++ class o2::calibration::TimeSlot < o2::ft0::FT0CalibInfoSlot>; -#pragma link C++ class o2::calibration::TimeSlotCalibration < o2::ft0::FT0CalibInfoSlot>; #pragma link C++ class o2::calibration::TimeSlot < o2::ft0::FT0TimeOffsetSlotContainer>; #pragma link C++ class o2::calibration::TimeSlotCalibration < o2::ft0::FT0TimeOffsetSlotContainer>; -#pragma link C++ class o2::calibration::TimeSlot < o2::ft0::GlobalOffsetsContainer>; -#pragma link C++ class o2::calibration::TimeSlotCalibration < o2::ft0::GlobalOffsetsContainer>; #endif diff --git a/Detectors/FIT/FT0/calibration/src/GlobalOffsetsContainer.cxx b/Detectors/FIT/FT0/calibration/src/GlobalOffsetsContainer.cxx deleted file mode 100644 index d768edc856952..0000000000000 --- a/Detectors/FIT/FT0/calibration/src/GlobalOffsetsContainer.cxx +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "Framework/Logger.h" -#include "MathUtils/fit.h" -#include "CommonUtils/MemFileHelper.h" -#include "CCDB/CcdbApi.h" -#include "DetectorsCalibration/Utils.h" -#include "FT0Calibration//GlobalOffsetsContainer.h" -#include "DataFormatsFT0/GlobalOffsetsInfoObject.h" -#include -#include -#include "MathUtils/fit.h" -#include -#include - -using namespace o2::ft0; -using o2::math_utils::fitGaus; - -bool GlobalOffsetsContainer::hasEnoughEntries() const -{ - return mEntries < mMinEntries; -} -void GlobalOffsetsContainer::fill(const gsl::span& data) -{ - // fill container - for (auto& entry : data) { - if (std::abs(entry.getT0AC()) < RANGE) { - updateFirstCreation(entry.getTimeStamp()); - auto time = entry.getT0AC(); - time += RANGE; - mHisto[(time)]++; - mEntries++; - } - } -} -void GlobalOffsetsContainer::merge(GlobalOffsetsContainer* prev) -{ - // merge data of 2 slots - for (int i = mHisto.size(); i--;) { - mHisto[i] += prev->mHisto[i]; - } - mEntries += prev->mEntries; - mFirstCreation = std::min(mFirstCreation, prev->mFirstCreation); -} - -int GlobalOffsetsContainer::getMeanGaussianFitValue() const -{ - if (!hasEnoughEntries()) { - return 0; - } - if (mEntries == 0) { - return 0; - } - float sum = 0; - for (int ic = 0; ic < NBINS; ic++) { - sum += float(ic - RANGE) * float(mHisto[ic]); - // LOG(info)<<" histo "< fitValues; - double fitres = fitGaus(NBINS, mHisto.data(), -RANGE, RANGE, fitValues); - if (fitres >= 0) { - LOG(info) << "Fit result " << fitres << " Mean = " << fitValues[1] << " Sigma = " << fitValues[2] << " size " << mEntries << " mean " << sum / mEntries; - return (static_cast(std::round(fitValues[1]))); - } else { - LOG(warning) << "Fit failed with result = " << fitres; - return 0; - } -} -GlobalOffsetsCalibrationObject GlobalOffsetsContainer::generateCalibrationObject(long, long, const std::string&) const -{ - GlobalOffsetsCalibrationObject calibrationObject; - calibrationObject.mCollisionTimeOffsets = getMeanGaussianFitValue(); - LOG(info) << "GlobalOffsetsCalibrationObjectAlgorithm generate CalibrationObject for T0" - << " = " << calibrationObject.mCollisionTimeOffsets; - return calibrationObject; -} - -void GlobalOffsetsContainer::print() const -{ - LOG(info) << "Container keep data for LHC phase calibration:"; - LOG(info) << "Gaussian mean time AC side " << getMeanGaussianFitValue() << " based on" << mEntries << " entries"; -} diff --git a/Detectors/FIT/FT0/calibration/src/RecoCalibInfoWorkflow.cxx b/Detectors/FIT/FT0/calibration/src/RecoCalibInfoWorkflow.cxx deleted file mode 100644 index f3ea99442efbf..0000000000000 --- a/Detectors/FIT/FT0/calibration/src/RecoCalibInfoWorkflow.cxx +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file RecoCalibInfoWorkflow.cxx -///\ brief Collect data for global offsets calibration -/// \author Alla.Maevskaya@cern.ch - -#include -#include -#include "Framework/DeviceSpec.h" -#include "Framework/WorkflowSpec.h" -#include "Framework/Task.h" -#include "DataFormatsGlobalTracking/RecoContainer.h" -#include "DataFormatsFT0/RecPoints.h" -#include "FT0Calibration/RecoCalibInfoWorkflow.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "CommonDataFormat/TimeStamp.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "DataFormatsFT0/RecoCalibInfoObject.h" -#include -#include -#include - -using namespace o2::framework; -using namespace o2::math_utils::detail; -using PVertex = o2::dataformats::PrimaryVertex; -using GIndex = o2::dataformats::VtxTrackIndex; -using DataRequest = o2::globaltracking::DataRequest; - -namespace o2::ft0 -{ -void RecoCalibInfoWorkflow::init(InitContext& ic) -{ - mTimer.Stop(); - mTimer.Reset(); -} -void RecoCalibInfoWorkflow::run(o2::framework::ProcessingContext& pc) -{ - o2::globaltracking::RecoContainer recoData; - recoData.collectData(pc, *mDataRequest); - auto primVertices = recoData.getPrimaryVertices(); - auto ft0RecPoints = recoData.getFT0RecPoints(); - std::map bcsMap; - auto& calib_data = pc.outputs().make>(o2::framework::OutputRef{"calib", 0}); - calib_data.reserve(ft0RecPoints.size()); - for (auto& vertex : primVertices) { - auto& timeStamp = vertex.getTimeStamp(); - double tsTimeStamp = timeStamp.getTimeStamp() * 1E3; // mus to ns - uint64_t globalBC = std::round(tsTimeStamp / o2::constants::lhc::LHCBunchSpacingNS); - LOG(debug) << "PrimVertices " << globalBC; - auto [iter, inserted] = bcsMap.try_emplace(globalBC, &vertex); - if (!inserted) { - iter->second = nullptr; - } - } - for (auto& ft0RecPoint : ft0RecPoints) { - uint64_t bc = ft0RecPoint.getInteractionRecord().toLong(); - auto item = bcsMap.find(bc); - LOG(debug) << " <second == nullptr) { - LOG(debug) << "Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " << bc; - continue; - } - auto& vertex = *item->second; - auto currentVertex = vertex.getZ(); - ushort ncont = vertex.getNContributors(); - LOG(debug) << "CurrentVertex " << currentVertex << " ncont " << int(ncont); - if (ncont < 3) { - continue; - } - auto shift = currentVertex / cSpeed; - short t0A = ft0RecPoint.getCollisionTimeA() + shift; - short t0C = ft0RecPoint.getCollisionTimeC() - shift; - short t0AC = ft0RecPoint.getCollisionTimeMean(); - LOG(debug) << " BC t0 " << bc << " shift " << shift << " A " << t0A << " C " << t0C << " AC " << t0AC; - calib_data.emplace_back(t0A, t0C, t0AC); - } - mTimer.Stop(); -} -void RecoCalibInfoWorkflow::endOfStream(EndOfStreamContext& ec) -{ - LOGF(info, "Reco calib info workflow dpl total timing: Cpu: %.3e Real: %.3e s in %d slots", - mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); -} - -DataProcessorSpec getRecoCalibInfoWorkflow(GID::mask_t src, bool useMC) -{ - auto dataRequest = std::make_shared(); - dataRequest->requestPrimaryVertices(false); - dataRequest->requestFT0RecPoints(false); - - return DataProcessorSpec{ - "ft0-calib-reco", - dataRequest->inputs, - Outputs{ - {{"calib"}, "FT0", "CALIB_INFO"}}, - AlgorithmSpec{adaptFromTask(src, dataRequest)}, - Options{}}; -} - -}; // namespace o2::ft0 diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibCollectorWriterSpec.h b/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibCollectorWriterSpec.h deleted file mode 100644 index 217561d815c91..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibCollectorWriterSpec.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_CALIBRATION_FT0CALIB_COLLECTOR_WRITER_H -#define O2_CALIBRATION_FT0CALIB_COLLECTOR_WRITER_H - -/// @file FT0CalibCollectorWriterSpec.h -/// @brief Device to write to tree the information for FT0 time slewing calibration. - -#include "DataFormatsFT0/FT0CalibrationInfoObject.h" -#include -#include -#include - -using namespace o2::framework; - -namespace o2 -{ -namespace calibration -{ - -class FT0CalibCollectorWriter : public o2::framework::Task -{ - - using Geo = o2::ft0::Geometry; - - public: - void createAndOpenFileAndTree() - { - TString filename = TString::Format("collFT0%d.root", mCount); - LOG(debug) << "opening file " << filename.Data(); - mfileOut.reset(TFile::Open(TString::Format("%s", filename.Data()), "RECREATE")); - mOutputTree = std::make_unique("treeCollectedCalibInfo", "Tree with FT0 calib info for Time Slewing"); - mOutputTree->Branch(mOutputBranchName.data(), &mPFT0CalibInfoOut); - LOG(info) << " @@@@@ createAndOpenFileAndTree tree set"; - } - - void init(o2::framework::InitContext& ic) final - { - mCount = 0; - createAndOpenFileAndTree(); - mFT0CalibInfoOut.reserve(1000000 * Geo::Nchannels); // tree size 216ch * 10^6 entries * 12 byte - LOG(info) << " @@@@@ init"; - } - - void run(o2::framework::ProcessingContext& pc) final - { - auto collectedInfo = pc.inputs().get>("collectedInfo"); - auto entriesPerChannel = pc.inputs().get>("entriesCh"); - int offsetStart = 0; - for (int ich = 0; ich < Geo::Nchannels; ich++) { - mFT0CalibInfoOut.clear(); - if (entriesPerChannel[ich] > 0) { - mFT0CalibInfoOut.resize(entriesPerChannel[ich]); - auto subSpanVect = collectedInfo.subspan(offsetStart, entriesPerChannel[ich]); - memcpy(&mFT0CalibInfoOut[0], subSpanVect.data(), sizeof(o2::ft0::FT0CalibrationInfoObject) * subSpanVect.size()); - const o2::ft0::FT0CalibrationInfoObject* tmp = subSpanVect.data(); - LOG(debug) << "@@@@@ run ich " << ich << " entries " << entriesPerChannel[ich]; - } - mOutputTree->Fill(); - offsetStart += entriesPerChannel[ich]; - } - sendOutput(pc.outputs()); - } - - void endOfStream(o2::framework::EndOfStreamContext& ec) final - { - mIsEndOfStream = true; - sendOutput(ec.outputs()); - } - - private: - int mCount = 0; // how many times we filled the tree - bool mIsEndOfStream = false; - std::vector mFT0CalibInfoOut, *mPFT0CalibInfoOut = &mFT0CalibInfoOut; ///< these are the object and pointer to the CalibInfo of a specific channel that we need to fill the output tree - std::unique_ptr mOutputTree; ///< tree for the collected calib FT0 info - std::string mFT0CalibInfoBranchName = "FT0CalibInfo"; ///< name of branch containing input FT0 calib infos - std::string mOutputBranchName = "FT0CollectedCalibInfo"; ///< name of branch containing output - std::unique_ptr mfileOut = nullptr; // file in which to write the output - - //________________________________________________________________ - void sendOutput(DataAllocator& output) - { - // This is to fill the tree. - // One file with an empty tree will be created at the end, because we have to have a - // tree opened before processing, since we do not know a priori if something else - // will still come. The size of this extra file is ~6.5 kB - - mfileOut->cd(); - mOutputTree->Write(); - mOutputTree->Reset(); - mCount++; - if (!mIsEndOfStream) { - createAndOpenFileAndTree(); - } - } -}; -} // namespace calibration - -namespace framework -{ - -DataProcessorSpec getFT0CalibCollectorWriterSpec() -{ - LOG(debug) << " @@@@ getFT0CalibCollectorWriterSpec "; - using device = o2::calibration::FT0CalibCollectorWriter; - std::vector inputs; - inputs.emplace_back("collectedInfo", o2::header::gDataOriginFT0, "COLLECTEDINFO"); - inputs.emplace_back("entriesCh", o2::header::gDataOriginFT0, "ENTRIESCH"); - - std::vector outputs; // empty - - return DataProcessorSpec{ - "ft0-calib-collector-writer", - inputs, - outputs, - AlgorithmSpec{adaptFromTask()}, - Options{}}; -} - -} // namespace framework -} // namespace o2 - -#endif diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibSlewingCollectorSpec.h b/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibSlewingCollectorSpec.h deleted file mode 100644 index 8a1a071a0a043..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/FT0CalibSlewingCollectorSpec.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_CALIBRATION_FT0CALIB_SLEWING_COLLECTOR_H -#define O2_CALIBRATION_FT0CALIB_SLEWING_COLLECTOR_H - -/// @file FT0CalibSlewingCollectorSpec.h -/// @brief Device to collect information for FT0 time slewing calibration. - -//#include "FT0Calibration/FT0CollectCalibInfo.h" -#include "FT0Calibration/FT0CalibCollector.h" -#include "DetectorsCalibration/Utils.h" -#include "DataFormatsFT0/FT0CalibrationInfoObject.h" -#include "Framework/Task.h" -#include "Framework/ConfigParamRegistry.h" -#include "Framework/ControlService.h" -#include "Framework/WorkflowSpec.h" -#include -#include "DetectorsBase/GRPGeomHelper.h" - -using namespace o2::framework; - -namespace o2 -{ -namespace ft0 -{ - -class FT0CalibCollectorDevice : public o2::framework::Task -{ - - public: - FT0CalibCollectorDevice(std::shared_ptr req) : mCCDBRequest(req) {} - void init(o2::framework::InitContext& ic) final - { - o2::base::GRPGeomHelper::instance().setRequest(mCCDBRequest); - bool isTFsendingPolicy = ic.options().get("tf-sending-policy"); - int maxEnt = ic.options().get("max-number-hits-to-fill-tree"); - auto slotL = ic.options().get("tf-per-slot"); - bool absMaxEnt = ic.options().get("is-max-number-hits-to-fill-tree-absolute"); - mCollector = std::make_unique(isTFsendingPolicy, maxEnt); - mCollector->setSlotLength(slotL); - } - - void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final - { - o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj); - } - - void run(o2::framework::ProcessingContext& pc) final - { - o2::base::GRPGeomHelper::instance().checkUpdates(pc); - o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCollector->getCurrentTFInfo()); - auto data = pc.inputs().get>("input"); - mCollector->process(data); - sendOutput(pc.outputs()); - } - - void endOfStream(o2::framework::EndOfStreamContext& ec) final - { - mCollector->checkSlotsToFinalize(o2::calibration::INFINITE_TF); - // we force finalizing slot zero (unless everything was already finalized), no matter how many entries we had - if (mCollector->getNSlots() != 0) { - mCollector->finalizeSlot(mCollector->getSlot(0)); - } - sendOutput(ec.outputs()); - } - - private: - std::unique_ptr mCollector; - std::shared_ptr mCCDBRequest; - int mMaxNumOfHits = 0; - - //________________________________________________________________ - void sendOutput(DataAllocator& output) - { - // in output we send the calibration tree - auto& collectedInfo = mCollector->getCollectedCalibInfo(); - LOG(debug) << "In CollectorSpec sendOutput: size = " << collectedInfo.size(); - if (collectedInfo.size()) { - auto entries = collectedInfo.size(); - // this means that we are ready to send the output - auto entriesPerChannel = mCollector->getEntriesPerChannel(); - output.snapshot(Output{o2::header::gDataOriginFT0, "COLLECTEDINFO", 0}, collectedInfo); - output.snapshot(Output{o2::header::gDataOriginFT0, "ENTRIESCH", 0}, entriesPerChannel); - mCollector->initOutput(); // reset the output for the next round - } - } -}; - -} // namespace ft0 - -namespace framework -{ - -DataProcessorSpec getFT0CalibCollectorDeviceSpec() -{ - using device = o2::ft0::FT0CalibCollectorDevice; - using clbUtils = o2::calibration::Utils; - - std::vector outputs; - outputs.emplace_back(o2::header::gDataOriginFT0, "COLLECTEDINFO", 0, Lifetime::Timeframe); - outputs.emplace_back(o2::header::gDataOriginFT0, "ENTRIESCH", 0, Lifetime::Timeframe); - - std::vector inputs; - inputs.emplace_back("input", "FT0", "CALIB_INFO"); - auto ccdbRequest = std::make_shared(true, // orbitResetTime - true, // GRPECS=true - false, // GRPLHCIF - false, // GRPMagField - false, // askMatLUT - o2::base::GRPGeomRequest::None, // geometry - inputs); - return DataProcessorSpec{ - "calib-ft0calib-collector", - inputs, - outputs, - AlgorithmSpec{adaptFromTask(ccdbRequest)}, - Options{ - {"max-number-hits-to-fill-tree", VariantType::Int, 1000, {"maximum number of entries in one channel to trigger teh filling of the tree"}}, - {"is-max-number-hits-to-fill-tree-absolute", VariantType::Bool, false, {"to decide if we want to multiply the max-number-hits-to-fill-tree by the number of channels (when set to true), or not (when set to false) for fast checks"}}, - {"tf-sending-policy", VariantType::Bool, false, {"if we are sending output at every TF; otherwise, we use the max-number-hits-to-fill-tree"}}, - {"tf-per-slot", o2::framework::VariantType::UInt32, 200000u, {"TF per slot "}}}}; -} - -} // namespace framework - -} // namespace o2 - -#endif diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/FT0SlewingCalibrationWorkflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/FT0SlewingCalibrationWorkflow.cxx deleted file mode 100644 index 9a9c8e078322a..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/FT0SlewingCalibrationWorkflow.cxx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "FT0SlewingCalibrationSpec.h" - -void customize(std::vector& workflowOptions) -{ - //probably some option will be added -} - -#include "Framework/runDataProcessing.h" - -using namespace o2::framework; -WorkflowSpec defineDataProcessing(ConfigContext const& config) -{ - WorkflowSpec workflow; - workflow.emplace_back(o2::ft0::getFT0SlewingCalibrationSpec()); - //add calib spec here... - return workflow; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationSpec.h b/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationSpec.h deleted file mode 100644 index d8e3414ca83ff..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationSpec.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_CALIBRATION_LHCCLOCK_CALIBRATOR_H -#define O2_CALIBRATION_LHCCLOCK_CALIBRATOR_H - -/// @file LHCClockCalibratorSpec.h -/// @brief Device to calibrate LHC clock phase using FT0 data - -#include "Framework/DataProcessorSpec.h" -#include "DataFormatsFT0/GlobalOffsetsCalibrationObject.h" -#include "DataFormatsFT0/GlobalOffsetsInfoObject.h" -#include "FT0Calibration/GlobalOffsetsContainer.h" -#include "FITCalibration/FITCalibrationDevice.h" - -using namespace o2::framework; -namespace o2::ft0 -{ -o2::framework::DataProcessorSpec getGlobalOffsetsCalibrationSpec() -{ - using CalibrationDeviceType = o2::fit::FITCalibrationDevice; - LOG(info) << " getGlobalOffsetsCalibrationSpec()"; - - std::vector inputs; - std::vector outputs; - const o2::header::DataDescription inputDataDescriptor{"CALIB_INFO"}; - const o2::header::DataDescription outputDataDescriptor{"FT0_GLTIME_CALIB"}; - CalibrationDeviceType::prepareVecInputSpec(inputs, o2::header::gDataOriginFT0, inputDataDescriptor); - CalibrationDeviceType::prepareVecOutputSpec(outputs, outputDataDescriptor); - auto ccdbRequest = std::make_shared(true, // orbitResetTime - true, // GRPECS=true - false, // GRPLHCIF - false, // GRPMagField - false, // askMatLUT - o2::base::GRPGeomRequest::None, // geometry - inputs); - return o2::framework::DataProcessorSpec{ - "ft0-global-offsets", - inputs, // o2::framework::Inputs{{"input", "FT0", "CALIBDATA"}}, - outputs, - o2::framework::AlgorithmSpec{o2::framework::adaptFromTask(ccdbRequest, outputDataDescriptor)}, - Options{ - {"tf-per-slot", VariantType::UInt32, 55000u, {"number of TFs per calibration time slot"}}, - {"max-delay", VariantType::UInt32, 3u, {"number of slots in past to consider"}}, - {"min-entries", VariantType::Int, 500, {"minimum number of entries to fit single time slot"}}, - {"extra-info-per-slot", o2::framework::VariantType::String, "", {"Extra info for time slot(usually for debugging)"}}}}; -} - -} // namespace o2::ft0 - -#endif diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationWorkflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationWorkflow.cxx deleted file mode 100644 index f355a96a4a792..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCalibrationWorkflow.cxx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "GlobalOffsetsCalibrationSpec.h" - -void customize(std::vector& workflowOptions) -{ - //probably some option will be added -} - -#include "Framework/runDataProcessing.h" - -using namespace o2::framework; -WorkflowSpec defineDataProcessing(ConfigContext const& config) -{ - - WorkflowSpec workflow; - workflow.emplace_back(o2::ft0::getGlobalOffsetsCalibrationSpec()); - return workflow; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCollectWorkflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCollectWorkflow.cxx deleted file mode 100644 index 3a90816f7d5c2..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/GlobalOffsetsCollectWorkflow.cxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "Framework/ConfigParamSpec.h" -#include -#include "Framework/DeviceSpec.h" -#include "Framework/WorkflowSpec.h" -#include "Framework/Task.h" -#include "DataFormatsFT0/GlobalOffsetsInfoObject.h" -#include "DataFormatsFT0/RecPoints.h" -#include "Framework/Logger.h" -using namespace o2::framework; - -namespace o2::ft0 -{ - -class GlobalOffsetsCollectWorkflow final : public o2::framework::Task -{ - - public: - void run(o2::framework::ProcessingContext& pc) final - { - auto creationTime = pc.services().get().creation; // approximate time in ms - auto recpoints = pc.inputs().get>("recpoints"); - auto& calib_data = pc.outputs().make>(o2::framework::OutputRef{"calib", 0}); - for (const auto& recpoint : recpoints) { - short t0AC = recpoint.getCollisionTimeMean(); - if (std::abs(t0AC) < 1000) { - calib_data.emplace_back(t0AC, uint64_t(creationTime)); - } - } - } -}; - -} // namespace o2::ft0 - -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - Inputs inputs{}; - inputs.push_back(InputSpec{{"recpoints"}, "FT0", "RECPOINTS"}); - - DataProcessorSpec dataProcessorSpec{ - "collect-global-offsets", - inputs, - Outputs{ - {{"calib"}, "FT0", "CALIB_INFO"}}, - AlgorithmSpec{adaptFromTask()}, - Options{}}; - - WorkflowSpec workflow; - workflow.emplace_back(dataProcessorSpec); - - return workflow; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/LHCClockCalibratorSpec.h b/Detectors/FIT/FT0/calibration/testWorkflow/LHCClockCalibratorSpec.h deleted file mode 100644 index 6dfaa636e1322..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/LHCClockCalibratorSpec.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_CALIBRATION_LHCCLOCK_CALIBRATOR_H -#define O2_CALIBRATION_LHCCLOCK_CALIBRATOR_H - -/// @file LHCClockCalibratorSpec.h -/// @brief Device to calibrate LHC clock phase using FT0 data - -#include "Framework/DataProcessorSpec.h" -#include "FT0Calibration/LHCClockDataHisto.h" -#include "FT0Calibration/LHCphaseCalibrationObject.h" -#include "FT0Calibration/FT0CalibrationInfoObject.h" -#include "FITCalibration/FITCalibrationDevice.h" - -using namespace o2::framework; -namespace o2::ft0 -{ -o2::framework::DataProcessorSpec getLHCClockCalibDeviceSpec() -{ - using CalibrationDeviceType = o2::fit::FITCalibrationDevice; - - constexpr const char* DEFAULT_INPUT_LABEL = "calib"; - - std::vector inputs; - inputs.emplace_back(DEFAULT_INPUT_LABEL, "FT0", "CALIB_INFO"); - auto ccdbRequest = std::make_shared(true, // orbitResetTime - true, // GRPECS=true - false, // GRPLHCIF - false, // GRPMagField - false, // askMatLUT - o2::base::GRPGeomRequest::None, // geometry - inputs); - std::vector outputs; - outputs.emplace_back(o2::framework::ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "FIT_CALIB"}, o2::framework::Lifetime::Sporadic); - outputs.emplace_back(o2::framework::ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "FIT_CALIB"}, o2::framework::Lifetime::Sporadic); - return o2::framework::DataProcessorSpec{ - "ft0-lhcphase-calibration", - inputs, // o2::framework::Inputs{{"input", "FT0", "CALIBDATA"}}, - outputs, - o2::framework::AlgorithmSpec{o2::framework::adaptFromTask(ccdbRequest, DEFAULT_INPUT_LABEL)}, - Options{ - {"tf-per-slot", VariantType::UInt32, 26000u, {"number of TFs per calibration time slot"}}, - {"max-delay", VariantType::UInt32, 3u, {"number of slots in past to consider"}}, - {"min-entries", VariantType::Int, 500, {"minimum number of entries to fit single time slot"}}}}; -} - -} // namespace o2::ft0 - -#endif diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/RecoCalibInfoWorkflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/RecoCalibInfoWorkflow.cxx deleted file mode 100644 index 1a77e43542816..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/RecoCalibInfoWorkflow.cxx +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include -#include -#include "Framework/DeviceSpec.h" -#include "Framework/WorkflowSpec.h" -#include "Framework/Task.h" -#include "DataFormatsFT0/ChannelData.h" -#include "DataFormatsFT0/Digit.h" -#include "DataFormatsGlobalTracking/RecoContainer.h" -#include "DataFormatsFT0/RecPoints.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "CommonDataFormat/TimeStamp.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "DataFormatsFT0/RecoCalibInfoObject.h" - -using namespace o2::framework; - -namespace o2::ft0 -{ - -class RecoCalibInfoWorkflow final : public o2::framework::Task -{ - using DataRequest = o2::globaltracking::DataRequest; - - public: - /* void collectBCs(gsl::span& ft0RecPoints, */ - /* gsl::span& primVertices, */ - /* std::map& bcsMap); */ - void run(o2::framework::ProcessingContext& pc) final - { - - o2::globaltracking::RecoContainer recoData; - recoData.collectData(pc, *mDataRequest); - LOG(info) << " @@@read RecoContainer"; - auto primVertices = recoData.getPrimaryVertices(); - LOG(info) << "@@@ primVertices "; - auto ft0RecPoints = recoData.getFT0RecPoints(); - LOG(info) << "@@@@ read T0 recpoints "; - std::map bcsMap; - for (auto& vertex : primVertices) { - auto& timeStamp = vertex.getTimeStamp(); - double tsTimeStamp = timeStamp.getTimeStamp() * 1E3; // mus to ns - uint64_t globalBC = std::round(tsTimeStamp / o2::constants::lhc::LHCBunchSpacingNS); - auto [iter, inserted] = bcsMap.try_emplace(globalBC, &vertex); - if (!inserted) - iter->second = nullptr; - } - /* collectBCs(ft0RecPoints, primVertices, bcsMap); */ - - for (auto& ft0RecPoint : ft0RecPoints) { - uint64_t bc = ft0RecPoint.getInteractionRecord().toLong(); - /* uint64_t bc = globalBC; */ - auto item = bcsMap.find(bc); - if (item == bcsMap.end() || item->second == nullptr) { - LOG(fatal) << "Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " << bc; - continue; - } - auto& vertex = *item->second; - /* int bcID = -1; */ - /* if (item != bcsMap.end()) { */ - /* bcID = item->second; */ - auto currentVertex = vertex.getZ(); - ushort ncont = vertex.getNContributors(); - LOG(info) << "@@@ currentVertex " << currentVertex << " ncont " << int(ncont); - if (ncont == 0) - continue; - auto shift = currentVertex / TMath::C(); - LOG(info) << " BC t0 " << bc; - short t0A = ft0RecPoint.getCollisionTimeA() + shift; - short t0C = ft0RecPoint.getCollisionTimeC() - shift; - short t0AC = ft0RecPoint.getCollisionTimeMean(); - - /* auto recpoints = */ - /* pc.inputs().get>("recpoints"); */ - auto& calib_data = pc.outputs().make>(o2::framework::OutputRef{"calib", 0}); - calib_data.emplace_back(t0A, t0C, t0AC); - } - } - - private: - std::shared_ptr mDataRequest; -}; - -} // namespace o2::ft0 - -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const&) -{ - - DataProcessorSpec dataProcessorSpec{ - "RecoCalibInfoWorkflow", - Inputs{ - {{"recpoints"}, "FT0", "FT0CLUSTER"}, - }, - Outputs{ - {{"calib"}, "FT0", "CALIB_INFO"}}, - AlgorithmSpec{adaptFromTask()}, - Options{}}; - - WorkflowSpec workflow; - workflow.emplace_back(dataProcessorSpec); - return workflow; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/RecoQAInfoWorkflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/RecoQAInfoWorkflow.cxx deleted file mode 100644 index 1a77e43542816..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/RecoQAInfoWorkflow.cxx +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include -#include -#include "Framework/DeviceSpec.h" -#include "Framework/WorkflowSpec.h" -#include "Framework/Task.h" -#include "DataFormatsFT0/ChannelData.h" -#include "DataFormatsFT0/Digit.h" -#include "DataFormatsGlobalTracking/RecoContainer.h" -#include "DataFormatsFT0/RecPoints.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "CommonDataFormat/TimeStamp.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "DataFormatsFT0/RecoCalibInfoObject.h" - -using namespace o2::framework; - -namespace o2::ft0 -{ - -class RecoCalibInfoWorkflow final : public o2::framework::Task -{ - using DataRequest = o2::globaltracking::DataRequest; - - public: - /* void collectBCs(gsl::span& ft0RecPoints, */ - /* gsl::span& primVertices, */ - /* std::map& bcsMap); */ - void run(o2::framework::ProcessingContext& pc) final - { - - o2::globaltracking::RecoContainer recoData; - recoData.collectData(pc, *mDataRequest); - LOG(info) << " @@@read RecoContainer"; - auto primVertices = recoData.getPrimaryVertices(); - LOG(info) << "@@@ primVertices "; - auto ft0RecPoints = recoData.getFT0RecPoints(); - LOG(info) << "@@@@ read T0 recpoints "; - std::map bcsMap; - for (auto& vertex : primVertices) { - auto& timeStamp = vertex.getTimeStamp(); - double tsTimeStamp = timeStamp.getTimeStamp() * 1E3; // mus to ns - uint64_t globalBC = std::round(tsTimeStamp / o2::constants::lhc::LHCBunchSpacingNS); - auto [iter, inserted] = bcsMap.try_emplace(globalBC, &vertex); - if (!inserted) - iter->second = nullptr; - } - /* collectBCs(ft0RecPoints, primVertices, bcsMap); */ - - for (auto& ft0RecPoint : ft0RecPoints) { - uint64_t bc = ft0RecPoint.getInteractionRecord().toLong(); - /* uint64_t bc = globalBC; */ - auto item = bcsMap.find(bc); - if (item == bcsMap.end() || item->second == nullptr) { - LOG(fatal) << "Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " << bc; - continue; - } - auto& vertex = *item->second; - /* int bcID = -1; */ - /* if (item != bcsMap.end()) { */ - /* bcID = item->second; */ - auto currentVertex = vertex.getZ(); - ushort ncont = vertex.getNContributors(); - LOG(info) << "@@@ currentVertex " << currentVertex << " ncont " << int(ncont); - if (ncont == 0) - continue; - auto shift = currentVertex / TMath::C(); - LOG(info) << " BC t0 " << bc; - short t0A = ft0RecPoint.getCollisionTimeA() + shift; - short t0C = ft0RecPoint.getCollisionTimeC() - shift; - short t0AC = ft0RecPoint.getCollisionTimeMean(); - - /* auto recpoints = */ - /* pc.inputs().get>("recpoints"); */ - auto& calib_data = pc.outputs().make>(o2::framework::OutputRef{"calib", 0}); - calib_data.emplace_back(t0A, t0C, t0AC); - } - } - - private: - std::shared_ptr mDataRequest; -}; - -} // namespace o2::ft0 - -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const&) -{ - - DataProcessorSpec dataProcessorSpec{ - "RecoCalibInfoWorkflow", - Inputs{ - {{"recpoints"}, "FT0", "FT0CLUSTER"}, - }, - Outputs{ - {{"calib"}, "FT0", "CALIB_INFO"}}, - AlgorithmSpec{adaptFromTask()}, - Options{}}; - - WorkflowSpec workflow; - workflow.emplace_back(dataProcessorSpec); - return workflow; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/calib-global-offsets.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/calib-global-offsets.cxx deleted file mode 100644 index 1f70538c2880b..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/calib-global-offsets.cxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// @file calib-global-offsets.cxx - -#include "FT0Calibration/GlobalOffsetsCalibInfoWorkflow.h" -#include "Framework/CompletionPolicy.h" -#include "CommonUtils/ConfigurableParam.h" -#include "GlobalTrackingWorkflowHelpers/InputHelper.h" -#include "DetectorsCommonDataFormats/DetID.h" -#include - -using namespace o2::framework; - -void customize(std::vector& workflowOptions) -{ - // option allowing to set parameters - std::vector options{ - {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation"}}, - {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; - - std::swap(workflowOptions, options); -} -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) -{ - o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); - auto useMC = !configcontext.options().get("disable-mc"); - - WorkflowSpec specs; - specs.emplace_back(o2::ft0::getRecoCalibInfoWorkflow(useMC)); - - return std::move(specs); -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/ft0-collect-calib-workflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/ft0-collect-calib-workflow.cxx deleted file mode 100644 index 29c7d9719e0c1..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/ft0-collect-calib-workflow.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "FT0CalibSlewingCollectorSpec.h" -#include "FT0CalibCollectorWriterSpec.h" -#include "Framework/DataProcessorSpec.h" - -using namespace o2::framework; - -// we need to add workflow options before including Framework/runDataProcessing -void customize(std::vector& workflowOptions) -{ - // option allowing to set parameters -} - -// ------------------------------------------------------------------ - -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) -{ - WorkflowSpec specs; - specs.emplace_back(getFT0CalibCollectorDeviceSpec()); - specs.emplace_back(getFT0CalibCollectorWriterSpec()); - - return specs; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/lhc-clockphase-workflow.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/lhc-clockphase-workflow.cxx deleted file mode 100644 index 4384bfb1c6e3c..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/lhc-clockphase-workflow.cxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "Framework/DataProcessorSpec.h" -#include "LHCClockCalibratorSpec.h" - -using namespace o2::framework; - -// we need to add workflow options before including Framework/runDataProcessing -void customize(std::vector& workflowOptions) -{ - // option allowing to set parameters -} - -// ------------------------------------------------------------------ - -#include "Framework/runDataProcessing.h" - -WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) -{ - WorkflowSpec specs; - specs.emplace_back(o2::ft0::getLHCClockCalibDeviceSpec()); - return specs; -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/slew_upload.cxx b/Detectors/FIT/FT0/calibration/testWorkflow/slew_upload.cxx deleted file mode 100644 index b5a60c68f37f1..0000000000000 --- a/Detectors/FIT/FT0/calibration/testWorkflow/slew_upload.cxx +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file slew_upload.cxx -/// \author Alla.Maevskaya@cern.ch - -#include -#include -#include -#include -#include "Framework/Logger.h" -#include -#include -#include "CommonUtils/StringUtils.h" -#include "CommonUtils/ConfigurableParam.h" -#include "CommonUtils/NameConf.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "FT0Calibration/FT0CalibTimeSlewing.h" -#include -#include -#include -#include -#include - -using o2::ccdb::BasicCCDBManager; -using o2::ccdb::CcdbApi; -using namespace o2::ft0; - -namespace bpo = boost::program_options; - -void slew_upload(const std::string& inFileName, const std::string& mergedFileName, int nFiles); - -int main(int argc, char** argv) -{ - bpo::variables_map vm; - bpo::options_description opt_general("Usage:\n " + std::string(argv[0]) + - "Upload FT0 slewing corrections\n"); - bpo::options_description opt_hidden(""); - bpo::options_description opt_all; - bpo::positional_options_description opt_pos; - - try { - auto add_option = opt_general.add_options(); - add_option("help,h", "Print this help message"); - add_option("input-file", bpo::value()->default_value("collFT0.root"), "verbosity level"); - add_option("merged-file", bpo::value()->default_value("FT0slewGraphs.root"), "input merged file"); - add_option("number-of-files", bpo::value()->default_value(1), "number of files to merge"); - add_option("configKeyValues", bpo::value()->default_value(""), "comma-separated configKeyValues"); - - opt_all.add(opt_general).add(opt_hidden); - bpo::store(bpo::command_line_parser(argc, argv).options(opt_all).positional(opt_pos).run(), vm); - - if (vm.count("help")) { - std::cout << opt_general << std::endl; - exit(0); - } - - bpo::notify(vm); - } catch (bpo::error& e) { - std::cerr << "ERROR: " << e.what() << std::endl - << std::endl; - std::cerr << opt_general << std::endl; - exit(1); - } catch (std::exception& e) { - std::cerr << e.what() << ", application will now exit" << std::endl; - exit(2); - } - o2::conf::ConfigurableParam::updateFromString(vm["configKeyValues"].as()); - - // o2::conf::ConfigurableParam::updateFromString(vm["configKeyValues"].as()); - slew_upload(vm["input-file"].as(), - vm["merged-file"].as(), - vm["number-of-files"].as()); - - return 0; -} - -void slew_upload(const std::string& inFileName, const std::string& mergedFileName, int nFiles) -{ - TStopwatch swTot; - swTot.Start(); - - o2::ft0::FT0CalibTimeSlewing sl; - sl.setSingleFileName(inFileName); - sl.setMergedFileName(mergedFileName); - sl.setNfiles(nFiles); - sl.mergeFilesWithTree(); - for (int iCh = 0; iCh < o2::ft0 ::Geometry::Nchannels; ++iCh) { - TH2F* hist = sl.getTimeAmpHist(iCh); - if (hist->GetEntries() < 100000) { - continue; - } - sl.fillGraph(iCh, hist); - } - std::array graphs = sl.getGraphs(); - TGraph& gr = graphs.at(29); - gr.Print(); - CcdbApi api; - std::map metadata; // can be empty - api.init(o2::base::NameConf::getCCDBServer()); // or http://localhost:8080 for a local installation - // store abitrary user object in strongly typed manner - api.storeAsTFileAny(&graphs, "FT0/Calib/SlewingCorr", metadata); - - // - swTot.Stop(); - swTot.Print(); -} diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/FT0TimeOffsetCalibration-Workflow.cxx b/Detectors/FIT/FT0/calibration/workflow/FT0TimeOffsetCalibration-Workflow.cxx similarity index 100% rename from Detectors/FIT/FT0/calibration/testWorkflow/FT0TimeOffsetCalibration-Workflow.cxx rename to Detectors/FIT/FT0/calibration/workflow/FT0TimeOffsetCalibration-Workflow.cxx diff --git a/Detectors/FIT/FT0/calibration/testWorkflow/FT0TimeSpectraProcessor-Workflow.cxx b/Detectors/FIT/FT0/calibration/workflow/FT0TimeSpectraProcessor-Workflow.cxx similarity index 96% rename from Detectors/FIT/FT0/calibration/testWorkflow/FT0TimeSpectraProcessor-Workflow.cxx rename to Detectors/FIT/FT0/calibration/workflow/FT0TimeSpectraProcessor-Workflow.cxx index f1dd64a250a3b..214d919196763 100644 --- a/Detectors/FIT/FT0/calibration/testWorkflow/FT0TimeSpectraProcessor-Workflow.cxx +++ b/Detectors/FIT/FT0/calibration/workflow/FT0TimeSpectraProcessor-Workflow.cxx @@ -40,8 +40,8 @@ class FT0TimeSpectraProcessor final : public o2::framework::Task int mTimeWindow{153}; uint8_t mPMbitsToCheck{0b11111110}; uint8_t mPMbitsGood{0b01001000}; - uint8_t mTrgBitsToCheck{0b11110000}; - uint8_t mTrgBitsGood{0b10010000}; + uint64_t mTrgBitsToCheck{0b11110000}; + uint64_t mTrgBitsGood{0b10010000}; void init(o2::framework::InitContext& ic) final { mNbinsY = ic.options().get("number-bins"); @@ -69,7 +69,8 @@ class FT0TimeSpectraProcessor final : public o2::framework::Task auto channels = pc.inputs().get>("channels"); o2::dataformats::FlatHisto2D timeSpectraInfoObject(sNCHANNELS + nExtraSpectraSlots, 0, sNCHANNELS + nExtraSpectraSlots, mNbinsY, mMinY, mMaxY); for (const auto& digit : digits) { - if ((digit.mTriggers.getTriggersignals() & mTrgBitsToCheck) != mTrgBitsGood) { + const uint64_t trgWordExt = digit.mTriggers.getExtendedTrgWordFT0(); + if ((trgWordExt & mTrgBitsToCheck) != mTrgBitsGood) { continue; } const auto& chan = digit.getBunchChannelData(channels); diff --git a/cmake/O2RootMacroExclusionList.cmake b/cmake/O2RootMacroExclusionList.cmake index e079ea8cc6909..137b449cba509 100644 --- a/cmake/O2RootMacroExclusionList.cmake +++ b/cmake/O2RootMacroExclusionList.cmake @@ -60,7 +60,6 @@ list(APPEND O2_ROOT_MACRO_EXCLUSION_LIST macro/load_all_libs.C macro/putCondition.C macro/rootlogon.C - Detectors/FIT/FT0/calibration/macros/makeChannelOffsetCalibObjectInCCDB.C Detectors/Upgrades/ALICE3/macros/ALICE3Field.C) From c8e9b40f04b8d91c88eb6cfda68dd221bbabfd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuba=20G=C3=BCndem?= <48834043+tubagundem@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:03:07 +0200 Subject: [PATCH 0261/2205] TPC: standalone dEdx calculation class is extended (#13484) --- .../include/TPCCalibration/CalculatedEdx.h | 96 ++++- .../TPC/calibration/src/CalculatedEdx.cxx | 330 +++++++++++++----- 2 files changed, 320 insertions(+), 106 deletions(-) diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h index 9a6cd8488f7c8..e5889cc302b38 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h @@ -46,9 +46,10 @@ namespace o2::tpc /// c.setMembers(tpcTrackClIdxVecInput, clusterIndex, tpcTracks); // set the member variables: TrackTPC, TPCClRefElem, o2::tpc::ClusterNativeAccess /// c.setRefit(); // set the refit pointer to perform refitting of tracks, otherwise setPropagateTrack to true /// start looping over the tracks -/// c.calculatedEdx(track, output, 0.01, 0.6, CorrectionFlags::TopologyPol | CorrectionFlags::GainFull | CorrectionFlags::GainResidual | CorrectionFlags::dEdxResidual) // this will fill the dEdxInfo output for given track +/// c.calculatedEdx(track, output, 0.015, 0.60, CorrectionFlags::TopologyPol | CorrectionFlags::dEdxResidual, ClusterFlags::ExcludeEdgeCl) // this will fill the dEdxInfo output for given track enum class CorrectionFlags : unsigned short { + None = 0, TopologySimple = 1 << 0, ///< flag for simple analytical topology correction TopologyPol = 1 << 1, ///< flag for topology correction from polynomials GainFull = 1 << 2, ///< flag for full gain map from calibration container @@ -56,10 +57,23 @@ enum class CorrectionFlags : unsigned short { dEdxResidual = 1 << 4, ///< flag for residual dEdx correction }; +enum class ClusterFlags : unsigned short { + None = 0, + ExcludeSingleCl = 1 << 0, ///< flag to exclude single clusters in dEdx calculation + ExcludeSplitCl = 1 << 1, ///< flag to exclude split clusters in dEdx calculation + ExcludeEdgeCl = 1 << 2, ///< flag to exclude sector edge clusters in dEdx calculation + ExcludeSubthresholdCl = 1 << 3, ///< flag to exclude subthreshold clusters in dEdx calculation + ExcludeSectorBoundaries = 1 << 4, ///< flag to exclude sector boundary clusters in subthreshold cluster treatment +}; + inline CorrectionFlags operator&(CorrectionFlags a, CorrectionFlags b) { return static_cast(static_cast(a) & static_cast(b)); } inline CorrectionFlags operator~(CorrectionFlags a) { return static_cast(~static_cast(a)); } inline CorrectionFlags operator|(CorrectionFlags a, CorrectionFlags b) { return static_cast(static_cast(a) | static_cast(b)); } +inline ClusterFlags operator&(ClusterFlags a, ClusterFlags b) { return static_cast(static_cast(a) & static_cast(b)); } +inline ClusterFlags operator~(ClusterFlags a) { return static_cast(~static_cast(a)); } +inline ClusterFlags operator|(ClusterFlags a, ClusterFlags b) { return static_cast(static_cast(a) | static_cast(b)); } + class CalculatedEdx { public: @@ -74,7 +88,7 @@ class CalculatedEdx void setMembers(std::vector* tpcTrackClIdxVecInput, const o2::tpc::ClusterNativeAccess& clIndex, std::vector* vTPCTracksArrayInp); /// set the refitter - void setRefit(); + void setRefit(const unsigned int nHbfPerTf = 32); /// \param propagate propagate the tracks to extract the track parameters instead of performing a refit void setPropagateTrack(const bool propagate) { mPropagateTrack = propagate; } @@ -88,8 +102,14 @@ class CalculatedEdx /// \param maxMissingCl maximum number of missing clusters for subthreshold check void setMaxMissingCl(int maxMissingCl) { mMaxMissingCl = maxMissingCl; } + /// \param minChargeTotThreshold upper limit for the possible minimum charge tot in subthreshold treatment + void setMinChargeTotThreshold(float minChargeTotThreshold) { mMinChargeTotThreshold = minChargeTotThreshold; } + + /// \param minChargeMaxThreshold upper limit for the possible minimum charge max in subthreshold treatment + void setMinChargeMaxThreshold(float minChargeMaxThreshold) { mMinChargeMaxThreshold = minChargeMaxThreshold; } + /// set the debug streamer - void setStreamer() { mStreamer = std::make_unique("dEdxDebug.root", "recreate"); }; + void setStreamer(const char* debugRootFile) { mStreamer = std::make_unique(debugRootFile, "recreate"); }; /// \return returns magnetic field in kG float getFieldNominalGPUBz() { return mFieldNominalGPUBz; } @@ -97,7 +117,13 @@ class CalculatedEdx /// \return returns maxMissingCl for subthreshold cluster treatment int getMaxMissingCl() { return mMaxMissingCl; } - /// fill missing clusters with minimum charge (method=0) or minimum charge/2 (method=1) + /// \return returns the upper limit for the possible minimum charge tot in subthreshold treatment + float getMinChargeTotThreshold() { return mMinChargeTotThreshold; } + + /// \return returns the upper limit for the possible minimum charge max in subthreshold treatment + float getMinChargeMaxThreshold() { return mMinChargeMaxThreshold; } + + /// fill missing clusters with minimum charge (method=0) or minimum charge/2 (method=1) or Landau (method=2) void fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method); /// get the truncated mean for the input track with the truncation range, charge type, region and corrections @@ -108,11 +134,11 @@ class CalculatedEdx /// \param high higher cluster cut /// \param mask to apply different corrections: TopologySimple = simple analytical topology correction, TopologyPol = topology correction from polynomials, GainFull = full gain map from calibration container, /// GainResidual = residuals gain map from calibration container, dEdxResidual = residual dEdx correction - void calculatedEdx(TrackTPC& track, dEdxInfo& output, float low = 0.05f, float high = 0.6f, CorrectionFlags mask = CorrectionFlags::TopologyPol | CorrectionFlags::GainFull | CorrectionFlags::GainResidual | CorrectionFlags::dEdxResidual); + void calculatedEdx(TrackTPC& track, dEdxInfo& output, float low = 0.015f, float high = 0.6f, CorrectionFlags correctionMask = CorrectionFlags::TopologyPol | CorrectionFlags::dEdxResidual, ClusterFlags clusterMask = ClusterFlags::None, int subthresholdMethod = 0, const char* debugRootFile = "dEdxDebug.root"); /// get the truncated mean for the input charge vector and the truncation range low*nCl& charge, float low, float high) const; @@ -136,14 +162,64 @@ class CalculatedEdx /// \param runNumberOrTimeStamp run number or time stamp void loadCalibsFromCCDB(long runNumberOrTimeStamp); + /// load calibration objects from local CCDB folder + /// \param localCCDBFolder local CCDB folder + void loadCalibsFromLocalCCDBFolder(const char* localCCDBFolder); + + /// load track topology correction from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setTrackTopologyCorrectionFromFile(const char* folder, const char* file, const char* object); + + /// load gain map from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setGainMapFromFile(const char* folder, const char* file, const char* object); + + /// load gain map residual from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setGainMapResidualFromFile(const char* folder, const char* file, const char* object); + + /// load dEdx residual correction from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setResidualCorrectionFromFile(const char* folder, const char* file, const char* object); + + /// load zero suppression threshold from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setZeroSuppressionThresholdFromFile(const char* folder, const char* file, const char* object); + + /// load magnetic field from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setMagneticFieldFromFile(const char* folder, const char* file, const char* object); + + /// load propagator from a local file + /// \param folder folder path without a trailing / + /// \param file file path starting with / + /// \param object name of the object to load + void setPropagatorFromFile(const char* folder, const char* file, const char* object); + private: - std::vector* mTracks{nullptr}; ///< vector containing the tpc tracks which will be processed. + std::vector* mTracks{nullptr}; ///< vector containing the tpc tracks which will be processed std::vector* mTPCTrackClIdxVecInput{nullptr}; ///< input vector with TPC tracks cluster indicies const o2::tpc::ClusterNativeAccess* mClusterIndex{nullptr}; ///< needed to access clusternative with tpctracks - o2::gpu::CorrectionMapsHelper mTPCCorrMapsHelper; ///< cluster corrections map helper + o2::gpu::CorrectionMapsHelper mTPCCorrMapsHelper; ///< cluster correction maps helper + std::vector mTPCRefitterShMap; ///< externally set TPC clusters sharing map + std::vector mTPCRefitterOccMap; ///< externally set TPC clusters occupancy map std::unique_ptr mRefit{nullptr}; ///< TPC refitter used for TPC tracks refit during the reconstruction - int mMaxMissingCl{2}; ///< maximum number of missing clusters for subthreshold check + int mMaxMissingCl{1}; ///< maximum number of missing clusters for subthreshold check + float mMinChargeTotThreshold{50}; ///< upper limit for minimum charge tot value in subthreshold treatment, i.e for a high dEdx track adding a minimum value of 500 to track as a virtual charge doesn't make sense + float mMinChargeMaxThreshold{50}; ///< upper limit for minimum charge max value in subthreshold treatment, i.e for a high dEdx track adding a minimum value of 500 to track as a virtual charge doesn't make sense float mFieldNominalGPUBz{5}; ///< magnetic field in kG, used for track propagation bool mPropagateTrack{false}; ///< propagating the track instead of performing a refit bool mDebug{false}; ///< use the debug streamer @@ -156,4 +232,4 @@ class CalculatedEdx } // namespace o2::tpc -#endif +#endif \ No newline at end of file diff --git a/Detectors/TPC/calibration/src/CalculatedEdx.cxx b/Detectors/TPC/calibration/src/CalculatedEdx.cxx index b70be764078b8..00c8a4c8aa743 100644 --- a/Detectors/TPC/calibration/src/CalculatedEdx.cxx +++ b/Detectors/TPC/calibration/src/CalculatedEdx.cxx @@ -23,7 +23,6 @@ #include "CCDB/BasicCCDBManager.h" #include "TPCBase/CDBInterface.h" #include "TPCReconstruction/TPCFastTransformHelperO2.h" -#include "TPCCalibration/CalibPadGainTracksBase.h" #include "CalibdEdxTrackTopologyPol.h" #include "DataFormatsParameters/GRPMagField.h" #include "GPUO2InterfaceUtils.h" @@ -43,47 +42,44 @@ void CalculatedEdx::setMembers(std::vector* tpcTrackClIdx mClusterIndex = &clIndex; } -void CalculatedEdx::setRefit() +void CalculatedEdx::setRefit(const unsigned int nHbfPerTf) { - mRefit = std::make_unique(mClusterIndex, &mTPCCorrMapsHelper, mFieldNominalGPUBz, mTPCTrackClIdxVecInput->data(), 0, nullptr, nullptr, -1, mTracks); + mTPCRefitterShMap.reserve(mClusterIndex->nClustersTotal); + auto sizeOcc = o2::gpu::GPUO2InterfaceRefit::fillOccupancyMapGetSize(nHbfPerTf, nullptr); + mTPCRefitterOccMap.resize(sizeOcc); + std::fill(mTPCRefitterOccMap.begin(), mTPCRefitterOccMap.end(), 0); + o2::gpu::GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(mClusterIndex, *mTracks, mTPCTrackClIdxVecInput->data(), mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), nHbfPerTf); + mRefit = std::make_unique(mClusterIndex, &mTPCCorrMapsHelper, mFieldNominalGPUBz, mTPCTrackClIdxVecInput->data(), nHbfPerTf, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size()); } void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method) { - // adding minimum charge - if (method == 0) { - for (int roc = 0; roc < 4; roc++) { - for (int i = 0; i < missingClusters[roc]; i++) { - mChargeTotROC[roc].emplace_back(minChargeTot); - mChargeTotROC[4].emplace_back(minChargeTot); - - mChargeMaxROC[roc].emplace_back(minChargeMax); - mChargeMaxROC[4].emplace_back(minChargeMax); - } - } + if (method != 0 && method != 1) { + LOGP(info, "Unrecognized subthreshold cluster treatment. Not adding virtual charges to the track!"); + return; } - // adding minimum charge/2 - else if (method == 1) { - for (int roc = 0; roc < 4; roc++) { - for (int i = 0; i < missingClusters[roc]; i++) { - mChargeTotROC[roc].emplace_back(minChargeTot / 2); - mChargeTotROC[4].emplace_back(minChargeTot / 2); + for (int roc = 0; roc < 4; roc++) { + for (int i = 0; i < missingClusters[roc]; i++) { + float chargeTot = (method == 1) ? minChargeTot / 2.f : minChargeTot; + float chargeMax = (method == 1) ? minChargeMax / 2.f : minChargeMax; - mChargeMaxROC[roc].emplace_back(minChargeMax / 2); - mChargeMaxROC[4].emplace_back(minChargeMax / 2); - } + mChargeTotROC[roc].emplace_back(chargeTot); + mChargeTotROC[4].emplace_back(chargeTot); + + mChargeMaxROC[roc].emplace_back(chargeMax); + mChargeMaxROC[4].emplace_back(chargeMax); } } } -void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, float low, float high, CorrectionFlags mask) +void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, float low, float high, CorrectionFlags correctionMask, ClusterFlags clusterMask, int subthresholdMethod, const char* debugRootFile) { // get number of clusters const int nClusters = track.getNClusterReferences(); - int nClsROC[4] = {0}; - int nClsSubThreshROC[4] = {0}; + int nClsROC[4] = {0, 0, 0, 0}; + int nClsSubThreshROC[4] = {0, 0, 0, 0}; mChargeTotROC[0].clear(); mChargeTotROC[1].clear(); @@ -98,11 +94,15 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl mChargeMaxROC[4].clear(); // debug vectors + std::vector excludeClVector; std::vector regionVector; std::vector rowIndexVector; std::vector padVector; - std::vector stackVector; std::vector sectorVector; + std::vector stackVector; + std::vector localXVector; + std::vector localYVector; + std::vector offsPadVector; std::vector topologyCorrVector; std::vector topologyCorrTotVector; @@ -112,19 +112,19 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl std::vector residualCorrTotVector; std::vector residualCorrMaxVector; - std::vector xPositionVector; - std::vector localYVector; - std::vector offsPadVector; - std::vector trackVector; std::vector clVector; if (mDebug) { + excludeClVector.reserve(nClusters); regionVector.reserve(nClusters); rowIndexVector.reserve(nClusters); padVector.reserve(nClusters); stackVector.reserve(nClusters); sectorVector.reserve(nClusters); + localXVector.reserve(nClusters); + localYVector.reserve(nClusters); + offsPadVector.reserve(nClusters); topologyCorrVector.reserve(nClusters); topologyCorrTotVector.reserve(nClusters); topologyCorrMaxVector.reserve(nClusters); @@ -132,9 +132,6 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl gainResidualVector.reserve(nClusters); residualCorrTotVector.reserve(nClusters); residualCorrMaxVector.reserve(nClusters); - xPositionVector.reserve(nClusters); - localYVector.reserve(nClusters); - offsPadVector.reserve(nClusters); trackVector.reserve(nClusters); clVector.reserve(nClusters); } @@ -157,7 +154,33 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // set sectorIndex, rowIndex, clusterIndexNumb track.getClusterReference(*mTPCTrackClIdxVecInput, iCl, sectorIndex, rowIndex, clusterIndexNumb); - // get x position of the track + // get region, pad, stack and stack ID + const int region = Mapper::REGION[rowIndex]; + const unsigned char pad = std::clamp(static_cast(cl.getPad() + 0.5f), static_cast(0), Mapper::PADSPERROW[region][Mapper::getLocalRowFromGlobalRow(rowIndex)] - 1); // the left side of the pad is defined at e.g. 3.5 and the right side at 4.5 + const CRU cru(Sector(sectorIndex), region); + const auto stack = cru.gemStack(); + StackID stackID{sectorIndex, stack}; + // the stack number for debugging + const int stackNumber = static_cast(stack); + + // get local coordinates, offset and flags + const float localX = o2::tpc::Mapper::instance().getPadCentre(PadPos(rowIndex, pad)).X(); + const float localY = Mapper::instance().getPadCentre(PadPos(rowIndex, pad)).Y(); + const float offsPad = (cl.getPad() - pad) * o2::tpc::Mapper::instance().getPadRegionInfo(Mapper::REGION[rowIndex]).getPadWidth(); + const auto flagsCl = cl.getFlags(); + + int excludeCl = 0; // works as a bit mask + if (((clusterMask & ClusterFlags::ExcludeSingleCl) == ClusterFlags::ExcludeSingleCl) && ((flagsCl & ClusterNative::flagSingle) == ClusterNative::flagSingle)) { + excludeCl += 0b001; // 1 for single cluster + } + if (((clusterMask & ClusterFlags::ExcludeSplitCl) == ClusterFlags::ExcludeSplitCl) && (((flagsCl & ClusterNative::flagSplitPad) == ClusterNative::flagSplitPad) || ((flagsCl & ClusterNative::flagSplitTime) == ClusterNative::flagSplitTime))) { + excludeCl += 0b010; // 2 for split cluster + } + if (((clusterMask & ClusterFlags::ExcludeEdgeCl) == ClusterFlags::ExcludeEdgeCl) && ((flagsCl & ClusterNative::flagEdge) == ClusterNative::flagEdge)) { + excludeCl += 0b100; // 4 for edge cluster + } + + // get the x position of the track const float xPosition = Mapper::instance().getPadCentre(PadPos(rowIndex, 0)).X(); bool check = true; @@ -170,44 +193,82 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl } else { // propagate this track to the plane X=xk (cm) in the field "b" (kG) track.rotate(o2::math_utils::detail::sector2Angle(sectorIndex)); - check = o2::base::Propagator::Instance()->PropagateToXBxByBz(track, xPosition, 0.9f, 2., o2::base::Propagator::MatCorrType::USEMatCorrLUT); + check = o2::base::Propagator::Instance()->PropagateToXBxByBz(track, xPosition, 0.999f, 2., o2::base::Propagator::MatCorrType::USEMatCorrLUT); } if (!check || std::isnan(track.getParam(1))) { + excludeCl += 0b1000; // 8 for failure of track propagation or refit + } + + if (excludeCl != 0) { + // for debugging + if (mDebug) { + excludeClVector.emplace_back(excludeCl); + regionVector.emplace_back(region); + rowIndexVector.emplace_back(rowIndex); + padVector.emplace_back(pad); + sectorVector.emplace_back(sectorIndex); + stackVector.emplace_back(stackNumber); + localXVector.emplace_back(localX); + localYVector.emplace_back(localY); + offsPadVector.emplace_back(offsPad); + trackVector.emplace_back(track); + clVector.emplace_back(cl); + + topologyCorrVector.emplace_back(-999.f); + topologyCorrTotVector.emplace_back(-999.f); + topologyCorrMaxVector.emplace_back(-999.f); + gainVector.emplace_back(-999.f); + gainResidualVector.emplace_back(-999.f); + residualCorrTotVector.emplace_back(-999.f); + residualCorrMaxVector.emplace_back(-999.f); + } + // to avoid counting the skipped cluster as a subthreshold cluster rowIndexOld = rowIndex; sectorIndexOld = sectorIndex; continue; } - // get region and charge value - const int region = Mapper::REGION[rowIndex]; + // get charge values float chargeTot = cl.qTot; float chargeMax = cl.qMax; - // get pad and threshold - const unsigned char pad = std::clamp(static_cast(cl.getPad() + 0.5f), static_cast(0), Mapper::PADSPERROW[region][Mapper::getLocalRowFromGlobalRow(rowIndex)] - 1); // the left side of the pad is defined at e.g. 3.5 and the right side at 4.5 + // get threshold const float threshold = mCalibCont.getZeroSupressionThreshold(sectorIndex, rowIndex, pad); - // get stack and stack ID - const CRU cru(Sector(sectorIndex), region); - const auto stack = cru.gemStack(); - StackID stackID{sectorIndex, stack}; - // find missing clusters int missingClusters = rowIndexOld - rowIndex - 1; - if ((missingClusters > 0) && (missingClusters <= mMaxMissingCl) && (sectorIndexOld == sectorIndex)) { - if (stack == GEMstack::IROCgem) { - nClsSubThreshROC[0] += missingClusters; - nClsROC[0] += missingClusters; - } else if (stack == GEMstack::OROC1gem) { - nClsSubThreshROC[1] += missingClusters; - nClsROC[1] += missingClusters; - } else if (stack == GEMstack::OROC2gem) { - nClsSubThreshROC[2] += missingClusters; - nClsROC[2] += missingClusters; - } else if (stack == GEMstack::OROC3gem) { - nClsSubThreshROC[3] += missingClusters; - nClsROC[3] += missingClusters; + if ((missingClusters > 0) && (missingClusters <= mMaxMissingCl)) { + if ((clusterMask & ClusterFlags::ExcludeSectorBoundaries) == ClusterFlags::ExcludeSectorBoundaries) { + if (sectorIndexOld == sectorIndex) { + if (stack == GEMstack::IROCgem) { + nClsSubThreshROC[0] += missingClusters; + nClsROC[0] += missingClusters; + } else if (stack == GEMstack::OROC1gem) { + nClsSubThreshROC[1] += missingClusters; + nClsROC[1] += missingClusters; + } else if (stack == GEMstack::OROC2gem) { + nClsSubThreshROC[2] += missingClusters; + nClsROC[2] += missingClusters; + } else if (stack == GEMstack::OROC3gem) { + nClsSubThreshROC[3] += missingClusters; + nClsROC[3] += missingClusters; + } + } + } else { + if (stack == GEMstack::IROCgem) { + nClsSubThreshROC[0] += missingClusters; + nClsROC[0] += missingClusters; + } else if (stack == GEMstack::OROC1gem) { + nClsSubThreshROC[1] += missingClusters; + nClsROC[1] += missingClusters; + } else if (stack == GEMstack::OROC2gem) { + nClsSubThreshROC[2] += missingClusters; + nClsROC[2] += missingClusters; + } else if (stack == GEMstack::OROC3gem) { + nClsSubThreshROC[3] += missingClusters; + nClsROC[3] += missingClusters; + } } }; rowIndexOld = rowIndex; @@ -217,12 +278,12 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl float effectiveLength = 1.0f; float effectiveLengthTot = 1.0f; float effectiveLengthMax = 1.0f; - if ((mask & CorrectionFlags::TopologySimple) == CorrectionFlags::TopologySimple) { + if ((correctionMask & CorrectionFlags::TopologySimple) == CorrectionFlags::TopologySimple) { effectiveLength = getTrackTopologyCorrection(track, region); chargeTot /= effectiveLength; chargeMax /= effectiveLength; }; - if ((mask & CorrectionFlags::TopologyPol) == CorrectionFlags::TopologyPol) { + if ((correctionMask & CorrectionFlags::TopologyPol) == CorrectionFlags::TopologyPol) { effectiveLengthTot = getTrackTopologyCorrectionPol(track, cl, region, chargeTot, ChargeType::Tot, threshold); effectiveLengthMax = getTrackTopologyCorrectionPol(track, cl, region, chargeMax, ChargeType::Max, threshold); chargeTot /= effectiveLengthTot; @@ -232,10 +293,10 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // get gain float gain = 1.0f; float gainResidual = 1.0f; - if ((mask & CorrectionFlags::GainFull) == CorrectionFlags::GainFull) { + if ((correctionMask & CorrectionFlags::GainFull) == CorrectionFlags::GainFull) { gain = mCalibCont.getGain(sectorIndex, rowIndex, pad); }; - if ((mask & CorrectionFlags::GainResidual) == CorrectionFlags::GainResidual) { + if ((correctionMask & CorrectionFlags::GainResidual) == CorrectionFlags::GainResidual) { gainResidual = mCalibCont.getResidualGain(sectorIndex, rowIndex, pad); }; chargeTot /= gain * gainResidual; @@ -244,7 +305,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // get dEdx correction on tgl and sector plane float corrTot = 1.0f; float corrMax = 1.0f; - if ((mask & CorrectionFlags::dEdxResidual) == CorrectionFlags::dEdxResidual) { + if ((correctionMask & CorrectionFlags::dEdxResidual) == CorrectionFlags::dEdxResidual) { corrTot = mCalibCont.getResidualCorrection(stackID, ChargeType::Tot, track.getTgl(), track.getSnp()); corrMax = mCalibCont.getResidualCorrection(stackID, ChargeType::Max, track.getTgl(), track.getSnp()); if (corrTot > 0) { @@ -287,22 +348,17 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // for debugging if (mDebug) { - // mapping for the stack info - std::map map; - map[GEMstack::IROCgem] = 0; - map[GEMstack::OROC1gem] = 1; - map[GEMstack::OROC2gem] = 2; - map[GEMstack::OROC3gem] = 3; - - const float localY = o2::tpc::Mapper::instance().getPadCentre(o2::tpc::PadPos(rowIndex, pad)).Y(); - const float offsPad = (cl.getPad() - pad) * o2::tpc::Mapper::instance().getPadRegionInfo(Mapper::REGION[rowIndex]).getPadWidth(); - - // filling debug vectors + excludeClVector.emplace_back(0); // cl is successfully processed regionVector.emplace_back(region); rowIndexVector.emplace_back(rowIndex); padVector.emplace_back(pad); - stackVector.emplace_back(map[stack]); sectorVector.emplace_back(sectorIndex); + stackVector.emplace_back(stackNumber); + localXVector.emplace_back(localX); + localYVector.emplace_back(localY); + offsPadVector.emplace_back(offsPad); + trackVector.emplace_back(track); + clVector.emplace_back(cl); topologyCorrVector.emplace_back(effectiveLength); topologyCorrTotVector.emplace_back(effectiveLengthTot); @@ -311,32 +367,32 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl gainResidualVector.emplace_back(gainResidual); residualCorrTotVector.emplace_back(corrTot); residualCorrMaxVector.emplace_back(corrMax); - - xPositionVector.emplace_back(xPosition); - localYVector.emplace_back(localY); - offsPadVector.emplace_back(offsPad); - - trackVector.emplace_back(track); - clVector.emplace_back(cl); }; } // number of clusters - output.NHitsIROC = nClsROC[0] - nClsSubThreshROC[0]; - output.NHitsOROC1 = nClsROC[1] - nClsSubThreshROC[1]; - output.NHitsOROC2 = nClsROC[2] - nClsSubThreshROC[2]; - output.NHitsOROC3 = nClsROC[3] - nClsSubThreshROC[3]; - output.NHitsSubThresholdIROC = nClsROC[0]; output.NHitsSubThresholdOROC1 = nClsROC[1]; output.NHitsSubThresholdOROC2 = nClsROC[2]; output.NHitsSubThresholdOROC3 = nClsROC[3]; - // fill subthreshold clusters - fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, 0); + // check if the lost clusters are subthreshold clusters based on the charge thresholds + if (minChargeTot <= mMinChargeTotThreshold && minChargeMax <= mMinChargeMaxThreshold) { + output.NHitsIROC = nClsROC[0] - nClsSubThreshROC[0]; + output.NHitsOROC1 = nClsROC[1] - nClsSubThreshROC[1]; + output.NHitsOROC2 = nClsROC[2] - nClsSubThreshROC[2]; + output.NHitsOROC3 = nClsROC[3] - nClsSubThreshROC[3]; - auto chargeTotVector = mChargeTotROC[4]; - auto chargeMaxVector = mChargeMaxROC[4]; + // fill subthreshold clusters if not excluded + if (((clusterMask & ClusterFlags::ExcludeSubthresholdCl) == ClusterFlags::None)) { + fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, subthresholdMethod); + } + } else { + output.NHitsIROC = nClsROC[0]; + output.NHitsOROC1 = nClsROC[1]; + output.NHitsOROC2 = nClsROC[2]; + output.NHitsOROC3 = nClsROC[3]; + } // calculate dEdx output.dEdxTotIROC = getTruncMean(mChargeTotROC[0], low, high); @@ -354,15 +410,17 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // for debugging if (mDebug) { if (mStreamer == nullptr) { - setStreamer(); + setStreamer(debugRootFile); } (*mStreamer) << "dEdxDebug" + << "Ncl=" << nClusters + << "excludeClVector=" << excludeClVector << "regionVector=" << regionVector << "rowIndexVector=" << rowIndexVector << "padVector=" << padVector - << "stackVector=" << stackVector << "sectorVector=" << sectorVector + << "stackVector=" << stackVector << "topologyCorrVector=" << topologyCorrVector << "topologyCorrTotVector=" << topologyCorrTotVector << "topologyCorrMaxVector=" << topologyCorrMaxVector @@ -370,13 +428,11 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl << "gainResidualVector=" << gainResidualVector << "residualCorrTotVector=" << residualCorrTotVector << "residualCorrMaxVector=" << residualCorrMaxVector - << "xPositionVector=" << xPositionVector + << "localXVector=" << localXVector << "localYVector=" << localYVector << "offsPadVector=" << offsPadVector << "trackVector=" << trackVector << "clVector=" << clVector - << "chargeTotVector=" << chargeTotVector - << "chargeMaxVector=" << chargeMaxVector << "minChargeTot=" << minChargeTot << "minChargeMax=" << minChargeMax << "output=" << output @@ -487,3 +543,85 @@ void CalculatedEdx::loadCalibsFromCCDB(long runNumberOrTimeStamp) const o2::base::MatLayerCylSet* matLut = o2::base::MatLayerCylSet::rectifyPtrFromFile(cm.get("GLO/Param/MatLUT")); propagator->setMatLUT(matLut); } + +void CalculatedEdx::loadCalibsFromLocalCCDBFolder(const char* localCCDBFolder) +{ + setTrackTopologyCorrectionFromFile(localCCDBFolder, "/TPC/Calib/TopologyGainPiecewise/snapshot.root", "ccdb_object"); + setGainMapFromFile(localCCDBFolder, "/TPC/Calib/PadGainFull/snapshot.root", "ccdb_object"); + setGainMapResidualFromFile(localCCDBFolder, "/TPC/Calib/PadGainResidual/snapshot.root", "ccdb_object"); + setResidualCorrectionFromFile(localCCDBFolder, "/TPC/Calib/TimeGain/snapshot.root", "ccdb_object"); + setZeroSuppressionThresholdFromFile(localCCDBFolder, "/TPC/Config/FEEPad/snapshot.root", "ccdb_object"); + setMagneticFieldFromFile(localCCDBFolder, "/GLO/Config/GRPMagField/snapshot.root", "ccdb_object"); + setPropagatorFromFile(localCCDBFolder, "/GLO/Param/MatLUT/snapshot.root", "ccdb_object"); +} + +void CalculatedEdx::setTrackTopologyCorrectionFromFile(const char* folder, const char* file, const char* object) +{ + o2::tpc::CalibdEdxTrackTopologyPol calibTrackTopology; + calibTrackTopology.loadFromFile(fmt::format("{}{}", folder, file).data(), object); + mCalibCont.setPolTopologyCorrection(calibTrackTopology); +} + +void CalculatedEdx::setGainMapFromFile(const char* folder, const char* file, const char* object) +{ + std::unique_ptr gainMapFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!gainMapFile->IsZombie()) { + LOGP(info, "Using file: {}", gainMapFile->GetName()); + o2::tpc::CalDet* gainMap = (o2::tpc::CalDet*)gainMapFile->Get(object); + mCalibCont.setGainMap(*gainMap, 0., 2.); + } +} + +void CalculatedEdx::setGainMapResidualFromFile(const char* folder, const char* file, const char* object) +{ + std::unique_ptr gainMapResidualFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!gainMapResidualFile->IsZombie()) { + LOGP(info, "Using file: {}", gainMapResidualFile->GetName()); + std::unordered_map>* gainMapResidual = (std::unordered_map>*)gainMapResidualFile->Get(object); + mCalibCont.setGainMapResidual(gainMapResidual->at("GainMap")); + } +} + +void CalculatedEdx::setResidualCorrectionFromFile(const char* folder, const char* file, const char* object) +{ + std::unique_ptr calibdEdxResidualFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!calibdEdxResidualFile->IsZombie()) { + LOGP(info, "Using file: {}", calibdEdxResidualFile->GetName()); + o2::tpc::CalibdEdxCorrection* calibdEdxResidual = (o2::tpc::CalibdEdxCorrection*)calibdEdxResidualFile->Get(object); + mCalibCont.setResidualCorrection(*calibdEdxResidual); + } +} + +void CalculatedEdx::setZeroSuppressionThresholdFromFile(const char* folder, const char* file, const char* object) +{ + std::unique_ptr zeroSuppressionFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!zeroSuppressionFile->IsZombie()) { + LOGP(info, "Using file: {}", zeroSuppressionFile->GetName()); + std::unordered_map>* zeroSupressionThresholdMap = (std::unordered_map>*)zeroSuppressionFile->Get(object); + mCalibCont.setZeroSupresssionThreshold(zeroSupressionThresholdMap->at("ThresholdMap")); + } +} + +void CalculatedEdx::setMagneticFieldFromFile(const char* folder, const char* file, const char* object) +{ + std::unique_ptr magFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!magFile->IsZombie()) { + LOGP(info, "Using file: {}", magFile->GetName()); + o2::parameters::GRPMagField* magField = (o2::parameters::GRPMagField*)magFile->Get(object); + o2::base::Propagator::initFieldFromGRP(magField); + float bz = GPUO2InterfaceUtils::getNominalGPUBz(*magField); + LOGP(info, "Magnetic field: {}", bz); + setFieldNominalGPUBz(bz); + } +} + +void CalculatedEdx::setPropagatorFromFile(const char* folder, const char* file, const char* object) +{ + auto propagator = o2::base::Propagator::Instance(); + std::unique_ptr matLutFile(TFile::Open(fmt::format("{}{}", folder, file).data())); + if (!matLutFile->IsZombie()) { + LOGP(info, "Using file: {}", matLutFile->GetName()); + o2::base::MatLayerCylSet* matLut = o2::base::MatLayerCylSet::rectifyPtrFromFile((o2::base::MatLayerCylSet*)matLutFile->Get(object)); + propagator->setMatLUT(matLut); + } +} \ No newline at end of file From 5189fa639807769be4de00c4ed77ce0105b852bf Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:11:29 +0200 Subject: [PATCH 0262/2205] DPL: Drop generic code chose between unique and shared pointers Just use an if constexpr nowadays... --- Framework/Core/CMakeLists.txt | 1 - Framework/Core/include/Framework/TypeTraits.h | 27 ----------- Framework/Core/src/runDataProcessing.cxx | 5 +-- Framework/Core/test/test_PtrHelpers.cxx | 45 ------------------- 4 files changed, 1 insertion(+), 77 deletions(-) delete mode 100644 Framework/Core/test/test_PtrHelpers.cxx diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index 7ddffda175a0a..8c2d9650776c0 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -229,7 +229,6 @@ add_executable(o2-test-framework-core test/test_OptionsHelpers.cxx test/test_OverrideLabels.cxx test/test_O2DataModelHelpers.cxx - test/test_PtrHelpers.cxx test/test_RootConfigParamHelpers.cxx test/test_Services.cxx test/test_StringHelpers.cxx diff --git a/Framework/Core/include/Framework/TypeTraits.h b/Framework/Core/include/Framework/TypeTraits.h index 6938b87238903..19ca548835cdd 100644 --- a/Framework/Core/include/Framework/TypeTraits.h +++ b/Framework/Core/include/Framework/TypeTraits.h @@ -164,32 +164,5 @@ struct has_root_setowner< void>> : public std::true_type { }; -/// Helper class to deal with the case we are creating the first instance of a -/// (possibly) shared resource. -/// -/// works for both: -/// -/// std::shared_ptr storage = make_matching(args...); -/// -/// or -/// -/// std::unique_ptr storage = make_matching(args...); -/// -/// Useful to deal with those who cannot make up their mind about ownership. -/// ;-) -template -static std::enable_if_t().unique()) != 0, HOLDER> - make_matching(ARGS&&... args) -{ - return std::make_shared(std::forward(args)...); -} - -template -static std::enable_if_t().get_deleter()) != 0, HOLDER> - make_matching(ARGS&&... args) -{ - return std::make_unique(std::forward(args)...); -} - } // namespace o2::framework #endif // FRAMEWORK_TYPETRAITS_H diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 4cec8c63fe856..7d298998d0563 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -1098,10 +1098,7 @@ int doChild(int argc, char** argv, ServiceRegistry& serviceRegistry, serviceRef.registerService(ServiceRegistryHelpers::handleForService(deviceContext.get())); serviceRef.registerService(ServiceRegistryHelpers::handleForService(&driverConfig)); - // The decltype stuff is to be able to compile with both new and old - // FairMQ API (one which uses a shared_ptr, the other one a unique_ptr. - decltype(r.fDevice) device; - device = make_matching(ref, serviceRegistry, processingPolicies); + auto device = std::make_unique(ref, serviceRegistry, processingPolicies); serviceRef.get().setDevice(device.get()); r.fDevice = std::move(device); diff --git a/Framework/Core/test/test_PtrHelpers.cxx b/Framework/Core/test/test_PtrHelpers.cxx deleted file mode 100644 index 01486c9371749..0000000000000 --- a/Framework/Core/test/test_PtrHelpers.cxx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include "Framework/TypeTraits.h" -#include - -/// exclude from doxygen, TODO: we might want to do this on a higher level -/// because of doxygen's autolinking of references, all 'A' are displayed as -/// reference to this struct. -/// @cond -struct Base { - int v; -}; -struct A : public Base { - A(int v_, int va_) : Base{v_}, va{va_} {} - int va; -}; -struct B : public Base { - B(int v_, int vb_) : Base{v_}, vb{vb_} {} - int vb; -}; - -TEST_CASE("MatchingPtrMaker") -{ - - std::shared_ptr s = std::move(o2::framework::make_matching(1, 3)); - std::unique_ptr u = std::move(o2::framework::make_matching(2, 4)); - - REQUIRE(s != nullptr); - REQUIRE(u != nullptr); - REQUIRE(s->v == 1); - REQUIRE(u->v == 2); - REQUIRE(static_cast(s.get())->va == 3); - REQUIRE(static_cast(u.get())->vb == 4); -} -// @endcond From 66e8774957de6066ad745c868cbe8e6ef07c73df Mon Sep 17 00:00:00 2001 From: yuanzhe Date: Tue, 27 Aug 2024 10:28:59 +0200 Subject: [PATCH 0263/2205] Add mass hypothesis for H4L, He4L, He5L and charge hypothesis for decays3Body Fix the description of decays3Body Fix the charge of hyperhelium4 Set the ID of hyperhelium4 as the last one Enable H4L and He4L Add mass hypothesis of He5L Use the hypothesis of daughter's charge for mass check Add new calcMass function and code format fix Remove space Parameters fix Move the momentum calculation of candidate outside Only modify the charge hypothesis for bachelors Small updates Please consider the following formatting changes --- .../ReconstructionDataFormats/Decay3Body.h | 2 +- .../include/ReconstructionDataFormats/PID.h | 20 +++-- DataFormats/Reconstruction/src/Decay3Body.cxx | 2 +- .../DetectorsVertexing/SVertexHypothesis.h | 4 + .../include/DetectorsVertexing/SVertexer.h | 2 + .../DetectorsVertexing/SVertexerParams.h | 2 + Detectors/Vertexing/src/SVertexer.cxx | 86 +++++++++++-------- .../include/Framework/AnalysisDataModel.h | 2 +- 8 files changed, 74 insertions(+), 46 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Decay3Body.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Decay3Body.h index eb7229252b586..f7f18976fa508 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Decay3Body.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Decay3Body.h @@ -29,7 +29,7 @@ class Decay3Body : public o2::track::TrackParCov /// TO BE DONE: extend to gener using PID = o2::track::PID; Decay3Body() = default; - Decay3Body(PID pid, const std::array& xyz, const std::array& pxyz, const std::array& covxyz, const Track& tr0, const Track& tr1, const Track& tr2); + Decay3Body(const std::array& xyz, const std::array& pxyz, const std::array& covxyz, const Track& tr0, const Track& tr1, const Track& tr2, o2::track::PID pid = o2::track::PID::HyperTriton); const Track& getProng(int i) const { return mProngs[i]; } Track& getProng(int i) { return mProngs[i]; } diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h index e01ce253156a7..ce70e69aa6ddd 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h @@ -33,19 +33,19 @@ namespace o2cp = o2::constants::physics; namespace pid_constants // GPUs currently cannot have static constexpr array members { typedef uint8_t ID; -static constexpr ID NIDsTot = 17; +static constexpr ID NIDsTot = 19; #if !defined(GPUCA_GPUCODE_DEVICE) || defined(GPUCA_GPU_DEBUG_PRINT) GPUconstexpr() const char* sNames[NIDsTot + 1] = ///< defined particle names {"Electron", "Muon", "Pion", "Kaon", "Proton", "Deuteron", "Triton", "He3", "Alpha", - "Pion0", "Photon", "K0", "Lambda", "HyperTriton", "Hyperhydrog4", "XiMinus", "OmegaMinus", nullptr}; + "Pion0", "Photon", "K0", "Lambda", "HyperTriton", "Hyperhydrog4", "XiMinus", "OmegaMinus", "HyperHelium4", "HyperHelium5", nullptr}; #endif GPUconstexpr() const float sMasses[NIDsTot] = ///< defined particle masses {o2cp::MassElectron, o2cp::MassMuon, o2cp::MassPionCharged, o2cp::MassKaonCharged, o2cp::MassProton, o2cp::MassDeuteron, o2cp::MassTriton, o2cp::MassHelium3, o2cp::MassAlpha, o2cp::MassPionNeutral, o2cp::MassPhoton, - o2cp::MassKaonNeutral, o2cp::MassLambda, o2cp::MassHyperTriton, o2cp::MassHyperhydrog4, o2cp::MassXiMinus, o2cp::MassOmegaMinus}; + o2cp::MassKaonNeutral, o2cp::MassLambda, o2cp::MassHyperTriton, o2cp::MassHyperhydrog4, o2cp::MassXiMinus, o2cp::MassOmegaMinus, o2cp::MassHyperHelium4, o2cp::MassHyperHelium5}; GPUconstexpr() const float sMasses2[NIDsTot] = ///< defined particle masses^2 {o2cp::MassElectron * o2cp::MassElectron, @@ -64,7 +64,9 @@ GPUconstexpr() const float sMasses2[NIDsTot] = ///< defined particle masses^2 o2cp::MassHyperTriton* o2cp::MassHyperTriton, o2cp::MassHyperhydrog4* o2cp::MassHyperhydrog4, o2cp::MassXiMinus* o2cp::MassXiMinus, - o2cp::MassOmegaMinus* o2cp::MassOmegaMinus}; + o2cp::MassOmegaMinus* o2cp::MassOmegaMinus, + o2cp::MassHyperHelium4* o2cp::MassHyperHelium4, + o2cp::MassHyperHelium5* o2cp::MassHyperHelium5}; GPUconstexpr() const float sMasses2Z[NIDsTot] = ///< defined particle masses / Z {o2cp::MassElectron, o2cp::MassMuon, @@ -73,12 +75,14 @@ GPUconstexpr() const float sMasses2Z[NIDsTot] = ///< defined particle masses / Z o2cp::MassTriton, o2cp::MassHelium3 / 2., o2cp::MassAlpha / 2., 0, 0, 0, 0, o2cp::MassHyperTriton, o2cp::MassHyperhydrog4, - o2cp::MassXiMinus, o2cp::MassOmegaMinus}; + o2cp::MassXiMinus, o2cp::MassOmegaMinus, + o2cp::MassHyperHelium4 / 2., o2cp::MassHyperHelium5 / 2.}; GPUconstexpr() const int sCharges[NIDsTot] = ///< defined particle charges {1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 1, 1, - 1, 1}; + 1, 1, + 2, 2}; } // namespace pid_constants class PID @@ -110,8 +114,10 @@ class PID static constexpr ID Hyperhydrog4 = 14; static constexpr ID XiMinus = 15; static constexpr ID OmegaMinus = 16; + static constexpr ID HyperHelium4 = 17; + static constexpr ID HyperHelium5 = 18; static constexpr ID FirstExt = PI0; - static constexpr ID LastExt = OmegaMinus; + static constexpr ID LastExt = HyperHelium5; static constexpr ID NIDsTot = pid_constants::NIDsTot; ///< total number of defined IDs static_assert(NIDsTot == LastExt + 1, "Incorrect NIDsTot, please update!"); diff --git a/DataFormats/Reconstruction/src/Decay3Body.cxx b/DataFormats/Reconstruction/src/Decay3Body.cxx index 46f5c9447c2fb..aa071cea675cd 100644 --- a/DataFormats/Reconstruction/src/Decay3Body.cxx +++ b/DataFormats/Reconstruction/src/Decay3Body.cxx @@ -13,7 +13,7 @@ using namespace o2::dataformats; -Decay3Body::Decay3Body(PID pid, const std::array& xyz, const std::array& pxyz, const std::array& covxyz, const Track& tr0, const Track& tr1, const Track& tr2) +Decay3Body::Decay3Body(const std::array& xyz, const std::array& pxyz, const std::array& covxyz, const Track& tr0, const Track& tr1, const Track& tr2, o2::track::PID pid) : mProngs{tr0, tr1, tr2} { std::array cov{}, cov1{}, cov2{}; diff --git a/Detectors/Vertexing/include/DetectorsVertexing/SVertexHypothesis.h b/Detectors/Vertexing/include/DetectorsVertexing/SVertexHypothesis.h index 0510290fb5ae8..1450e0c15e98c 100644 --- a/Detectors/Vertexing/include/DetectorsVertexing/SVertexHypothesis.h +++ b/Detectors/Vertexing/include/DetectorsVertexing/SVertexHypothesis.h @@ -131,10 +131,14 @@ class SVertex3Hypothesis void set(PID v0, PID ppos, PID pneg, PID pbach, float sig, float nSig, float margin, float cpt, float bz = 0.f); void set(PID v0, PID ppos, PID pneg, PID pbach, const float pars[NPIDParams], float bz = 0.f); + PID getPIDHyp() const { return mPIDV0; } float getMassV0Hyp() const { return PID::getMass(mPIDV0); } float getMassPosProng() const { return PID::getMass(mPIDPosProng); } float getMassNegProng() const { return PID::getMass(mPIDNegProng); } float getMassBachProng() const { return PID::getMass(mPIDBachProng); } + float getChargePosProng() const { return PID::getCharge(mPIDPosProng); } + float getChargeNegProng() const { return PID::getCharge(mPIDNegProng); } + float getChargeBachProng() const { return PID::getCharge(mPIDBachProng); } float calcMass2(float p2Pos, float p2Neg, float p2Bach, float p2Tot) const { diff --git a/Detectors/Vertexing/include/DetectorsVertexing/SVertexer.h b/Detectors/Vertexing/include/DetectorsVertexing/SVertexer.h index 9d0823a04e625..b933363bb352d 100644 --- a/Detectors/Vertexing/include/DetectorsVertexing/SVertexer.h +++ b/Detectors/Vertexing/include/DetectorsVertexing/SVertexer.h @@ -87,6 +87,8 @@ class SVertexer enum Hyp3body { H3L3body, AntiH3L3body, + H4L3body, + AntiH4L3body, He4L3body, AntiHe4L3body, He5L3body, diff --git a/Detectors/Vertexing/include/DetectorsVertexing/SVertexerParams.h b/Detectors/Vertexing/include/DetectorsVertexing/SVertexerParams.h index b1ce6c1dfd4ad..1a21cf1d89393 100644 --- a/Detectors/Vertexing/include/DetectorsVertexing/SVertexerParams.h +++ b/Detectors/Vertexing/include/DetectorsVertexing/SVertexerParams.h @@ -138,7 +138,9 @@ struct SVertexerParams : public o2::conf::ConfigurableParamHelper d p pi- + float pidCutsH4L3body[SVertex3Hypothesis::NPIDParams] = {0.0025, 14, 0.07, 0.5}; // H4L -> t p pi- float pidCutsHe4L3body[SVertex3Hypothesis::NPIDParams] = {0.0025, 14, 0.07, 0.5}; // He4L -> He3 p pi- + float pidCutsHe5L3body[SVertex3Hypothesis::NPIDParams] = {0.0025, 14, 0.07, 0.5}; // He5L -> He4 p pi- O2ParamDef(SVertexerParams, "svertexer"); }; diff --git a/Detectors/Vertexing/src/SVertexer.cxx b/Detectors/Vertexing/src/SVertexer.cxx index 78e0ce309d6ba..1d48bcceb0097 100644 --- a/Detectors/Vertexing/src/SVertexer.cxx +++ b/Detectors/Vertexing/src/SVertexer.cxx @@ -298,6 +298,12 @@ void SVertexer::updateTimeDependentParams() m3bodyHyps[Hyp3body::H3L3body].set(PID::HyperTriton, PID::Proton, PID::Pion, PID::Deuteron, mSVParams->pidCutsH3L3body, bz); m3bodyHyps[Hyp3body::AntiH3L3body].set(PID::HyperTriton, PID::Pion, PID::Proton, PID::Deuteron, mSVParams->pidCutsH3L3body, bz); + m3bodyHyps[Hyp3body::H4L3body].set(PID::Hyperhydrog4, PID::Proton, PID::Pion, PID::Triton, mSVParams->pidCutsH4L3body, bz); + m3bodyHyps[Hyp3body::AntiH4L3body].set(PID::Hyperhydrog4, PID::Pion, PID::Proton, PID::Triton, mSVParams->pidCutsH4L3body, bz); + m3bodyHyps[Hyp3body::He4L3body].set(PID::HyperHelium4, PID::Proton, PID::Pion, PID::Helium3, mSVParams->pidCutsHe4L3body, bz); + m3bodyHyps[Hyp3body::AntiHe4L3body].set(PID::HyperHelium4, PID::Pion, PID::Proton, PID::Helium3, mSVParams->pidCutsHe4L3body, bz); + m3bodyHyps[Hyp3body::He5L3body].set(PID::HyperHelium5, PID::Proton, PID::Pion, PID::Alpha, mSVParams->pidCutsHe5L3body, bz); + m3bodyHyps[Hyp3body::AntiHe5L3body].set(PID::HyperHelium5, PID::Pion, PID::Proton, PID::Alpha, mSVParams->pidCutsHe5L3body, bz); for (auto& ft : mFitterV0) { ft.setBz(bz); @@ -1090,52 +1096,60 @@ int SVertexer::check3bodyDecays(const V0Index& v0Idx, const V0& v0, float rv0, s tr0.getPxPyPzGlo(p0); tr1.getPxPyPzGlo(p1); tr2.getPxPyPzGlo(p2); - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; - float pt2candidate = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2candidate = pt2candidate + p3B[2] * p3B[2]; - if (pt2candidate < mMinPt23Body) { // pt cut - continue; - } - if (p3B[2] * p3B[2] / pt2candidate > mMaxTgl23Body) { // tgLambda cut - continue; - } - - // compute primary vertex and cosPA of the 3-body decay - auto bestCosPA = mSVParams->minCosPA3body; + bool goodHyp = false; + o2::track::PID pidHyp = o2::track::PID::Electron; // Update if goodHyp is true auto decay3bodyVtxID = -1; + auto vtxCosPA = -1; + + std::array pbach = {0, 0, 0}, p3B = {0, 0, 0}; // Update during the check of invariant mass + for (int ipid = 0; ipid < NHyp3body; ipid++) { + // check mass based on hypothesis of charge of bachelor (pos and neg expected to be proton/pion) + float bachChargeFactor = m3bodyHyps[ipid].getChargeBachProng() / tr2.getAbsCharge(); + pbach = {bachChargeFactor * p2[0], bachChargeFactor * p2[1], bachChargeFactor * p2[2]}; + p3B = {p0[0] + p1[0] + pbach[0], p0[1] + p1[1] + pbach[1], p0[2] + p1[2] + pbach[2]}; + float sqP0 = p0[0] * p0[0] + p0[1] * p0[1] + p0[2] * p0[2], sqP1 = p1[0] * p1[0] + p1[1] * p1[1] + p1[2] * p1[2], sqPBach = pbach[0] * pbach[0] + pbach[1] * pbach[1] + pbach[2] * pbach[2]; + float pt2Candidate = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2Candidate = pt2Candidate + p3B[2] * p3B[2]; + float ptCandidate = std::sqrt(pt2Candidate); + if (m3bodyHyps[ipid].check(sqP0, sqP1, sqPBach, p2Candidate, ptCandidate)) { + if (pt2Candidate < mMinPt23Body) { // pt cut + continue; + } + if (p3B[2] * p3B[2] > pt2Candidate * mMaxTgl23Body) { // tgLambda cut + continue; + } - for (int iv = decay3bodyVlist.getMin(); iv <= decay3bodyVlist.getMax(); iv++) { - const auto& pv = mPVertices[iv]; - // check cos of pointing angle - float dx = vertexXYZ[0] - pv.getX(), dy = vertexXYZ[1] - pv.getY(), dz = vertexXYZ[2] - pv.getZ(), prodXYZ3body = dx * p3B[0] + dy * p3B[1] + dz * p3B[2]; - float cosPA = prodXYZ3body / std::sqrt((dx * dx + dy * dy + dz * dz) * p2candidate); - if (cosPA < bestCosPA) { - LOG(debug) << "Rej. cosPA: " << cosPA; - continue; - } - decay3bodyVtxID = iv; - bestCosPA = cosPA; - } - if (decay3bodyVtxID == -1) { - LOG(debug) << "3-body decay not compatible with any vertex"; - continue; - } - - const auto& decay3bodyPv = mPVertices[decay3bodyVtxID]; - float sqP0 = p0[0] * p0[0] + p0[1] * p0[1] + p0[2] * p0[2], sqP1 = p1[0] * p1[0] + p1[1] * p1[1] + p1[2] * p1[2], sqP2 = p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2]; - float pt3B = std::sqrt(pt2candidate); + // compute primary vertex and cosPA of the 3-body decay + auto bestCosPA = mSVParams->minCosPA3body; + for (int iv = decay3bodyVlist.getMin(); iv <= decay3bodyVlist.getMax(); iv++) { + const auto& pv = mPVertices[iv]; + // check cos of pointing angle + float dx = vertexXYZ[0] - pv.getX(), dy = vertexXYZ[1] - pv.getY(), dz = vertexXYZ[2] - pv.getZ(), prodXYZ3body = dx * p3B[0] + dy * p3B[1] + dz * p3B[2]; + float cosPA = prodXYZ3body / std::sqrt((dx * dx + dy * dy + dz * dz) * p2Candidate); + if (cosPA < bestCosPA) { + LOG(debug) << "Rej. cosPA: " << cosPA; + continue; + } + decay3bodyVtxID = iv; + bestCosPA = cosPA; + } + if (decay3bodyVtxID == -1) { + LOG(debug) << "3-body decay not compatible with any vertex"; + continue; + } - bool goodHyp = false; - for (int ipid = 0; ipid < 2; ipid++) { // TODO: expand this loop to cover all the 3body cases if (m3bodyHyps[ipid].check(sqP0, sqP1, sqP2, sqPtot, pt3B)) - if (m3bodyHyps[ipid].check(sqP0, sqP1, sqP2, p2candidate, pt3B)) { goodHyp = true; + pidHyp = m3bodyHyps[ipid].getPIDHyp(); + vtxCosPA = bestCosPA; break; } } if (!goodHyp) { continue; } - Decay3Body candidate3B(PID::HyperTriton, vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(cand3B), tr0, tr1, tr2); + + const auto& decay3bodyPv = mPVertices[decay3bodyVtxID]; + Decay3Body candidate3B(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(cand3B), tr0, tr1, tr2, pidHyp); o2::track::TrackParCov trc = candidate3B; o2::dataformats::DCA dca; if (!trc.propagateToDCA(decay3bodyPv, fitter3body.getBz(), &dca, 5.) || @@ -1143,7 +1157,7 @@ int SVertexer::check3bodyDecays(const V0Index& v0Idx, const V0& v0, float rv0, s continue; } if (mSVParams->createFull3Bodies) { - candidate3B.setCosPA(bestCosPA); + candidate3B.setCosPA(vtxCosPA); candidate3B.setDCA(fitter3body.getChi2AtPCACandidate()); m3bodyTmp[ithread].push_back(candidate3B); } diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 0833c6e4aae65..9c939412cd941 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -1480,7 +1480,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! Track 2 in DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision index } // namespace decay3body -DECLARE_SOA_TABLE(Decay3Bodys, "AOD", "DECAY3BODY", //! Run 2 cascade table +DECLARE_SOA_TABLE(Decay3Bodys, "AOD", "DECAY3BODY", //! 3-body decay table o2::soa::Index<>, decay3body::CollisionId, decay3body::Track0Id, decay3body::Track1Id, decay3body::Track2Id); using Decay3Bodys = Decay3Bodys; //! this defines the current default version From bc67e6d479c32947e1d4105ae73c3f11b266e559 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 19 Sep 2024 09:18:58 +0200 Subject: [PATCH 0264/2205] Add processBulk to perform fits in parallel (#13527) --- Common/DCAFitter/GPU/cuda/DCAFitterN.cu | 107 +++- .../GPU/cuda/test/testDCAFitterNGPU.cxx | 558 +++++++++++++++++- .../DCAFitter/include/DCAFitter/DCAFitterN.h | 16 +- Common/DCAFitter/test/testDCAFitterN.cxx | 54 +- 4 files changed, 660 insertions(+), 75 deletions(-) diff --git a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu index 74c27796a6ebb..5cb93d474eb86 100644 --- a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu +++ b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu @@ -36,34 +36,51 @@ namespace o2::vertexing::device { namespace kernel { +GPUg() void warmUpGpuKernel() +{ + unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x; + float ia, ib; + ia = ib = 0.0f; + ib += ia + tid; +} + template -GPUg() void printKernel(Fitter* ft) +GPUg() void printKernel(Fitter* fitter) { if (threadIdx.x == 0) { - printf(" =============== GPU DCA Fitter %d prongs ================\n", Fitter::getNProngs()); - ft->print(); + printf(" =============== GPU DCA Fitter %d prongs =================\n", Fitter::getNProngs()); + fitter->print(); printf(" =========================================================\n"); } } template -GPUg() void processKernel(Fitter* ft, int* res, Tr*... tracks) +GPUg() void processKernel(Fitter* fitter, int* res, Tr*... tracks) { - *res = ft->process(*tracks...); + *res = fitter->process(*tracks...); } + +template +GPUg() void processBulkKernel(Fitter* fitters, int* results, unsigned int N, Tr*... tracks) +{ + for (auto iThread{blockIdx.x * blockDim.x + threadIdx.x}; iThread < N; iThread += blockDim.x * gridDim.x) { + results[iThread] = fitters[iThread].process(tracks[iThread]...); + } +} + } // namespace kernel /// CPU handlers template void print(const int nBlocks, const int nThreads, - Fitter& ft) + Fitter& fitter) { - Fitter* ft_device; - gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(Fitter))); - gpuCheckError(cudaMemcpy(ft_device, &ft, sizeof(Fitter), cudaMemcpyHostToDevice)); + Fitter* fitter_device; + gpuCheckError(cudaMalloc(reinterpret_cast(&fitter_device), sizeof(Fitter))); + gpuCheckError(cudaMemcpy(fitter_device, &fitter, sizeof(Fitter), cudaMemcpyHostToDevice)); - kernel::printKernel<<>>(ft_device); + kernel::printKernel<<>>(fitter_device); gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); @@ -75,11 +92,11 @@ int process(const int nBlocks, Fitter& fitter, Tr&... args) { - Fitter* ft_device; + Fitter* fitter_device; std::array tracks_device; int result, *result_device; - gpuCheckError(cudaMalloc(reinterpret_cast(&ft_device), sizeof(Fitter))); + gpuCheckError(cudaMalloc(reinterpret_cast(&fitter_device), sizeof(Fitter))); gpuCheckError(cudaMalloc(reinterpret_cast(&result_device), sizeof(int))); int iArg{0}; @@ -90,15 +107,15 @@ int process(const int nBlocks, }(), ...); - gpuCheckError(cudaMemcpy(ft_device, &fitter, sizeof(Fitter), cudaMemcpyHostToDevice)); + gpuCheckError(cudaMemcpy(fitter_device, &fitter, sizeof(Fitter), cudaMemcpyHostToDevice)); - std::apply([&](auto&&... args) { kernel::processKernel<<>>(ft_device, result_device, args...); }, tracks_device); + std::apply([&](auto&&... args) { kernel::processKernel<<>>(fitter_device, result_device, args...); }, tracks_device); gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); gpuCheckError(cudaMemcpy(&result, result_device, sizeof(int), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaMemcpy(&fitter, ft_device, sizeof(Fitter), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaMemcpy(&fitter, fitter_device, sizeof(Fitter), cudaMemcpyDeviceToHost)); iArg = 0; ([&] { gpuCheckError(cudaMemcpy(&args, tracks_device[iArg], sizeof(o2::track::TrackParCov), cudaMemcpyDeviceToHost)); @@ -107,11 +124,71 @@ int process(const int nBlocks, }(), ...); + gpuCheckError(cudaFree(fitter_device)); gpuCheckError(cudaFree(result_device)); return result; } +template +std::vector processBulk(const int nBlocks, + const int nThreads, + std::vector& fitters, + std::vector&... args) +{ + kernel::warmUpGpuKernel<<<1, 1>>>(); + + cudaEvent_t start, stop; + gpuCheckError(cudaEventCreate(&start)); + gpuCheckError(cudaEventCreate(&stop)); + const auto nFits{fitters.size()}; // for clarity: size of all the vectors needs to be equal, not enforcing it here yet. + std::vector results(nFits); + int* results_device; + Fitter* fitters_device; + std::array tracks_device; + + int iArg{0}; + ([&] { + gpuCheckError(cudaMalloc(reinterpret_cast(&(tracks_device[iArg])), sizeof(Tr) * args.size())); + gpuCheckError(cudaMemcpy(tracks_device[iArg], args.data(), sizeof(Tr) * args.size(), cudaMemcpyHostToDevice)); + ++iArg; + }(), + ...); + gpuCheckError(cudaMalloc(reinterpret_cast(&results_device), sizeof(int) * nFits)); + gpuCheckError(cudaMalloc(reinterpret_cast(&fitters_device), sizeof(Fitter) * nFits)); + gpuCheckError(cudaMemcpy(fitters_device, fitters.data(), sizeof(Fitter) * nFits, cudaMemcpyHostToDevice)); + + gpuCheckError(cudaEventRecord(start)); + std::apply([&](auto&&... args) { kernel::processBulkKernel<<>>(fitters_device, results_device, nFits, args...); }, tracks_device); + gpuCheckError(cudaEventRecord(stop)); + + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); + + gpuCheckError(cudaMemcpy(results.data(), results_device, sizeof(int) * results.size(), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaMemcpy(fitters.data(), fitters_device, sizeof(Fitter) * nFits, cudaMemcpyDeviceToHost)); + + iArg = 0; + ([&] { + gpuCheckError(cudaMemcpy(args.data(), tracks_device[iArg], sizeof(Tr) * args.size(), cudaMemcpyDeviceToHost)); + gpuCheckError(cudaFree(tracks_device[iArg])); + ++iArg; + }(), + ...); + + gpuCheckError(cudaFree(fitters_device)); + gpuCheckError(cudaFree(results_device)); + gpuCheckError(cudaEventSynchronize(stop)); + + float milliseconds = 0; + gpuCheckError(cudaEventElapsedTime(&milliseconds, start, stop)); + + LOGP(info, "Kernel run in: {} ms using {} blocks and {} threads.", milliseconds, nBlocks, nThreads); + return results; +} + +template std::vector processBulk(const int, const int, std::vector>&, std::vector&, std::vector&); +template std::vector processBulk(const int, const int, std::vector>&, std::vector&, std::vector&, std::vector&); template int process(const int, const int, o2::vertexing::DCAFitterN<2>&, o2::track::TrackParCov&, o2::track::TrackParCov&); template int process(const int, const int, o2::vertexing::DCAFitterN<3>&, o2::track::TrackParCov&, o2::track::TrackParCov&, o2::track::TrackParCov&); template void print(const int, const int, o2::vertexing::DCAFitterN<2>&); diff --git a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx index 8a2a70f65ac1c..ff4f12827f1e8 100644 --- a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx +++ b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx @@ -23,6 +23,10 @@ #include #include +#define nBlocks 60 +#define nThreads 1024 +#define NTest 1000000 + namespace o2 { namespace vertexing @@ -142,11 +146,11 @@ TLorentzVector generate(Vec3D& vtx, std::vector& vctr, f return parent; } +#ifdef DO_SINGLE_THREAD_TEST BOOST_AUTO_TEST_CASE(DCAFitterNProngs) { - gRandom->Delete(); - gRandom = new TRandom(42); - constexpr int NTest = 10000; + // gRandom->Delete(); + // gRandom = new TRandom(42); o2::utils::TreeStreamRedirector outStream("dcafitterNTest.root"); TGenPhaseSpace genPHS; @@ -222,17 +226,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; - meanDAW /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundA : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " GPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " GPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " GPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -301,17 +305,16 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) } } - device::print(1, 1, ft); meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundA ? nfoundA : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -379,17 +382,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -456,17 +459,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -532,17 +535,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - device::print(1, 1, ft); + meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 3-prong vertices"; LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -553,6 +556,513 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) outStream.Close(); } +#endif + +BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) +{ + // gRandom->Delete(); + // gRandom = new TRandom(42); + o2::utils::TreeStreamRedirector outStreamB("dcafitterNTestBulk.root"); + + TGenPhaseSpace genPHS; + constexpr double ele = 0.00051; + constexpr double gamma = 2 * ele + 1e-6; + constexpr double pion = 0.13957; + constexpr double k0 = 0.49761; + constexpr double kch = 0.49368; + constexpr double dch = 1.86965; + std::vector gammadec = {ele, ele}; + std::vector k0dec = {pion, pion}; + std::vector dchdec = {pion, kch, pion}; + std::vector> vctracks(3, std::vector(NTest)); + std::vector vtxGen(NTest); + + double bz = 5.0; + { // 2 prongs vertices bulk processing + LOG(info) << "\n\nBulk-processing 2-prong Helix - Helix case"; + std::vector forceQ{1, 1}; + + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::vector> fitters_host(NTest); + std::vector genParents(NTest); + + std::string treeName2Abulk = "pr2aBulk", treeName2AWbulk = "pr2awBulk", treeName2Wbulk = "pr2wBulk"; + TStopwatch swAb, swAWb, swWb; + int nfoundAb = 0, nfoundAWb = 0, nfoundWb = 0; + double meanDAb = 0, meanDAWb = 0, meanDWb = 0; + swAb.Stop(); + swAWb.Stop(); + swWb.Stop(); + + ft.setUseAbsDCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + for (int iev = 0; iev < NTest; iev++) { + std::vector vc(2); + genParents[iev] = generate(vtxGen[iev], vc, bz, genPHS, k0, k0dec, forceQ); + vctracks[0][iev] = vc[0]; + vctracks[1][iev] = vc[1]; + } + + swAb.Start(false); + auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Abulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAb += minDb; + nfoundAb++; + } + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swAWb.Start(false); + auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2AWbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAWb += minDb; + nfoundAWb++; + } + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swWb.Start(false); + auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Wbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDWb += minDb; + nfoundWb++; + } + } + // + meanDAb /= nfoundAb ? nfoundAb : 1; + meanDAWb /= nfoundAWb ? nfoundAWb : 1; + meanDWb /= nfoundWb ? nfoundWb : 1; + LOGP(info, "Bulk-processed {} 2-prong vertices Helix : Helix", NTest); + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; + BOOST_CHECK(nfoundAb > 0.99 * NTest); + BOOST_CHECK(nfoundAWb > 0.99 * NTest); + BOOST_CHECK(nfoundWb > 0.99 * NTest); + BOOST_CHECK(meanDAb < 0.1); + BOOST_CHECK(meanDAWb < 0.1); + BOOST_CHECK(meanDWb < 0.1); + } + + { // 2 prongs vertices bulk processing for gamma conversion + LOG(info) << "\n\nBulk-processing 2-prong Helix - Helix case gamma conversion"; + std::vector forceQ{1, 1}; + + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMaxDXYIni(4); // do not consider V0 seeds with tracks XY-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::vector> fitters_host(NTest); + std::vector genParents(NTest); + + std::string treeName2Abulk = "gpr2aBulk", treeName2AWbulk = "gpr2awBulk", treeName2Wbulk = "gpr2wBulk"; + TStopwatch swAb, swAWb, swWb; + int nfoundAb = 0, nfoundAWb = 0, nfoundWb = 0; + double meanDAb = 0, meanDAWb = 0, meanDWb = 0; + swAb.Stop(); + swAWb.Stop(); + swWb.Stop(); + + ft.setUseAbsDCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + for (int iev = 0; iev < NTest; iev++) { + std::vector vc(2); + genParents[iev] = generate(vtxGen[iev], vc, bz, genPHS, gamma, gammadec, forceQ); + vctracks[0][iev] = vc[0]; + vctracks[1][iev] = vc[1]; + } + + swAb.Start(false); + auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Abulk, fitters_host[iev], vtxGen[iev], genParents[iev], gammadec); + meanDAb += minDb; + nfoundAb++; + } + } + // + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swAWb.Start(false); + auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2AWbulk, fitters_host[iev], vtxGen[iev], genParents[iev], gammadec); + meanDAWb += minDb; + nfoundAWb++; + } + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swWb.Start(false); + auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Wbulk, fitters_host[iev], vtxGen[iev], genParents[iev], gammadec); + meanDWb += minDb; + nfoundWb++; + } + } + // + + meanDAb /= nfoundAb ? nfoundAb : 1; + meanDAWb /= nfoundAWb ? nfoundAWb : 1; + meanDWb /= nfoundWb ? nfoundWb : 1; + LOGP(info, "Bulk-processed {} 2-prong vertices Helix : Helix from gamma conversion", NTest); + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; + BOOST_CHECK(nfoundAb > 0.99 * NTest); + BOOST_CHECK(nfoundAWb > 0.99 * NTest); + BOOST_CHECK(nfoundWb > 0.99 * NTest); + BOOST_CHECK(meanDAb < 2.1); + BOOST_CHECK(meanDAWb < 2.1); + BOOST_CHECK(meanDWb < 2.1); + } + + // 2 prongs vertices bulk processing with one of charges set to 0: Helix : Line + { + std::vector forceQ{1, 1}; + LOG(info) << "\n\nBulk-processing 2-prong Helix - Line case"; + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::vector> fitters_host(NTest); + std::vector genParents(NTest); + + std::string treeName2Abulk = "pr2aHLb", treeName2AWbulk = "pr2awHLb", treeName2Wbulk = "pr2wHLb"; + TStopwatch swAb, swAWb, swWb; + int nfoundAb = 0, nfoundAWb = 0, nfoundWb = 0; + double meanDAb = 0, meanDAWb = 0, meanDWb = 0; + swAb.Stop(); + swAWb.Stop(); + swWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + forceQ[iev % 2] = 1; + forceQ[1 - iev % 2] = 0; + std::vector vc(2); + genParents[iev] = generate(vtxGen[iev], vc, bz, genPHS, k0, k0dec, forceQ); + vctracks[0][iev] = vc[0]; + vctracks[1][iev] = vc[1]; + } + ft.setUseAbsDCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + + swAb.Start(false); + auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist with final weighted DCA " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Abulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAb += minDb; + nfoundAb++; + } + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swAWb.Start(false); + auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2AWbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAWb += minDb; + nfoundAWb++; + } + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swWb.Start(false); + auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Wbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDWb += minDb; + nfoundWb++; + } + } + + // + meanDAb /= nfoundAb ? nfoundAb : 1; + meanDAWb /= nfoundAWb ? nfoundAWb : 1; + meanDWb /= nfoundWb ? nfoundWb : 1; + LOG(info) << "Bulk-processed " << NTest << " 2-prong vertices: Helix : Line"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; + BOOST_CHECK(nfoundAb > 0.99 * NTest); + BOOST_CHECK(nfoundAWb > 0.99 * NTest); + BOOST_CHECK(nfoundWb > 0.99 * NTest); + BOOST_CHECK(meanDAb < 0.1); + BOOST_CHECK(meanDAWb < 0.1); + BOOST_CHECK(meanDWb < 0.1); + } + + // 2 prongs vertices with both of charges set to 0: Line : Line + { + std::vector forceQ{0, 0}; + LOG(info) << "\n\nBulk-processing 2-prong Line - Line case"; + o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::vector> fitters_host(NTest); + std::vector genParents(NTest); + + std::string treeName2Abulk = "pr2aLL", treeName2AWbulk = "pr2awLL", treeName2Wbulk = "pr2wLL"; + TStopwatch swAb, swAWb, swWb; + int nfoundAb = 0, nfoundAWb = 0, nfoundWb = 0; + double meanDAb = 0, meanDAWb = 0, meanDWb = 0; + swAb.Stop(); + swAWb.Stop(); + swWb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + forceQ[0] = forceQ[1] = 0; + std::vector vc(2); + genParents[iev] = generate(vtxGen[iev], vc, bz, genPHS, k0, k0dec, forceQ); + vctracks[0][iev] = vc[0]; + vctracks[1][iev] = vc[1]; + } + + ft.setUseAbsDCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + + swAb.Start(false); + auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Abulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAb += minDb; + nfoundAb++; + } + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swAWb.Start(false); + auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swAWb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2AWbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDAWb += minDb; + nfoundAWb++; + } + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + + swWb.Start(false); + auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + swWb.Stop(); + + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncWb[iev]) { + auto minDb = checkResults(outStreamB, treeName2Wbulk, fitters_host[iev], vtxGen[iev], genParents[iev], k0dec); + meanDWb += minDb; + nfoundWb++; + } + } + // ft.print(); + meanDAb /= nfoundAb ? nfoundAb : 1; + meanDAWb /= nfoundAWb ? nfoundAWb : 1; + meanDWb /= nfoundWb ? nfoundWb : 1; + LOG(info) << "Bulk-processed " << NTest << " 2-prong vertices: Line : Line"; + LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; + LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; + BOOST_CHECK(nfoundAb > 0.99 * NTest); + BOOST_CHECK(nfoundAWb > 0.99 * NTest); + BOOST_CHECK(nfoundWb > 0.99 * NTest); + BOOST_CHECK(meanDAb < 0.1); + BOOST_CHECK(meanDAWb < 0.1); + BOOST_CHECK(meanDWb < 0.1); + } + + // Bulk-process 3 prongs vertices + { + LOG(info) << "\n\nBulk-processing 3-prongs"; + std::vector forceQ{1, 1, 1}; + + o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter + ft.setBz(bz); + ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway + ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway + ft.setMaxDZIni(4); // do not consider V0 seeds with tracks Z-distance exceeding this. This is default anyway + ft.setMinParamChange(1e-3); // stop iterations if max correction is below this value. This is default anyway + ft.setMinRelChi2Change(0.9); // stop iterations if chi2 improves by less that this factor + + std::vector> fitters_host(NTest); + std::vector genParents(NTest); + + std::string treeName3Abulk = "pr3a", treeName3AWbulk = "pr3aw", treeName3Wbulk = "pr3w"; + TStopwatch swAb, swAWb, swWb; + int nfoundAb = 0, nfoundAWb = 0, nfoundWb = 0; + double meanDAb = 0, meanDAWb = 0, meanDWb = 0; + swAb.Stop(); + swAWb.Stop(); + swWb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + std::vector vc(3); + genParents[iev] = generate(vtxGen[iev], vc, bz, genPHS, dch, dchdec, forceQ); + + vctracks[0][iev] = vc[0]; + vctracks[1][iev] = vc[1]; + vctracks[2][iev] = vc[2]; + } + + ft.setUseAbsDCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + swAb.Start(false); + auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + swAb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAb[iev]) { + auto minDb = checkResults(outStreamB, treeName3Abulk, fitters_host[iev], vtxGen[iev], genParents[iev], dchdec); + meanDAb += minDb; + nfoundAb++; + } + } + + ft.setUseAbsDCA(true); + ft.setWeightedFinalPCA(true); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + + swAWb.Start(false); + auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + swAWb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncAWb[iev]) { + auto minDb = checkResults(outStreamB, treeName3AWbulk, fitters_host[iev], vtxGen[iev], genParents[iev], dchdec); + meanDAWb += minDb; + nfoundAWb++; + } + } + + ft.setUseAbsDCA(false); + ft.setWeightedFinalPCA(false); + std::fill(fitters_host.begin(), fitters_host.end(), ft); + + swWb.Start(false); + auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + swWb.Stop(); + for (int iev = 0; iev < NTest; iev++) { + LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); + if (ncWb[iev]) { + auto minDb = checkResults(outStreamB, treeName3Wbulk, fitters_host[iev], vtxGen[iev], genParents[iev], dchdec); + meanDWb += minDb; + nfoundWb++; + } + } + + // ft.print(); + meanDAb /= nfoundAb ? nfoundAb : 1; + meanDAWb /= nfoundAWb ? nfoundAWb : 1; + meanDWb /= nfoundWb ? nfoundWb : 1; + LOG(info) << "Bulk-processed " << NTest << " 3-prong vertices"; + LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; + LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; + LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; + BOOST_CHECK(nfoundAb > 0.99 * NTest); + BOOST_CHECK(nfoundAWb > 0.99 * NTest); + BOOST_CHECK(nfoundWb > 0.99 * NTest); + BOOST_CHECK(meanDAb < 0.1); + BOOST_CHECK(meanDAWb < 0.1); + BOOST_CHECK(meanDWb < 0.1); + } + outStreamB.Close(); +} } // namespace vertexing } // namespace o2 \ No newline at end of file diff --git a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h index b063d1f587fe9..5a89597ad379a 100644 --- a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h +++ b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h @@ -17,10 +17,10 @@ #ifndef _ALICEO2_DCA_FITTERN_ #define _ALICEO2_DCA_FITTERN_ -#include "MathUtils/Cartesian.h" -#include "ReconstructionDataFormats/Track.h" #include "DCAFitter/HelixHelper.h" #include "DetectorsBase/Propagator.h" +#include "MathUtils/Cartesian.h" +#include "ReconstructionDataFormats/Track.h" namespace o2 { @@ -1136,15 +1136,13 @@ using DCAFitter3 = DCAFitterN<3, o2::track::TrackParCov>; namespace device { template -void print(const int nBlocks, - const int nThreads, - Fitter& ft); +void print(const int nBlocks, const int nThreads, Fitter& ft); template -int process(const int nBlocks, - const int nThreads, - Fitter&, - Tr&... args); +int process(const int nBlocks, const int nThreads, Fitter&, Tr&... args); + +template +std::vector processBulk(const int nBlocks, const int nThreads, std::vector& fitters, std::vector
&... args); } // namespace device } // namespace vertexing diff --git a/Common/DCAFitter/test/testDCAFitterN.cxx b/Common/DCAFitter/test/testDCAFitterN.cxx index bfd671315adf6..2f9c4d455376e 100644 --- a/Common/DCAFitter/test/testDCAFitterN.cxx +++ b/Common/DCAFitter/test/testDCAFitterN.cxx @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) double bz = 5.0; // 2 prongs vertices { - LOG(info) << "Processing 2-prong Helix - Helix case"; + LOG(info) << "\n\nProcessing 2-prong Helix - Helix case"; std::vector forceQ{1, 1}; o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter @@ -221,17 +221,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); + // ft.print(); meanDA /= nfoundA ? nfoundA : 1; - meanDAW /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) // 2 prongs vertices with collinear tracks (gamma conversion) { - LOG(info) << "Processing 2-prong Helix - Helix case gamma conversion"; + LOG(info) << "\n\nProcessing 2-prong Helix - Helix case gamma conversion"; std::vector forceQ{1, 1}; o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter @@ -299,17 +299,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); + // ft.print(); meanDA /= nfoundA ? nfoundA : 1; - meanDAW /= nfoundA ? nfoundA : 1; + meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) // 2 prongs vertices with one of charges set to 0: Helix : Line { std::vector forceQ{1, 1}; - LOG(info) << "Processing 2-prong Helix - Line case"; + LOG(info) << "\n\nProcessing 2-prong Helix - Line case"; o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter ft.setBz(bz); ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway @@ -377,17 +377,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); + // ft.print(); meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -399,7 +399,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) // 2 prongs vertices with both of charges set to 0: Line : Line { std::vector forceQ{0, 0}; - LOG(info) << "Processing 2-prong Line - Line case"; + LOG(info) << "\n\nProcessing 2-prong Line - Line case"; o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter ft.setBz(bz); ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway @@ -454,17 +454,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); + // ft.print(); meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); @@ -475,8 +475,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) // 3 prongs vertices { + LOG(info) << "\n\nProcessing 3-prong vertices"; std::vector forceQ{1, 1, 1}; - o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter ft.setBz(bz); ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway @@ -530,17 +530,17 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) nfoundW++; } } - ft.print(); + // ft.print(); meanDA /= nfoundA ? nfoundA : 1; meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 3-prong vertices"; LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest - << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime(); + << " mean.dist to truth: " << meanDA << " CPU time: " << swA.CpuTime() * 1000 << " ms"; LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest - << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime(); + << " mean.dist to truth: " << meanDAW << " CPU time: " << swAW.CpuTime() * 1000 << " ms"; LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest - << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime(); + << " mean.dist to truth: " << meanDW << " CPU time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); BOOST_CHECK(nfoundW > 0.99 * NTest); From 2a45b16c6ad1ea20793894542e64b1bdd108d500 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:21:51 +0200 Subject: [PATCH 0265/2205] DPL: AsyncQueue without std::function --- Framework/Core/include/Framework/AsyncQueue.h | 74 ++++++++--- Framework/Core/src/AsyncQueue.cxx | 17 +-- Framework/Core/src/CommonServices.cxx | 118 +++++++++++------- Framework/Core/src/DataProcessingDevice.cxx | 62 +++++---- Framework/Core/test/test_AsyncQueue.cxx | 91 +++++++++----- 5 files changed, 236 insertions(+), 126 deletions(-) diff --git a/Framework/Core/include/Framework/AsyncQueue.h b/Framework/Core/include/Framework/AsyncQueue.h index 6945c2a5ab1da..d214b9bfc09ba 100644 --- a/Framework/Core/include/Framework/AsyncQueue.h +++ b/Framework/Core/include/Framework/AsyncQueue.h @@ -12,49 +12,91 @@ #define O2_FRAMEWORK_ASYNCQUUE_H_ #include "Framework/TimesliceSlot.h" -#include #include #include namespace o2::framework { -struct AsyncTaskSpec { - std::string name; - // Its priority compared to the other tasks - int score = 0; -}; - /// The position of the TaskSpec in the prototypes +/// Up to 127 different kind of tasks are allowed per queue struct AsyncTaskId { - int value = -1; + int16_t value = -1; }; /// An actuatual task to be executed struct AsyncTask { - // The task to be executed. Id can be used as unique - // id for the signpost in the async_queue stream. - std::function task; - // The associated task spec - AsyncTaskId id = {-1}; + // The timeslice after which this callback should be executed. TimesliceId timeslice = {TimesliceId::INVALID}; // Only the task with the highest debounce value will be executed - int debounce = 0; + // The associated task spec. Notice that the context + // is stored separately so that we do not need to + // manage lifetimes of std::functions + AsyncTaskId id = {-1}; + // Debounce value. + int8_t debounce = 0; bool runnable = false; + // Some unuser integer + int32_t unused = 0; + // The callback to be executed. id can be used as unique + // id for the signpost in the async_queue stream. + // Context is provided by the userdata attached to the + // task the moment we post it. + // Notice that we do not store the task in the prototype + // because we do support at the moment coalescing two + // different callbaks with the same id. + void (*callback)(AsyncTask& task, size_t id); + // Some user data e.g. to decode what comes next + // This can either be used via the .data pointer + // or by asking a cast to the appropriate type via + // the user() method. + void* data[5] = {nullptr, nullptr, nullptr, nullptr, nullptr}; + + // Helper to return userdata + template + T& user() + { + static_assert(sizeof(T) <= 5 * sizeof(void*), "User object does not fit user data"); + return *(T*)data; + } + + // Helper to set userdata + // @return a reference to this task modified. This is meant to be used like: + // + // AsyncQueueHelpers::post(queue, AsyncTask{.id = myTask}.user(Context{.contextValue})); + // + // Coupled with the other one: + // + // task.user().contextValue; + // + // it can be used to mimick capturing lambdas + template + AsyncTask& user(T&& value) + { + static_assert(sizeof(T) <= 5 * sizeof(void*), "User object does not fit user data"); + new (&data[0])(T){value}; + return *this; + } +}; + +struct AsyncTaskSpec { + std::string name; + // Its priority compared to the other tasks + int score = 0; }; struct AsyncQueue { std::vector prototypes; std::vector tasks; size_t iteration = 0; + AsyncQueue(); }; struct AsyncQueueHelpers { - using AsyncCallback = std::function; static AsyncTaskId create(AsyncQueue& queue, AsyncTaskSpec spec); // Schedule a task with @a taskId to be executed whenever the timeslice // is past timeslice. If debounce is provided, only execute the task - static void post(AsyncQueue& queue, AsyncTaskId taskId, AsyncCallback task, TimesliceId timeslice, int64_t debounce = 0); + static void post(AsyncQueue& queue, AsyncTask const& task); /// Run all the tasks which are older than the oldestPossible timeslice /// executing them by: /// 1. sorting the tasks by timeslice diff --git a/Framework/Core/src/AsyncQueue.cxx b/Framework/Core/src/AsyncQueue.cxx index 36c0c17009f82..e0e44da9cd19c 100644 --- a/Framework/Core/src/AsyncQueue.cxx +++ b/Framework/Core/src/AsyncQueue.cxx @@ -17,6 +17,10 @@ O2_DECLARE_DYNAMIC_LOG(async_queue); namespace o2::framework { +AsyncQueue::AsyncQueue() +{ +} + auto AsyncQueueHelpers::create(AsyncQueue& queue, AsyncTaskSpec spec) -> AsyncTaskId { AsyncTaskId id; @@ -25,14 +29,9 @@ auto AsyncQueueHelpers::create(AsyncQueue& queue, AsyncTaskSpec spec) -> AsyncTa return id; } -auto AsyncQueueHelpers::post(AsyncQueue& queue, AsyncTaskId id, AsyncCallback task, TimesliceId timeslice, int64_t debounce) -> void +auto AsyncQueueHelpers::post(AsyncQueue& queue, AsyncTask const& task) -> void { - AsyncTask taskToPost; - taskToPost.task = task; - taskToPost.id = id; - taskToPost.timeslice = timeslice; - taskToPost.debounce = debounce; - queue.tasks.push_back(taskToPost); + queue.tasks.push_back(task); } auto AsyncQueueHelpers::run(AsyncQueue& queue, TimesliceId oldestPossible) -> void @@ -85,6 +84,8 @@ auto AsyncQueueHelpers::run(AsyncQueue& queue, TimesliceId oldestPossible) -> vo } } // Keep only the tasks with the highest debounce value for a given id + // For this reason I need to keep the callback in the task itself, because + // two different callbacks with the same id will be coalesced. auto newEnd = std::unique(order.begin(), order.end(), [&queue](int a, int b) { return queue.tasks[a].runnable == queue.tasks[b].runnable && queue.tasks[a].id.value == queue.tasks[b].id.value && queue.tasks[a].debounce >= 0 && queue.tasks[b].debounce >= 0; }); @@ -111,7 +112,7 @@ auto AsyncQueueHelpers::run(AsyncQueue& queue, TimesliceId oldestPossible) -> vo O2_SIGNPOST_EVENT_EMIT(async_queue, opid, "run", "Running task %{public}s (%d) for timeslice %zu", queue.prototypes[queue.tasks[i].id.value].name.c_str(), i, queue.tasks[i].timeslice.value); - queue.tasks[i].task(opid.value); + queue.tasks[i].callback(queue.tasks[i], opid.value); O2_SIGNPOST_EVENT_EMIT(async_queue, opid, "run", "Done running %d", i); } } diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index 13b02c74839b9..9192cbd0c965d 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -529,12 +529,72 @@ o2::framework::ServiceSpec CommonServices::ccdbSupportSpec() } }, .kind = ServiceKind::Global}; } +struct DecongestionContext { + ServiceRegistryRef ref; + TimesliceIndex::OldestOutputInfo oldestPossibleOutput; +}; + +auto decongestionCallback = [](AsyncTask& task, size_t id) -> void { + auto& oldestPossibleOutput = task.user().oldestPossibleOutput; + auto& ref = task.user().ref; + + auto& decongestion = ref.get(); + auto& proxy = ref.get(); + + O2_SIGNPOST_ID_GENERATE(cid, async_queue); + cid.value = id; + if (decongestion.lastTimeslice >= oldestPossibleOutput.timeslice.value) { + O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Not sending already sent value: %" PRIu64 "> %" PRIu64, + decongestion.lastTimeslice, (uint64_t)oldestPossibleOutput.timeslice.value); + return; + } + O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Running oldest possible timeslice %" PRIu64 " propagation.", + (uint64_t)oldestPossibleOutput.timeslice.value); + DataProcessingHelpers::broadcastOldestPossibleTimeslice(ref, oldestPossibleOutput.timeslice.value); + + for (int fi = 0; fi < proxy.getNumForwardChannels(); fi++) { + auto& info = proxy.getForwardChannelInfo(ChannelIndex{fi}); + auto& state = proxy.getForwardChannelState(ChannelIndex{fi}); + // TODO: this we could cache in the proxy at the bind moment. + if (info.channelType != ChannelAccountingType::DPL) { + O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Skipping channel %{public}s", info.name.c_str()); + continue; + } + if (DataProcessingHelpers::sendOldestPossibleTimeframe(ref, info, state, oldestPossibleOutput.timeslice.value)) { + O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", + "Forwarding to channel %{public}s oldest possible timeslice %" PRIu64 ", priority %d", + info.name.c_str(), (uint64_t)oldestPossibleOutput.timeslice.value, 20); + } + } + decongestion.lastTimeslice = oldestPossibleOutput.timeslice.value; +}; + +auto decongestionCallbackOrdered = [](AsyncTask& task, size_t id) -> void { + auto& oldestPossibleOutput = task.user().oldestPossibleOutput; + auto& ref = task.user().ref; + + auto& decongestion = ref.get(); + auto& state = ref.get(); + auto& timesliceIndex = ref.get(); + O2_SIGNPOST_ID_GENERATE(cid, async_queue); + int64_t oldNextTimeslice = decongestion.nextTimeslice; + decongestion.nextTimeslice = std::max(decongestion.nextTimeslice, (int64_t)oldestPossibleOutput.timeslice.value); + if (oldNextTimeslice != decongestion.nextTimeslice) { + if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { + O2_SIGNPOST_EVENT_EMIT_WARN(async_queue, cid, "oldest_possible_timeslice", "Stop transition requested. Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } else { + O2_SIGNPOST_EVENT_EMIT_ERROR(async_queue, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); + } + timesliceIndex.rescan(); + } +}; // Decongestion service // If we do not have any Timeframe input, it means we must be creating timeslices // in order and that we should propagate the oldest possible timeslice at the end // of each processing step. -o2::framework::ServiceSpec CommonServices::decongestionSpec() +o2::framework::ServiceSpec + CommonServices::decongestionSpec() { return ServiceSpec{ .name = "decongestion", @@ -548,7 +608,7 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() } } auto& queue = services.get(); - decongestion->oldestPossibleTimesliceTask = AsyncQueueHelpers::create(queue, {"oldest-possible-timeslice", 100}); + decongestion->oldestPossibleTimesliceTask = AsyncQueueHelpers::create(queue, {.name = "oldest-possible-timeslice", .score = 100}); return ServiceHandle{TypeIdHelpers::uniqueId(), decongestion, ServiceKind::Serial}; }, .postForwarding = [](ProcessingContext& ctx, void* service) { @@ -632,7 +692,6 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() auto& decongestion = services.get(); auto& relayer = services.get(); auto& timesliceIndex = services.get(); - auto& proxy = services.get(); O2_SIGNPOST_ID_FROM_POINTER(cid, data_processor_context, &decongestion); O2_SIGNPOST_EVENT_EMIT(data_processor_context, cid, "oldest_possible_timeslice", "Received oldest possible timeframe %" PRIu64 " from channel %d", (uint64_t)oldestPossibleTimeslice, channel.value); @@ -650,59 +709,22 @@ o2::framework::ServiceSpec CommonServices::decongestionSpec() return; } auto& queue = services.get(); - const auto& spec = services.get(); const auto& state = services.get(); - auto *device = services.get().device(); /// We use the oldest possible timeslice to debounce, so that only the latest one /// at the end of one iteration is sent. O2_SIGNPOST_EVENT_EMIT(data_processor_context, cid, "oldest_possible_timeslice", "Queueing oldest possible timeslice %" PRIu64 " propagation for execution.", (uint64_t)oldestPossibleOutput.timeslice.value); AsyncQueueHelpers::post( - queue, decongestion.oldestPossibleTimesliceTask, [ref = services, oldestPossibleOutput, &decongestion, &proxy, &spec, device, ×liceIndex](size_t id) { - O2_SIGNPOST_ID_GENERATE(cid, async_queue); - cid.value = id; - if (decongestion.lastTimeslice >= oldestPossibleOutput.timeslice.value) { - O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Not sending already sent value: %" PRIu64 "> %" PRIu64, - decongestion.lastTimeslice, (uint64_t)oldestPossibleOutput.timeslice.value); - return; - } - O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Running oldest possible timeslice %" PRIu64 " propagation.", - (uint64_t)oldestPossibleOutput.timeslice.value); - DataProcessingHelpers::broadcastOldestPossibleTimeslice(ref, oldestPossibleOutput.timeslice.value); - - for (int fi = 0; fi < proxy.getNumForwardChannels(); fi++) { - auto& info = proxy.getForwardChannelInfo(ChannelIndex{fi}); - auto& state = proxy.getForwardChannelState(ChannelIndex{fi}); - // TODO: this we could cache in the proxy at the bind moment. - if (info.channelType != ChannelAccountingType::DPL) { - O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", "Skipping channel %{public}s", info.name.c_str()); - continue; - } - if (DataProcessingHelpers::sendOldestPossibleTimeframe(ref, info, state, oldestPossibleOutput.timeslice.value)) { - O2_SIGNPOST_EVENT_EMIT(async_queue, cid, "oldest_possible_timeslice", - "Forwarding to channel %{public}s oldest possible timeslice %" PRIu64 ", priority %d", - info.name.c_str(), (uint64_t)oldestPossibleOutput.timeslice.value, 20); - } - } - decongestion.lastTimeslice = oldestPossibleOutput.timeslice.value; - }, - TimesliceId{oldestPossibleTimeslice}, -1); + queue, AsyncTask{ .timeslice = TimesliceId{oldestPossibleTimeslice}, + .id = decongestion.oldestPossibleTimesliceTask, + .debounce = -1, .callback = decongestionCallback} + .user(DecongestionContext{.ref = services, .oldestPossibleOutput = oldestPossibleOutput})); + if (decongestion.orderedCompletionPolicyActive) { AsyncQueueHelpers::post( - queue, decongestion.oldestPossibleTimesliceTask, [ref = services, oldestPossibleOutput, &decongestion, &proxy, &spec, &state, device, ×liceIndex](size_t id) { - O2_SIGNPOST_ID_GENERATE(cid, async_queue); - int64_t oldNextTimeslice = decongestion.nextTimeslice; - decongestion.nextTimeslice = std::max(decongestion.nextTimeslice, (int64_t)oldestPossibleOutput.timeslice.value); - if (oldNextTimeslice != decongestion.nextTimeslice) { - if (state.transitionHandling != TransitionHandlingState::NoTransition && DefaultsHelpers::onlineDeploymentMode()) { - O2_SIGNPOST_EVENT_EMIT_WARN(async_queue, cid, "oldest_possible_timeslice", "Stop transition requested. Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); - } else { - O2_SIGNPOST_EVENT_EMIT_ERROR(async_queue, cid, "oldest_possible_timeslice", "Some Lifetime::Timeframe data got dropped starting at %" PRIi64, oldNextTimeslice); - } - timesliceIndex.rescan(); - } - }, - TimesliceId{oldestPossibleOutput.timeslice.value}, -1); + queue, AsyncTask{.timeslice = TimesliceId{oldestPossibleOutput.timeslice.value},.id = decongestion.oldestPossibleTimesliceTask, .debounce = -1, + .callback = decongestionCallbackOrdered} + .user({.ref = services, .oldestPossibleOutput = oldestPossibleOutput})); } }, .kind = ServiceKind::Serial}; } diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 1c46ee9ae0ac6..f3fe328e78a06 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -636,6 +636,39 @@ static auto toBeforwardedMessageSet = [](std::vector& cachedForwar return cachedForwardingChoices.empty() == false; }; +struct DecongestionContext { + ServiceRegistryRef ref; + TimesliceIndex::OldestOutputInfo oldestTimeslice; +}; + +auto decongestionCallbackLate = [](AsyncTask& task, size_t aid) -> void { + auto& oldestTimeslice = task.user().oldestTimeslice; + auto& ref = task.user().ref; + + auto& decongestion = ref.get(); + auto& proxy = ref.get(); + if (oldestTimeslice.timeslice.value <= decongestion.lastTimeslice) { + LOG(debug) << "Not sending already sent oldest possible timeslice " << oldestTimeslice.timeslice.value; + return; + } + for (int fi = 0; fi < proxy.getNumForwardChannels(); fi++) { + auto& info = proxy.getForwardChannelInfo(ChannelIndex{fi}); + auto& state = proxy.getForwardChannelState(ChannelIndex{fi}); + O2_SIGNPOST_ID_GENERATE(aid, async_queue); + // TODO: this we could cache in the proxy at the bind moment. + if (info.channelType != ChannelAccountingType::DPL) { + O2_SIGNPOST_EVENT_EMIT(async_queue, aid, "forwardInputsCallback", "Skipping channel %{public}s because it's not a DPL channel", + info.name.c_str()); + + continue; + } + if (DataProcessingHelpers::sendOldestPossibleTimeframe(ref, info, state, oldestTimeslice.timeslice.value)) { + O2_SIGNPOST_EVENT_EMIT(async_queue, aid, "forwardInputsCallback", "Forwarding to channel %{public}s oldest possible timeslice %zu, prio 20", + info.name.c_str(), oldestTimeslice.timeslice.value); + } + } +}; + // This is how we do the forwarding, i.e. we push // the inputs which are shared between this device and others // to the next one in the daisy chain. @@ -721,36 +754,13 @@ static auto forwardInputs = [](ServiceRegistryRef registry, TimesliceSlot slot, auto& asyncQueue = registry.get(); auto& decongestion = registry.get(); - auto& timesliceIndex = registry.get(); O2_SIGNPOST_ID_GENERATE(aid, async_queue); O2_SIGNPOST_EVENT_EMIT(async_queue, aid, "forwardInputs", "Queuing forwarding oldestPossible %zu", oldestTimeslice.timeslice.value); - AsyncQueueHelpers::post( - asyncQueue, decongestion.oldestPossibleTimesliceTask, [&proxy, &decongestion, registry, oldestTimeslice, ×liceIndex](size_t aid) { - // DataProcessingHelpers::broadcastOldestPossibleTimeslice(proxy, oldestTimeslice.timeslice.value); - if (oldestTimeslice.timeslice.value <= decongestion.lastTimeslice) { - LOG(debug) << "Not sending already sent oldest possible timeslice " << oldestTimeslice.timeslice.value; - return; - } - for (int fi = 0; fi < proxy.getNumForwardChannels(); fi++) { - auto& info = proxy.getForwardChannelInfo(ChannelIndex{fi}); - auto& state = proxy.getForwardChannelState(ChannelIndex{fi}); - O2_SIGNPOST_ID_GENERATE(aid, async_queue); - // TODO: this we could cache in the proxy at the bind moment. - if (info.channelType != ChannelAccountingType::DPL) { - O2_SIGNPOST_EVENT_EMIT(async_queue, aid, "forwardInputsCallback", "Skipping channel %{public}s because it's not a DPL channel", - info.name.c_str()); - - continue; - } - if (DataProcessingHelpers::sendOldestPossibleTimeframe(registry, info, state, oldestTimeslice.timeslice.value)) { - O2_SIGNPOST_EVENT_EMIT(async_queue, aid, "forwardInputsCallback", "Forwarding to channel %{public}s oldest possible timeslice %zu, prio 20", - info.name.c_str(), oldestTimeslice.timeslice.value); - } - } - }, - oldestTimeslice.timeslice, -1); + AsyncQueueHelpers::post(asyncQueue, AsyncTask{.timeslice = oldestTimeslice.timeslice, .id = decongestion.oldestPossibleTimesliceTask, .debounce = -1, .callback = decongestionCallbackLate} + .user({.ref = registry, .oldestTimeslice = oldestTimeslice})); O2_SIGNPOST_END(forwarding, sid, "forwardInputs", "Forwarding done"); }; + extern volatile int region_read_global_dummy_variable; volatile int region_read_global_dummy_variable; diff --git a/Framework/Core/test/test_AsyncQueue.cxx b/Framework/Core/test/test_AsyncQueue.cxx index 635eb131cc666..7103bb087bb87 100644 --- a/Framework/Core/test/test_AsyncQueue.cxx +++ b/Framework/Core/test/test_AsyncQueue.cxx @@ -8,10 +8,13 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. - #include #include "Framework/AsyncQueue.h" +struct TaskContext { + int& count; +}; + /// Test debouncing functionality. The same task cannot be executed more than once /// in a given run. TEST_CASE("TestDebouncing") @@ -20,11 +23,11 @@ TEST_CASE("TestDebouncing") AsyncQueue queue; auto taskId = AsyncQueueHelpers::create(queue, {.name = "test", .score = 10}); // Push two tasks on the queue with the same id - auto count = 0; - AsyncQueueHelpers::post( - queue, taskId, [&count](size_t) { count += 1; }, TimesliceId{0}, 10); - AsyncQueueHelpers::post( - queue, taskId, [&count](size_t) { count += 2; }, TimesliceId{1}, 20); + int count = 0; + AsyncQueueHelpers::post(queue, + AsyncTask{.timeslice = TimesliceId{0}, .id = taskId, .debounce = 10, .callback = [](AsyncTask& task, size_t) { task.user().count += 1; }}.user({.count = count})); + AsyncQueueHelpers::post(queue, + AsyncTask{.timeslice = TimesliceId{1}, .id = taskId, .debounce = 20, .callback = [](AsyncTask& task, size_t) { task.user().count += 2; }}.user({.count = count})); AsyncQueueHelpers::run(queue, TimesliceId{2}); REQUIRE(count == 2); } @@ -37,11 +40,9 @@ TEST_CASE("TestPriority") auto taskId1 = AsyncQueueHelpers::create(queue, {.name = "test1", .score = 10}); auto taskId2 = AsyncQueueHelpers::create(queue, {.name = "test2", .score = 20}); // Push two tasks on the queue with the same id - auto count = 0; - AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 10; }, TimesliceId{0}); - AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count /= 10; }, TimesliceId{0}); + int count = 0; + AsyncQueueHelpers::post(queue, AsyncTask{.timeslice = TimesliceId{0}, .id = taskId1, .callback = [](AsyncTask& task, size_t) { task.user().count += 10; }}.user({.count = count})); + AsyncQueueHelpers::post(queue, AsyncTask{.timeslice = TimesliceId{0}, .id = taskId2, .callback = [](AsyncTask& task, size_t) { task.user().count /= 10; }}.user({.count = count})); AsyncQueueHelpers::run(queue, TimesliceId{2}); REQUIRE(count == 10); } @@ -56,9 +57,9 @@ TEST_CASE("TestOldestTimeslice") // Push two tasks on the queue with the same id auto count = 0; AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 10; }, TimesliceId{1}); + queue, AsyncTask{.timeslice = TimesliceId{1}, .id = taskId1, .callback = [](AsyncTask& task, size_t) { task.user().count += 10; }}.user({.count = count})); AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count += 20; }, TimesliceId{0}); + queue, AsyncTask{.timeslice = TimesliceId{0}, .id = taskId2, .callback = [](AsyncTask& task, size_t) { task.user().count += 20; }}.user({.count = count})); AsyncQueueHelpers::run(queue, TimesliceId{0}); REQUIRE(count == 20); AsyncQueueHelpers::run(queue, TimesliceId{0}); @@ -72,16 +73,28 @@ TEST_CASE("TestOldestTimesliceWithBounce") { using namespace o2::framework; AsyncQueue queue; - auto taskId1 = AsyncQueueHelpers::create(queue, {.name = "test1", .score = 10}); - auto taskId2 = AsyncQueueHelpers::create(queue, {.name = "test2", .score = 20}); // Push two tasks on the queue with the same id auto count = 0; - AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 10; }, TimesliceId{2}); - AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count += 20; }, TimesliceId{1}, 10); - AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count += 30; }, TimesliceId{1}, 20); + auto taskId1 = AsyncQueueHelpers::create(queue, {.name = "test1", .score = 10}); + auto taskId2 = AsyncQueueHelpers::create(queue, {.name = "test2", .score = 20}); + REQUIRE(taskId1.value != taskId2.value); + AsyncQueueHelpers::post(queue, AsyncTask{ + .timeslice = TimesliceId{2}, + .id = taskId1, + .callback = [](AsyncTask& task, size_t) { task.user().count += 10; }} + .user({.count = count})); + AsyncQueueHelpers::post(queue, AsyncTask{ + .timeslice = TimesliceId{1}, + .id = taskId2, + .debounce = 10, + .callback = [](AsyncTask& task, size_t) { task.user().count += 20; }} + .user({.count = count})); + AsyncQueueHelpers::post(queue, AsyncTask{ + .timeslice = TimesliceId{1}, + .id = taskId2, + .debounce = 20, + .callback = [](AsyncTask& task, size_t) { task.user().count += 30; }} + .user({.count = count})); AsyncQueueHelpers::run(queue, TimesliceId{0}); REQUIRE(count == 0); REQUIRE(queue.tasks.size() == 3); @@ -98,16 +111,27 @@ TEST_CASE("TestOldestTimesliceWithNegativeBounce") { using namespace o2::framework; AsyncQueue queue; + int count = 0; auto taskId1 = AsyncQueueHelpers::create(queue, {.name = "test1", .score = 10}); auto taskId2 = AsyncQueueHelpers::create(queue, {.name = "test2", .score = 20}); // Push two tasks on the queue with the same id - auto count = 0; AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 10; }, TimesliceId{2}); + queue, AsyncTask{.timeslice = TimesliceId{2}, + .id = taskId1, + .callback = [](AsyncTask& task, size_t) { task.user().count += 10; }} + .user({.count = count})); AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count += 20; }, TimesliceId{1}, -10); + queue, AsyncTask{.timeslice = TimesliceId{1}, + .id = taskId2, + .debounce = -10, + .callback = [](AsyncTask& task, size_t) { task.user().count += 20; }} + .user({.count = count})); AsyncQueueHelpers::post( - queue, taskId2, [&count](size_t) { count += 30; }, TimesliceId{1}, -20); + queue, AsyncTask{.timeslice = TimesliceId{1}, + .id = taskId2, + .debounce = -20, + .callback = [](AsyncTask& task, size_t) { task.user().count += 30; }} + .user({.count = count})); AsyncQueueHelpers::run(queue, TimesliceId{0}); REQUIRE(count == 0); REQUIRE(queue.tasks.size() == 3); @@ -126,15 +150,26 @@ TEST_CASE("TestOldestTimeslicePerTimeslice") AsyncQueue queue; auto taskId1 = AsyncQueueHelpers::create(queue, {.name = "test1", .score = 10}); // Push two tasks on the queue with the same id - auto count = 0; + int count = 0; AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 10; }, TimesliceId{1}); + queue, AsyncTask{.timeslice = TimesliceId{1}, + .id = taskId1, + .callback = [](AsyncTask& task, size_t) { task.user().count += 10; }} + .user({.count = count})); + // The size of the queue is only updated once a flush happens + REQUIRE(queue.tasks.size() == 0); + AsyncQueueHelpers::flushPending(queue); REQUIRE(queue.tasks.size() == 1); AsyncQueueHelpers::run(queue, TimesliceId{0}); REQUIRE(queue.tasks.size() == 1); REQUIRE(count == 0); AsyncQueueHelpers::post( - queue, taskId1, [&count](size_t) { count += 20; }, TimesliceId{2}); + queue, AsyncTask{.timeslice = TimesliceId{2}, + .id = taskId1, + .callback = [](AsyncTask& task, size_t) { task.user().count += 20; }} + .user({.count = count})); + REQUIRE(queue.tasks.size() == 1); + AsyncQueueHelpers::flushPending(queue); REQUIRE(queue.tasks.size() == 2); AsyncQueueHelpers::run(queue, TimesliceId{1}); REQUIRE(queue.tasks.size() == 1); From 30680d5add91da0015d26229220497ede8525474 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:21:51 +0200 Subject: [PATCH 0266/2205] Import x9 library for blazing fast interthread message passing --- Framework/Foundation/3rdparty/CMakeLists.txt | 7 + Framework/Foundation/3rdparty/x9/LICENSE | 24 + Framework/Foundation/3rdparty/x9/README.md | 68 +++ .../Foundation/3rdparty/x9/examples/README.md | 241 ++++++++ .../3rdparty/x9/examples/run_examples.sh | 26 + .../3rdparty/x9/examples/x9_example_1.c | 113 ++++ .../3rdparty/x9/examples/x9_example_2.c | 197 +++++++ .../3rdparty/x9/examples/x9_example_3.c | 207 +++++++ .../3rdparty/x9/examples/x9_example_4.c | 158 ++++++ .../3rdparty/x9/examples/x9_example_5.c | 161 ++++++ .../3rdparty/x9/examples/x9_example_6.c | 159 ++++++ .../3rdparty/x9/profiling/README.md | 106 ++++ .../3rdparty/x9/profiling/compile_profiler.sh | 3 + .../3rdparty/x9/profiling/x9_profiler.c | 524 ++++++++++++++++++ Framework/Foundation/3rdparty/x9/x9.c | 424 ++++++++++++++ Framework/Foundation/3rdparty/x9/x9.h | 166 ++++++ 16 files changed, 2584 insertions(+) create mode 100644 Framework/Foundation/3rdparty/x9/LICENSE create mode 100644 Framework/Foundation/3rdparty/x9/README.md create mode 100644 Framework/Foundation/3rdparty/x9/examples/README.md create mode 100755 Framework/Foundation/3rdparty/x9/examples/run_examples.sh create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_1.c create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_2.c create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_3.c create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_4.c create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_5.c create mode 100644 Framework/Foundation/3rdparty/x9/examples/x9_example_6.c create mode 100644 Framework/Foundation/3rdparty/x9/profiling/README.md create mode 100755 Framework/Foundation/3rdparty/x9/profiling/compile_profiler.sh create mode 100644 Framework/Foundation/3rdparty/x9/profiling/x9_profiler.c create mode 100644 Framework/Foundation/3rdparty/x9/x9.c create mode 100644 Framework/Foundation/3rdparty/x9/x9.h diff --git a/Framework/Foundation/3rdparty/CMakeLists.txt b/Framework/Foundation/3rdparty/CMakeLists.txt index 5001ad38ed6b5..1a490278a8d37 100644 --- a/Framework/Foundation/3rdparty/CMakeLists.txt +++ b/Framework/Foundation/3rdparty/CMakeLists.txt @@ -16,5 +16,12 @@ o2_add_library(Catch2 TARGETVARNAME targetName PUBLIC_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/catch2) +o2_add_library(X9 + SOURCES x9/x9.c + TARGETVARNAME targetName + PUBLIC_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/x9) + install(FILES ${CMAKE_CURRENT_LIST_DIR}/catch2/catch_amalgamated.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${CMAKE_CURRENT_LIST_DIR}/x9/x9.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Framework/Foundation/3rdparty/x9/LICENSE b/Framework/Foundation/3rdparty/x9/LICENSE new file mode 100644 index 0000000000000..7b90e16605089 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/LICENSE @@ -0,0 +1,24 @@ +BSD 2-Clause License + +Copyright (c) 2023, Diogo Flores + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Framework/Foundation/3rdparty/x9/README.md b/Framework/Foundation/3rdparty/x9/README.md new file mode 100644 index 0000000000000..1b7ead68961eb --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/README.md @@ -0,0 +1,68 @@ +X9 +--- + +*Note: I am currently working on v2.0 which will bring further performance +gains and flexibility to the user at the (unfortunate) cost of breaking the +current API. I expect to release v2.0 by September/October 2024 and for it to be the +last major/API-breaking change to X9.* + +X9 is a low level high performance message passing library, based on a +lock-free ring buffer implemented with atomic variables, for low latency +multithreading work. +It allows for multiple producers/consumers to concurrently access the same +underlying ring buffer and provides both spinning (busy loop) and non-blocking +read and write functions. + +The library is based on three concepts: + +- A message, which is a user defined struct. +- A `x9_inbox`, which is where messages are both written to and read from. +- A `x9_node`, which is an abstraction that unifies x9_inbox(es). + +The library provides multiple functions to both read from and write to a +`x9_inbox`, as the right choice depends on the user needs. +Refer to _x9.h_, where all public functions are properly documented and their +use cases explained, and the examples folder for comprehensive examples of +different architectures. + +Enabling `X9_DEBUG` at compile time will print to stdout the reason why the +functions `x9_inbox_is_valid` and `x9_node_is_valid` returned 'false' (if they +indeed returned 'false'), or why `x9_select_inbox_from_node` did not return a +valid `x9_inbox`. + +To use the library just link with x9.c and include x9.h where necessary. + +X9 is as generic, performant and intuitive as C allows, without forcing the +user to any sort of build system preprocessor hell, pseudo-C macro based +library, or worse. +It was originally written in the context of an high-frequency-trading system +that this author developed, and was made public in June of 2023. +It is released under the BSD-2-Clause license, with the purpose of serving +others and other programs. + +Benchmarks +--- + +- Single producer and single consumer transmitting 100M messages via a single +`x9_inbox`. +- Run on Intel 11900k (cpu and ram untuned). +- _Msg size_ expressed in bytes, and _Inbox size_ in number of slots in the +ring buffer. +- _(See /profiling for how to run your own tests)_ + +``` +Inbox size | Msg size | Time (secs) | Msgs/second +------------------------------------------------- + 1024 | 16 | 4.00 | 25.01M + 1024 | 32 | 4.03 | 24.82M + 1024 | 64 | 4.17 | 23.99M +------------------------------------------------- + 2048 | 16 | 3.90 | 25.63M + 2048 | 32 | 3.96 | 25.26M + 2048 | 64 | 4.09 | 24.43M +------------------------------------------------- + 4096 | 16 | 3.86 | 25.88M + 4096 | 32 | 3.92 | 25.50M + 4096 | 64 | 4.05 | 24.67M +------------------------------------------------- +``` diff --git a/Framework/Foundation/3rdparty/x9/examples/README.md b/Framework/Foundation/3rdparty/x9/examples/README.md new file mode 100644 index 0000000000000..c2525d76cd585 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/README.md @@ -0,0 +1,241 @@ +Notes: +--- + +- Inbox N is always associated with a message of type N, hence to inbox 1 +producers will write messages of type 1 and consumers will read messages of +type 1, and so on. + +- Each producer/consumer runs in a unique thread. + +- All x9_inbox sizes equal 4. This is not ideal for performance and should not +be used as a guideline. The reason why I use such a small buffer is because +I wanted to saturate the inbox and make it much more likely to trigger a data +race (which there is none). + +- All examples/tests can be run by executing ./run_examples.sh + +``` +──────▷ write to +─ ─ ─ ▷ read from +``` + +Examples +--- +``` +x9_example_1.c: + + One producer + One consumer + One message type + + ┌────────┐ ┏━━━━━━━━┓ ┌────────┐ + │Producer│──────▷┃ inbox ┃◁ ─ ─ ─│Consumer│ + └────────┘ ┗━━━━━━━━┛ └────────┘ + + This example showcases the simplest (multi-threading) pattern. + + Data structures used: + - x9_inbox + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_write_to_inbox_spin + - x9_read_from_inbox_spin + - x9_free_inbox + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). + ``` +------------------------------------------------------------------------------- +``` +x9_example_2.c + + Two producers. + One consumer and producer simultaneously. + One consumer. + + ┌────────┐ ┏━━━━━━━━┓ ┏━━━━━━━━┓ + │Producer│─────▷┃ ┃ ┌────────┐ ┃ ┃ + └────────┘ ┃ ┃ │Consumer│ ┃ ┃ ┌────────┐ + ┃inbox 1 ┃◁ ─ ─ │ and │─────▷┃inbox 2 ┃◁ ─ ─ │Consumer│ + ┌────────┐ ┃ ┃ │Producer│ ┃ ┃ └────────┘ + │Producer│─────▷┃ ┃ └────────┘ ┃ ┃ + └────────┘ ┗━━━━━━━━┛ ┗━━━━━━━━┛ + + This example showcase using multiple threads to write to the same inbox, + using multiple message types, the 'x9_node' abstraction, and + respective create/free and select functions. + + Data structures used: + - x9_inbox + - x9_node + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_create_node + - x9_node_is_valid + - x9_select_inbox_from_node + - x9_write_to_inbox_spin + - x9_read_from_inbox_spin + - x9_free_node_and_attached_inboxes + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). +``` +------------------------------------------------------------------------------- +``` +x9_example_3.c + + Two producers and simultaneously consumers. + + ┌────────┐ ┏━━━━━━━━┓ ┌────────┐ + │Producer│──────▷┃inbox 1 ┃◁ ─ ─ ─│Producer│ + │ │ ┗━━━━━━━━┛ │ │ + │ and │ │ and │ + │ │ ┏━━━━━━━━┓ │ │ + │Consumer│─ ─ ─ ▷┃inbox 2 ┃◁──────│Consumer│ + └────────┘ ┗━━━━━━━━┛ └────────┘ + + This example showcases the use of: 'x9_write_to_inbox' + and 'x9_read_from_inbox', which, unlike 'x9_write_to_inbox_spin' and + 'x9_read_from_inbox_spin' do not block until are able to write/read a msg. + + Data structures used: + - x9_inbox + - x9_node + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_create_node + - x9_node_is_valid + - x9_select_inbox_from_node + - x9_write_to_inbox + - x9_read_from_inbox + - x9_free_node_and_attached_inboxes + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). +``` +------------------------------------------------------------------------------- +``` +x9_example_4.c + + One producer broadcasts the same message to three inboxes. + Three consumers read from each inbox. + One message type. + + ┏━━━━━━━━┓ ┌────────┐ + ┌──▷┃ inbox ┃◁─ ─ ─│Consumer│ + │ ┗━━━━━━━━┛ └────────┘ + ┌────────┐ │ ┏━━━━━━━━┓ ┌────────┐ + │Producer│───┼──▷┃ inbox ┃◁─ ─ ─│Consumer│ + └────────┘ │ ┗━━━━━━━━┛ └────────┘ + │ ┏━━━━━━━━┓ ┌────────┐ + └──▷┃ inbox ┃◁─ ─ ─│Consumer│ + ┗━━━━━━━━┛ └────────┘ + + + This example showcases the use of 'x9_broadcast_msg_to_all_node_inboxes'. + + Data structures used: + - x9_inbox + - x9_node + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_create_node + - x9_node_is_valid + - x9_broadcast_msg_to_all_node_inboxes + - x9_read_from_inbox_spin + - x9_free_node_and_attached_inboxes + + IMPORTANT: + - All inboxes must receive messages of the same type (or at least of the + same size) that its being broadcasted. + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). +``` +------------------------------------------------------------------------------- +``` +x9_example_5.c + + Three producers. + Three consumers reading concurrently from the same inbox. + One message type. + + ┌────────┐ + ┌────────┐ ┏━━━━━━━━┓ ─ ─│Consumer│ + │Producer│──────▷┃ ┃ │ └────────┘ + ├────────┤ ┃ ┃ ┌────────┐ + │Producer│──────▷┃ inbox ┃◁──┤─ ─│Consumer│ + ├────────┤ ┃ ┃ └────────┘ + │Producer│──────▷┃ ┃ │ ┌────────┐ + └────────┘ ┗━━━━━━━━┛ ─ ─│Consumer│ + └────────┘ + + This example showcases the use of 'x9_read_from_shared_inbox'. + + Data structures used: + - x9_inbox + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_write_to_inbox_spin + - x9_read_from_shared_inbox + - x9_free_inbox + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). + - Each consumer processes at least one message. +``` +------------------------------------------------------------------------------- +``` +x9_example_6.c + + One producer + Two consumers reading from the same inbox concurrently (busy loop). + One message type. + + ┏━━━━━━━━┓ ┌────────┐ + ┃ ┃ ─ ─│Consumer│ + ┌────────┐ ┃ ┃ │ └────────┘ + │Producer│──────▷┃ inbox ┃◁ ─ + └────────┘ ┃ ┃ │ ┌────────┐ + ┃ ┃ ─ ─│Consumer│ + ┗━━━━━━━━┛ └────────┘ + + This example showcases the use of 'x9_read_from_shared_inbox_spin'. + + Data structures used: + - x9_inbox + + Functions used: + - x9_create_inbox + - x9_inbox_is_valid + - x9_write_to_inbox_spin + - x9_read_from_shared_inbox_spin + - x9_free_inbox + + Test is considered passed iff: + - None of the threads stall and exit cleanly after doing the work. + - All messages sent by the producer(s) are received and asserted to be + valid by the consumer(s). + - Each consumer processes at least one message. +``` +------------------------------------------------------------------------------- diff --git a/Framework/Foundation/3rdparty/x9/examples/run_examples.sh b/Framework/Foundation/3rdparty/x9/examples/run_examples.sh new file mode 100755 index 0000000000000..6719bd9b4bb86 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/run_examples.sh @@ -0,0 +1,26 @@ +#/bin/bash + +echo "- Running examples with GCC with \"-fsanitize=thread,undefined\" enabled."; +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_1.c ../x9.c -o X9_TEST_1 -fsanitize=thread,undefined -D X9_DEBUG +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_2.c ../x9.c -o X9_TEST_2 -fsanitize=thread,undefined -D X9_DEBUG +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_3.c ../x9.c -o X9_TEST_3 -fsanitize=thread,undefined -D X9_DEBUG +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_4.c ../x9.c -o X9_TEST_4 -fsanitize=thread,undefined -D X9_DEBUG +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_5.c ../x9.c -o X9_TEST_5 -fsanitize=thread,undefined -D X9_DEBUG +gcc -Wextra -Wall -Werror -pedantic -O3 -march=native x9_example_6.c ../x9.c -o X9_TEST_6 -fsanitize=thread,undefined -D X9_DEBUG + +./X9_TEST_1; ./X9_TEST_2; ./X9_TEST_3; ./X9_TEST_4; ./X9_TEST_5; ./X9_TEST_6 +rm X9_TEST_1 X9_TEST_2 X9_TEST_3 X9_TEST_4 X9_TEST_5 X9_TEST_6 + +echo "" +echo "- Running examples with clang with \"-fsanitize=address,undefined,leak\" enabled."; + +clang -Wextra -Wall -Werror -O3 -march=native x9_example_1.c ../x9.c -o X9_TEST_1 -fsanitize=address,undefined,leak -D X9_DEBUG +clang -Wextra -Wall -Werror -O3 -march=native x9_example_2.c ../x9.c -o X9_TEST_2 -fsanitize=address,undefined,leak -D X9_DEBUG +clang -Wextra -Wall -Werror -O3 -march=native x9_example_3.c ../x9.c -o X9_TEST_3 -fsanitize=address,undefined,leak -D X9_DEBUG +clang -Wextra -Wall -Werror -O3 -march=native x9_example_4.c ../x9.c -o X9_TEST_4 -fsanitize=address,undefined,leak -D X9_DEBUG +clang -Wextra -Wall -Werror -O3 -march=native x9_example_5.c ../x9.c -o X9_TEST_5 -fsanitize=address,undefined,leak -D X9_DEBUG +clang -Wextra -Wall -Werror -O3 -march=native x9_example_6.c ../x9.c -o X9_TEST_6 -fsanitize=address,undefined,leak -D X9_DEBUG + +./X9_TEST_1; ./X9_TEST_2; ./X9_TEST_3; ./X9_TEST_4; ./X9_TEST_5; ./X9_TEST_6 +rm X9_TEST_1 X9_TEST_2 X9_TEST_3 X9_TEST_4 X9_TEST_5 X9_TEST_6 + diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_1.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_1.c new file mode 100644 index 0000000000000..6498ac2a76da7 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_1.c @@ -0,0 +1,113 @@ +/* x9_example_1.c: + * + * One producer + * One consumer + * One message type + * + * ┌────────┐ ┏━━━━━━━━┓ ┌────────┐ + * │Producer│──────▷┃ inbox ┃◁ ─ ─ ─│Consumer│ + * └────────┘ ┗━━━━━━━━┛ └────────┘ + * + * This example showcases the simplest (multi-threading) pattern. + * + * Data structures used: + * - x9_inbox + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_write_to_inbox_spin + * - x9_read_from_inbox_spin + * - x9_free_inbox + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + */ + +#include /* assert */ +#include /* pthread_t, pthread functions */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +typedef struct { + x9_inbox* inbox; +} th_struct; + +typedef struct { + int a; + int b; + int sum; +} msg; + +static int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline void fill_msg_1(msg* const msg) { + msg->a = random_int(0, 10); + msg->b = random_int(0, 10); + msg->sum = msg->a + msg->b; +} + +static void* producer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (uint64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + fill_msg_1(&m); + x9_write_to_inbox_spin(data->inbox, sizeof(msg), &m); + } + return 0; +} + +static void* consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (uint64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + x9_read_from_inbox_spin(data->inbox, sizeof(msg), &m); + assert(m.sum == (m.a + m.b)); + } + return 0; +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inbox */ + x9_inbox* const inbox = x9_create_inbox(4, "ibx_1", sizeof(msg)); + + /* Using assert to simplify code for presentation purpose. */ + assert(x9_inbox_is_valid(inbox)); + + /* Producer */ + pthread_t producer_th = {0}; + th_struct producer_struct = {.inbox = inbox}; + + /* Consumer */ + pthread_t consumer_th = {0}; + th_struct consumer_struct = {.inbox = inbox}; + + /* Launch threads */ + pthread_create(&producer_th, NULL, producer_fn, &producer_struct); + pthread_create(&consumer_th, NULL, consumer_fn, &consumer_struct); + + /* Join them */ + pthread_join(consumer_th, NULL); + pthread_join(producer_th, NULL); + + /* Cleanup */ + x9_free_inbox(inbox); + + printf("TEST PASSED: x9_example_1.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_2.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_2.c new file mode 100644 index 0000000000000..411c7c8128779 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_2.c @@ -0,0 +1,197 @@ +/* x9_example_2.c + * + * Two producers. + * One consumer and producer simultaneously. + * One consumer. + * + * ┌────────┐ ┏━━━━━━━━┓ ┏━━━━━━━━┓ + * │Producer│─────▷┃ ┃ ┌────────┐ ┃ ┃ + * └────────┘ ┃ ┃ │Consumer│ ┃ ┃ ┌────────┐ + * ┃inbox 1 ┃◁ ─ ─ │ and │─────▷┃inbox 2 ┃◁ ─ ─ │Consumer│ + * ┌────────┐ ┃ ┃ │Producer│ ┃ ┃ └────────┘ + * │Producer│─────▷┃ ┃ └────────┘ ┃ ┃ + * └────────┘ ┗━━━━━━━━┛ ┗━━━━━━━━┛ + * + * This example showcase using multiple threads to write to the same inbox, + * using multiple message types, the 'x9_node' abstraction, and + * respective create/free and select functions. + * + * Data structures used: + * - x9_inbox + * - x9_node + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_create_node + * - x9_node_is_valid + * - x9_select_inbox_from_node + * - x9_write_to_inbox_spin + * - x9_read_from_inbox_spin + * - x9_free_node_and_attached_inboxes + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + */ + +#include /* assert */ +#include /* pthread_t, pthread functions */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +#define NUMBER_OF_PRODUCER_THREADS 2 + +typedef struct { + x9_node* node; +} th_struct; + +typedef struct { + int a; + int b; + int sum; + +} msg_type_1; + +typedef struct { + int x; + int y; + int sum; + int product; +} msg_type_2; + +static inline int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline void fill_msg_type_1(msg_type_1 msg[const static 1]) { + msg->a = random_int(0, 10); + msg->b = random_int(0, 10); + msg->sum = msg->a + msg->b; +} + +static inline void fill_msg_type_2(msg_type_2 to[const static 1], + msg_type_1 const from[const static 1]) { + to->x = from->a; + to->y = from->b; + to->sum = from->sum; + to->product = (from->a * from->b); +} + +static void* producer_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const destination = x9_select_inbox_from_node(data->node, "ibx_1"); + assert(x9_inbox_is_valid(destination)); + + msg_type_1 msg = {0}; + for (uint64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + fill_msg_type_1(&msg); + x9_write_to_inbox_spin(destination, sizeof(msg_type_1), &msg); + } + return 0; +} + +static void* producer_consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const inbox = x9_select_inbox_from_node(data->node, "ibx_1"); + + assert(x9_inbox_is_valid(inbox)); + + x9_inbox* const destination = x9_select_inbox_from_node(data->node, "ibx_2"); + + assert(x9_inbox_is_valid(destination)); + + msg_type_1 incoming_msg = {0}; + msg_type_2 outgoing_msg = {0}; + for (uint64_t k = 0; k != (NUMBER_OF_MESSAGES * NUMBER_OF_PRODUCER_THREADS); + ++k) { + x9_read_from_inbox_spin(inbox, sizeof(msg_type_1), &incoming_msg); + assert(incoming_msg.sum == (incoming_msg.a + incoming_msg.b)); + fill_msg_type_2(&outgoing_msg, &incoming_msg); + x9_write_to_inbox_spin(destination, sizeof(msg_type_2), &outgoing_msg); + } + return 0; +} + +static void* consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const inbox = x9_select_inbox_from_node(data->node, "ibx_2"); + + assert(x9_inbox_is_valid(inbox)); + + msg_type_2 msg = {0}; + for (uint64_t k = 0; k != (NUMBER_OF_MESSAGES * NUMBER_OF_PRODUCER_THREADS); + ++k) { + x9_read_from_inbox_spin(inbox, sizeof(msg_type_2), &msg); + assert(msg.sum == (msg.x + msg.y)); + assert(msg.product == (msg.x * msg.y)); + } + return 0; +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inboxes */ + x9_inbox* const inbox_msg_type_1 = + x9_create_inbox(4, "ibx_1", sizeof(msg_type_1)); + + x9_inbox* const inbox_msg_type_2 = + x9_create_inbox(4, "ibx_2", sizeof(msg_type_2)); + + /* Using asserts to simplify code for presentation purpose. */ + assert(x9_inbox_is_valid(inbox_msg_type_1)); + assert(x9_inbox_is_valid(inbox_msg_type_2)); + + /* Create node */ + x9_node* const node = + x9_create_node("my_node", 2, inbox_msg_type_1, inbox_msg_type_2); + + /* Assert - Same reason as above. */ + assert(x9_node_is_valid(node)); + + /* Producers */ + pthread_t producer_th_1 = {0}; + th_struct producer_1_struct = {.node = node}; + + pthread_t producer_th_2 = {0}; + th_struct producer_2_struct = {.node = node}; + + /* Producer/Consumer */ + pthread_t producer_consumer_th = {0}; + th_struct prod_cons_struct = {.node = node}; + + /* Consumer */ + pthread_t consumer_th = {0}; + th_struct consumer_struct = {.node = node}; + + /* Launch threads */ + pthread_create(&producer_th_1, NULL, producer_fn, &producer_1_struct); + pthread_create(&producer_th_2, NULL, producer_fn, &producer_2_struct); + pthread_create(&consumer_th, NULL, consumer_fn, &consumer_struct); + pthread_create(&producer_consumer_th, NULL, &producer_consumer_fn, + &prod_cons_struct); + + /* Join them */ + pthread_join(consumer_th, NULL); + pthread_join(producer_consumer_th, NULL); + pthread_join(producer_th_1, NULL); + pthread_join(producer_th_2, NULL); + + /* Cleanup */ + x9_free_node_and_attached_inboxes(node); + + printf("TEST PASSED: x9_example_2.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_3.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_3.c new file mode 100644 index 0000000000000..c10824e208c3c --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_3.c @@ -0,0 +1,207 @@ +/* x9_example_3.c + * + * Two producers and simultaneously consumers. + * + * ┌────────┐ ┏━━━━━━━━┓ ┌────────┐ + * │Producer│──────▷┃inbox 1 ┃◁ ─ ─ ─│Producer│ + * │ │ ┗━━━━━━━━┛ │ │ + * │ and │ │ and │ + * │ │ ┏━━━━━━━━┓ │ │ + * │Consumer│─ ─ ─ ▷┃inbox 2 ┃◁──────│Consumer│ + * └────────┘ ┗━━━━━━━━┛ └────────┘ + * + * This example showcases the use of: 'x9_write_to_inbox' + * and 'x9_read_from_inbox', which, unlike 'x9_write_to_inbox_spin' and + * 'x9_read_from_inbox_spin' do not block until are able to write/read a msg. + * + * Data structures used: + * - x9_inbox + * - x9_node + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_create_node + * - x9_node_is_valid + * - x9_select_inbox_from_node + * - x9_write_to_inbox + * - x9_read_from_inbox + * - x9_free_node_and_attached_inboxes + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + */ + +#include /* assert */ +#include /* fabs */ +#include /* pthread_t, pthread functions */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +typedef struct { + x9_node* node; +} th_struct; + +typedef struct { + int a; + int b; + int sum; +} msg_type_1; + +typedef struct { + double x; + double y; + double product; +} msg_type_2; + +static inline int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline double random_double(int const min, int const max) { + return ((double)(random_int(min, max) * 1.0)); +} + +static inline void fill_msg_type_1(msg_type_1* const msg) { + msg->a = random_int(0, 10); + msg->b = random_int(0, 10); + msg->sum = msg->a + msg->b; +} + +static inline void fill_msg_type_2(msg_type_2* const msg) { + msg->x = random_double(0, 10); + msg->y = random_double(0, 10); + msg->product = msg->x * msg->y; +} + +static void* producer_1_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const write_inbox = x9_select_inbox_from_node(data->node, "ibx_1"); + assert(write_inbox); + + x9_inbox* const read_inbox = x9_select_inbox_from_node(data->node, "ibx_2"); + assert(read_inbox); + + uint64_t msgs_read = {0}; + uint64_t msgs_sent = {0}; + + msg_type_2 incoming_msg = {0}; + msg_type_1 outgoing_msg = {0}; + + for (;;) { + if ((msgs_read == NUMBER_OF_MESSAGES) && + (msgs_sent == NUMBER_OF_MESSAGES)) { + break; + } + + if (msgs_sent != NUMBER_OF_MESSAGES) { + fill_msg_type_1(&outgoing_msg); + if (x9_write_to_inbox(write_inbox, sizeof(msg_type_1), &outgoing_msg)) { + ++msgs_sent; + } + } + + if (msgs_read != NUMBER_OF_MESSAGES) { + if (x9_read_from_inbox(read_inbox, sizeof(msg_type_2), &incoming_msg)) { + ++msgs_read; + assert(fabs(incoming_msg.product - (incoming_msg.x * incoming_msg.y)) < + 0.1); + } + } + } + + return 0; +} + +static void* producer_2_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const write_inbox = x9_select_inbox_from_node(data->node, "ibx_2"); + assert(write_inbox); + + x9_inbox* const read_inbox = x9_select_inbox_from_node(data->node, "ibx_1"); + assert(read_inbox); + + uint64_t msgs_read = {0}; + uint64_t msgs_sent = {0}; + + msg_type_1 incoming_msg = {0}; + msg_type_2 outgoing_msg = {0}; + + for (;;) { + if ((msgs_read == NUMBER_OF_MESSAGES) && + (msgs_sent == NUMBER_OF_MESSAGES)) { + break; + } + + if (msgs_read != NUMBER_OF_MESSAGES) { + if (x9_read_from_inbox(read_inbox, sizeof(msg_type_1), &incoming_msg)) { + ++msgs_read; + assert(incoming_msg.sum == (incoming_msg.a + incoming_msg.b)); + } + } + + if (msgs_sent != NUMBER_OF_MESSAGES) { + fill_msg_type_2(&outgoing_msg); + if (x9_write_to_inbox(write_inbox, sizeof(msg_type_2), &outgoing_msg)) { + ++msgs_sent; + } + } + } + + return 0; +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inboxes */ + x9_inbox* const inbox_msg_type_1 = + x9_create_inbox(4, "ibx_1", sizeof(msg_type_1)); + + x9_inbox* const inbox_msg_type_2 = + x9_create_inbox(4, "ibx_2", sizeof(msg_type_2)); + + /* Using asserts to simplify code for presentation purpose. */ + assert(x9_inbox_is_valid(inbox_msg_type_1)); + assert(x9_inbox_is_valid(inbox_msg_type_2)); + + /* Create node */ + x9_node* const node = + x9_create_node("my_node", 2, inbox_msg_type_1, inbox_msg_type_2); + + /* Asserts - Same reason as above.*/ + assert(x9_node_is_valid(node)); + + /* Producer 1 (left on diagram) */ + pthread_t producer_1_th = {0}; + th_struct producer_1_struct = {.node = node}; + + /* Producer 2 (right on diagram) */ + pthread_t producer_2_th = {0}; + th_struct producer_2_struct = {.node = node}; + + /* Launch threads */ + pthread_create(&producer_1_th, NULL, producer_1_fn, &producer_1_struct); + pthread_create(&producer_2_th, NULL, producer_2_fn, &producer_2_struct); + + /* Join them */ + pthread_join(producer_1_th, NULL); + pthread_join(producer_2_th, NULL); + + /* Cleanup */ + x9_free_node_and_attached_inboxes(node); + + printf("TEST PASSED: x9_example_3.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_4.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_4.c new file mode 100644 index 0000000000000..a4a096bebce94 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_4.c @@ -0,0 +1,158 @@ +/* x9_example_4.c + * + * One producer broadcasts the same message to three inboxes. + * Three consumers read from each inbox. + * One message type. + * + * ┏━━━━━━━━┓ ┌────────┐ + * ┌──▷┃ inbox ┃◁─ ─ ─│Consumer│ + * │ ┗━━━━━━━━┛ └────────┘ + * ┌────────┐ │ ┏━━━━━━━━┓ ┌────────┐ + * │Producer│───┼──▷┃ inbox ┃◁─ ─ ─│Consumer│ + * └────────┘ │ ┗━━━━━━━━┛ └────────┘ + * │ ┏━━━━━━━━┓ ┌────────┐ + * └──▷┃ inbox ┃◁─ ─ ─│Consumer│ + * ┗━━━━━━━━┛ └────────┘ + * + * + * This example showcases the use of 'x9_broadcast_msg_to_all_node_inboxes'. + * + * Data structures used: + * - x9_inbox + * - x9_node + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_create_node + * - x9_node_is_valid + * - x9_broadcast_msg_to_all_node_inboxes + * - x9_read_from_inbox_spin + * - x9_free_node_and_attached_inboxes + * + * IMPORTANT: + * - All inboxes must receive messages of the same type (or at least of the + * same size) that its being broadcasted. + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + */ + +#include /* assert */ +#include /* pthread_t, pthread functions */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +typedef struct { + x9_node* node; + char* inbox_to_consume_from; +} th_struct; + +typedef struct { + int a; + int b; + int sum; +} msg; + +static inline int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline void fill_msg_type(msg* const m) { + m->a = random_int(0, 10); + m->b = random_int(0, 10); + m->sum = m->a + m->b; +} + +static void* producer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (uint_fast64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + fill_msg_type(&m); + x9_broadcast_msg_to_all_node_inboxes(data->node, sizeof(msg), &m); + } + return 0; +} + +static void* consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + + x9_inbox* const inbox = + x9_select_inbox_from_node(data->node, data->inbox_to_consume_from); + assert(x9_inbox_is_valid(inbox)); + + msg m = {0}; + + for (uint64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + x9_read_from_inbox_spin(inbox, sizeof(msg), &m); + assert(m.sum == (m.a + m.b)); + } + return 0; +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inboxes */ + x9_inbox* const inbox_consumer_1 = x9_create_inbox(4, "ibx_1", sizeof(msg)); + x9_inbox* const inbox_consumer_2 = x9_create_inbox(4, "ibx_2", sizeof(msg)); + x9_inbox* const inbox_consumer_3 = x9_create_inbox(4, "ibx_3", sizeof(msg)); + + /* Using asserts to simplify code for presentation purpose. */ + assert(x9_inbox_is_valid(inbox_consumer_1)); + assert(x9_inbox_is_valid(inbox_consumer_2)); + assert(x9_inbox_is_valid(inbox_consumer_3)); + + /* Create node */ + x9_node* const node = x9_create_node("my_node", 3, inbox_consumer_1, + inbox_consumer_2, inbox_consumer_3); + + /* Assert - Same reason as above. */ + assert(x9_node_is_valid(node)); + + /* Producer */ + pthread_t producer_th = {0}; + th_struct producer_struct = {.node = node}; + + /* Consumer 1 */ + pthread_t consumer_1_th = {0}; + th_struct consumer_1_struct = {.node = node, + .inbox_to_consume_from = "ibx_1"}; + /* Consumer 2 */ + pthread_t consumer_2_th = {0}; + th_struct consumer_2_struct = {.node = node, + .inbox_to_consume_from = "ibx_2"}; + + /* Consumer 3 */ + pthread_t consumer_3_th = {0}; + th_struct consumer_3_struct = {.node = node, + .inbox_to_consume_from = "ibx_3"}; + + /* Launch threads */ + pthread_create(&producer_th, NULL, producer_fn, &producer_struct); + pthread_create(&consumer_1_th, NULL, consumer_fn, &consumer_1_struct); + pthread_create(&consumer_2_th, NULL, consumer_fn, &consumer_2_struct); + pthread_create(&consumer_3_th, NULL, consumer_fn, &consumer_3_struct); + + /* Join them */ + pthread_join(producer_th, NULL); + pthread_join(consumer_1_th, NULL); + pthread_join(consumer_2_th, NULL); + pthread_join(consumer_3_th, NULL); + + /* Cleanup */ + x9_free_node_and_attached_inboxes(node); + + printf("TEST PASSED: x9_example_4.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_5.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_5.c new file mode 100644 index 0000000000000..9f310feed6b90 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_5.c @@ -0,0 +1,161 @@ +/* x9_example_5.c + * + * Three producers. + * Three consumers reading concurrently from the same inbox. + * One message type. + * + * ┌────────┐ + * ┌────────┐ ┏━━━━━━━━┓ ─ ─│Consumer│ + * │Producer│──────▷┃ ┃ │ └────────┘ + * ├────────┤ ┃ ┃ ┌────────┐ + * │Producer│──────▷┃ inbox ┃◁──┤─ ─│Consumer│ + * ├────────┤ ┃ ┃ └────────┘ + * │Producer│──────▷┃ ┃ │ ┌────────┐ + * └────────┘ ┗━━━━━━━━┛ ─ ─│Consumer│ + * └────────┘ + * + * This example showcases the use of 'x9_read_from_shared_inbox'. + * + * Data structures used: + * - x9_inbox + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_write_to_inbox_spin + * - x9_read_from_shared_inbox + * - x9_free_inbox + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + * - Each consumer processes at least one message. + */ + +#include /* assert */ +#include /* pthread_t, pthread functions */ +#include /* bool */ +#include /* uint64_t */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +#define NUMBER_OF_PRODUCER_THREADS 3 + +typedef struct { + x9_inbox* inbox; + uint64_t msgs_read; +} th_struct; + +typedef struct { + int a; + int b; + int sum; + bool last_message; + char pad[3]; +} msg; + +static inline int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline void fill_msg_type(msg* const m) { + m->a = random_int(0, 10); + m->b = random_int(0, 10); + m->sum = m->a + m->b; +} + +static void* producer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (uint_fast64_t k = 0; k != NUMBER_OF_MESSAGES; ++k) { + fill_msg_type(&m); + if (k == (NUMBER_OF_MESSAGES - 1)) { m.last_message = true; } + x9_write_to_inbox_spin(data->inbox, sizeof(msg), &m); + } + return 0; +} + +static void* consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (;;) { + if (x9_read_from_shared_inbox(data->inbox, sizeof(msg), &m)) { + assert(m.sum == (m.a + m.b)); + ++data->msgs_read; + if (m.last_message) { return 0; } + } + } +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inbox */ + x9_inbox* const inbox = x9_create_inbox(4, "ibx", sizeof(msg)); + + /* Using assert to simplify code for presentation purpose. */ + assert(x9_inbox_is_valid(inbox)); + + /* Producers */ + pthread_t producer_1_th = {0}; + th_struct producer_1_struct = {.inbox = inbox}; + + pthread_t producer_2_th = {0}; + th_struct producer_2_struct = {.inbox = inbox}; + + pthread_t producer_3_th = {0}; + th_struct producer_3_struct = {.inbox = inbox}; + + /* Consumers */ + pthread_t consumer_1_th = {0}; + th_struct consumer_1_struct = {.inbox = inbox}; + + pthread_t consumer_2_th = {0}; + th_struct consumer_2_struct = {.inbox = inbox}; + + pthread_t consumer_3_th = {0}; + th_struct consumer_3_struct = {.inbox = inbox}; + + /* Launch threads */ + pthread_create(&producer_1_th, NULL, producer_fn, &producer_1_struct); + pthread_create(&producer_2_th, NULL, producer_fn, &producer_2_struct); + pthread_create(&producer_3_th, NULL, producer_fn, &producer_3_struct); + pthread_create(&consumer_1_th, NULL, consumer_fn, &consumer_1_struct); + pthread_create(&consumer_2_th, NULL, consumer_fn, &consumer_2_struct); + pthread_create(&consumer_3_th, NULL, consumer_fn, &consumer_3_struct); + + /* Join them */ + pthread_join(producer_1_th, NULL); + pthread_join(producer_2_th, NULL); + pthread_join(producer_3_th, NULL); + pthread_join(consumer_1_th, NULL); + pthread_join(consumer_2_th, NULL); + pthread_join(consumer_3_th, NULL); + + /* Assert that all of the consumers read from the shared inbox. */ + assert(consumer_1_struct.msgs_read > 0); + assert(consumer_2_struct.msgs_read > 0); + assert(consumer_3_struct.msgs_read > 0); + + /* Assert that the total number of messages read == (NUMBER_OF_MESSAGES * + * NUMBER_OF_PRODUCER_THREADS) */ + assert((NUMBER_OF_MESSAGES * NUMBER_OF_PRODUCER_THREADS) == + (consumer_1_struct.msgs_read + consumer_2_struct.msgs_read + + consumer_3_struct.msgs_read)); + + /* Cleanup */ + x9_free_inbox(inbox); + + printf("TEST PASSED: x9_example_5.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/examples/x9_example_6.c b/Framework/Foundation/3rdparty/x9/examples/x9_example_6.c new file mode 100644 index 0000000000000..1faad026e1feb --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/examples/x9_example_6.c @@ -0,0 +1,159 @@ +/* x9_example_6.c + * + * One producer + * Two consumers reading from the same inbox concurrently (busy loop). + * One message type. + * + * ┏━━━━━━━━┓ ┌────────┐ + * ┃ ┃ ─ ─│Consumer│ + * ┌────────┐ ┃ ┃ │ └────────┘ + * │Producer│──────▷┃ inbox ┃◁ ─ + * └────────┘ ┃ ┃ │ ┌────────┐ + * ┃ ┃ ─ ─│Consumer│ + * ┗━━━━━━━━┛ └────────┘ + * + * This example showcases the use of 'x9_read_from_shared_inbox_spin'. + * + * Data structures used: + * - x9_inbox + * + * Functions used: + * - x9_create_inbox + * - x9_inbox_is_valid + * - x9_write_to_inbox_spin + * - x9_read_from_shared_inbox_spin + * - x9_free_inbox + * + * Test is considered passed iff: + * - None of the threads stall and exit cleanly after doing the work. + * - All messages sent by the producer(s) are received and asserted to be + * valid by the consumer(s). + * - Each consumer processes at least one message. + */ + +#include /* assert */ +#include /* pthread_t, pthread functions */ +#include /* atomic_* */ +#include /* bool */ +#include /* uint64_t */ +#include /* printf */ +#include /* rand, RAND_MAX */ + +#include "../x9.h" + +/* Both producer and consumer loops, would commonly be infinite loops, but for + * the purpose of testing a reasonable NUMBER_OF_MESSAGES is defined. */ +#define NUMBER_OF_MESSAGES 1000000 + +typedef struct { + x9_inbox* inbox; + uint64_t msgs_read; +} th_struct; + +typedef struct { + int a; + int b; + int sum; + bool last_message; + char pad[3]; +} msg; + +static inline int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static inline void fill_msg_type(msg* const m) { + m->a = random_int(0, 10); + m->b = random_int(0, 10); + m->sum = m->a + m->b; +} + +static void* producer_fn(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {0}; + for (uint_fast64_t k = 0; k != (NUMBER_OF_MESSAGES); ++k) { + fill_msg_type(&m); + if (k == (NUMBER_OF_MESSAGES - 1)) { m.last_message = true; } + x9_write_to_inbox_spin(data->inbox, sizeof(msg), &m); + } + return 0; +} + +static void* consumer_fn(void* args) { + th_struct* data = (th_struct*)args; + msg m = {0}; + for (;;) { + x9_read_from_shared_inbox_spin(data->inbox, sizeof(msg), &m); + assert(m.sum == (m.a + m.b)); + + /* The First thread to read the 'last message' writes the same message back + * to the inbox, so in case the second thread had already entered + * 'x9_read_from_shared_inbox_spin' function, it will be able to read the + * message and do a clean exit. + * If the second thread, at the time that the first thread set + * 'g_read_last= true' to hasn't entered 'x9_write_to_inbox_spin', then it + * will check the if(g_read_last) condition above and exit. + * The first case would equal NUMBER_OF_MESSAGES + 1 read. + * The second case, NUMBER_OF_MESSAGES. + * Given the implementation of 'x9_read_from_shared_inbox_spin', this is + * the only way to get a clean exit without killing the second thread. */ + if (m.last_message) { + x9_write_to_inbox_spin(data->inbox, sizeof(msg), &m); + ++data->msgs_read; + return 0; + } + ++data->msgs_read; + } +} + +int main(void) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + /* Create inbox */ + x9_inbox* const inbox = x9_create_inbox(4, "ibx", sizeof(msg)); + + /* Using assert to simplify code for presentation purpose */ + assert(x9_inbox_is_valid(inbox)); + + /* Producer */ + pthread_t producer_th = {0}; + th_struct producer_struct = {.inbox = inbox}; + + /* Consumers */ + pthread_t consumer_1_th = {0}; + th_struct consumer_1_struct = {.inbox = inbox}; + + pthread_t consumer_2_th = {0}; + th_struct consumer_2_struct = {.inbox = inbox}; + + /* Launch threads */ + pthread_create(&producer_th, NULL, producer_fn, &producer_struct); + pthread_create(&consumer_1_th, NULL, consumer_fn, &consumer_1_struct); + pthread_create(&consumer_2_th, NULL, consumer_fn, &consumer_2_struct); + + /* Join them */ + pthread_join(producer_th, NULL); + pthread_join(consumer_1_th, NULL); + pthread_join(consumer_2_th, NULL); + + /* Assert that all of the consumers read from the shared inbox. */ + assert(consumer_1_struct.msgs_read > 0); + assert(consumer_2_struct.msgs_read > 0); + + /* Assert that the total number of messages read == NUMBER_OF_MESSAGES or + * NUMBER_OF_MESSAGES + 1 */ + assert((NUMBER_OF_MESSAGES + 1) == + (consumer_1_struct.msgs_read + consumer_2_struct.msgs_read) || + (NUMBER_OF_MESSAGES) == + (consumer_1_struct.msgs_read + consumer_2_struct.msgs_read) + + ); + + /* Cleanup */ + x9_free_inbox(inbox); + + printf("TEST PASSED: x9_example_6.c\n"); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/profiling/README.md b/Framework/Foundation/3rdparty/x9/profiling/README.md new file mode 100644 index 0000000000000..c10f3f1c658cc --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/profiling/README.md @@ -0,0 +1,106 @@ +Notes: +--- + +``` +x9_profiler.c + +- One producer thread +- One consumer thread +- One x9_inbox + +┌────────┐ ┏━━━━━━━━┓ ┌────────┐ +│Producer│──────▷┃ inbox ┃◁ ─ ─ ─│Consumer│ +└────────┘ ┗━━━━━━━━┛ └────────┘ +``` + +`x9_profiler.c` allows to test the performance of the library given different +parameters, such as the _inbox size_, _message size_ and in which _cpu cores_ +the test is performed. +It does so by having the producer/writer write _N messages_ to the _inbox_ and +the consumer/reader read them. +All of these parameters are user defined and passed to the program as command +line arguments, as shown below. + +Additionally, two different types of tests can be run: +- **--test 1** should be used to get an idea of the raw performance of the +library since it calls `x9_write_to_inbox_spin` and `x9_read_from_inbox_spin` +in the background, which is ideal for low latency systems. +- **--test 2** uses the non spinning version of the functions above, and while +it will be slower, it allows to understand the _hit ratio_ of +both the producer and consumer. + +_Hit ratio_ is defined as the number of messages the writer(reader) wrote(read) +divided by the number of times it attempted to write(read), and can be helpful +when deciding in which _cpu cores_ to run specific threads. + +Overall, both tests are useful for fine-tuning which _inbox size_ to use and +gaining a better understanding of the expected performance when transmitting +_messages_ of a given type (i.e. sizeof(some_type)). +Moreover, they can be used to measure the impact of overclocking +(on specific cores or as a whole). + +- When `--n_its` > 1 the results presented will be the _median_ of all +iterations. +- The writer will run on the first core of the values passed to +`--run_in_cores` and the reader in the second. + +The program can be compiled with: _./compile_profiler.sh_ and run as follows: + +``` +Example (test 1): + +$ ./X9_PROF \ + --test 1 \ + --inboxes_szs 1024,2048,4096 \ + --msgs_szs 16,32,64 \ + --n_msgs 100000000 \ + --n_its 1 \ + --run_in_cores 2,4 + + +Inbox size | Msg size | Time (secs) | Msgs/Second +------------------------------------------------- + 1024 | 16 | 8.82 | 11.33M + 1024 | 32 | 8.70 | 11.50M + 1024 | 64 | 8.65 | 11.56M +------------------------------------------------- + 2048 | 16 | 9.10 | 10.99M + 2048 | 32 | 9.53 | 10.49M + 2048 | 64 | 9.44 | 10.60M +------------------------------------------------- + 4096 | 16 | 9.08 | 11.01M + 4096 | 32 | 9.53 | 10.50M + 4096 | 64 | 9.43 | 10.60M +------------------------------------------------- +``` + +``` +Example (test 2): + +$ ./X9_PROF \ + --test 2 \ + --inboxes_szs 1024,2048,4096 \ + --msgs_szs 16,32,64,128 \ + --n_msgs 100000000 \ + --n_its 1 \ + --run_in_cores 2,4 + + +Inbox size | Msg size | Time (secs) | Msgs/second | Writer hit ratio | Reader hit ratio +--------------------------------------------------------------------------------------- + 1024 | 16 | 12.69 | 7.88M | 100.00% | 69.92% + 1024 | 32 | 13.00 | 7.69M | 100.00% | 56.46% + 1024 | 64 | 13.79 | 7.25M | 46.85% | 99.88% + 1024 | 128 | 11.53 | 8.68M | 100.00% | 67.11% +--------------------------------------------------------------------------------------- + 2048 | 16 | 11.92 | 8.39M | 100.00% | 68.22% + 2048 | 32 | 11.65 | 8.58M | 100.00% | 82.29% + 2048 | 64 | 10.05 | 9.95M | 81.91% | 99.81% + 2048 | 128 | 11.64 | 8.59M | 100.00% | 78.21% +--------------------------------------------------------------------------------------- + 4096 | 16 | 12.19 | 8.21M | 100.00% | 79.13% + 4096 | 32 | 12.75 | 7.84M | 100.00% | 65.95% + 4096 | 64 | 12.10 | 8.26M | 100.00% | 67.25% + 4096 | 128 | 11.61 | 8.61M | 100.00% | 78.29% +--------------------------------------------------------------------------------------- +``` diff --git a/Framework/Foundation/3rdparty/x9/profiling/compile_profiler.sh b/Framework/Foundation/3rdparty/x9/profiling/compile_profiler.sh new file mode 100755 index 0000000000000..0f89b0e9acdc1 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/profiling/compile_profiler.sh @@ -0,0 +1,3 @@ +#/bin/bash + +gcc -Wextra -Wall -Werror -pedantic -flto -O3 -march=native x9_profiler.c ../x9.c -o X9_PROF diff --git a/Framework/Foundation/3rdparty/x9/profiling/x9_profiler.c b/Framework/Foundation/3rdparty/x9/profiling/x9_profiler.c new file mode 100644 index 0000000000000..d596dd816791d --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/profiling/x9_profiler.c @@ -0,0 +1,524 @@ +/* x9_profiler.c: + * + * One producer + * One consumer + * One message type + * + * ┌────────┐ ┏━━━━━━━━┓ ┌────────┐ + * │Producer│──────▷┃ inbox ┃◁ ─ ─ ─│Consumer│ + * └────────┘ ┗━━━━━━━━┛ └────────┘ + * + * '--test 1' uses 'x9_write_to_inbox_spin' and 'x9_read_from_inbox_spin' + * '--test 2' uses x9_read_from_inbox and 'x9_read_from_inbox' + * + * The advantage of '--test 2' is that, given its non spinning nature, + * it's possible to gather more performance metrics. + */ + +#define _GNU_SOURCE /* cpu_*, pthread_setaffinity_np */ +#include /* assert */ +#include /* required_argument, getopt_long */ +#include /* pthread_t, pthread functions */ +#include /* uint8_t, uint64_t, int64_t */ +#include /* printf */ +#include /* qsort, rand, RAND_MAX */ +#include /* memset, strcmp */ +#include /* sysconf, _SC_NPROCESSORS_ONLN */ + +#include "../x9.h" + +typedef enum { HEADER = 1, SEPARATOR } stdout_output; + +#define ARG(arg_name) (!strcmp(long_options[option_idx].name, arg_name)) + +typedef struct vector { + uint64_t size; + uint64_t used; + int64_t* data; +} vector; + +typedef struct { + vector* inboxes_sizes; + vector* msgs_sizes; + vector* run_in_cores; + int64_t n_messages; + int64_t n_iterations; + int64_t test; +} perf_config; + +typedef struct { + double time_secs; + double writer_hit_ratio; + double reader_hit_ratio; +} perf_results; + +typedef struct { + x9_inbox* inbox; + uint64_t msg_sz; + uint64_t n_msgs; + double writer_hit_ratio; + double reader_hit_ratio; +} th_struct; + +typedef struct { + uint8_t* a; +} msg; + +__attribute__((noreturn)) static void abort_test(char const* const msg) { + printf("%s\n", msg); + abort(); +} + +static vector* vector_init(uint64_t const sz) { + if ((sz % 2)) { abort_test("ERROR: vector sz must be % 2 == 0"); } + vector* const v = calloc(1, sizeof(vector)); + if (NULL == v) { abort_test("ERROR: failed to allocate vector."); } + v->data = calloc(1, sz * sizeof(*v->data)); + if (NULL == v->data) { abort_test("ERROR: failed to allocate v->data."); } + v->size = sz; + return v; +} + +static void vector_insert(vector* const v, int64_t value) { + if (v->used == v->size) { + v->size *= 2; + v->data = realloc(v->data, v->size * sizeof(*v->data)); + if (NULL == v->data) { abort_test("ERROR: realloc failed."); } + } + v->data[v->used++] = value; +} + +static void vector_free(vector* const v) { + free(v->data); + free(v); +} + +static int random_int(int const min, int const max) { + return min + rand() / (RAND_MAX / (max - min + 1) + 1); +} + +static void* producer_fn_test_1(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {.a = calloc(data->msg_sz, sizeof(uint8_t))}; + if (NULL == m.a) { abort_test("ERROR: failed to allocate msg buffer"); } + + for (uint64_t k = 0; k != data->n_msgs; ++k) { + int32_t const random_val = random_int(1, 9); + memset(m.a, random_val, data->msg_sz); + x9_write_to_inbox_spin(data->inbox, data->msg_sz, m.a); + } + free(m.a); + return 0; +} + +static void* consumer_fn_test_1(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {.a = calloc(data->msg_sz, sizeof(uint8_t))}; + if (NULL == m.a) { abort_test("ERROR: failed to allocate msg buffer"); } + + for (uint64_t k = 0; k != data->n_msgs; ++k) { + x9_read_from_inbox_spin(data->inbox, data->msg_sz, m.a); + assert(m.a[(data->msg_sz - 1)] == (m.a[0])); + } + free(m.a); + return 0; +} + +static void* producer_fn_test_2(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {.a = calloc(data->msg_sz, sizeof(uint8_t))}; + if (NULL == m.a) { abort_test("ERROR: failed to allocate msg buffer"); } + + uint64_t write_attempts = 0; + uint64_t msgs_written = 0; + + for (;;) { + if (msgs_written == data->n_msgs) { break; } + int32_t const random_val = random_int(1, 9); + memset(m.a, random_val, data->msg_sz); + if (x9_write_to_inbox(data->inbox, data->msg_sz, m.a)) { ++msgs_written; } + ++write_attempts; + } + + data->writer_hit_ratio = (double)msgs_written / (double)write_attempts; + free(m.a); + return 0; +} + +static void* consumer_fn_test_2(void* args) { + th_struct* data = (th_struct*)args; + + msg m = {.a = calloc(data->msg_sz, sizeof(uint8_t))}; + if (NULL == m.a) { abort_test("ERROR: failed to allocate msg buffer"); } + + uint64_t read_attempts = 0; + uint64_t msgs_read = 0; + + for (;;) { + if (msgs_read == data->n_msgs) { break; } + if (x9_read_from_inbox(data->inbox, data->msg_sz, m.a)) { + ++msgs_read; + assert(m.a[(data->msg_sz - 1)] == (m.a[0])); + } + ++read_attempts; + } + + data->reader_hit_ratio = (double)msgs_read / (double)read_attempts; + free(m.a); + return 0; +} + +static perf_results run_test(uint64_t const ibx_sz, + uint64_t const msg_sz, + uint64_t const n_msgs, + uint64_t const first_core, + uint64_t const second_core, + uint64_t const test + +) { + /* Create inbox */ + x9_inbox* const inbox = x9_create_inbox(ibx_sz, "ibx_1", msg_sz); + + /* Confirm that it's valid */ + if (!(x9_inbox_is_valid(inbox))) { + abort_test("ERROR: x9_inbox is invalid"); + } + + /* Producer */ + pthread_t producer_th = {0}; + pthread_attr_t producer_attr = {0}; + pthread_attr_init(&producer_attr); + th_struct producer_struct = { + .inbox = inbox, .msg_sz = msg_sz, .n_msgs = n_msgs}; + + /* Consumer */ + pthread_t consumer_th = {0}; + pthread_attr_t consumer_attr = {0}; + pthread_attr_init(&consumer_attr); + th_struct consumer_struct = { + .inbox = inbox, .msg_sz = msg_sz, .n_msgs = n_msgs}; + + /* Set affinity */ + cpu_set_t f_core = {0}; + CPU_ZERO(&f_core); + CPU_SET(first_core, &f_core); + + cpu_set_t s_core = {0}; + CPU_ZERO(&s_core); + CPU_SET(second_core, &s_core); + + pthread_attr_setaffinity_np(&producer_attr, sizeof(cpu_set_t), &f_core); + pthread_attr_setaffinity_np(&consumer_attr, sizeof(cpu_set_t), &s_core); + + /* Start timer */ + struct timespec tic = {0}; + clock_gettime(CLOCK_MONOTONIC, &tic); + + /* Launch threads */ + if (1 == test) { + pthread_create(&consumer_th, &consumer_attr, consumer_fn_test_1, + &consumer_struct); + pthread_create(&producer_th, &producer_attr, producer_fn_test_1, + &producer_struct); + + } else { + pthread_create(&consumer_th, &consumer_attr, consumer_fn_test_2, + &consumer_struct); + pthread_create(&producer_th, &producer_attr, producer_fn_test_2, + &producer_struct); + } + + /* Join them */ + pthread_join(consumer_th, NULL); + pthread_join(producer_th, NULL); + + /* Stop timer */ + struct timespec toc = {0}; + clock_gettime(CLOCK_MONOTONIC, &toc); + + uint64_t const before = + ((uint64_t)tic.tv_sec * 1000000000UL) + (uint64_t)tic.tv_nsec; + uint64_t const after = + ((uint64_t)toc.tv_sec * 1000000000UL) + (uint64_t)toc.tv_nsec; + + /* Cleanup */ + pthread_attr_destroy(&producer_attr); + pthread_attr_destroy(&consumer_attr); + x9_free_inbox(inbox); + + return (perf_results){.time_secs = (double)(after - before) / 1e9, + .writer_hit_ratio = producer_struct.writer_hit_ratio, + .reader_hit_ratio = consumer_struct.reader_hit_ratio}; +} + +static void parse_array_arguments(char* restrict const args, + vector* const write_to) { + char* args_start = args; + char const* const args_end = args + strlen(args); + + for (; args_start < args_end;) { + char* begin = args_start; + char* end = args_start; + for (; end != args_end; ++end) { + if (',' == *end) { break; } + } + args_start = end + 1; + int64_t const n = strtoll(begin, &end, 10); + vector_insert(write_to, n); + } +} + +static perf_config* parse_command_line_args(int argc, char** argv) { + perf_config* config = calloc(1, sizeof(perf_config)); + if (NULL == config) { + abort_test("ERROR: failed to allocate 'perf_config'"); + } + + for (;;) { + int option_idx = 0; + static struct option long_options[] = { + {"inboxes_szs", required_argument, 0, 0}, + {"msgs_szs", required_argument, 0, 0}, + {"n_msgs", required_argument, 0, 0}, + {"n_its", required_argument, 0, 0}, + {"run_in_cores", required_argument, 0, 0}, + {"test", required_argument, 0, 0}, + {0, 0, 0, 0} + + }; + + int const c = getopt_long(argc, argv, "", long_options, &option_idx); + if (-1 == c) { break; } + + switch (c) { + case 0: + if (ARG("inboxes_szs")) { + config->inboxes_sizes = vector_init(8); + + parse_array_arguments(optarg, config->inboxes_sizes); + + if (!config->inboxes_sizes->data[0]) { + abort_test( + "ERROR: test requires at least one value for " + "'--inboxes_sizes'"); + } + + for (uint64_t k = 0; k != config->inboxes_sizes->used; ++k) { + int64_t const n = config->inboxes_sizes->data[k]; + if (!((n > 0) && ((n % 2) == 0))) { + abort_test( + "ERROR: '--inboxes_sizes' values must be > 0 and % 2 == " + "0"); + } + } + } + if (ARG("msgs_szs")) { + config->msgs_sizes = vector_init(8); + parse_array_arguments(optarg, config->msgs_sizes); + + if (!config->msgs_sizes->data[0]) { + abort_test( + "ERROR: test requires at least one value for " + "'--msgs_sizes'"); + } + + for (uint64_t k = 0; k != config->msgs_sizes->used; ++k) { + int64_t const n = config->msgs_sizes->data[k]; + if (!(n > 0)) { + abort_test("ERROR: '--msgs_sizes' values must be > 0"); + } + } + } + + if (ARG("run_in_cores")) { + config->run_in_cores = vector_init(8); + parse_array_arguments(optarg, config->run_in_cores); + + if (config->run_in_cores->used != 2) { + abort_test("ERROR: --run_in_cores requires two values."); + } + + int64_t const n_cores = sysconf(_SC_NPROCESSORS_ONLN); + + if ((config->run_in_cores->data[0] < 0) || + config->run_in_cores->data[0] > n_cores || + (config->run_in_cores->data[1] < 0) || + config->run_in_cores->data[1] > n_cores) { + char abort_msg[128] = {0}; + sprintf(abort_msg, + "ERROR: '--run_in_cores' values must be between 0 " + "and %ld", + n_cores); + abort_test(abort_msg); + } + } + + if (ARG("n_msgs")) { + int64_t const n = atoll(optarg); + if (!(n > 0)) { abort_test("ERROR: '--n_msgs' value must be > 0"); } + config->n_messages = n; + } + + if (ARG("n_its")) { + int64_t const n = atoll(optarg); + if (!(n > 0)) { abort_test("ERROR: '--n_its' value must be > 0"); } + config->n_iterations = n; + } + + if (ARG("test")) { + int64_t n = atoll(optarg); + if (!((n > 0) && (n < 3))) { + abort_test("ERROR: '--test' value must be either '1' or '2'"); + } + config->test = n; + } + } + } + + if (!config->test || !config->inboxes_sizes || !config->msgs_sizes || + !config->n_messages || !config->n_iterations || !config->run_in_cores) { + abort_test("ERROR: missing command line arguments."); + } + + if (1 == config->test) { + if (config->run_in_cores->data[0] == config->run_in_cores->data[1]) { + abort_test( + "ERROR: for '--test 1' the values of '--run_in_cores' can not be " + "equal because there's no sched_yield())'"); + } + } + return config; +} + +static void free_perf_config(perf_config* config) { + vector_free(config->inboxes_sizes); + vector_free(config->msgs_sizes); + vector_free(config->run_in_cores); + free(config); +} + +static void print_to_stdout(perf_config const* const config, + stdout_output const what_to_print) { + char const* const i_sz = "Inbox size"; + char const* const sep = " | "; + char const* const m_sz = "Msg size"; + char const* const time = "Time (secs)"; + char const* const m_sec = "Msgs/second"; + char const* const prod_hit = "Writer hit ratio"; + char const* const cons_hit = "Reader hit ratio"; + + uint64_t const test_1_sep_len = strlen(i_sz) + strlen(m_sz) + strlen(time) + + strlen(m_sec) + (3 * strlen(sep)); + + uint64_t const test_2_sep_len = strlen(i_sz) + strlen(m_sz) + strlen(time) + + strlen(m_sec) + strlen(prod_hit) + + strlen(cons_hit) + (5 * strlen(sep)); + + if (HEADER == what_to_print) { + if (1 == config->test) { + printf("\n%s%s%s%s%s%s%s\n", i_sz, sep, m_sz, sep, time, sep, m_sec); + + } else { + printf("\n%s%s%s%s%s%s%s%s%s%s%s\n", i_sz, sep, m_sz, sep, time, sep, + m_sec, sep, prod_hit, sep, cons_hit); + } + } + if (1 == config->test) { + for (uint64_t k = 0; k != test_1_sep_len; ++k) { fputs("-", stdout); } + } else { + for (uint64_t k = 0; k != test_2_sep_len; ++k) { fputs("-", stdout); } + } + puts(""); +} + +static int cmp(const void* a, const void* b) { + return (*(const double*)a > *(const double*)b) ? 1 + : (*(const double*)a < *(const double*)b) ? -1 + : 0; +} + +static double calculate_median(uint64_t const sz, double* const arr) { + qsort(arr, sz, sizeof(double), cmp); + return ((sz % 2) == 0) ? ((arr[sz / 2 - 1] + arr[sz / 2]) / 2) : arr[sz / 2]; +} + +int main(int argc, char** argv) { + /* Seed random generator */ + srand((uint32_t)time(0)); + + perf_config* config = parse_command_line_args(argc, argv); + + print_to_stdout(config, HEADER); + + double* time_secs = calloc((uint64_t)config->n_iterations, sizeof(double)); + if (NULL == time_secs) { + abort_test("ERROR: failed to allocate 'time_secs'"); + } + + double* writer_hit_ratio = + calloc((uint64_t)config->n_iterations, sizeof(double)); + if (NULL == writer_hit_ratio) { + abort_test("ERROR: failed to allocate 'writer_hit_ratio'"); + } + + double* reader_hit_ratio = + calloc((uint64_t)config->n_iterations, sizeof(double)); + if (NULL == reader_hit_ratio) { + abort_test("ERROR: failed to allocate 'reader_hit_ratio'"); + } + + for (uint64_t k = 0; k != config->inboxes_sizes->used; ++k) { + if (config->inboxes_sizes->data[k]) { + for (uint64_t j = 0; j != config->msgs_sizes->used; ++j) { + if (config->msgs_sizes->data[j]) { + for (uint64_t it = 0; it != (uint64_t)config->n_iterations; ++it) { + perf_results results = + run_test((uint64_t)config->inboxes_sizes->data[k], + (uint64_t)config->msgs_sizes->data[j], + (uint64_t)config->n_messages, + (uint64_t)config->run_in_cores->data[0], + (uint64_t)config->run_in_cores->data[1], + (uint64_t)config->test); + + time_secs[it] = results.time_secs; + writer_hit_ratio[it] = results.writer_hit_ratio; + reader_hit_ratio[it] = results.reader_hit_ratio; + } + + double const median_secs = + calculate_median((uint64_t)config->n_iterations, time_secs); + + printf("%10ld | ", config->inboxes_sizes->data[k]); + printf("%8ld | ", config->msgs_sizes->data[j]); + median_secs > 1 ? printf("%*.2f | ", 11, median_secs) + : printf("%*.4f | ", 11, median_secs); + printf("%*.2fM", 10, + ((double)config->n_messages / median_secs) / 1e6); + + if (2 == config->test) { + double const median_writer_hit = calculate_median( + (uint64_t)config->n_iterations, writer_hit_ratio); + + double const median_reader_hit = calculate_median( + (uint64_t)config->n_iterations, reader_hit_ratio); + + printf(" |%*.2f%% | ", 16, median_writer_hit * 100); + printf("%*.2f%%", 15, median_reader_hit * 100); + } + } + puts(""); + } + print_to_stdout(config, SEPARATOR); + } + } + + puts(""); + free(time_secs); + free(writer_hit_ratio); + free(reader_hit_ratio); + free_perf_config(config); + return EXIT_SUCCESS; +} diff --git a/Framework/Foundation/3rdparty/x9/x9.c b/Framework/Foundation/3rdparty/x9/x9.c new file mode 100644 index 0000000000000..46d3d126de9f4 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/x9.c @@ -0,0 +1,424 @@ +/* + X9 - high performance message passing library. + Copyright (c) 2023, Diogo Flores + + BSD 2-Clause License (https://opensource.org/license/bsd-2-clause/) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at: diogoxflores@gmail.com +*/ + +#pragma GCC diagnostic ignored "-Wpadded" + +#include "x9.h" + +#include /* assert */ +#include /* _mm_pause */ +#include /* va_* */ +#include /* atomic_* */ +#include /* bool */ +#include /* printf */ +#include /* aligned_alloc, calloc */ +#include /* strcmp */ +#include /* memcpy */ + +/* CPU cache line size */ +#define X9_CL_SIZE 64 +#define X9_ALIGN_TO_CL() __attribute__((__aligned__(X9_CL_SIZE))) + +#ifdef X9_DEBUG +static void x9_print_error_msg(char const* const error_msg) { + printf("X9_ERROR: %s\n", error_msg); + fflush(stdout); + return; +} +#endif + +/* --- Internal types --- */ + +typedef struct { + _Atomic(bool) slot_has_data; + _Atomic(bool) msg_written; + _Atomic(bool) shared; + char const pad[5]; +} x9_msg_header; + +typedef struct x9_inbox_internal { + _Atomic(uint64_t) read_idx X9_ALIGN_TO_CL(); + _Atomic(uint64_t) write_idx X9_ALIGN_TO_CL(); + uint64_t sz X9_ALIGN_TO_CL(); + uint64_t msg_sz; + uint64_t constant; + void* msgs; + char* name; + char pad[24]; +} x9_inbox; + +typedef struct x9_node_internal { + x9_inbox** inboxes; + uint64_t n_inboxes; + char* name; +} x9_node; + +/* --- Internal functions --- */ + +static inline uint64_t x9_load_idx(x9_inbox* const inbox, + bool const read_idx) { + /* From paper: Faster Remainder by Direct Computation, Lemire et al */ + register uint64_t const low_bits = + inbox->constant * + (read_idx ? atomic_load_explicit(&inbox->read_idx, __ATOMIC_RELAXED) + : atomic_load_explicit(&inbox->write_idx, __ATOMIC_RELAXED)); + return ((__uint128_t)low_bits * inbox->sz) >> 64; +} + +static inline uint64_t x9_increment_idx(x9_inbox* const inbox, + bool const read_idx) { + /* From paper: Faster Remainder by Direct Computation, Lemire et al */ + register uint64_t const low_bits = + inbox->constant * + (read_idx + ? atomic_fetch_add_explicit(&inbox->read_idx, 1, __ATOMIC_RELAXED) + : atomic_fetch_add_explicit(&inbox->write_idx, 1, + __ATOMIC_RELAXED)); + return ((__uint128_t)low_bits * inbox->sz) >> 64; +} + +static inline void* x9_header_ptr(x9_inbox const* const inbox, + uint64_t const idx) { + return &((char*)inbox->msgs)[idx * (inbox->msg_sz + sizeof(x9_msg_header))]; +} + +/* --- Public functions --- */ + +x9_inbox* x9_create_inbox(uint64_t const sz, + char const* restrict const name, + uint64_t const msg_sz) { + if (!((sz > 0) && !(sz % 2))) { goto inbox_incorrect_size; } + + x9_inbox* inbox = aligned_alloc(X9_CL_SIZE, sizeof(x9_inbox)); + if (NULL == inbox) { goto inbox_allocation_failed; } + memset(inbox, 0, sizeof(x9_inbox)); + + uint64_t const name_len = strlen(name); + char* ibx_name = calloc(name_len + 1, sizeof(char)); + if (NULL == ibx_name) { goto inbox_name_allocation_failed; } + memcpy(ibx_name, name, name_len); + + void* msgs = calloc(sz, msg_sz + sizeof(x9_msg_header)); + if (NULL == msgs) { goto inbox_msgs_allocation_failed; } + + inbox->constant = UINT64_C(0xFFFFFFFFFFFFFFFF) / sz + 1; + inbox->name = ibx_name; + inbox->msgs = msgs; + inbox->sz = sz; + inbox->msg_sz = msg_sz; + return inbox; + +inbox_incorrect_size: +#ifdef X9_DEBUG + x9_print_error_msg("INBOX_INCORRECT_SIZE"); +#endif + return NULL; + +inbox_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("INBOX_ALLOCATION_FAILED"); +#endif + return NULL; + +inbox_name_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("INBOX_NAME_ALLOCATION_FAILED"); +#endif + free(inbox); + return NULL; + +inbox_msgs_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("INBOX_MSGS_ALLOCATION_FAILED"); +#endif + free(ibx_name); + free(inbox); + return NULL; +} + +bool x9_inbox_is_valid(x9_inbox const* const inbox) { + return !(NULL == inbox); +} + +bool x9_inbox_name_is(x9_inbox const* const inbox, + char const* restrict const cmp) { + return !strcmp(inbox->name, cmp) ? true : false; +} + +void x9_free_inbox(x9_inbox* const inbox) { + free(inbox->msgs); + free(inbox->name); + free(inbox); +} + +x9_inbox* x9_select_inbox_from_node(x9_node const* const node, + char const* restrict const name) { + for (uint64_t k = 0; k != node->n_inboxes; ++k) { + if (x9_inbox_name_is(node->inboxes[k], name)) { return node->inboxes[k]; } + } +#ifdef X9_DEBUG + x9_print_error_msg("NODE_DOES_NOT_CONTAIN_INBOX"); +#endif + return NULL; +} + +x9_node* x9_create_node(char* restrict const name, + uint64_t const n_inboxes, + ...) { + if (!(n_inboxes > 0)) { goto node_incorrect_definition; } + + x9_node* node = calloc(1, sizeof(x9_node)); + if (NULL == node) { goto node_allocation_failed; } + + uint64_t const name_len = strlen(name); + char* node_name = calloc(name_len + 1, sizeof(char)); + if (NULL == node_name) { goto node_name_allocation_failed; } + memcpy(node_name, name, name_len); + node->name = node_name; + + va_list argp = {0}; + va_start(argp, n_inboxes); + + x9_inbox** inboxes = calloc(n_inboxes, sizeof(x9_inbox)); + if (NULL == inboxes) { goto node_inboxes_allocation_failed; } + node->inboxes = inboxes; + node->n_inboxes = n_inboxes; + + for (uint64_t k = 0; k != n_inboxes; ++k) { + x9_inbox* inbox = va_arg(argp, x9_inbox*); + if (k) { + for (uint64_t j = 0; j != k; ++j) { + if (inbox == node->inboxes[j]) { + goto node_multiple_equal_inboxes; + } else { + node->inboxes[k] = inbox; + } + } + } else { + node->inboxes[k] = inbox; + } + } + va_end(argp); + + return node; + +node_incorrect_definition: +#ifdef X9_DEBUG + x9_print_error_msg("NODE_INCORRECT_DEFINITION"); +#endif + return NULL; + +node_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("NODE_ALLOCATION_FAILED"); +#endif + return NULL; + +node_name_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("NODE_NAME_ALLOCATION_FAILED"); +#endif + free(node); + return NULL; + +node_inboxes_allocation_failed: +#ifdef X9_DEBUG + x9_print_error_msg("NODE_INBOXES_ALLOCATION_FAILED"); +#endif + va_end(argp); + free(node_name); + free(node); + return NULL; + +node_multiple_equal_inboxes: +#ifdef X9_DEBUG + x9_print_error_msg("NODE_MULTIPLE_EQUAL_INBOXES"); +#endif + va_end(argp); + free(node_name); + free(node->inboxes); + free(node); + return NULL; +} + +bool x9_node_is_valid(x9_node const* const node) { return !(NULL == node); } + +bool x9_node_name_is(x9_node const* const node, + char const* restrict const cmp) { + return !strcmp(node->name, cmp) ? true : false; +} + +void x9_free_node(x9_node* const node) { + free(node->name); + free(node->inboxes); + free(node); +} + +void x9_free_node_and_attached_inboxes(x9_node* const node) { + for (uint64_t k = 0; k != node->n_inboxes; ++k) { + if (NULL != node->inboxes[k]) { + x9_free_inbox(node->inboxes[k]); + node->inboxes[k] = NULL; + } + } + x9_free_node(node); +} + +bool x9_write_to_inbox(x9_inbox* const inbox, + uint64_t const msg_sz, + void const* restrict const msg) { + bool f = false; + register uint64_t const idx = x9_load_idx(inbox, false); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + + if (atomic_compare_exchange_strong_explicit(&header->slot_has_data, &f, true, + __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED)) { + memcpy((char*)header + sizeof(x9_msg_header), msg, msg_sz); + atomic_fetch_add_explicit(&inbox->write_idx, 1, __ATOMIC_RELEASE); + atomic_store_explicit(&header->msg_written, true, __ATOMIC_RELEASE); + return true; + } + return false; +} + +void x9_write_to_inbox_spin(x9_inbox* const inbox, + uint64_t const msg_sz, + void const* restrict const msg) { + for (;;) { + bool f = false; + register uint64_t const idx = x9_increment_idx(inbox, false); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + if (atomic_compare_exchange_weak_explicit(&header->slot_has_data, &f, true, + __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED)) { + memcpy((char*)header + sizeof(x9_msg_header), msg, msg_sz); + atomic_store_explicit(&header->msg_written, true, __ATOMIC_RELEASE); + break; + } + } +} + +void x9_broadcast_msg_to_all_node_inboxes(x9_node const* const node, + uint64_t const msg_sz, + void const* restrict const msg) { + for (uint64_t k = 0; k != node->n_inboxes; ++k) { + x9_write_to_inbox_spin(node->inboxes[k], msg_sz, msg); + } +} + +bool x9_read_from_inbox(x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam) { + register uint64_t const idx = x9_load_idx(inbox, true); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + + if (atomic_load_explicit(&header->slot_has_data, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->msg_written, __ATOMIC_ACQUIRE)) { + memcpy(outparam, (char*)header + sizeof(x9_msg_header), msg_sz); + atomic_store_explicit(&header->msg_written, false, __ATOMIC_RELAXED); + atomic_store_explicit(&header->slot_has_data, false, __ATOMIC_RELEASE); + atomic_fetch_add_explicit(&inbox->read_idx, 1, __ATOMIC_RELEASE); + return true; + } + } + return false; +} + +void x9_read_from_inbox_spin(x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam) { + register uint64_t const idx = x9_increment_idx(inbox, true); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + + for (;;) { + _mm_pause(); + if (atomic_load_explicit(&header->slot_has_data, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->msg_written, __ATOMIC_ACQUIRE)) { + memcpy(outparam, (char*)header + sizeof(x9_msg_header), msg_sz); + atomic_store_explicit(&header->msg_written, false, __ATOMIC_RELAXED); + atomic_store_explicit(&header->slot_has_data, false, __ATOMIC_RELEASE); + return; + } + } + } +} + +bool x9_read_from_shared_inbox(x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam) { + bool f = false; + register uint64_t const idx = x9_load_idx(inbox, true); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + + if (atomic_compare_exchange_strong_explicit( + &header->shared, &f, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->slot_has_data, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->msg_written, __ATOMIC_ACQUIRE)) { + memcpy(outparam, (char*)header + sizeof(x9_msg_header), msg_sz); + atomic_fetch_add_explicit(&inbox->read_idx, 1, __ATOMIC_RELEASE); + atomic_store_explicit(&header->msg_written, false, __ATOMIC_RELAXED); + atomic_store_explicit(&header->slot_has_data, false, __ATOMIC_RELEASE); + atomic_store_explicit(&header->shared, false, __ATOMIC_RELEASE); + return true; + } + } + atomic_store_explicit(&header->shared, false, __ATOMIC_RELEASE); + } + return false; +} + +void x9_read_from_shared_inbox_spin(x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam) { + for (;;) { + bool f = false; + register uint64_t const idx = x9_increment_idx(inbox, true); + register x9_msg_header* const header = x9_header_ptr(inbox, idx); + + if (atomic_compare_exchange_strong_explicit( + &header->shared, &f, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->slot_has_data, __ATOMIC_RELAXED)) { + if (atomic_load_explicit(&header->msg_written, __ATOMIC_ACQUIRE)) { + memcpy(outparam, (char*)header + sizeof(x9_msg_header), msg_sz); + atomic_store_explicit(&header->msg_written, false, __ATOMIC_RELAXED); + atomic_store_explicit(&header->slot_has_data, false, + __ATOMIC_RELEASE); + atomic_store_explicit(&header->shared, false, __ATOMIC_RELEASE); + return; + } + } + atomic_store_explicit(&header->shared, false, __ATOMIC_RELEASE); + } + } +} + diff --git a/Framework/Foundation/3rdparty/x9/x9.h b/Framework/Foundation/3rdparty/x9/x9.h new file mode 100644 index 0000000000000..bd8717916ddc3 --- /dev/null +++ b/Framework/Foundation/3rdparty/x9/x9.h @@ -0,0 +1,166 @@ +/* + X9 - high performance message passing library. + Copyright (c) 2023, Diogo Flores + + BSD 2-Clause License (https://opensource.org/license/bsd-2-clause/) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at: diogoxflores@gmail.com +*/ + +#pragma once + +#include /* bool */ +#include /* uint64_t */ + +/* --- Opaque types --- */ + +typedef struct x9_node_internal x9_node; +typedef struct x9_inbox_internal x9_inbox; + +/* --- Public API --- */ + +/* Creates a x9_inbox with a buffer of size 'sz', which must be positive and + * mod 2 == 0, a 'name', which can be used for comparison by calling + * 'x9_inbox_name_is' or for selecting a specific x9_inbox from a x9_node by + * calling 'x9_select_inbox_from_node', and a 'msg_sz' which the inbox is + * expected to receive. + * + * Example: + * x9_inbox* inbox = x9_create_inbox(512, "ibx", sizeof());*/ +__attribute__((nonnull)) x9_inbox* x9_create_inbox( + uint64_t const sz, char const* restrict const name, uint64_t const msg_sz); + +/* Variadic function that creates a 'x9_node', which is an abstraction that + * unifies x9_inbox(es). + * 'name' can be used for comparison by calling 'x9_node_name_is', + * 'n_inboxes' must be > 0 and equal the number of inboxes passed to the + * function to be attached to the x9_node. + * + * Example: + * x9_node* node = x9_create_node("my_node", 3, inbox_1, inbox_2, inbox_3);*/ +__attribute__((nonnull)) x9_node* x9_create_node(char* restrict const name, + uint64_t const n_inboxes, + ...); + +/* Returns 'true' if the 'inbox' is valid, 'false' otherwise. + * Should always be called after 'x9_create_inbox' to validate the correct + * initialization of the underlying data structure, and after calling + * 'x9_select_inbox_from_node' to ensure that the user selected a valid inbox. + * If the return value is 'false', and it's unclear why it is so, the user can + * enable the 'X9_DEBUG' macro at compile time for precise error information.*/ +bool x9_inbox_is_valid(x9_inbox const* const inbox); + +/* Returns 'true' if the 'node' is valid, 'false' otherwise. + * Should always be called after 'x9_create_node' to validate the correct + * initialization of the underlying data structure. + * If the return value is 'false', and it's unclear why it is so, the user can + * enable the 'X9_DEBUG' macro at compile time for precise error information.*/ +bool x9_node_is_valid(x9_node const* const node); + +/* Selects a x9_inbox from a 'node' by its 'name'. + * Returns NULL if the 'node' does not contain an x9_inbox with such 'name'.*/ +__attribute__((nonnull)) x9_inbox* x9_select_inbox_from_node( + x9_node const* const node, char const* restrict const name); + +/* Returns 'true' if the 'inbox' name == 'cmp', 'false' otherwise.*/ +__attribute__((nonnull)) bool x9_inbox_name_is(x9_inbox const* const inbox, + char const* restrict const cmp); + +/* Returns 'true' if the 'node' name == 'cmp', 'false' otherwise.*/ +__attribute__((nonnull)) bool x9_node_name_is(x9_node const* const node, + char const* restrict const cmp); + +/* Frees the 'inbox' data structure and its internal components. */ +__attribute__((nonnull)) void x9_free_inbox(x9_inbox* const inbox); + +/* Frees the 'node' data structure and its internal components. */ +__attribute__((nonnull)) void x9_free_node(x9_node* const node); + +/* Frees the 'node' and all the x9_inbox(es) attached to it. + * IMPORTANT: should only be used when the attached x9_inbox(es) are not shared + * with other nodes.*/ +__attribute__((nonnull)) void x9_free_node_and_attached_inboxes( + x9_node* const node); + +/* Returns 'true' if a message was read, 'false' otherwise. + * If 'true', the message will be written to 'outparam'. + * IMPORTANT: Can only be used to read from inboxes where the thread calling + * this function is the only thread reading from said 'inbox'.*/ +__attribute__((nonnull)) bool x9_read_from_inbox( + x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam); + +/* Reads the next unread message in the 'inbox' to 'outparam'. + * Uses spinning, that is, it wil not return until it has read a message, and + * it will keep checking if a message was written and try to read it. */ +__attribute__((nonnull)) void x9_read_from_inbox_spin( + x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam); + +/* Returns 'true' if a message was read, 'false' otherwise. + * If 'true', the msg contents will be written to the 'outparam'. + * Use this function when multiple threads read from the same inbox. */ +__attribute__((nonnull)) bool x9_read_from_shared_inbox( + x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam); + +/* Reads the next unread message in the 'inbox' to 'outparam'. + * Use this function when multiple threads read from the same inbox. + * Uses spinning, that is, it wil not return until it has read a message, and + * it will keep checking if a message was written and try to read it. */ +__attribute__((nonnull)) void x9_read_from_shared_inbox_spin( + x9_inbox* const inbox, + uint64_t const msg_sz, + void* restrict const outparam); + +/* Returns 'true' if the message was written to the 'inbox', 'false' + * otherwise. */ +__attribute__((nonnull)) bool x9_write_to_inbox( + x9_inbox* const inbox, + uint64_t const msg_sz, + void const* restrict const msg); + +/* Writes the 'msg' to the 'inbox'. + * Uses spinning, that is, it wil not not return until it has written the + * 'msg', and it will keep checking if the destination inbox has a free + * slot that it can write the 'msg' to. */ +__attribute__((nonnull)) void x9_write_to_inbox_spin( + x9_inbox* const inbox, + uint64_t const msg_sz, + void const* restrict const msg); + +/* Writes the same 'msg' to all 'node' inboxes. + * Calls 'x9_write_to_inbox_spin' in the background. + * Users must guarantee that all 'node' inboxes accept messages of the + * same type (or at least of the same 'msg_sz') */ +__attribute__((nonnull)) void x9_broadcast_msg_to_all_node_inboxes( + x9_node const* const node, + uint64_t const msg_sz, + void const* restrict const msg); + From 481cfe3ced62f9dbfd63635fe1e6a289759635a5 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:21:51 +0200 Subject: [PATCH 0267/2205] Platform independent yielding --- Framework/Foundation/3rdparty/x9/x9.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Framework/Foundation/3rdparty/x9/x9.c b/Framework/Foundation/3rdparty/x9/x9.c index 46d3d126de9f4..2ca4bb80237b3 100644 --- a/Framework/Foundation/3rdparty/x9/x9.c +++ b/Framework/Foundation/3rdparty/x9/x9.c @@ -35,7 +35,12 @@ #include "x9.h" #include /* assert */ +#if defined(__x86_64__) || defined(__i386__) #include /* _mm_pause */ +#elif defined(__aarch64__) +#else +#error Not supported architecture +#endif #include /* va_* */ #include /* atomic_* */ #include /* bool */ @@ -361,7 +366,13 @@ void x9_read_from_inbox_spin(x9_inbox* const inbox, register x9_msg_header* const header = x9_header_ptr(inbox, idx); for (;;) { +#if defined(__x86_64__) || defined(__i386__) _mm_pause(); +#elif defined(__aarch64__) + __asm__ __volatile__ ("yield"); +#else +#error Not supported architecture +#endif if (atomic_load_explicit(&header->slot_has_data, __ATOMIC_RELAXED)) { if (atomic_load_explicit(&header->msg_written, __ATOMIC_ACQUIRE)) { memcpy(outparam, (char*)header + sizeof(x9_msg_header), msg_sz); From 13baa03bc133b928b82e67f460d322dea1f4de65 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:21:51 +0200 Subject: [PATCH 0268/2205] Support using X9 from C++ --- Framework/Foundation/3rdparty/x9/x9.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Framework/Foundation/3rdparty/x9/x9.h b/Framework/Foundation/3rdparty/x9/x9.h index bd8717916ddc3..229d7adf7dba0 100644 --- a/Framework/Foundation/3rdparty/x9/x9.h +++ b/Framework/Foundation/3rdparty/x9/x9.h @@ -32,6 +32,11 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#define restrict __restrict__ +#endif + #include /* bool */ #include /* uint64_t */ @@ -164,3 +169,6 @@ __attribute__((nonnull)) void x9_broadcast_msg_to_all_node_inboxes( uint64_t const msg_sz, void const* restrict const msg); +#ifdef __cplusplus +} +#endif From 8dddc1554e868135e6d9702a4bb84afcb6c82c6b Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:21:51 +0200 Subject: [PATCH 0269/2205] DPL: Use X9 to make AsyncQueue atomic --- Framework/Core/CMakeLists.txt | 1 + Framework/Core/include/Framework/AsyncQueue.h | 12 +++++++ Framework/Core/src/AsyncQueue.cxx | 33 ++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index 8c2d9650776c0..c01ef534eb212 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -163,6 +163,7 @@ o2_add_library(Framework O2::Headers O2::MemoryResources O2::PCG + O2::X9 RapidJSON::RapidJSON Arrow::arrow_shared Microsoft.GSL::GSL diff --git a/Framework/Core/include/Framework/AsyncQueue.h b/Framework/Core/include/Framework/AsyncQueue.h index d214b9bfc09ba..0f25410179c1f 100644 --- a/Framework/Core/include/Framework/AsyncQueue.h +++ b/Framework/Core/include/Framework/AsyncQueue.h @@ -14,6 +14,10 @@ #include "Framework/TimesliceSlot.h" #include #include +#include + +typedef struct x9_inbox_internal x9_inbox; +typedef struct x9_node_internal x9_node; namespace o2::framework { @@ -89,6 +93,12 @@ struct AsyncQueue { std::vector prototypes; std::vector tasks; size_t iteration = 0; + + std::atomic first = true; + + // Inbox for the message queue used to append + // tasks to this queue. + x9_inbox* inbox = nullptr; AsyncQueue(); }; @@ -104,6 +114,8 @@ struct AsyncQueueHelpers { /// 3. only execute the highest (timeslice, debounce) value static void run(AsyncQueue& queue, TimesliceId oldestPossibleTimeslice); + // Flush tasks which were posted but not yet committed to the queue + static void flushPending(AsyncQueue& queue); /// Reset the queue to its initial state static void reset(AsyncQueue& queue); }; diff --git a/Framework/Core/src/AsyncQueue.cxx b/Framework/Core/src/AsyncQueue.cxx index e0e44da9cd19c..c9be88f096c0d 100644 --- a/Framework/Core/src/AsyncQueue.cxx +++ b/Framework/Core/src/AsyncQueue.cxx @@ -11,6 +11,7 @@ #include "Framework/AsyncQueue.h" #include "Framework/Signpost.h" +#include "x9.h" #include O2_DECLARE_DYNAMIC_LOG(async_queue); @@ -18,7 +19,9 @@ O2_DECLARE_DYNAMIC_LOG(async_queue); namespace o2::framework { AsyncQueue::AsyncQueue() + : inbox(x9_create_inbox(16, "async_queue", sizeof(AsyncTask))) { + this->inbox = x9_create_inbox(16, "async_queue", sizeof(AsyncTask)); } auto AsyncQueueHelpers::create(AsyncQueue& queue, AsyncTaskSpec spec) -> AsyncTaskId @@ -31,11 +34,39 @@ auto AsyncQueueHelpers::create(AsyncQueue& queue, AsyncTaskSpec spec) -> AsyncTa auto AsyncQueueHelpers::post(AsyncQueue& queue, AsyncTask const& task) -> void { - queue.tasks.push_back(task); + // Until we do not manage to write to the inbox, keep removing + // items from the queue if you are the first one which fails to + // write. + while (!x9_write_to_inbox(queue.inbox, sizeof(AsyncTask), &task)) { + AsyncQueueHelpers::flushPending(queue); + } +} + +auto AsyncQueueHelpers::flushPending(AsyncQueue& queue) -> void +{ + bool isFirst = true; + if (!std::atomic_compare_exchange_strong(&queue.first, &isFirst, false)) { + // Not the first, try again. + return; + } + // First thread which does not manage to write to the queue. + // Flush it a bit before we try again. + AsyncTask toFlush; + // This potentially stalls if the inserting tasks are faster to insert + // than we are to retrieve. We should probably have a cut-off + while (x9_read_from_inbox(queue.inbox, sizeof(AsyncTask), &toFlush)) { + queue.tasks.push_back(toFlush); + } + queue.first = true; } auto AsyncQueueHelpers::run(AsyncQueue& queue, TimesliceId oldestPossible) -> void { + // We synchronize right before we run to get as many + // tasks as possible. Notice we might still miss some + // which will have to handled on a subsequent iteration. + AsyncQueueHelpers::flushPending(queue); + if (queue.tasks.empty()) { return; } From 05dc2f9eca1ab287bd355b17424bab4af3702436 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:46:56 +0200 Subject: [PATCH 0270/2205] DPL: avoid pragma once --- Framework/Foundation/3rdparty/x9/x9.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Framework/Foundation/3rdparty/x9/x9.h b/Framework/Foundation/3rdparty/x9/x9.h index 229d7adf7dba0..587e0f3116642 100644 --- a/Framework/Foundation/3rdparty/x9/x9.h +++ b/Framework/Foundation/3rdparty/x9/x9.h @@ -30,7 +30,8 @@ You can contact the author at: diogoxflores@gmail.com */ -#pragma once +#ifndef O2_FRAMEWORK_FOUDATION_X9_H_ +#define O2_FRAMEWORK_FOUDATION_X9_H_ #ifdef __cplusplus extern "C" { @@ -172,3 +173,4 @@ __attribute__((nonnull)) void x9_broadcast_msg_to_all_node_inboxes( #ifdef __cplusplus } #endif +#endif // O2_FRAMEWORK_FOUDATION_X9_H_ From c6da49b873d8645c1a753efd4108ee6b65bcf2d1 Mon Sep 17 00:00:00 2001 From: Sergio Date: Tue, 3 Sep 2024 14:37:26 +0200 Subject: [PATCH 0271/2205] Github Actions: Add new CI checks to clean-PR action --- .github/workflows/clean-test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/clean-test.yml b/.github/workflows/clean-test.yml index c926d5a7dea46..cbc524910c33e 100644 --- a/.github/workflows/clean-test.yml +++ b/.github/workflows/clean-test.yml @@ -43,6 +43,15 @@ name: Clean PR checks description: build/O2/o2-dataflow-cs8 type: boolean default: true + 'check_build/O2/o2/aarch64': + description: build/O2/o2/aarch64 + type: boolean + default: true + 'check_build/O2/o2_slc9': + description: build/O2/o2_slc9 + type: boolean + default: true + permissions: {} From 1561ebbc868b0ad50ffbb4968d936c460c6376f5 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 20 Sep 2024 00:48:57 +0200 Subject: [PATCH 0272/2205] DPL Analysis: make sure VLAs use only one basket Otherwise it seems to create issues with ROOT bulk reading if the baskets are split across multiple clusters. In particular, each row needs 4 bytes for the size of the elements in the row and the _size branch needs to also have its size correctly set. --- .../Core/include/Framework/TableTreeHelpers.h | 5 +++-- Framework/Core/src/TableTreeHelpers.cxx | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Framework/Core/include/Framework/TableTreeHelpers.h b/Framework/Core/include/Framework/TableTreeHelpers.h index e12f4a38a973b..ccc7035ba3435 100644 --- a/Framework/Core/include/Framework/TableTreeHelpers.h +++ b/Framework/Core/include/Framework/TableTreeHelpers.h @@ -83,8 +83,9 @@ class ColumnToBranch ColumnToBranch(ColumnToBranch const& other) = delete; ColumnToBranch(ColumnToBranch&& other) = delete; void at(const int64_t* pos); - int fieldSize() const { return mFieldSize; } - char const* branchName() const { return mBranchName.c_str(); } + [[nodiscard]] int fieldSize() const { return mFieldSize; } + [[nodiscard]] int columnEntries() const { return mColumn->length(); } + [[nodiscard]] char const* branchName() const { return mBranchName.c_str(); } private: void accessChunk(); diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index e6e6a1349e619..14e4a43ea6cba 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -454,9 +454,23 @@ std::shared_ptr TableToTree::process() } for (auto& reader : mColumnReaders) { - int idealBasketSize = 1024 + reader->fieldSize() * mRows; // minimal additional size needed, otherwise we get 2 baskets + int idealBasketSize = 1024 + reader->fieldSize() * reader->columnEntries(); // minimal additional size needed, otherwise we get 2 baskets int basketSize = std::max(32000, idealBasketSize); // keep a minimum value + // std::cout << "Setting baskets size for " << reader->branchName() << " to " << basketSize << " = 1024 + " + // << reader->fieldSize() << " * " << reader->columnEntries() << ". mRows was " << mRows << std::endl; mTree->SetBasketSize(reader->branchName(), basketSize); + // If it starts with fIndexArray, also set the size branch basket size + if (strncmp(reader->branchName(), "fIndexArray", strlen("fIndexArray")) == 0) { + std::string sizeBranch = reader->branchName(); + sizeBranch += "_size"; + // std::cout << "Setting baskets size for " << sizeBranch << " to " << basketSize << " = 1024 + " + // << reader->fieldSize() << " * " << reader->columnEntries() << ". mRows was " << mRows << std::endl; + // One int per array to keep track of the size + int idealBasketSize = 4 * mRows + 1024 + reader->fieldSize() * reader->columnEntries(); // minimal additional size needed, otherwise we get 2 baskets + int basketSize = std::max(32000, idealBasketSize); // keep a minimum value + mTree->SetBasketSize(sizeBranch.c_str(), basketSize); + mTree->SetBasketSize(reader->branchName(), basketSize); + } } while (row < mRows) { From d97113d7111980e3ec7b76b4b44f3426d933075b Mon Sep 17 00:00:00 2001 From: noferini <9963644+noferini@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:58:22 +0200 Subject: [PATCH 0273/2205] finalizing tool to test TOF digitizer --- .../include/TOFSimulation/Digitizer.h | 14 +++++--- Detectors/TOF/simulation/src/Digitizer.cxx | 34 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h index 91ae26f2c9451..feb35c769d6ba 100644 --- a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h +++ b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h @@ -61,13 +61,14 @@ class Digitizer : public WindowFiller Float_t getEffZ(Float_t z); Float_t getFractionOfCharge(Float_t x, Float_t z); - Float_t getTimeLastHit(Int_t idigit) const { return 0; } - Float_t getTotLastHit(Int_t idigit) const { return 0; } - Int_t getXshift(Int_t idigit) const { return 0; } - Int_t getZshift(Int_t idigit) const { return 0; } + Float_t getTimeLastHit(Int_t idigit) const { return mTimeLastHit[idigit]; } + Float_t getTotLastHit(Int_t idigit) const { return mTotLastHit[idigit]; } + Int_t getXshift(Int_t idigit) const { return mXLastShift[idigit]; } + Int_t getZshift(Int_t idigit) const { return mZLastShift[idigit]; } void setEventID(Int_t id) { mEventID = id; } void setSrcID(Int_t id) { mSrcID = id; } + void runFullTestExample(const char* geo = ""); void test(const char* geo = ""); void testFromHits(const char* geo = "", const char* hits = "AliceO2_TGeant3.tof.mc_10_event.root"); @@ -134,6 +135,11 @@ class Digitizer : public WindowFiller void checkIfReuseFutureDigits(); + int mNLastHit = 0; + float mTimeLastHit[10]; + float mTotLastHit[10]; + Int_t mXLastShift[10]; + Int_t mZLastShift[10]; ClassDefNV(Digitizer, 1); }; } // namespace tof diff --git a/Detectors/TOF/simulation/src/Digitizer.cxx b/Detectors/TOF/simulation/src/Digitizer.cxx index cb2d36fa654a1..d8ef99ae1bd22 100644 --- a/Detectors/TOF/simulation/src/Digitizer.cxx +++ b/Detectors/TOF/simulation/src/Digitizer.cxx @@ -128,6 +128,8 @@ int Digitizer::process(const std::vector* hits, std::vector* dig Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) { + mNLastHit = 0; + Float_t pos[3] = {hit.GetX(), hit.GetY(), hit.GetZ()}; Float_t deltapos[3]; Int_t detInd[5]; @@ -169,6 +171,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) // check the fired PAD 1 (A) if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = 0; + mZLastShift[mNLastHit] = 0; addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, 0, detInd[3], trackID); } @@ -184,6 +188,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) } if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = 0; + mZLastShift[mNLastHit] = iZshift; addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, iZshift, detInd[3], trackID); } @@ -196,6 +202,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) zLocal = deltapos[2]; // recompute local coordinates if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = -1; + mZLastShift[mNLastHit] = 0; addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, 0, detInd[3], trackID); } } @@ -209,6 +217,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) zLocal = deltapos[2]; // recompute local coordinates if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = 1; + mZLastShift[mNLastHit] = 0; addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, 0, detInd[3], trackID); } } @@ -226,6 +236,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) } if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = -1; + mZLastShift[mNLastHit] = iZshift; addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, iZshift, detInd[3], trackID); } } @@ -243,6 +255,8 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) } if (isFired(xLocal, zLocal, charge)) { ndigits++; + mXLastShift[mNLastHit] = 1; + mZLastShift[mNLastHit] = iZshift; addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, iZshift, detInd[3], trackID); } } @@ -297,6 +311,11 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, LOG(error) << "Wrong de-calibration correction for ch = " << channel << ", tot = " << tot << " (Skip it)"; return; } + + mTimeLastHit[mNLastHit] = time; + mTotLastHit[mNLastHit] = tot; + mNLastHit++; + time -= tsCorr; // TODO: to be checked that "-" is correct, and we did not need "+" instead :-) // let's move from time to bc, tdc @@ -590,7 +609,17 @@ void Digitizer::printParameters() printf("Time walk ON = %f ps/cm\n", mTimeWalkeSlope); } } - +//______________________________________________________________________ +void Digitizer::runFullTestExample(const char* geo) +{ + initParameters(); + o2::tof::CalibTOFapi* api = new o2::tof::CalibTOFapi(); + api->setTimeStamp(0); + api->readLHCphase(); + api->readTimeSlewingParam(); + setCalibApi(api); + test(geo); +} //______________________________________________________________________ void Digitizer::test(const char* geo) { @@ -696,7 +725,8 @@ void Digitizer::test(const char* geo) hit->SetEnergyLoss(0.0001); - Int_t ndigits = processHit(*hit, mEventTime.getTimeOffsetWrtBC()); + processHit(*hit, mEventTime.getTimeOffsetWrtBC()); + Int_t ndigits = mNLastHit; h3->Fill(ndigits); hpadAll->Fill(xlocal, zlocal); From d55ec92a83e1cb67afc204c03905aab4f947807d Mon Sep 17 00:00:00 2001 From: afurs Date: Thu, 19 Sep 2024 22:04:26 +0200 Subject: [PATCH 0274/2205] FT0: beamtype dependent trg settings for FT0 calibration --- prodtests/full-system-test/aggregator-workflow.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index aedd9f7b3bc2f..4e5f6f2a4c8ad 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -113,10 +113,12 @@ if [[ $BEAMTYPE == "PbPb" ]]; then : ${LHCPHASE_TF_PER_SLOT:=100000} : ${TOF_CHANNELOFFSETS_UPDATE:=300000} : ${TOF_CHANNELOFFSETS_DELTA_UPDATE:=50000} + : ${FT0_TIMEOFFSET_TRG_BITS:=384} # min bias and data validity else : ${LHCPHASE_TF_PER_SLOT:=100000} : ${TOF_CHANNELOFFSETS_UPDATE:=300000} : ${TOF_CHANNELOFFSETS_DELTA_UPDATE:=50000} + : ${FT0_TIMEOFFSET_TRG_BITS:=144} # vertex and data validity fi # special settings for aggregator workflows @@ -361,7 +363,7 @@ fi if [[ $AGGREGATOR_TASKS == FORWARD_TF || $AGGREGATOR_TASKS == ALL ]]; then # FT0 if [[ $CALIB_FT0_TIMEOFFSET == 1 ]]; then - add_W o2-calibration-ft0-time-offset-calib "--tf-per-slot $FT0_TIMEOFFSET_TF_PER_SLOT --max-delay 0" "FT0CalibParam.mNExtraSlots=0;FT0CalibParam.mRebinFactorPerChID[180]=4;" + add_W o2-calibration-ft0-time-offset-calib "--tf-per-slot $FT0_TIMEOFFSET_TF_PER_SLOT --max-delay 0" "FT0CalibParam.mNExtraSlots=0;FT0CalibParam.mRebinFactorPerChID[180]=4;FT0DigitFilterParam.mTrgBitsGood=${FT0_TIMEOFFSET_TRG_BITS};FT0DigitFilterParam.mTrgBitsToCheck=${FT0_TIMEOFFSET_TRG_BITS};" fi fi From 2f7add519aa4495f3ab2f6005d5e6b90acdc3c02 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 22 Sep 2024 09:38:27 +0200 Subject: [PATCH 0275/2205] DPL: thread safe activity detection This makes sure that the detection of active data processors in a device is threadsafe by recording the last active one. The main loop will then short circuit libuv in case the last active dataprocessor was reported and it will reset the last active pointer to nullptr if it has not changed in the meanwhile (meaning that another data processor was actually able to process something). --- .../include/Framework/DataProcessingContext.h | 4 +- .../include/Framework/DataProcessingDevice.h | 1 - .../Core/include/Framework/DeviceState.h | 7 +++ Framework/Core/src/DataProcessingDevice.cxx | 60 ++++++++++++------- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/Framework/Core/include/Framework/DataProcessingContext.h b/Framework/Core/include/Framework/DataProcessingContext.h index d71ad203b1580..9b7cbc238c942 100644 --- a/Framework/Core/include/Framework/DataProcessingContext.h +++ b/Framework/Core/include/Framework/DataProcessingContext.h @@ -26,9 +26,7 @@ struct DataProcessorSpec; struct DataProcessorContext { DataProcessorContext(DataProcessorContext const&) = delete; DataProcessorContext() = default; - // These are specific of a given context and therefore - // not shared by threads. - bool* wasActive = nullptr; + bool allDone = false; /// Latest run number we processed globally for this DataProcessor. int64_t lastRunNumberProcessed = -1; diff --git a/Framework/Core/include/Framework/DataProcessingDevice.h b/Framework/Core/include/Framework/DataProcessingDevice.h index d9565ebef84a2..67edaa99e532b 100644 --- a/Framework/Core/include/Framework/DataProcessingDevice.h +++ b/Framework/Core/include/Framework/DataProcessingDevice.h @@ -113,7 +113,6 @@ class DataProcessingDevice : public fair::mq::Device std::vector mPendingRegionInfos; /// A list of the region infos not yet notified. std::mutex mRegionInfoMutex; ProcessingPolicies mProcessingPolicies; /// User policies related to data processing - bool mWasActive = false; /// Whether or not the device was active at last iteration. std::vector mHandles; /// Handles to use to schedule work. std::vector mStreams; /// Information about the task running in the associated mHandle. /// Handle to wake up the main loop from other threads diff --git a/Framework/Core/include/Framework/DeviceState.h b/Framework/Core/include/Framework/DeviceState.h index 89961b3e92dc7..f6d863064ee66 100644 --- a/Framework/Core/include/Framework/DeviceState.h +++ b/Framework/Core/include/Framework/DeviceState.h @@ -30,6 +30,8 @@ typedef struct uv_async_s uv_async_t; namespace o2::framework { +struct DataProcessorContext; + /// Running state information of a given device struct DeviceState { /// Motivation for the loop being triggered. @@ -108,6 +110,11 @@ struct DeviceState { /// the bits we are interested in. std::vector severityStack; TransitionHandlingState transitionHandling = TransitionHandlingState::NoTransition; + + // The DataProcessorContext which was most recently active. + // We use this to determine if we should trigger the loop without + // waiting for some events. + std::atomic lastActiveDataProcessor = nullptr; }; } // namespace o2::framework diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index f3fe328e78a06..169613b18a2ee 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -1061,7 +1061,11 @@ void DataProcessingDevice::InitTask() // Whenever we InitTask, we consider as if the previous iteration // was successful, so that even if there is no timer or receiving // channel, we can still start an enumeration. - mWasActive = true; + DataProcessorContext* initialContext = nullptr; + bool idle = state.lastActiveDataProcessor.compare_exchange_strong(initialContext, (DataProcessorContext*)-1); + if (!idle) { + LOG(error) << "DataProcessor " << state.lastActiveDataProcessor.load()->spec->name << " was unexpectedly active"; + } // We should be ready to run here. Therefore we copy all the // required parts in the DataProcessorContext. Eventually we should @@ -1093,8 +1097,6 @@ void DataProcessingDevice::InitTask() void DataProcessingDevice::fillContext(DataProcessorContext& context, DeviceContext& deviceContext) { - context.wasActive = &mWasActive; - context.isSink = false; // If nothing is a sink, the rate limiting simply does not trigger. bool enableRateLimiting = std::stoi(fConfig->GetValue("timeframes-rate-limit")); @@ -1308,14 +1310,19 @@ void DataProcessingDevice::Run() { ServiceRegistryRef ref{mServiceRegistry}; ref.get().flushPending(mServiceRegistry); - auto shouldNotWait = (mWasActive && + DataProcessorContext* lastActive = state.lastActiveDataProcessor.load(); + // Reset to zero unless some other DataPorcessorContext completed in the meanwhile. + // In such case we will take care of it at next iteration. + state.lastActiveDataProcessor.compare_exchange_strong(lastActive, nullptr); + + auto shouldNotWait = (lastActive != nullptr && (state.streaming != StreamingState::Idle) && (state.activeSignals.empty())) || (state.streaming == StreamingState::EndOfStreaming); if (firstLoop) { shouldNotWait = true; firstLoop = false; } - if (mWasActive) { + if (lastActive != nullptr) { state.loopReason |= DeviceState::LoopReason::PREVIOUSLY_ACTIVE; } if (NewStatePending()) { @@ -1485,10 +1492,7 @@ void DataProcessingDevice::Run() } else { auto ref = ServiceRegistryRef{mServiceRegistry}; ref.get().handleExpired(reportExpiredOffer); - mWasActive = false; } - } else { - mWasActive = false; } } @@ -1510,7 +1514,6 @@ void DataProcessingDevice::doPrepare(ServiceRegistryRef ref) O2_SIGNPOST_ID_FROM_POINTER(dpid, device, &context); O2_SIGNPOST_START(device, dpid, "do_prepare", "Starting DataProcessorContext::doPrepare."); - *context.wasActive = false; { ref.get().call(); } @@ -1669,7 +1672,10 @@ void DataProcessingDevice::doPrepare(ServiceRegistryRef ref) socket.Events(&info.hasPendingEvents); if (info.hasPendingEvents) { info.readPolled = false; - *context.wasActive |= newMessages; + // In case there were messages, we consider it as activity + if (newMessages) { + state.lastActiveDataProcessor.store(&context); + } } O2_SIGNPOST_END(device, cid, "channels", "Done processing channel %{public}s (%d).", channelSpec.name.c_str(), info.id.value); @@ -1693,24 +1699,29 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) auto& spec = ref.get(); if (state.streaming == StreamingState::Idle) { - *context.wasActive = false; return; } context.completed.clear(); context.completed.reserve(16); - *context.wasActive |= DataProcessingDevice::tryDispatchComputation(ref, context.completed); + if (DataProcessingDevice::tryDispatchComputation(ref, context.completed)) { + state.lastActiveDataProcessor.store(&context); + } DanglingContext danglingContext{*context.registry}; context.preDanglingCallbacks(danglingContext); - if (*context.wasActive == false) { + if (state.lastActiveDataProcessor.load() == nullptr) { ref.get().call(); } auto activity = ref.get().processDanglingInputs(context.expirationHandlers, *context.registry, true); - *context.wasActive |= activity.expiredSlots > 0; + if (activity.expiredSlots > 0) { + state.lastActiveDataProcessor = &context; + } context.completed.clear(); - *context.wasActive |= DataProcessingDevice::tryDispatchComputation(ref, context.completed); + if (DataProcessingDevice::tryDispatchComputation(ref, context.completed)) { + state.lastActiveDataProcessor = &context; + } context.postDanglingCallbacks(danglingContext); @@ -1720,7 +1731,7 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) // framework itself. if (context.allDone == true && state.streaming == StreamingState::Streaming) { switchState(StreamingState::EndOfStreaming); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; } if (state.streaming == StreamingState::EndOfStreaming) { @@ -1766,7 +1777,10 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref) // This is needed because the transport is deleted before the device. relayer.clear(); switchState(StreamingState::Idle); - *context.wasActive = shouldProcess; + // In case we should process, note the data processor responsible for it + if (shouldProcess) { + state.lastActiveDataProcessor = &context; + } // On end of stream we shut down all output pollers. O2_SIGNPOST_EVENT_EMIT(device, dpid, "state", "Shutting down output pollers."); for (auto& poller : state.activeOutputPollers) { @@ -1834,6 +1848,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& O2_SIGNPOST_ID_FROM_POINTER(cid, device, &info); auto ref = ServiceRegistryRef{*context.registry}; auto& stats = ref.get(); + auto& state = ref.get(); auto& parts = info.parts; stats.updateStats({(int)ProcessingStatsId::TOTAL_INPUTS, DataProcessingStats::Op::Set, (int64_t)parts.Size()}); @@ -1856,14 +1871,14 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& O2_SIGNPOST_EVENT_EMIT(device, cid, "handle_data", "Got SourceInfoHeader with state %d", (int)sih->state); info.state = sih->state; insertInputInfo(pi, 2, InputType::SourceInfo, info.id); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; continue; } auto dih = o2::header::get(headerData); if (dih) { O2_SIGNPOST_EVENT_EMIT(device, cid, "handle_data", "Got DomainInfoHeader with oldestPossibleTimeslice %d", (int)dih->oldestPossibleTimeslice); insertInputInfo(pi, 2, InputType::DomainInfo, info.id); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; continue; } auto dh = o2::header::get(headerData); @@ -1925,6 +1940,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& auto handleValidMessages = [&info, ref, &reportError](std::vector const& inputInfos) { auto& relayer = ref.get(); + auto& state = ref.get(); static WaitBackpressurePolicy policy; auto& parts = info.parts; // We relay execution to make sure we have a complete set of parts @@ -2012,7 +2028,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& case InputType::SourceInfo: { LOGP(detail, "Received SourceInfo"); auto& context = ref.get(); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; auto headerIndex = input.position; auto payloadIndex = input.position + 1; assert(payloadIndex < parts.Size()); @@ -2030,7 +2046,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& /// We have back pressure, therefore we do not process DomainInfo anymore. /// until the previous message are processed. auto& context = ref.get(); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; auto headerIndex = input.position; auto payloadIndex = input.position + 1; assert(payloadIndex < parts.Size()); @@ -2058,7 +2074,7 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo& auto& context = ref.get(); context.domainInfoUpdatedCallback(*context.registry, oldestPossibleTimeslice, info.id); ref.get().call((ServiceRegistryRef)*context.registry, (size_t)oldestPossibleTimeslice, (ChannelIndex)info.id); - *context.wasActive = true; + state.lastActiveDataProcessor = &context; } auto it = std::remove_if(parts.fParts.begin(), parts.fParts.end(), [](auto& msg) -> bool { return msg.get() == nullptr; }); parts.fParts.erase(it, parts.end()); From eaa7fbb3745567c59cf1266cfb7c8c5f5c44e85f Mon Sep 17 00:00:00 2001 From: wiechula <11199190+wiechula@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:48:24 +0200 Subject: [PATCH 0276/2205] TPC: Multiple fixes and extensions (#13533) * fix completion policy * Add possibility for a common file name extension saving canvases * Extend FW parameter file creation * Allow for different thresholds for each ROC Type in pedestal file creation * Add common mode k-values in float precision and inverse k-factors with truncated precision * Digit class extension for simple drawing * Extend TPC refitter * possibility to dump ITS-TPC * Tsallis downsampling * MB sampling * shared flag added to native clusters * Charge info now via native clusters * Write full native clusters * add occupancy info * add cosmics refitting with TOF cluster time * Extend time gain calibration * Undo previous timeGain corrections to allow for residual calibration * slot length in seconds * slot extension for CCDB (for residual calibration) * simple looper cut * settable debug output name * dumping of calibration histograms per slot * debug output on track level * average entries for calibration * Update event display - Pad vs time view for a single row * visualisation of hovered time bin in ADC vs. time - cluster overlay in pad vs. time view * selection of cluster flags - Pad vs. row view for a single time bin * visualisation of hovered time bin in ADC vs. time --- .../DataFormatsTPC/CalibdEdxCorrection.h | 6 + .../TPC/include/DataFormatsTPC/TrackCuts.h | 13 +- .../Detectors/TPC/src/CalibdEdxCorrection.cxx | 20 + DataFormats/Detectors/TPC/src/TrackCuts.cxx | 3 + .../include/DetectorsBase/DPLWorkflowUtils.h | 1 + .../base/include/TPCBase/CRUCalibHelpers.h | 5 +- Detectors/TPC/base/include/TPCBase/Utils.h | 20 +- Detectors/TPC/base/src/CRUCalibHelpers.cxx | 24 +- Detectors/TPC/base/src/Utils.cxx | 12 +- Detectors/TPC/calibration/CMakeLists.txt | 4 +- .../include/TPCCalibration/CalibdEdx.h | 41 +- .../include/TPCCalibration/CalibratordEdx.h | 10 + .../include/TPCCalibration/DigitAdd.h | 39 + .../TPC/calibration/macro/prepareCMFiles.C | 21 + .../calibration/macro/preparePedestalFiles.C | 7 +- .../calibration/macro/preparePedestalFiles.sh | 10 +- Detectors/TPC/calibration/src/CalibdEdx.cxx | 88 ++- .../TPC/calibration/src/CalibratordEdx.cxx | 21 + Detectors/TPC/calibration/src/DigitAdd.cxx | 54 ++ .../calibration/src/TPCCalibrationLinkDef.h | 2 + .../include/TPCMonitor/SimpleEventDisplay.h | 13 +- .../TPCMonitor/SimpleEventDisplayGUI.h | 41 +- .../TPC/monitor/src/SimpleEventDisplay.cxx | 88 ++- .../TPC/monitor/src/SimpleEventDisplayGUI.cxx | 504 +++++++++++-- .../include/TPCWorkflow/TPCRefitter.h | 6 +- Detectors/TPC/workflow/src/CalibdEdxSpec.cxx | 24 +- .../TPC/workflow/src/CalibratordEdxSpec.cxx | 74 +- .../TPC/workflow/src/MIPTrackFilterSpec.cxx | 7 +- Detectors/TPC/workflow/src/TPCRefitter.cxx | 700 +++++++++++++----- .../TPC/workflow/src/tpc-miptrack-filter.cxx | 8 +- .../workflow/src/tpc-refitter-workflow.cxx | 18 +- 31 files changed, 1571 insertions(+), 313 deletions(-) create mode 100644 Detectors/TPC/calibration/include/TPCCalibration/DigitAdd.h create mode 100644 Detectors/TPC/calibration/src/DigitAdd.cxx diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h index ace488b652559..482c577ec9083 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h @@ -109,6 +109,12 @@ class CalibdEdxCorrection /// Single fit parameters averaged over all sectors for a stack type float getMeanParam(const GEMstack stack, ChargeType charge, uint32_t param) const; + /// Single fit parameters averaged over all sectors for a stack type + float getMeanEntries(ChargeType charge) const; + + /// Single fit parameters averaged over all sectors for a stack type + float getMeanEntries(const GEMstack stack, ChargeType charge) const; + #endif private: diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackCuts.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackCuts.h index f8bcc601cf659..451acfe9d1fa0 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackCuts.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/TrackCuts.h @@ -46,13 +46,16 @@ class TrackCuts void setNClusMin(float NClusMin) { mNClusMin = NClusMin; } void setdEdxMin(float dEdxMin) { mdEdxMin = dEdxMin; } void setdEdxMax(float dEdxMax) { mdEdxMax = dEdxMax; } + /// try to remove looper cutting on (abs(z_out) - abs(z_in)) < -10), not very precise + void setCutLooper(bool cut) { mCutLooper = cut; } private: - float mPMin{0}; ///< min momentum allowed - float mPMax{1e10}; ///< max momentum allowed - float mNClusMin{0}; ///< min number of clusters in track allowed - float mdEdxMin{0}; ///< min dEdx - float mdEdxMax{1e10}; ///< max dEdx + float mPMin{0}; ///< min momentum allowed + float mPMax{1e10}; ///< max momentum allowed + float mNClusMin{0}; ///< min number of clusters in track allowed + float mdEdxMin{0}; ///< min dEdx + float mdEdxMax{1e10}; ///< max dEdx + bool mCutLooper{false}; ///< cut looper comparing zout-zin ClassDefNV(TrackCuts, 1) }; diff --git a/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx b/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx index 28a44f15cf18c..1a66eb962cdf0 100644 --- a/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx +++ b/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx @@ -135,3 +135,23 @@ float CalibdEdxCorrection::getMeanParam(const GEMstack stack, ChargeType charge, return mean / (SECTORSPERSIDE * SIDES); } + +float CalibdEdxCorrection::getMeanEntries(ChargeType charge) const +{ + float mean{}; + for (int index = 0; index < FitSize / 2; ++index) { + mean += mEntries[index + charge * FitSize / 2]; + } + + return mean / (0.5f * FitSize); +} + +float CalibdEdxCorrection::getMeanEntries(const GEMstack stack, ChargeType charge) const +{ + float mean{}; + for (int index = 0; index < SECTORSPERSIDE * SIDES; ++index) { + mean += getEntries(StackID{index, stack}, charge); + } + + return mean / (SECTORSPERSIDE * SIDES); +} diff --git a/DataFormats/Detectors/TPC/src/TrackCuts.cxx b/DataFormats/Detectors/TPC/src/TrackCuts.cxx index 43039e25734b0..111f3c3da8920 100644 --- a/DataFormats/Detectors/TPC/src/TrackCuts.cxx +++ b/DataFormats/Detectors/TPC/src/TrackCuts.cxx @@ -49,5 +49,8 @@ bool TrackCuts::goodTrack(o2::tpc::TrackTPC const& track) if (dEdx < mdEdxMin) { return false; } + if ((std::abs(track.getOuterParam().getZ()) - std::abs(track.getZ())) < -10) { + return false; + } return true; } diff --git a/Detectors/Base/include/DetectorsBase/DPLWorkflowUtils.h b/Detectors/Base/include/DetectorsBase/DPLWorkflowUtils.h index 6249b9c693b8c..ba3dd821fa118 100644 --- a/Detectors/Base/include/DetectorsBase/DPLWorkflowUtils.h +++ b/Detectors/Base/include/DetectorsBase/DPLWorkflowUtils.h @@ -25,6 +25,7 @@ #include "Framework/CompletionPolicy.h" #include "Framework/CompletionPolicyHelpers.h" #include "Framework/DeviceSpec.h" +#include "Framework/Task.h" #include "Framework/DataSpecUtils.h" #include #include diff --git a/Detectors/TPC/base/include/TPCBase/CRUCalibHelpers.h b/Detectors/TPC/base/include/TPCBase/CRUCalibHelpers.h index 464a5eb24d4f7..818a9a41d0dcc 100644 --- a/Detectors/TPC/base/include/TPCBase/CRUCalibHelpers.h +++ b/Detectors/TPC/base/include/TPCBase/CRUCalibHelpers.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace fs = std::filesystem; #include "Rtypes.h" @@ -246,7 +247,9 @@ o2::tpc::CalDet getCalPad(const std::string_view fileName, const std::str return calPad; } -std::unordered_map preparePedestalFiles(const CalPad& pedestals, const CalPad& noise, float sigmaNoise = 3, float minADC = 2, float pedestalOffset = 0, bool onlyFilled = false, bool maskBad = true, float noisyChannelThreshold = 1.5, float sigmaNoiseNoisyChannels = 4, float badChannelThreshold = 6, bool fixedSize = false); +/// \param sigmaNoiseROCType can be either one value for all ROC types, or {IROC, OROC}, or {IROC, OROC1, OROC2, OROC3} +/// \param minADCROCType can be either one value for all ROC types, or {IROC, OROC}, or {IROC, OROC1, OROC2, OROC3} +std::unordered_map preparePedestalFiles(const CalPad& pedestals, const CalPad& noise, std::vector sigmaNoiseROCType = {3, 3, 3, 3}, std::vector minADCROCType = {2, 2, 2, 2}, float pedestalOffset = 0, bool onlyFilled = false, bool maskBad = true, float noisyChannelThreshold = 1.5, float sigmaNoiseNoisyChannels = 4, float badChannelThreshold = 6, bool fixedSize = false); } // namespace o2::tpc::cru_calib_helpers diff --git a/Detectors/TPC/base/include/TPCBase/Utils.h b/Detectors/TPC/base/include/TPCBase/Utils.h index b72c2a20fb45f..fbeb51f8bee69 100644 --- a/Detectors/TPC/base/include/TPCBase/Utils.h +++ b/Detectors/TPC/base/include/TPCBase/Utils.h @@ -17,6 +17,7 @@ /// \author Jens Wiechula, Jens.Wiechula@ikf.uni-frankfurt.de /// +#include #include #include @@ -44,9 +45,9 @@ namespace utils const std::vector tokenize(const std::string_view input, const std::string_view pattern); TH1* getBinInfoXY(int& binx, int& biny, float& bincx, float& bincy); void addFECInfo(); -void saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types = "png,pdf", std::string_view rootFileName = ""); -void saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types = "png,pdf", std::string_view rootFileName = ""); -void saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types); +void saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types = "png,pdf", std::string_view rootFileName = "", std::string nameAdd = ""); +void saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types = "png,pdf", std::string_view rootFileName = "", std::string nameAdd = ""); +void saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types, std::string nameAdd = ""); std::vector readCalPads(const std::string_view fileName, const std::vector& calPadNames); std::vector readCalPads(const std::string_view fileName, const std::string_view calPadNames); @@ -69,6 +70,19 @@ void mergeCalPads(std::string_view outputFileName, std::string_view inputFileNam /// \param treeTitle title of the tree TChain* buildChain(std::string_view command, std::string_view treeName, std::string_view treeTitle = "", bool checkSubDir = false); +template +std::string elementsToString(Iterator begin, Iterator end, const std::string separator = ", ") +{ + return std::accumulate(std::next(begin), end, std::to_string(*begin), + [&separator](auto s, auto f) { return std::move(s) + separator + std::to_string(f); }); +} + +template +std::string elementsToString(const T& val, const std::string separator = ", ") +{ + return elementsToString(val.begin(), val.end(), separator); +} + } // namespace utils } // namespace o2::tpc diff --git a/Detectors/TPC/base/src/CRUCalibHelpers.cxx b/Detectors/TPC/base/src/CRUCalibHelpers.cxx index 2a0b23b6470b4..f18baa6571f66 100644 --- a/Detectors/TPC/base/src/CRUCalibHelpers.cxx +++ b/Detectors/TPC/base/src/CRUCalibHelpers.cxx @@ -12,7 +12,9 @@ #include #include #include +#include +#include "TPCBase/Utils.h" #include "TROOT.h" #include "Framework/Logger.h" @@ -102,10 +104,26 @@ void cru_calib_helpers::debugDiff(std::string_view file1, std::string_view file2 } } -std::unordered_map cru_calib_helpers::preparePedestalFiles(const CalPad& pedestals, const CalPad& noise, float sigmaNoise, float minADC, float pedestalOffset, bool onlyFilled, bool maskBad, float noisyChannelThreshold, float sigmaNoiseNoisyChannels, float badChannelThreshold, bool fixedSize) +std::unordered_map cru_calib_helpers::preparePedestalFiles(const CalPad& pedestals, const CalPad& noise, std::vector sigmaNoiseROCType, std::vector minADCROCType, float pedestalOffset, bool onlyFilled, bool maskBad, float noisyChannelThreshold, float sigmaNoiseNoisyChannels, float badChannelThreshold, bool fixedSize) { const auto& mapper = Mapper::instance(); + auto expandVector = [](std::vector& vec, const std::string name) { + if (vec.size() == 1) { + vec.resize(4); + std::fill_n(&vec[1], 3, vec[0]); + } else if (vec.size() == 2) { + vec.resize(4); + std::fill_n(&vec[2], 2, vec[1]); + } else if (vec.size() != 4) { + LOGP(fatal, "{} definition must be either one value for all ROC types, or {{IROC, OROC}}, or {{IROC, OROC1, OROC2, OROC3}}", name); + } + LOGP(info, "Using {} = {{{}}}", name, utils::elementsToString(vec)); + }; + + expandVector(sigmaNoiseROCType, "sigmaNoiseROCType"); + expandVector(minADCROCType, "minADCROCType"); + std::unordered_map pedestalsThreshold; pedestalsThreshold["Pedestals"] = CalPad("Pedestals"); pedestalsThreshold["ThresholdMap"] = CalPad("ThresholdMap"); @@ -147,6 +165,9 @@ std::unordered_map cru_calib_helpers::preparePedestalFiles( const int fecInPartition = fecInfo.getIndex() - partInfo.getSectorFECOffset(); // const int dataWrapperID = fecInPartition >= fecOffset; // const int globalLinkID = (fecInPartition % fecOffset) + dataWrapperID * 12; + const int rocType = roc.isIROC() ? 0 : cru.partition() - 1; + const float sigmaNoise = sigmaNoiseROCType[rocType]; + const float minADC = minADCROCType[rocType]; const auto traceLength = traceLengths[ipad]; @@ -174,6 +195,7 @@ std::unordered_map cru_calib_helpers::preparePedestalFiles( float threshold = (noise > 0) ? std::max(sigmaNoise * noise, minADC) : 0; threshold = std::min(threshold, 1023.f); float thresholdHighNoise = (noiseCorr > noisyChannelThreshold) ? std::max(sigmaNoiseNoisyChannels * noise, minADC) : threshold; + thresholdHighNoise = std::min(thresholdHighNoise, 1023.f); float pedestalHighNoise = pedestal; if (noiseCorr > badChannelThreshold) { diff --git a/Detectors/TPC/base/src/Utils.cxx b/Detectors/TPC/base/src/Utils.cxx index 5ddd649166b43..8879e8ab342d2 100644 --- a/Detectors/TPC/base/src/Utils.cxx +++ b/Detectors/TPC/base/src/Utils.cxx @@ -133,11 +133,11 @@ void utils::addFECInfo() h->SetTitle(title.data()); } -void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types, std::string_view rootFileName) +void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types, std::string_view rootFileName, std::string nameAdd) { if (types.size()) { for (auto c : arr) { - utils::saveCanvas(*static_cast(c), outDir, types); + utils::saveCanvas(*static_cast(c), outDir, types, nameAdd); } } @@ -148,24 +148,24 @@ void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_vi } } -void utils::saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types, std::string_view rootFileName) +void utils::saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types, std::string_view rootFileName, std::string nameAdd) { TObjArray arr; for (auto c : canvases) { arr.Add(c); } - saveCanvases(arr, outDir, types, rootFileName); + saveCanvases(arr, outDir, types, rootFileName, nameAdd); } -void utils::saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types) +void utils::saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types, std::string nameAdd) { if (!types.size()) { return; } const auto typesVec = tokenize(types, ","); for (const auto& type : typesVec) { - c.SaveAs(fmt::format("{}/{}.{}", outDir, c.GetName(), type).data()); + c.SaveAs(fmt::format("{}/{}{}.{}", outDir, c.GetName(), nameAdd, type).data()); } } diff --git a/Detectors/TPC/calibration/CMakeLists.txt b/Detectors/TPC/calibration/CMakeLists.txt index 6e53a4af40f26..4e569774c86a5 100644 --- a/Detectors/TPC/calibration/CMakeLists.txt +++ b/Detectors/TPC/calibration/CMakeLists.txt @@ -55,6 +55,7 @@ o2_add_library(TPCCalibration src/TPCScaler.cxx src/CorrMapParam.cxx src/TPCMShapeCorrection.cxx + src/DigitAdd.cxx PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBase O2::TPCReconstruction ROOT::Minuit Microsoft.GSL::GSL @@ -109,7 +110,8 @@ o2_target_root_dictionary(TPCCalibration include/TPCCalibration/CalculatedEdx.h include/TPCCalibration/TPCScaler.h include/TPCCalibration/CorrMapParam.h - include/TPCCalibration/TPCMShapeCorrection.h) + include/TPCCalibration/TPCMShapeCorrection.h + include/TPCCalibration/DigitAdd.h) o2_add_test_root_macro(macro/comparePedestalsAndNoise.C PUBLIC_LINK_LIBRARIES O2::TPCBase diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h index b07d00c132175..470e2c84b5b60 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h @@ -19,14 +19,15 @@ #include #include #include -#include // o2 includes +#include "CommonDataFormat/TFIDInfo.h" #include "DataFormatsTPC/TrackTPC.h" #include "DataFormatsTPC/TrackCuts.h" #include "DataFormatsTPC/Defs.h" #include "DataFormatsTPC/CalibdEdxCorrection.h" #include "DetectorsBase/Propagator.h" +#include "CommonUtils/TreeStreamRedirector.h" // boost includes #include @@ -54,6 +55,8 @@ class CalibdEdx // Float axis to store data, without under and overflow bins. using FloatAxis = boost::histogram::axis::regular; + using TFIDInfo = o2::dataformats::TFIDInfo; + // Histogram axes types using AxesType = std::tuple< FloatAxis, // dEdx @@ -66,6 +69,9 @@ class CalibdEdx using Hist = boost::histogram::histogram; + /// copy ctor + CalibdEdx(const CalibdEdx& other); + /// \param angularBins number of bins for Tgl and Snp /// \param fitSnp enable Snp correction CalibdEdx(int dEdxBins = 60, float mindEdx = 20, float maxdEdx = 90, int angularBins = 36, bool fitSnp = false); @@ -106,6 +112,13 @@ class CalibdEdx void fill(const gsl::span); void fill(const std::vector& tracks) { fill(gsl::span(tracks)); } + void fill(const TFIDInfo& tfid, const gsl::span tracks) + { + mTFID = tfid; + fill(tracks); + } + void fill(const TFIDInfo& tfid, const std::vector& tracks) { fill(tfid, gsl::span(tracks)); } + /// Add counts from another container. void merge(const CalibdEdx* other); @@ -120,6 +133,10 @@ class CalibdEdx const CalibdEdxCorrection& getCalib() const { return mCalib; } + /// calibration used during reconstruction + void setCalibrationInput(const CalibdEdxCorrection& calib) { mCalibIn = calib; } + const CalibdEdxCorrection& getCalibrationInput() const { return mCalibIn; } + /// Return the number of hist entries of the gem stack with less statistics int minStackEntries() const; @@ -136,12 +153,25 @@ class CalibdEdx /// Save the histograms to a TTree. void writeTTree(std::string_view fileName) const; + /// Enable debug output to file of the time slots calibrations outputs and dE/dx histograms + void enableDebugOutput(std::string_view fileName); + + /// Disable debug output to file. Also writes and closes stored time slots. + void disableDebugOutput(); + + /// Write debug output to file + void finalizeDebugOutput() const; + + /// \return if debug output is enabled + bool hasDebugOutput() const { return static_cast(mDebugOutputStreamer); } + constexpr static float MipScale = 1.0 / 50.0; ///< Inverse of target dE/dx value for MIPs constexpr static float scaleTgl(float tgl, GEMstack rocType) { return tgl / conf_dedx_corr::TglScale[rocType]; } constexpr static float recoverTgl(float scaledTgl, GEMstack rocType) { return scaledTgl * conf_dedx_corr::TglScale[rocType]; } private: + // ATTENTION: Adjust copy constructor bool mFitSnp{}; bool mApplyCuts{true}; ///< Wether or not to apply tracks cuts TrackCuts mCuts{0.3, 0.7, 60}; ///< MIP @@ -151,13 +181,16 @@ class CalibdEdx float mFitCut = 0.2; ///< dEdx cut value used to remove electron tracks float mFitLowCutFactor = 1.5; ///< dEdx cut multiplier for the lower dE/dx range int mFitPasses = 3; ///< number of fit passes used to remove electron tracks + TFIDInfo mTFID{}; ///< current TFID - Hist mHist; ///< dEdx multidimensional histogram - CalibdEdxCorrection mCalib{}; ///< Calibration output + Hist mHist; ///< dEdx multidimensional histogram + CalibdEdxCorrection mCalib{}; ///< Calibration output + CalibdEdxCorrection mCalibIn{}; ///< Calibration output o2::base::Propagator::MatCorrType mMatType{}; ///< material type for track propagation - ClassDefNV(CalibdEdx, 3); + std::unique_ptr mDebugOutputStreamer; ///< Debug output streamer + ClassDefNV(CalibdEdx, 4); }; } // namespace o2::tpc diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalibratordEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalibratordEdx.h index 1b90e525cf6dc..1de0e79b1fde6 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalibratordEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalibratordEdx.h @@ -95,13 +95,23 @@ class CalibratordEdx final : public o2::calibration::TimeSlotCalibration mFitThreshold{}; ///< Minimum entries per stack to perform sector, 1D and 2D fit bool mApplyCuts{true}; ///< Flag to enable tracks cuts std::tuple mElectronCut{}; ///< Values passed to CalibdEdx::setElectronCut diff --git a/Detectors/TPC/calibration/include/TPCCalibration/DigitAdd.h b/Detectors/TPC/calibration/include/TPCCalibration/DigitAdd.h new file mode 100644 index 0000000000000..b6e34b2fa59e9 --- /dev/null +++ b/Detectors/TPC/calibration/include/TPCCalibration/DigitAdd.h @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file DigitAdd.h +/// \brief Extension of TPC Digit adding draw query functions for simple drawing +/// \author Jens Wiechula (Jens.Wiechula@ikf.uni-frankfurt.de) + +#ifndef ALICEO2_TPC_DIGITADD_H_ +#define ALICEO2_TPC_DIGITADD_H_ + +#include "DataFormatsTPC/Digit.h" + +namespace o2::tpc +{ +/// \class Digit +class DigitAdd : public Digit +{ + public: + int sector() const; + float lx() const; + float ly() const; + float gx() const; + float gy() const; + float cpad() const; + + ClassDefNV(DigitAdd, 1) +}; + +} // namespace o2::tpc + +#endif // ALICEO2_TPC_DIGITADD_H_ diff --git a/Detectors/TPC/calibration/macro/prepareCMFiles.C b/Detectors/TPC/calibration/macro/prepareCMFiles.C index ec0abeb9fb259..dc14bc61aa793 100644 --- a/Detectors/TPC/calibration/macro/prepareCMFiles.C +++ b/Detectors/TPC/calibration/macro/prepareCMFiles.C @@ -38,6 +38,7 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " // ===| load noise and pedestal from file |=== CalDet output("CMkValues"); + CalDet outputInv("InvCMkValues"); CalDet* pulserQtot{nullptr}; const CDBInterface::CalPadMapType* calPulser = nullptr; @@ -80,7 +81,9 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " } } + DataMapF commonModeKValuesFloat; DataMapU32 commonModeKValues; + DataMapU32 commonModeInvKValues; // ===| prepare values |=== for (size_t iroc = 0; iroc < pulserQtot->getData().size(); ++iroc) { @@ -131,14 +134,32 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " // default thresholds const auto pulserValFixed = floatToFixedSize(pulserVal); + const auto pulserValFixedInv = floatToFixedSize(1. / pulserVal); + commonModeKValuesFloat[LinkInfo(cruID, globalLinkID)][hwChannel] = pulserVal; commonModeKValues[LinkInfo(cruID, globalLinkID)][hwChannel] = pulserValFixed; + commonModeInvKValues[LinkInfo(cruID, globalLinkID)][hwChannel] = pulserValFixedInv; } } const bool onlyFilled = false; + // ===| k-Values full float precision |=== + const auto outFileFloatTxt = (outputDir + "/commonMode_K_values_float.txt"); + const auto outFileFloatRoot = (outputDir + "/commonMode_K_values_float.root"); + writeValues(outFileFloatTxt, commonModeKValuesFloat, onlyFilled); + + getCalPad(outFileFloatTxt, outFileFloatRoot, "CMkValues"); + + // ===| k-Values limited precision 2I6F |=== const auto outFileTxt = (outputDir + "/commonMode_K_values.txt"); const auto outFileRoot = (outputDir + "/commonMode_K_values.root"); writeValues(outFileTxt, commonModeKValues, onlyFilled); getCalPad(outFileTxt, outFileRoot, "CMkValues"); + + // ===| inverse k-Values limited precision 2I6F |=== + const auto outFileInvTxt = (outputDir + "/commonMode_inv_K_values.txt"); + const auto outFileInvRoot = (outputDir + "/commonMode_inv_K_values.root"); + writeValues(outFileInvTxt, commonModeInvKValues, onlyFilled); + + getCalPad(outFileInvTxt, outFileInvRoot, "InvCMkValues"); } diff --git a/Detectors/TPC/calibration/macro/preparePedestalFiles.C b/Detectors/TPC/calibration/macro/preparePedestalFiles.C index fce04d9683652..0dcd02b64551a 100644 --- a/Detectors/TPC/calibration/macro/preparePedestalFiles.C +++ b/Detectors/TPC/calibration/macro/preparePedestalFiles.C @@ -11,6 +11,7 @@ #if !defined(__CLING__) || defined(__ROOTCLING__) #include +#include #include #include @@ -27,7 +28,9 @@ using namespace o2::tpc; using namespace o2::tpc::cru_calib_helpers; -void preparePedestalFiles(const std::string_view pedestalFile, std::string outputDir = "./", float sigmaNoise = 3, float minADC = 2, float pedestalOffset = 0, bool onlyFilled = false, bool maskBad = true, float noisyChannelThreshold = 1.5, float sigmaNoiseNoisyChannels = 4, float badChannelThreshold = 6) +/// \param sigmaNoiseROCType can be either one value for all ROC types, or {IROC, OROC}, or {IROC, OROC1, OROC2, OROC3} +/// \param minADCROCType can be either one value for all ROC types, or {IROC, OROC}, or {IROC, OROC1, OROC2, OROC3} +void preparePedestalFiles(const std::string_view pedestalFile, std::string outputDir = "./", std::vector sigmaNoiseROCType = {3}, std::vector minADCROCType = {2}, float pedestalOffset = 0, bool onlyFilled = false, bool maskBad = true, float noisyChannelThreshold = 1.5, float sigmaNoiseNoisyChannels = 4, float badChannelThreshold = 6) { const auto& mapper = Mapper::instance(); @@ -62,7 +65,7 @@ void preparePedestalFiles(const std::string_view pedestalFile, std::string outpu DataMapU32 pedestalValuesPhysics; DataMapU32 thresholdlValuesPhysics; - auto pedestalsThreshold = preparePedestalFiles(*calPedestal, *calNoise, sigmaNoise, minADC, pedestalOffset, onlyFilled, maskBad, noisyChannelThreshold, sigmaNoiseNoisyChannels, badChannelThreshold); + auto pedestalsThreshold = preparePedestalFiles(*calPedestal, *calNoise, sigmaNoiseROCType, minADCROCType, pedestalOffset, onlyFilled, maskBad, noisyChannelThreshold, sigmaNoiseNoisyChannels, badChannelThreshold); // ===| prepare values |=== for (size_t iroc = 0; iroc < calPedestal->getData().size(); ++iroc) { diff --git a/Detectors/TPC/calibration/macro/preparePedestalFiles.sh b/Detectors/TPC/calibration/macro/preparePedestalFiles.sh index 8cb894807b483..f4f5abc921202 100755 --- a/Detectors/TPC/calibration/macro/preparePedestalFiles.sh +++ b/Detectors/TPC/calibration/macro/preparePedestalFiles.sh @@ -9,8 +9,8 @@ required arguments optional arguments: -o, --outputDir= : set output directory for (default: ./) --m, --minADC= : minimal ADC value accepted for threshold (default: $minADC) --s, --sigmaNoise= : number of sigmas for the threshold (default: $sigmaNoise) +-m, --minADC= : minimal ADC value accepted for threshold, either one value for all ROC types, or 'IROC,OROC' or 'IROC,OROC1,OROC2,OROC3' (default: $minADC) +-s, --sigmaNoise= : number of sigmas for the threshold, either one value for all ROC types, or 'IROC,OROC' or 'IROC,OROC1,OROC2,OROC3' (default: $sigmaNoise) -p, --pedestalOffset= : pedestal offset value -f, --onlyFilled : only write links which have data -k, --noMaskZero : don't set pedetal value of missing pads to 1023 @@ -34,8 +34,8 @@ usageAndExit() { # ===| default variable values |================================================ fileInfo= outputDir="./" -minADC=2 -sigmaNoise=3 +minADC="2" +sigmaNoise="3" pedestalOffset=0 onlyFilled=0 maskZero=1 @@ -76,6 +76,6 @@ if [[ -z "$inputFile" ]]; then fi # ===| command building and execution |========================================= -cmd="root.exe -b -q -l -n -x $O2_SRC/Detectors/TPC/calibration/macro/preparePedestalFiles.C+g'(\"$inputFile\",\"$outputDir\", $sigmaNoise, $minADC, $pedestalOffset, $onlyFilled, $maskZero, $noisyThreshold, $sigmaNoiseNoisy, $badChannelThreshold)'" +cmd="root.exe -b -q -l -n -x $O2_SRC/Detectors/TPC/calibration/macro/preparePedestalFiles.C+g'(\"$inputFile\",\"$outputDir\", {$sigmaNoise}, {$minADC}, $pedestalOffset, $onlyFilled, $maskZero, $noisyThreshold, $sigmaNoiseNoisy, $badChannelThreshold)'" echo "running: $cmd" eval $cmd diff --git a/Detectors/TPC/calibration/src/CalibdEdx.cxx b/Detectors/TPC/calibration/src/CalibdEdx.cxx index 6d6aa980b9680..114081f57c2f0 100644 --- a/Detectors/TPC/calibration/src/CalibdEdx.cxx +++ b/Detectors/TPC/calibration/src/CalibdEdx.cxx @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include "DataFormatsTPC/TrackCuts.h" #include "Framework/Logger.h" #include "TPCBase/ParameterGas.h" +#include "TPCBase/Utils.h" // root includes #include "TFile.h" @@ -55,6 +57,28 @@ CalibdEdx::CalibdEdx(int dEdxBins, float mindEdx, float maxdEdx, int angularBins IntAxis(0, CHARGETYPES, "charge")); } +CalibdEdx::CalibdEdx(const CalibdEdx& other) +{ + mFitSnp = other.mFitSnp; + mApplyCuts = other.mApplyCuts; + mCuts = other.mCuts; + mSectorThreshold = other.mSectorThreshold; + m1DThreshold = other.m1DThreshold; + m2DThreshold = other.m2DThreshold; + mFitCut = other.mFitCut; + mFitLowCutFactor = other.mFitLowCutFactor; + mFitPasses = other.mFitPasses; + mTFID = other.mTFID; + + mHist = other.mHist; + mCalib = other.mCalib; + mCalibIn = other.mCalibIn; + + mMatType = other.mMatType; + + // debug streamer not copied on purpose +} + void CalibdEdx::fill(const TrackTPC& track) { // applying cuts @@ -64,8 +88,11 @@ void CalibdEdx::fill(const TrackTPC& track) const auto& dEdx = track.getdEdx(); const auto sideOffset = track.hasASideClustersOnly() ? 0 : SECTORSPERSIDE; - const std::array dEdxMax{dEdx.dEdxMaxIROC, dEdx.dEdxMaxOROC1, dEdx.dEdxMaxOROC2, dEdx.dEdxMaxOROC3}; - const std::array dEdxTot{dEdx.dEdxTotIROC, dEdx.dEdxTotOROC1, dEdx.dEdxTotOROC2, dEdx.dEdxTotOROC3}; + const std::vector dEdxMax{dEdx.dEdxMaxIROC, dEdx.dEdxMaxOROC1, dEdx.dEdxMaxOROC2, dEdx.dEdxMaxOROC3}; + const std::vector dEdxTot{dEdx.dEdxTotIROC, dEdx.dEdxTotOROC1, dEdx.dEdxTotOROC2, dEdx.dEdxTotOROC3}; + std::vector dEdxMaxCorr(4); // for deugging + std::vector dEdxTotCorr(4); // for deugging + // We need a copy of the track to perform propagations o2::track::TrackPar cpTrack = track; @@ -96,13 +123,43 @@ void CalibdEdx::fill(const TrackTPC& track) } } const float snp = cpTrack.getSnp(); - const float scaledTgl = scaleTgl(std::abs(cpTrack.getTgl()), roc); + const float tgl = cpTrack.getTgl(); + const float scaledTgl = scaleTgl(std::abs(tgl), roc); if (track.hasCSideClusters()) { sector += SECTORSPERSIDE; } - mHist(dEdxMax[roc] * dEdxScale, scaledTgl, snp, sector, roc, ChargeType::Max); - mHist(dEdxTot[roc] * dEdxScale, scaledTgl, snp, sector, roc, ChargeType::Tot); + // undo previously done corrections, to allow for residual corrections + // output will still be the full correction + const float corrMax = mCalibIn.getCorrection(StackID{static_cast(sector), roc}, ChargeType::Max, tgl, snp); + const float corrTot = mCalibIn.getCorrection(StackID{static_cast(sector), roc}, ChargeType::Tot, tgl, snp); + dEdxMaxCorr[roc] = corrMax; + dEdxTotCorr[roc] = corrTot; + + static bool reported = false; + if (!reported && mCalibIn.getDims() >= 0) { + const auto meanParamTot = mCalibIn.getMeanParams(ChargeType::Tot); + LOGP(info, "Undoing previously apllied corrections with mean qTot Params {}", utils::elementsToString(meanParamTot)); + reported = true; + } + + mHist(dEdxMax[roc] * dEdxScale * corrMax, scaledTgl, snp, sector, roc, ChargeType::Max); + mHist(dEdxTot[roc] * dEdxScale * corrTot, scaledTgl, snp, sector, roc, ChargeType::Tot); + } + + if (mDebugOutputStreamer) { + const float tgl = track.getTgl(); + const float p = track.getP(); + + (*mDebugOutputStreamer) << "dedx" + << "dEdxMax=" << dEdxMax + << "dEdxMaxCorr=" << dEdxMaxCorr + << "dEdxTot=" << dEdxTot + << "dEdxTotCorr=" << dEdxTotCorr + << "tgl=" << tgl + << "p=" << p + << "tfid=" << mTFID + << "\n"; } } @@ -240,7 +297,7 @@ void CalibdEdx::finalize() } LOGP(info, "Fitting {}D dE/dx correction for GEM stacks", mCalib.getDims()); - // if entries bellow minimum sector threshold, integrate all sectors + // if entries below minimum sector threshold, integrate all sectors if (mCalib.getDims() == 0 || entries >= mSectorThreshold) { fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses); } else { @@ -342,3 +399,22 @@ void CalibdEdx::writeTTree(std::string_view fileName) const f.Write(); f.Close(); } + +void CalibdEdx::enableDebugOutput(std::string_view fileName) +{ + mDebugOutputStreamer = std::make_unique(fileName.data(), "recreate"); +} + +void CalibdEdx::disableDebugOutput() +{ + // This will call the TreeStream destructor and write any stored data. + mDebugOutputStreamer.reset(); +} + +void CalibdEdx::finalizeDebugOutput() const +{ + if (mDebugOutputStreamer) { + LOGP(info, "Closing dump file"); + mDebugOutputStreamer->Close(); + } +} diff --git a/Detectors/TPC/calibration/src/CalibratordEdx.cxx b/Detectors/TPC/calibration/src/CalibratordEdx.cxx index f16fb6f19ebdf..15a7335ef90d3 100644 --- a/Detectors/TPC/calibration/src/CalibratordEdx.cxx +++ b/Detectors/TPC/calibration/src/CalibratordEdx.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. #include "TPCCalibration/CalibratordEdx.h" +#include #include #include @@ -40,6 +41,7 @@ void CalibratordEdx::finalizeSlot(Slot& slot) // compute calibration values from histograms CalibdEdx* container = slot.getContainer(); container->finalize(); + container->finalizeDebugOutput(); mCalibs.push_back(container->getCalib()); TFType startTF = slot.getTFStart(); @@ -61,6 +63,21 @@ void CalibratordEdx::finalizeSlot(Slot& slot) << "correction=" << calibCopy // dE/dx corretion << "\n"; } + + if (mDumpHistograms) { + const auto fileName = fmt::format("o2tpc_CalibratordEdx_Histos_{}_{}_{}_{}.root", startTime, endTime, startTF, endTF); + const auto dumpTHn = (mDumpHistograms & 0x1) == 0x1; + const auto dumpTree = (mDumpHistograms & 0x2) == 0x2; + if (dumpTree) { + container->writeTTree(fileName); + } + if (dumpTHn) { + auto f = std::make_unique(fileName.data(), dumpTree ? "update" : "recreate"); + auto hn = container->getRootHist(); + hn->Write("calibHist"); + f->Close(); + } + } } CalibratordEdx::Slot& CalibratordEdx::emplaceNewSlot(bool front, TFType tstart, TFType tend) @@ -77,6 +94,10 @@ CalibratordEdx::Slot& CalibratordEdx::emplaceNewSlot(bool front, TFType tstart, const auto [cut, iterations, cutLowFactor] = mElectronCut; container->setElectronCut(cut, iterations, cutLowFactor); container->setMaterialType(mMatType); + if (mEnableTrackDebug) { + const auto fileName = fmt::format("o2tpc_CalibratordEdx_TrackDebug_{}_{}.root", tstart, tend); + container->enableDebugOutput(fileName); + } slot.setContainer(std::move(container)); return slot; diff --git a/Detectors/TPC/calibration/src/DigitAdd.cxx b/Detectors/TPC/calibration/src/DigitAdd.cxx new file mode 100644 index 0000000000000..bb5e4c5f31c51 --- /dev/null +++ b/Detectors/TPC/calibration/src/DigitAdd.cxx @@ -0,0 +1,54 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "GPUTPCGeometry.h" +#include "TPCBase/Mapper.h" +#include "TPCBase/CRU.h" +#include "TPCCalibration/DigitAdd.h" + +using namespace o2::tpc; + +int DigitAdd::sector() const +{ + return CRU(mCRU).sector(); +} + +float DigitAdd::lx() const +{ + const GPUCA_NAMESPACE::gpu::GPUTPCGeometry gpuGeom; + return gpuGeom.Row2X(mRow); +} + +float DigitAdd::ly() const +{ + const GPUCA_NAMESPACE::gpu::GPUTPCGeometry gpuGeom; + return gpuGeom.LinearPad2Y(sector(), mRow, getPad()); +} + +float DigitAdd::gx() const +{ + const LocalPosition2D l2D{lx(), ly()}; + const auto g2D = Mapper::LocalToGlobal(l2D, Sector(sector())); + return g2D.x(); +} + +float DigitAdd::gy() const +{ + const LocalPosition2D l2D{lx(), ly()}; + const auto g2D = Mapper::LocalToGlobal(l2D, Sector(sector())); + return g2D.y(); +} + +float DigitAdd::cpad() const +{ + const GPUCA_NAMESPACE::gpu::GPUTPCGeometry gpuGeom; + return getPad() - gpuGeom.NPads(mRow) / 2.f; +} diff --git a/Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h b/Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h index a751dbd85f10c..097ea756d370e 100644 --- a/Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h +++ b/Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h @@ -117,4 +117,6 @@ #pragma link C++ class o2::tpc::TPCMShapeCorrection + ; #pragma link C++ struct o2::tpc::TPCMShape + ; #pragma link C++ struct o2::tpc::BoundaryPotentialIFC + ; +#pragma link C++ class o2::tpc::DigitAdd + ; +#pragma link C++ class std::vector < o2::tpc::DigitAdd> + ; #endif diff --git a/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplay.h b/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplay.h index d9c51d0a1ee3b..95e8407fab5ec 100644 --- a/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplay.h +++ b/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplay.h @@ -22,6 +22,7 @@ #include "TPCCalibration/CalibRawBase.h" class TH2D; +class TH2Poly; namespace o2 { @@ -50,6 +51,8 @@ class SimpleEventDisplay : public CalibRawBase Int_t updateCRU(const CRU& cru, const Int_t row, const Int_t pad, const Int_t timeBin, const Float_t signal) final { return 0; } + void updateSectorHists(); + CalPad* getCalPadMax() { return &mPadMax; } CalPad* getCalPadOccupancy() { return &mPadOccupancy; } @@ -71,6 +74,11 @@ class SimpleEventDisplay : public CalibRawBase TH1D* makePadSignals(Int_t roc, Int_t row, Int_t pad); + TH2D* getSigIROC() const { return mHSigIROC; } + TH2D* getSigOROC() const { return mHSigOROC; } + + void fillSectorHistSingleTimeBin(TH2Poly* h, Int_t timeBin); + /// set time bin range void setTimeBinRange(int firstBin, int lastBin) { @@ -79,8 +87,11 @@ class SimpleEventDisplay : public CalibRawBase initHistograms(); } + Int_t getFirstTimeBin() const { return mFirstTimeBin; } + Int_t getLastTimeBin() const { return mLastTimeBin; } + /// Dummy end event - void endEvent() final{}; + void endEvent() final {}; private: CalPad mPadMax; ///< Cal Pad with max Entry per channel diff --git a/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplayGUI.h b/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplayGUI.h index 8000cea04a813..21dac37212115 100644 --- a/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplayGUI.h +++ b/Detectors/TPC/monitor/include/TPCMonitor/SimpleEventDisplayGUI.h @@ -17,10 +17,13 @@ #define TPC_SimpleEventDisplayGUI_H_ #include +#include #include "TString.h" #include "TPCMonitor/SimpleEventDisplay.h" +#include "DataFormatsTPC/ClusterNative.h" +#include "DataFormatsTPC/ClusterNativeHelper.h" class TH2F; class TH1F; @@ -28,6 +31,9 @@ class TH1; class TGTextEntry; class TGTextButton; class TGCheckButton; +class TGNumberEntry; +class TGVButtonGroup; +class TH2Poly; namespace o2::tpc { @@ -47,6 +53,9 @@ class SimpleEventDisplayGUI void toggleFFT(); void toggleOccupancy(); + void togglePadTime(); + void toggleSingleTimeBin(); + void toggleClusters(); void monitorGui(); void exitRoot(); void update(TString clist); @@ -60,6 +69,8 @@ class SimpleEventDisplayGUI void next(int eventNumber = -1); void callEventNumber(); void applySignalThreshold(); + void selectTimeBin(); + void showClusters(int roc, int row); void runSimpleEventDisplay(std::string_view fileInfo, std::string_view pedestalFile = "", int firstTimeBin = 0, int lastTimeBin = 500, int nTimeBinsPerCall = 500, uint32_t verbosity = 0, uint32_t debugLevel = 0, int selectedSector = 0, bool showSides = 1); @@ -103,17 +114,45 @@ class SimpleEventDisplayGUI TH2F* mHOccupancyC = nullptr; TH2F* mHOccupancyIROC = nullptr; TH2F* mHOccupancyOROC = nullptr; - + TH2F* mHPadTimeIROC = nullptr; + TH2F* mHPadTimeOROC = nullptr; + TH2Poly* mSectorPolyTimeBin = nullptr; + TPolyMarker* mClustersIROC = nullptr; + TPolyMarker* mClustersOROC = nullptr; + TPolyMarker* mClustersRowPad = nullptr; + + TGCheckButton* mCheckSingleTB = nullptr; TGCheckButton* mCheckFFT = nullptr; TGCheckButton* mCheckOccupancy = nullptr; + TGCheckButton* mCheckPadTime = nullptr; + TGCheckButton* mCheckShowClusters = nullptr; + static constexpr int NCheckClFlags = 5; + TGCheckButton* mCheckClFlags[NCheckClFlags] = {}; + TGVButtonGroup* mFlagGroup = nullptr; TGTextEntry* mEventNumber = nullptr; TGTextEntry* mSignalThresholdValue = nullptr; + TGNumberEntry* mSelTimeBin = nullptr; + + std::string mInputFileInfo{}; + + o2::tpc::ClusterNativeHelper::Reader mTPCclusterReader; + o2::tpc::ClusterNativeAccess mClusterIndex; + std::unique_ptr mClusterBuffer; + o2::tpc::ClusterNativeHelper::ConstMCLabelContainerViewWithBuffer mClusterMCBuffer; TH1* getBinInfoXY(int& binx, int& biny, float& bincx, float& bincy); void initOccupancyHists(); void deleteOccupancyHists(); + void initPadTimeHists(); + void deletePadTimeHists(); + + void initSingleTBHists(); + void deleteSingleTBHists(); + + void fillClusters(Long64_t entry); + ClassDefNV(SimpleEventDisplayGUI, 0); }; diff --git a/Detectors/TPC/monitor/src/SimpleEventDisplay.cxx b/Detectors/TPC/monitor/src/SimpleEventDisplay.cxx index 5c68ca497c453..5953b93355f6e 100644 --- a/Detectors/TPC/monitor/src/SimpleEventDisplay.cxx +++ b/Detectors/TPC/monitor/src/SimpleEventDisplay.cxx @@ -16,6 +16,7 @@ #include "TH2S.h" #include "TROOT.h" #include "TString.h" +#include "TH2Poly.h" #include "DataFormatsTPC/Defs.h" #include "TPCBase/CalArray.h" @@ -158,6 +159,17 @@ Int_t SimpleEventDisplay::updateROC(const Int_t roc, return 0; } +//_____________________________________________________________________ +void SimpleEventDisplay::updateSectorHists() +{ + if (mSelectedSector % 36 != mLastSelSector % 36) { + mSectorLoop = kTRUE; + processEvent(getPresentEventNumber()); + mLastSelSector = mSelectedSector; + mSectorLoop = kFALSE; + } +} + //_____________________________________________________________________ TH1D* SimpleEventDisplay::makePadSignals(Int_t roc, Int_t row, Int_t pad) { @@ -177,17 +189,47 @@ TH1D* SimpleEventDisplay::makePadSignals(Int_t roc, Int_t row, Int_t pad) mSelectedSector = roc; // attention change for if event has changed - if (mSelectedSector % 36 != mLastSelSector % 36) { - mSectorLoop = kTRUE; - processEvent(getPresentEventNumber()); - mLastSelSector = mSelectedSector; - mSectorLoop = kFALSE; - } - TH1D* h = nullptr; + updateSectorHists(); + const Int_t nbins = mLastTimeBin - mFirstTimeBin; if (nbins <= 0) { return nullptr; } + + TH2D* hPadSignals = nullptr; + + // ===| ADC vs. Pad vs. Time for row |======================================== + TH2F* hPadTime = nullptr; + if (roc < (Int_t)mTPCmapper.getNumberOfIROCs()) { + hPadTime = static_cast(gROOT->FindObject("hPadTimeValsI")); + hPadSignals = mHSigIROC; + } else { + hPadTime = static_cast(gROOT->FindObject("hPadTimeValsO")); + hPadSignals = mHSigOROC; + } + + static Int_t lastRoc = -1; + static Int_t lastRow = -1; + if (hPadTime && ((lastRoc != roc) || (lastRow != row))) { + hPadTime->Reset(); + const auto nPads = mTPCmapper.getNumberOfPadsInRowROC(roc, row); + const auto nBins = hPadTime->GetNbinsY(); + const auto shift = nBins / 2 - nPads / 2; + for (int iPad = 0; iPad < nPads; ++iPad) { + const int ichannel = mTPCmapper.getPadNumberInROC(PadROCPos(roc, row, iPad)); + const Int_t offset = (nbins + 2) * (ichannel + 1); + const double* arrSig = hPadSignals->GetArray() + offset; + for (int iTime = 0; iTime < nbins; ++iTime) { + hPadTime->SetBinContent(iTime + 1, iPad + shift + 1, arrSig[iTime + 1]); + } + } + hPadTime->SetEntries(nPads * nbins); + hPadTime->SetTitle(fmt::format("Pad row {}", row).data()); + hPadTime->SetUniqueID(row); + } + + // ===| ADC vs. time for single pad |========================================= + TH1D* h = nullptr; const Int_t offset = (nbins + 2) * (channel + 1); Double_t* arrP = nullptr; @@ -196,15 +238,15 @@ TH1D* SimpleEventDisplay::makePadSignals(Int_t roc, Int_t row, Int_t pad) if (roc < (Int_t)mTPCmapper.getNumberOfIROCs()) { h = (TH1D*)gROOT->FindObject("PadSignals_IROC"); if (!h) { - h = new TH1D("PadSignals_IROC", "PadSignals IROC;time bins (200ns);amplitude (ADC counts)", nbins, mFirstTimeBin, mLastTimeBin); + h = new TH1D("PadSignals_IROC", "PadSignals IROC;time bin (200ns);amplitude (ADC counts)", nbins, mFirstTimeBin, mLastTimeBin); } h->SetFillColor(kBlue - 10); arrP = mHSigIROC->GetArray() + offset; - // title+="IROC "; + title += "IROC "; } else { h = (TH1D*)gROOT->FindObject("PadSignals_OROC"); if (!h) { - h = new TH1D("PadSignals_OROC", "PadSignals OROC;time bins (200ns);amplitude (ADC counts)", nbins, mFirstTimeBin, mLastTimeBin); + h = new TH1D("PadSignals_OROC", "PadSignals OROC;time bin (200ns);amplitude (ADC counts)", nbins, mFirstTimeBin, mLastTimeBin); } h->SetFillColor(kBlue - 10); arrP = mHSigOROC->GetArray() + offset; @@ -223,6 +265,7 @@ TH1D* SimpleEventDisplay::makePadSignals(Int_t roc, Int_t row, Int_t pad) h->SetEntries(entries); return h; } + //_____________________________________________________________________ void SimpleEventDisplay::resetEvent() { @@ -236,3 +279,28 @@ void SimpleEventDisplay::resetEvent() mHSigIROC->Reset(); mHSigOROC->Reset(); } + +//______________________________________________________________________________ +void SimpleEventDisplay::fillSectorHistSingleTimeBin(TH2Poly* h, Int_t timeBin) +{ + if (!h) { + return; + } + if (timeBin < mFirstTimeBin || timeBin > mLastTimeBin) { + return; + } + + int ichannel = 0; + const int iTimeBin = timeBin - mFirstTimeBin + 1; + // IROC loop + for (int ipad = 0; ipad < mHSigIROC->GetNbinsY(); ++ipad, ++ichannel) { + h->SetBinContent(ichannel + 1, mHSigIROC->GetBinContent(iTimeBin, ipad + 1)); + } + + // OROC loop + for (int ipad = 0; ipad < mHSigOROC->GetNbinsY(); ++ipad, ++ichannel) { + h->SetBinContent(ichannel + 1, mHSigOROC->GetBinContent(iTimeBin, ipad + 1)); + } + + h->SetEntries(ichannel); +} diff --git a/Detectors/TPC/monitor/src/SimpleEventDisplayGUI.cxx b/Detectors/TPC/monitor/src/SimpleEventDisplayGUI.cxx index ac3f08ec37743..20da28eefe364 100644 --- a/Detectors/TPC/monitor/src/SimpleEventDisplayGUI.cxx +++ b/Detectors/TPC/monitor/src/SimpleEventDisplayGUI.cxx @@ -15,17 +15,24 @@ #include #include #include +#include #include "TGFrame.h" #include "TGTextEntry.h" #include "TGLabel.h" #include "TGButton.h" +#include "TGNumberEntry.h" +#include "TGButtonGroup.h" #include "TQObject.h" +#include "TH2Poly.h" +#include "TPolyMarker.h" +#include "TLine.h" #include "TH1F.h" #include "TH2F.h" #include "TFile.h" #include "TSystem.h" +#include "TStyle.h" #include "TCanvas.h" #include "TObjArray.h" #include "TROOT.h" @@ -34,31 +41,40 @@ #include +#include "GPUTPCGeometry.h" #include "TPCBase/Mapper.h" #include "TPCBase/CalDet.h" #include "TPCBase/CalArray.h" #include "TPCBase/Painter.h" +#include "DataFormatsTPC/Constants.h" #include "TPCMonitor/SimpleEventDisplayGUI.h" using namespace o2::tpc; +namespace fs = std::filesystem; //__________________________________________________________________________ void SimpleEventDisplayGUI::monitorGui() { - float xsize = 145; + float xsize = 160; float ysize = 25; float yoffset = 10; float ysize_dist = 2; - float mainx = 170; - float mainy = 200; + float mainx = xsize + 2 * 10; + float mainy = 335; int ycount = 0; + float currentY = yoffset + ycount * (ysize_dist + ysize); - TGMainFrame* mFrameMain = new TGMainFrame(gClient->GetRoot(), 200, 200, kMainFrame | kVerticalFrame); + auto nextY = [&ycount, ¤tY, yoffset, ysize, ysize_dist]() { + ++ycount; + currentY = yoffset + ycount * (ysize_dist + ysize); + }; + + TGMainFrame* mFrameMain = new TGMainFrame(gClient->GetRoot(), mainx, mainy, kMainFrame | kVerticalFrame); mFrameMain->SetLayoutBroken(kTRUE); mFrameMain->SetCleanup(kDeepCleanup); - TGCompositeFrame* mContRight = new TGCompositeFrame(mFrameMain, 155, mainy, kVerticalFrame | kFixedWidth | kFitHeight); + TGCompositeFrame* mContRight = new TGCompositeFrame(mFrameMain, xsize + 5, mainy, kVerticalFrame | kFixedWidth | kFitHeight); mFrameMain->AddFrame(mContRight, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY | kLHintsExpandX, 3, 5, 3, 3)); //--------------------------- @@ -68,8 +84,8 @@ void SimpleEventDisplayGUI::monitorGui() mFrameNextEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "next(=-1)"); mFrameNextEvent->SetTextColor(200); mFrameNextEvent->SetToolTipText("Go to next event"); - mFrameNextEvent->MoveResize(10, yoffset + ycount * (ysize_dist + ysize), xsize, (unsigned int)ysize); - ++ycount; + mFrameNextEvent->MoveResize(10, currentY, xsize, (unsigned int)ysize); + nextY(); //--------------------------- TGTextButton* mFramePreviousEvent = new TGTextButton(mContRight, "&Previous Event"); @@ -81,8 +97,8 @@ void SimpleEventDisplayGUI::monitorGui() mFramePreviousEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "next(=-2)"); mFramePreviousEvent->SetTextColor(200); mFramePreviousEvent->SetToolTipText("Go to previous event"); - mFramePreviousEvent->MoveResize(10, yoffset + ycount * (ysize_dist + ysize), xsize, (unsigned int)ysize); - ++ycount; + mFramePreviousEvent->MoveResize(10, currentY, xsize, (unsigned int)ysize); + nextY(); //--------------------------- @@ -91,7 +107,7 @@ void SimpleEventDisplayGUI::monitorGui() mGoToEvent->SetTextColor(200); mGoToEvent->SetToolTipText("Go to event"); - mGoToEvent->MoveResize(10, yoffset + ycount * (ysize_dist + ysize), 0.65 * xsize, (unsigned int)ysize); + mGoToEvent->MoveResize(10, currentY, 0.65 * xsize, (unsigned int)ysize); mGoToEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "callEventNumber()"); // @@ -99,9 +115,9 @@ void SimpleEventDisplayGUI::monitorGui() ftbuf->AddText(0, "0"); mEventNumber = new TGTextEntry(mContRight, ftbuf); mContRight->AddFrame(mEventNumber, new TGLayoutHints(kFitHeight)); - mEventNumber->MoveResize(0.7 * xsize, yoffset + ycount * (ysize_dist + ysize), 0.3 * xsize, (unsigned int)ysize); + mEventNumber->MoveResize(0.7 * xsize, currentY, 0.3 * xsize, (unsigned int)ysize); mEventNumber->SetAlignment(kTextRight); - ++ycount; + nextY(); //--------------------------- TGTextButton* mApplySignalThreshold = new TGTextButton(mContRight, "&Apply Threshold"); @@ -109,16 +125,36 @@ void SimpleEventDisplayGUI::monitorGui() mApplySignalThreshold->SetTextColor(200); mApplySignalThreshold->SetToolTipText("Apply Threshold"); - mApplySignalThreshold->MoveResize(10, yoffset + ycount * (ysize_dist + ysize), 0.65 * xsize, (unsigned int)ysize); + mApplySignalThreshold->MoveResize(10, currentY, 0.65 * xsize, (unsigned int)ysize); mApplySignalThreshold->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "applySignalThreshold()"); auto* signalThresholdBuf = new TGTextBuffer(10); signalThresholdBuf->AddText(0, "0"); mSignalThresholdValue = new TGTextEntry(mContRight, signalThresholdBuf); - mSignalThresholdValue->MoveResize(0.7 * xsize, yoffset + ycount * (ysize_dist + ysize), 0.3 * xsize, (unsigned int)ysize); + mSignalThresholdValue->MoveResize(0.7 * xsize, currentY, 0.3 * xsize, (unsigned int)ysize); mSignalThresholdValue->SetAlignment(kTextRight); mSignalThresholdValue->Connect("ReturnPressed()", "o2::tpc::SimpleEventDisplayGUI", this, "applySignalThreshold()"); - ++ycount; + nextY(); + + //--------------------------- + mCheckSingleTB = new TGCheckButton(mContRight, "One TB"); + mContRight->AddFrame(mCheckSingleTB, new TGLayoutHints(kLHintsExpandX)); + + mCheckSingleTB->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleSingleTimeBin()"); + mCheckSingleTB->SetTextColor(200); + mCheckSingleTB->SetToolTipText("Show single time bin"); + mCheckSingleTB->MoveResize(10, currentY, 0.5 * xsize, (unsigned int)ysize); + mCheckSingleTB->SetDown(0); + + mSelTimeBin = new TGNumberEntry(mContRight, mEvDisp.getFirstTimeBin(), 6, 999, TGNumberFormat::kNESInteger, + TGNumberFormat::kNEAPositive, + TGNumberFormat::kNELLimitMinMax, + mEvDisp.getFirstTimeBin(), mEvDisp.getLastTimeBin()); + + mSelTimeBin->MoveResize(0.55 * xsize, currentY, 0.45 * xsize, (unsigned int)ysize); + mSelTimeBin->Connect("ValueSet(Long_t)", "o2::tpc::SimpleEventDisplayGUI", this, "selectTimeBin()"); + (mSelTimeBin->GetNumberEntry())->Connect("ReturnPressed()", "o2::tpc::SimpleEventDisplayGUI", this, "selectTimeBin()"); + nextY(); //--------------------------- mCheckFFT = new TGCheckButton(mContRight, "Show FFT"); @@ -127,9 +163,10 @@ void SimpleEventDisplayGUI::monitorGui() mCheckFFT->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleFFT()"); mCheckFFT->SetTextColor(200); mCheckFFT->SetToolTipText("Switch on FFT calculation"); - mCheckFFT->MoveResize(10, 10 + ysize * 4, xsize, (unsigned int)ysize); + mCheckFFT->MoveResize(10, currentY, xsize, (unsigned int)ysize); mCheckFFT->SetDown(0); toggleFFT(); + nextY(); //--------------------------- mCheckOccupancy = new TGCheckButton(mContRight, "Show Occupancy"); @@ -138,9 +175,54 @@ void SimpleEventDisplayGUI::monitorGui() mCheckOccupancy->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleOccupancy()"); mCheckOccupancy->SetTextColor(200); mCheckOccupancy->SetToolTipText("Switch on Occupancy calculation"); - mCheckOccupancy->MoveResize(10, 10 + ysize * 5, xsize, (unsigned int)ysize); + mCheckOccupancy->MoveResize(10, currentY, xsize, (unsigned int)ysize); mCheckOccupancy->SetDown(0); toggleOccupancy(); + nextY(); + + //--------------------------- + mCheckPadTime = new TGCheckButton(mContRight, "Show PadTime"); + mContRight->AddFrame(mCheckPadTime, new TGLayoutHints(kLHintsExpandX)); + + mCheckPadTime->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "togglePadTime()"); + mCheckPadTime->SetTextColor(200); + mCheckPadTime->SetToolTipText("Switch on PadTime calculation"); + mCheckPadTime->MoveResize(10, currentY, xsize, (unsigned int)ysize); + mCheckPadTime->SetDown(0); + nextY(); + + //--------------------------- + mCheckShowClusters = new TGCheckButton(mContRight, "Overlay clusters"); + mContRight->AddFrame(mCheckShowClusters, new TGLayoutHints(kLHintsExpandX)); + + mCheckShowClusters->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleClusters()"); + mCheckShowClusters->SetTextColor(200); + mCheckShowClusters->SetToolTipText("Switch on ShowClusters calculation"); + mCheckShowClusters->MoveResize(10, currentY, xsize, (unsigned int)ysize); + mCheckShowClusters->SetDown(0); + mCheckShowClusters->SetEnabled(kFALSE); + + nextY(); + + //--------------------------- + mFlagGroup = new TGVButtonGroup(mContRight, "Cl Flags"); + auto hframe = new TGHorizontalFrame(mFlagGroup); + const std::string flagTips[NCheckClFlags] = {"Golden", "Split Pad", "Split Time", "Edge", "Single Pad and/or Time"}; + for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) { + mCheckClFlags[iCheck] = new TGCheckButton(hframe, "", 10000 + iCheck); + mCheckClFlags[iCheck]->SetToolTipText(flagTips[iCheck].data()); + mCheckClFlags[iCheck]->SetDown(1); + mCheckClFlags[iCheck]->SetEnabled(kFALSE); + mCheckClFlags[iCheck]->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "showClusters(=-1,-1)"); + hframe->AddFrame(mCheckClFlags[iCheck], new TGLayoutHints(kLHintsExpandX)); + } + mFlagGroup->AddFrame(hframe, new TGLayoutHints(kLHintsExpandX)); + mFlagGroup->Show(); + mFlagGroup->MoveResize(10, currentY, xsize, (unsigned int)2 * ysize); + mContRight->AddFrame(mFlagGroup, new TGLayoutHints(kLHintsExpandX)); + mFlagGroup->SetState(kFALSE); + nextY(); + nextY(); //--------------------------- TGTextButton* mFrameExit = new TGTextButton(mContRight, "Exit ROOT"); @@ -149,13 +231,14 @@ void SimpleEventDisplayGUI::monitorGui() mFrameExit->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "exitRoot()"); mFrameExit->SetTextColor(200); mFrameExit->SetToolTipText("Exit the ROOT process"); - mFrameExit->MoveResize(10, 10 + ysize * 6, xsize, (unsigned int)ysize); + mFrameExit->MoveResize(10, currentY, xsize, (unsigned int)ysize); + nextY(); //--------------------------- mFrameMain->MapSubwindows(); mFrameMain->MapWindow(); mFrameMain->SetWindowName("OM"); - mFrameMain->MoveResize(50, 50, (unsigned int)mainx, (unsigned int)mainy); + mFrameMain->MoveResize(50, 50, (unsigned int)mainx, (unsigned int)currentY + 20); mFrameMain->Move(4 * 400 + 10, 10); } @@ -182,6 +265,7 @@ void SimpleEventDisplayGUI::toggleFFT() } } +//______________________________________________________________________________ void SimpleEventDisplayGUI::initOccupancyHists() { const int w = 400; @@ -266,6 +350,120 @@ void SimpleEventDisplayGUI::deleteOccupancyHists() delete gROOT->GetListOfCanvases()->FindObject("hOccupancyValsOROC"); } +void SimpleEventDisplayGUI::initPadTimeHists() +{ + // histograms and canvases for pad vs. time values IROC + const int w = 400; + const int h = 400; + const int hOff = 60; + const int vOff = 4; + TCanvas* c = nullptr; + + const Int_t firstTimeBin = mEvDisp.getFirstTimeBin(); + const Int_t lastTimeBin = mEvDisp.getLastTimeBin(); + const Int_t nTimeBins = mEvDisp.getLastTimeBin() - mEvDisp.getFirstTimeBin(); + + c = new TCanvas("PadTimeValsI", "PadTimeValsI", -3 * (w + vOff), 0 * h, w, h); + + c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", + "o2::tpc::SimpleEventDisplayGUI", this, + "drawPadSignal(int,int,int,TObject*)"); + mHPadTimeIROC = new TH2F("hPadTimeValsI", "PadTime Values IROC;time bin;pad", nTimeBins, firstTimeBin, lastTimeBin, 108, -54, 54); + // mHPadTimeIROC->SetDirectory(nullptr); + mHPadTimeIROC->SetStats(kFALSE); + mHPadTimeIROC->Draw("colz"); + if (!mClustersIROC) { + mClustersIROC = new TPolyMarker; + mClustersIROC->SetMarkerSize(1); + mClustersIROC->SetMarkerStyle(29); + mClustersIROC->SetMarkerColor(kMagenta); + mClustersIROC->Draw(); + } + + // histograms and canvases for pad vs. time values OROC + c = new TCanvas("PadTimeValsO", "PadTimeValsO", -3 * (w + vOff), 1 * h + hOff, w, h); + + c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", + "o2::tpc::SimpleEventDisplayGUI", this, + "drawPadSignal(int,int,int,TObject*)"); + mHPadTimeOROC = new TH2F("hPadTimeValsO", "PadTime Values OROC;time bin;pad", nTimeBins, firstTimeBin, lastTimeBin, 140, -70, 70); + // mHPadTimeOROC->SetDirectory(nullptr); + mHPadTimeOROC->SetStats(kFALSE); + mHPadTimeOROC->Draw("colz"); + if (!mClustersOROC) { + mClustersOROC = new TPolyMarker; + mClustersOROC->SetMarkerSize(1); + mClustersOROC->SetMarkerStyle(29); + mClustersOROC->SetMarkerColor(kMagenta); + mClustersOROC->Draw(); + } +} + +void SimpleEventDisplayGUI::deletePadTimeHists() +{ + delete gROOT->GetListOfCanvases()->FindObject("PadTimeValsO"); + delete mHPadTimeOROC; + mHPadTimeOROC = nullptr; + + delete gROOT->GetListOfCanvases()->FindObject("PadTimeValsI"); + delete mHPadTimeIROC; + mHPadTimeIROC = nullptr; + + delete gROOT->GetListOfCanvases()->FindObject("hPadTimeValsIROC"); + delete gROOT->GetListOfCanvases()->FindObject("hPadTimeValsOROC"); +} + +void SimpleEventDisplayGUI::initSingleTBHists() +{ + // histograms and canvases for pad vs. time values IROC + const int w = 400; + const int h = 400; + const int hOff = 60; + const int vOff = 4; + TCanvas* c = nullptr; + + const Int_t firstTimeBin = mEvDisp.getFirstTimeBin(); + const Int_t lastTimeBin = mEvDisp.getLastTimeBin(); + const Int_t nTimeBins = mEvDisp.getLastTimeBin() - mEvDisp.getFirstTimeBin(); + + c = new TCanvas("SingleTB", "SingleTB", -3 * (w + vOff), 1 * h + hOff, 1.8 * w, h); + + c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", + "o2::tpc::SimpleEventDisplayGUI", this, + "drawPadSignal(int,int,int,TObject*)"); + mSectorPolyTimeBin = painter::makeSectorHist("hSingleTB"); + // mHPadTimeIROC->SetDirectory(nullptr); + mSectorPolyTimeBin->SetStats(kFALSE); + mSectorPolyTimeBin->Draw("colz"); + + if (!mClustersRowPad) { + mClustersRowPad = new TPolyMarker; + mClustersRowPad->SetMarkerSize(1); + mClustersRowPad->SetMarkerStyle(29); + mClustersRowPad->SetMarkerColor(kMagenta); + } + mClustersRowPad->Draw(); +} + +void SimpleEventDisplayGUI::deleteSingleTBHists() +{ + delete gROOT->GetListOfCanvases()->FindObject("SingleTB"); + delete mSectorPolyTimeBin; + mSectorPolyTimeBin = nullptr; +} + +//__________________________________________________________________________ +void SimpleEventDisplayGUI::togglePadTime() +{ + if (mCheckPadTime->IsDown()) { + initPadTimeHists(); + mCheckShowClusters->SetEnabled(kTRUE); + } else { + deletePadTimeHists(); + mCheckShowClusters->SetEnabled(kFALSE); + } +} + //__________________________________________________________________________ void SimpleEventDisplayGUI::toggleOccupancy() { @@ -276,6 +474,58 @@ void SimpleEventDisplayGUI::toggleOccupancy() } } +//__________________________________________________________________________ +void SimpleEventDisplayGUI::toggleSingleTimeBin() +{ + if (mCheckSingleTB->IsDown()) { + initSingleTBHists(); + selectTimeBin(); + } else { + deleteSingleTBHists(); + if (mClustersRowPad) { + mClustersRowPad->SetPolyMarker(0); + } + } +} + +//______________________________________________________________________________ +void SimpleEventDisplayGUI::toggleClusters() +{ + if (mCheckShowClusters->IsDown()) { + if (mTPCclusterReader.getTreeSize() > 0) { + return; + } + fs::path p{mInputFileInfo}; + std::string clusterFile = fmt::format("{}/tpc-native-clusters.root", p.parent_path().c_str()); + if (!fs::exists(clusterFile)) { + LOGP(warn, "Clusters file '{}' does not exist, trying local 'tpc-native-clusters.root'", clusterFile); + clusterFile = "tpc-native-clusters.root"; + if (!fs::exists(clusterFile)) { + LOGP(error, "Clusters file '{}' does not exist, can't load clusters", clusterFile); + return; + } + } + LOGP(info, "loading clusters from file '{}'", clusterFile); + mTPCclusterReader.init(clusterFile.data()); + gROOT->cd(); + const auto presentEventNumber = mEvDisp.getPresentEventNumber(); + fillClusters(presentEventNumber); + mFlagGroup->SetState(kTRUE); + for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) { + mCheckClFlags[iCheck]->SetEnabled(kTRUE); + } + } else { + if (mClustersIROC) { + mClustersIROC->SetPolyMarker(0); + mClustersOROC->SetPolyMarker(0); + } + mFlagGroup->SetState(kFALSE); + for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) { + mCheckClFlags[iCheck]->SetEnabled(kFALSE); + } + } +} + //__________________________________________________________________________ void SimpleEventDisplayGUI::exitRoot() { @@ -368,10 +618,19 @@ TH1* SimpleEventDisplayGUI::getBinInfoXY(int& binx, int& biny, float& bincx, flo const float yy = pad->AbsPixeltoY(py); const float y = pad->PadtoX(yy); - binx = h->GetXaxis()->FindBin(x); - biny = h->GetYaxis()->FindBin(y); - bincx = h->GetXaxis()->GetBinCenter(binx); - bincy = h->GetYaxis()->GetBinCenter(biny); + if (h->InheritsFrom(TH2Poly::Class())) { + auto hPoly = (TH2Poly*)h; + binx = hPoly->GetXaxis()->FindBin(x); + biny = hPoly->GetYaxis()->FindBin(y); + bincx = hPoly->GetXaxis()->GetBinCenter(binx); + bincy = hPoly->GetYaxis()->GetBinCenter(biny); + binx = biny = hPoly->FindBin(x, y); + } else { + binx = h->GetXaxis()->FindBin(x); + biny = h->GetYaxis()->FindBin(y); + bincx = h->GetXaxis()->GetBinCenter(binx); + bincy = h->GetYaxis()->GetBinCenter(biny); + } return h; } @@ -383,18 +642,11 @@ void SimpleEventDisplayGUI::drawPadSignal(int event, int x, int y, TObject* o) // type: name of canvas // + // fmt::print("o: {}, type: {}, name: {}\n", (void*)o, o ? o->IsA()->GetName() : "", o ? o->GetName() : ""); if (!o) { return; } - TString type; - if (std::string_view(o->GetName()) == "hMaxValsIROC" || std::string_view(o->GetName()) == "hOccupancyValsIROC") { - type = "SigI"; - } else if (std::string_view(o->GetName()) == "hMaxValsOROC" || std::string_view(o->GetName()) == "hOccupancyValsOROC") { - type = "SigO"; - } else { - return; - } // check if an event was alreay loaded if (!mEvDisp.getNumberOfProcessedEvents()) { return; @@ -411,25 +663,62 @@ void SimpleEventDisplayGUI::drawPadSignal(int event, int x, int y, TObject* o) if (!h) { return; } + // fmt::print("binx {}, biny {}, cx {}, cy {}\n", binx, biny, bincx, bincy); + + const auto& mapper = Mapper::instance(); + // int roc = h->GetUniqueID(); + int roc = mSelectedSector; + TString type; + const std::string_view objectName(o->GetName()); + + // for standard row vs cpad histo, is overwritte in case of TH2Poly sector histo below + int row = int(TMath::Floor(bincx)); - const int row = int(TMath::Floor(bincx)); - const int cpad = int(TMath::Floor(bincy)); // find pad and channel - const int roc = h->GetUniqueID(); - if (roc < 0 || roc >= (int)ROC::MaxROC) { + int pad = -1; + + if (objectName == "hMaxValsIROC" || objectName == "hOccupancyValsIROC") { + type = "SigI"; + } else if (objectName == "hMaxValsOROC" || objectName == "hOccupancyValsOROC") { + type = "SigO"; + roc += 36; + } else if (objectName == "hPadTimeValsI") { + type = "SigI"; + row = h->GetUniqueID(); + } else if (objectName == "hPadTimeValsO") { + type = "SigO"; + row = h->GetUniqueID(); + roc += 36; + } else if (objectName == "hSingleTB") { + type = "SigI"; + const auto padPosSec = mapper.padPos(binx - 1); + pad = padPosSec.getPad(); + row = padPosSec.getRow(); + if (bincx > 133) { + type = "SigO"; + roc += 36; + row -= mapper.getNumberOfRowsROC(0); + } + // fmt::print("roc {}, row {}, pad {}\n", roc, row, pad); + } else { return; } + const int nPads = mapper.getNumberOfPadsInRowROC(roc, row); + if (pad == -1) { + const int cpad = int(TMath::Floor(bincy)); + pad = cpad + nPads / 2; + } - const auto& mapper = Mapper::instance(); + if (pad < 0 || pad >= (int)nPads) { + return; + } if (row < 0 || row >= (int)mapper.getNumberOfRowsROC(roc)) { return; } - - const int nPads = mapper.getNumberOfPadsInRowROC(roc, row); - const int pad = cpad + nPads / 2; - if (pad < 0 || pad >= (int)nPads) { + if (roc < 0 || roc >= (int)ROC::MaxROC) { return; } + const TString rocType = (roc < 36) ? "I" : "O"; // draw requested pad signal @@ -456,7 +745,7 @@ void SimpleEventDisplayGUI::drawPadSignal(int event, int x, int y, TObject* o) xax->SetRange(2, nbinsx / 2); if (init) { xax->Set(nbinsx, xax->GetXmin() / maxTime, xax->GetXmax() / maxTime); - hFFT->SetNameTitle(Form("hFFT_%sROC", (roc < 36) ? "I" : "O"), "FFT magnitude;frequency (kHz);amplitude"); + hFFT->SetNameTitle(Form("hFFT_%sROC", rocType.Data()), "FFT magnitude;frequency (kHz);amplitude"); } hFFT->Scale(2. / (nbinsx - 1)); cFFT->cd(); @@ -464,7 +753,28 @@ void SimpleEventDisplayGUI::drawPadSignal(int event, int x, int y, TObject* o) } } } - update(Form("%s;%sFFT", type.Data(), type.Data())); + if (mCheckSingleTB) { + TLine l; + l.SetLineColor(kRed); + const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber(); + h = (TH1D*)gROOT->FindObject(fmt::format("PadSignals_{}ROC", rocType.Data()).data()); + if (h) { + l.DrawLine(timeBin + 0.5, h->GetMinimum(), timeBin + 0.5, h->GetMaximum()); + } + } + if (mCheckPadTime && objectName.find("hPadTimeVals") == 0) { + TLine l; + l.SetLineColor(kMagenta); + const auto timeBin = bincx; + h = (TH1D*)gROOT->FindObject(fmt::format("PadSignals_{}ROC", rocType.Data()).data()); + if (h) { + l.DrawLine(timeBin + 0.5, h->GetMinimum(), timeBin, h->GetMaximum()); + } + } + if (mCheckShowClusters->IsDown()) { + showClusters(roc, row); + } + update(Form("%s;%sFFT;PadTimeVals%s;SingleTB", type.Data(), type.Data(), rocType.Data())); } // printf("bin=%03d.%03d(%03d)[%05d], name=%s, ROC=%02d content=%.1f, ev: %d\n",row,pad,cpad,chn,h->GetName(), roc, h->GetBinContent(binx,biny), event); } @@ -546,6 +856,8 @@ void SimpleEventDisplayGUI::selectSector(int sector) if (mCheckOccupancy->IsDown()) { fillHists(1, Occupancy); } + mEvDisp.updateSectorHists(); + selectTimeBin(); } //__________________________________________________________________________ @@ -751,6 +1063,8 @@ void SimpleEventDisplayGUI::next(int eventNumber) if (mRunMode == RunMode::Online) { mProcessingEvent = false; } + + fillClusters(presentEventNumber); } //__________________________________________________________________________ @@ -765,6 +1079,7 @@ void SimpleEventDisplayGUI::runSimpleEventDisplay(std::string_view fileInfo, std { fair::Logger::SetVerbosity("LOW"); fair::Logger::SetConsoleSeverity("DEBUG"); + gStyle->SetNumberContours(255); if (pedestalFile.size()) { TFile f(pedestalFile.data()); if (f.IsOpen()) { @@ -788,6 +1103,10 @@ void SimpleEventDisplayGUI::runSimpleEventDisplay(std::string_view fileInfo, std monitorGui(); next(0); + + mInputFileInfo = fileInfo; + + memset(&mClusterIndex, 0, sizeof(mClusterIndex)); } //_____________________________________________________________________________ @@ -816,3 +1135,104 @@ void SimpleEventDisplayGUI::applySignalThreshold() mEvDisp.setSignalThreshold(signalThreshold); callEventNumber(); } + +//______________________________________________________________________________ +void SimpleEventDisplayGUI::selectTimeBin() +{ + if (!mCheckSingleTB->IsDown()) { + return; + } + const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber(); + mEvDisp.fillSectorHistSingleTimeBin(mSectorPolyTimeBin, timeBin); + mSectorPolyTimeBin->SetTitle(fmt::format("Sector {:02}, time bin {:6}", mSelectedSector, timeBin).data()); + showClusters(-1, -1); + update("SingleTB"); +} + +//______________________________________________________________________________ +void SimpleEventDisplayGUI::showClusters(int roc, int row) +{ + static int lastRow = -1; + static int lastROC = -1; + static int lastTimeBin = -1; + const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber(); + bool forceUpdate = false; + // fmt::print("roc {}, row {}, lastROC {}, lastRow {}\n", roc, row, lastROC, lastRow); + if (roc == -1) { + roc = lastROC; + forceUpdate = true; + } + if ((mTPCclusterReader.getTreeSize() == 0) || (lastRow == row) || (roc == -1)) { + return; + } + if (row == -1) { + if (lastRow == -1) { + return; + } + row = lastRow; + } + lastRow = row; + lastROC = roc; + + const auto& mapper = Mapper::instance(); + const int sector = roc % 36; + TPolyMarker* marker = mClustersIROC; + const int nPads = mapper.getNumberOfPadsInRowROC(roc, row); + + if (roc >= 36) { + marker = mClustersOROC; + row += mapper.getNumberOfRowsROC(0); // cluster access is using the global row in sector + } + + marker->SetPolyMarker(0); + if (mClustersRowPad) { + mClustersRowPad->SetPolyMarker(0); + } + size_t iSelClusters = 0; + int selFlags = 0; + bool golden = mCheckClFlags[0]->IsDown(); + for (int iFlag = 1; iFlag < NCheckClFlags; ++iFlag) { + selFlags += mCheckClFlags[iFlag]->IsDown() << (iFlag - 1); + } + const bool fillSingleTB = mCheckSingleTB->IsDown(); + const GPUCA_NAMESPACE::gpu::GPUTPCGeometry gpuGeom; + + const int rowMin = fillSingleTB ? 0 : row; + const int rowMax = fillSingleTB ? constants::MAXGLOBALPADROW : row + 1; + + for (int irow = rowMin; irow < rowMax; ++irow) { + const auto nClusters = mClusterIndex.nClusters[sector][irow]; + for (size_t icl = 0; icl < nClusters; ++icl) { + const auto& cl = mClusterIndex.clusters[sector][irow][icl]; + const auto flags = cl.getFlags(); + // fmt::print("flags: {}, selFlags: {}, selGolden: {}, ", flags, selFlags, golden); + if (((flags == 0) && golden) || (flags & selFlags)) { + // fmt::print("sel"); + if (row == irow) { + marker->SetPoint(iSelClusters, cl.getTime() + 0.5, cl.getPad() + 0.5 - nPads / 2.); + ++iSelClusters; + } + if (fillSingleTB && std::abs(cl.getTime() - timeBin) < 2) { + const auto ly = gpuGeom.LinearPad2Y(sector, irow, cl.getPad() + 0.5); + mClustersRowPad->SetNextPoint(gpuGeom.Row2X(irow), (sector >= GPUCA_NSLICES / 2) ? -ly : ly); + } + } + // fmt::print("\n"); + } + } + // marker->SetPolyMarker(iSelClusters); + + if (forceUpdate) { + update(Form("PadTimeVals%s;SingleTB", (roc < 36) ? "I" : "O")); + } +} + +//______________________________________________________________________________ +void SimpleEventDisplayGUI::fillClusters(Long64_t entry) +{ + if (mTPCclusterReader.getTreeSize() > 0) { + mTPCclusterReader.read(entry); + mTPCclusterReader.fillIndex(mClusterIndex, mClusterBuffer, mClusterMCBuffer); + LOGP(info, "Loaded cluster tree entry {} with {} clusters", entry, mClusterIndex.nClustersTotal); + } +} diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h index c57b147cdfd62..31a5ce756142a 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCRefitter.h @@ -13,11 +13,7 @@ #define O2_TPC_DATA_FILTER_H #include "ReconstructionDataFormats/GlobalTrackID.h" -#include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" -#include "ReconstructionDataFormats/Track.h" -#include "MathUtils/detail/Bracket.h" -#include "DataFormatsTPC/ClusterNative.h" namespace o2::tpc { @@ -27,7 +23,7 @@ struct CorrectionMapsLoaderGloOpts; namespace o2::trackstudy { /// create a processor spec -o2::framework::DataProcessorSpec getTPCRefitterSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts); +o2::framework::DataProcessorSpec getTPCRefitterSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool requestCosmics = false); } // namespace o2::trackstudy diff --git a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx index 2447b1f3969f2..046585e8c96b6 100644 --- a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx @@ -25,9 +25,11 @@ #include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" #include "Framework/ConfigParamRegistry.h" +#include "Framework/CCDBParamSpec.h" #include "TPCCalibration/CalibdEdx.h" #include "TPCWorkflow/ProcessingHelpers.h" #include "TPCBase/CDBInterface.h" +#include "TPCBase/Utils.h" #include "DetectorsBase/GRPGeomHelper.h" using namespace o2::framework; @@ -69,12 +71,21 @@ class CalibdEdxDevice : public Task void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final { - o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj); + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } + if (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0)) { + mCalib->setCalibrationInput(*(o2::tpc::CalibdEdxCorrection*)obj); + const auto meanParamTot = mCalib->getCalibrationInput().getMeanParams(ChargeType::Tot); + LOGP(info, "Updating TimeGain with {} dimensions and mean qTot Params {}", mCalib->getCalibrationInput().getDims(), utils::elementsToString(meanParamTot)); + return; + } } void run(ProcessingContext& pc) final { o2::base::GRPGeomHelper::instance().checkUpdates(pc); + checkUpdates(pc); const auto tfcounter = o2::header::get(pc.inputs().get("tracks").header)->startTime; const auto tracks = pc.inputs().get>("tracks"); @@ -115,6 +126,15 @@ class CalibdEdxDevice : public Task output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TPC_CalibdEdx", 0}, info); } + void checkUpdates(ProcessingContext& pc) const + { + if (pc.inputs().isValid("tpctimegain")) { + pc.inputs().get("tpctimegain"); + } else { + return; + } + } + std::shared_ptr mCCDBRequest; const o2::base::Propagator::MatCorrType mMatType{}; int mDumpToFile{}; @@ -130,6 +150,8 @@ DataProcessorSpec getCalibdEdxSpec(const o2::base::Propagator::MatCorrType matTy outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TPC_CalibdEdx"}, Lifetime::Sporadic); outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TPC_CalibdEdx"}, Lifetime::Sporadic); std::vector inputs{{"tracks", "TPC", "MIPS", Lifetime::Sporadic}}; + inputs.emplace_back("tpctimegain", "TPC", "TIMEGAIN", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalTimeGain), {}, 1)); // time-dependent + auto ccdbRequest = std::make_shared(true, // orbitResetTime false, // GRPECS=true false, // GRPLHCIF diff --git a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx index 08b93b0b915c7..70b27443018bb 100644 --- a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx @@ -28,10 +28,12 @@ #include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" #include "Framework/ConfigParamRegistry.h" +#include "Framework/CCDBParamSpec.h" #include "TPCCalibration/CalibratordEdx.h" #include "TPCWorkflow/ProcessingHelpers.h" #include "DetectorsBase/GRPGeomHelper.h" #include "TPCBase/CDBInterface.h" +#include "TPCBase/Utils.h" using namespace o2::framework; @@ -45,9 +47,11 @@ class CalibratordEdxDevice : public Task void init(framework::InitContext& ic) final { o2::base::GRPGeomHelper::instance().setRequest(mCCDBRequest); - const auto slotLength = ic.options().get("tf-per-slot"); + const auto slotLengthTF = ic.options().get("tf-per-slot"); + const auto slotLengthSeconds = ic.options().get("seconds-per-slot"); const auto maxDelay = ic.options().get("max-delay"); const auto minEntries = ic.options().get("min-entries"); + mCalibIntervalExtensionMS = ic.options().get("calib-interval-extension") * 1000l; const auto minEntriesSector = ic.options().get("min-entries-sector"); const auto minEntries1D = ic.options().get("min-entries-1d"); @@ -63,32 +67,65 @@ class CalibratordEdxDevice : public Task const auto fitSnp = ic.options().get("fit-snp"); const auto dumpData = ic.options().get("file-dump"); + const auto dumpHistograms = ic.options().get("dump-histograms"); + const auto trackDebug = ic.options().get("track-debug"); mCalibrator = std::make_unique(); mCalibrator->setHistParams(dEdxBins, mindEdx, maxdEdx, angularBins, fitSnp); mCalibrator->setApplyCuts(false); mCalibrator->setFitThresholds(minEntriesSector, minEntries1D, minEntries2D); mCalibrator->setMinEntries(minEntries); - mCalibrator->setSlotLength(slotLength); + mCalibrator->setSlotLength(slotLengthTF); + mCalibrator->setSlotLengthInSeconds(slotLengthSeconds); mCalibrator->setMaxSlotsDelay(maxDelay); mCalibrator->setElectronCut({fitThreshold, fitPasses, fitThresholdLowFactor}); mCalibrator->setMaterialType(mMatType); + mCalibrator->setDumpHistograms(dumpHistograms); + mCalibrator->setTrackDebug(trackDebug); if (dumpData) { - mCalibrator->enableDebugOutput("calibratordEdx.root"); + const auto dumpDataName = ic.options().get("file-dump-name"); + mCalibrator->enableDebugOutput(dumpDataName); } } void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final { - o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj); + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } + if (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0)) { + mTimeGain = *(o2::tpc::CalibdEdxCorrection*)obj; + const auto meanParamTot = mTimeGain.getMeanParams(ChargeType::Tot); + LOGP(info, "Updating TimeGain with {} dimensions and mean qTot Params {}", mTimeGain.getDims(), utils::elementsToString(meanParamTot)); + return; + } } void run(ProcessingContext& pc) final { + o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCalibrator->getCurrentTFInfo()); o2::base::GRPGeomHelper::instance().checkUpdates(pc); + checkUpdates(pc); + static bool slotLengthSet = false; + if (!slotLengthSet) { + // Important, otherwise the call to getSlotForTF below will be wrong, must be called after GRPGeomHelper update to get the correct TF length + mCalibrator->checkSlotLength(); + slotLengthSet = true; + } + + auto& slotTF = mCalibrator->getSlotForTF(mCalibrator->getCurrentTFInfo().tfCounter); + auto calib = slotTF.getContainer(); + const auto stackID = StackID{0, GEMstack::IROCgem}; + const auto calibInEnties = calib->getCalibrationInput().getEntries(stackID, ChargeType::Tot); + calib->setCalibrationInput(mTimeGain); + if (calibInEnties != mTimeGain.getEntries(stackID, ChargeType::Tot)) { + const auto meanParamTot = calib->getCalibrationInput().getMeanParams(ChargeType::Tot); + LOGP(info, "Updating TimeGain with {} dimensions and mean qTot Params {} for slot with TF range {} <=TF<= {}", + calib->getCalibrationInput().getDims(), utils::elementsToString(meanParamTot), slotTF.getTFStart(), slotTF.getTFEnd()); + } + const auto tracks = pc.inputs().get>("tracks"); - o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCalibrator->getCurrentTFInfo()); LOGP(detail, "Processing TF {} with {} tracks", mCalibrator->getCurrentTFInfo().tfCounter, tracks.size()); mRunNumber = mCalibrator->getCurrentTFInfo().runNumber; mCalibrator->process(tracks); @@ -118,7 +155,7 @@ class CalibratordEdxDevice : public Task assert(calibrations.size() == intervals.size()); for (unsigned int i = 0; i < calibrations.size(); i++) { const auto& object = calibrations[i]; - o2::ccdb::CcdbObjectInfo info(CDBTypeMap.at(CDBType::CalTimeGain), std::string{}, std::string{}, std::map{{"runNumber", std::to_string(mRunNumber)}}, intervals[i].first, intervals[i].second + 1); + o2::ccdb::CcdbObjectInfo info(CDBTypeMap.at(CDBType::CalTimeGain), std::string{}, std::string{}, std::map{{"runNumber", std::to_string(mRunNumber)}}, intervals[i].first, intervals[i].second + mCalibIntervalExtensionMS + 1); auto image = o2::ccdb::CcdbApi::createObjectImage(&object, &info); LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", info.getPath(), info.getFileName(), image->size(), info.getStartValidityTimestamp(), info.getEndValidityTimestamp()); output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TPC_CalibdEdx", i}, *image.get()); // vector @@ -127,10 +164,21 @@ class CalibratordEdxDevice : public Task mCalibrator->initOutput(); // empty the outputs after they are send } + void checkUpdates(ProcessingContext& pc) const + { + if (pc.inputs().isValid("tpctimegain")) { + pc.inputs().get("tpctimegain"); + } else { + return; + } + } + std::unique_ptr mCalibrator; const o2::base::Propagator::MatCorrType mMatType{}; std::shared_ptr mCCDBRequest; - uint64_t mRunNumber{0}; ///< processed run number + uint32_t mRunNumber{0}; ///< processed run number + long mCalibIntervalExtensionMS{0}; ///< Extension of the calibration interval end in ms + o2::tpc::CalibdEdxCorrection mTimeGain{}; ///< currently valid TimeGain }; DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType matType) @@ -140,6 +188,8 @@ DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TPC_CalibdEdx"}, Lifetime::Sporadic); outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TPC_CalibdEdx"}, Lifetime::Sporadic); std::vector inputs{{"tracks", "TPC", "MIPS", Lifetime::Sporadic}}; + inputs.emplace_back("tpctimegain", "TPC", "TIMEGAIN", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalTimeGain), {}, 1)); // time-dependent + auto ccdbRequest = std::make_shared(true, // orbitResetTime true, // GRPECS=true false, // GRPLHCIF @@ -155,9 +205,11 @@ DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType outputs, adaptFromTask(ccdbRequest, matType), Options{ - {"tf-per-slot", VariantType::UInt32, 6000u, {"number of TFs per calibration time slot"}}, + {"tf-per-slot", VariantType::UInt32, 6000u, {"number of TFs per calibration time slot, is overwritten by seconds-per-slot if > 0"}}, + {"seconds-per-slot", VariantType::Int, 180, {"seconds per calibration time slot, overwrites tf-per-slot if > 0"}}, {"max-delay", VariantType::UInt32, 10u, {"number of slots in past to consider"}}, {"min-entries", VariantType::Int, 10000, {"minimum entries per stack to fit a single time slot"}}, + {"calib-interval-extension", VariantType::UInt32, 3600u, {"seconds by which to extend the calibration interval beyond the end of the time slot"}}, {"min-entries-sector", VariantType::Int, 1000, {"min entries per GEM stack to enable sector by sector correction. Below this value we only perform one fit per ROC type (IROC, OROC1, ...; no side nor sector information)."}}, {"min-entries-1d", VariantType::Int, 10000, {"minimum entries per stack to fit 1D correction"}}, @@ -172,7 +224,11 @@ DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType {"angularbins", VariantType::Int, 36, {"number of angular bins: Tgl and Snp"}}, {"fit-snp", VariantType::Bool, false, {"enable Snp correction"}}, - {"file-dump", VariantType::Bool, false, {"directly dump calibration to file"}}}}; + {"dump-histograms", VariantType::UInt32, 0u, {"dump calibration histograms bitmask: 0x1 = as THn; 0x2 as TTree"}}, + {"file-dump", VariantType::Bool, false, {"directly dump calibration to file"}}, + {"file-dump-name", VariantType::String, "calibratordEdx.root", {"name of the file dump output file"}}, + {"track-debug", VariantType::Bool, false, {"track dEdx debugging"}}, + }}; } } // namespace o2::tpc diff --git a/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx b/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx index 2e60ba0bc72f6..7d8d2439e7295 100644 --- a/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx +++ b/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx @@ -63,7 +63,8 @@ void MIPTrackFilterDevice::init(framework::InitContext& ic) const double mindEdx = ic.options().get("min-dedx"); const double maxdEdx = ic.options().get("max-dedx"); const int minClusters = std::max(10, ic.options().get("min-clusters")); - const double mSendDummy = ic.options().get("send-dummy-data"); + const auto cutLoopers = !ic.options().get("dont-cut-loopers"); + mSendDummy = ic.options().get("send-dummy-data"); mMaxTracksPerTF = ic.options().get("maxTracksPerTF"); if (mMaxTracksPerTF > 0) { mMIPTracks.reserve(mMaxTracksPerTF); @@ -87,6 +88,7 @@ void MIPTrackFilterDevice::init(framework::InitContext& ic) mCuts.setNClusMin(minClusters); mCuts.setdEdxMin(mindEdx); mCuts.setdEdxMax(maxdEdx); + mCuts.setCutLooper(cutLoopers); } void MIPTrackFilterDevice::run(ProcessingContext& pc) @@ -169,7 +171,8 @@ DataProcessorSpec getMIPTrackFilterSpec() {"processEveryNthTF", VariantType::Int, 1, {"Using only a fraction of the data: 1: Use every TF, 10: Process only every tenth TF."}}, {"maxTracksPerTF", VariantType::Int, -1, {"Maximum number of processed tracks per TF (-1 for processing all tracks)"}}, {"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}}, - {"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}}}}; + {"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}}, + {"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}}}}; } } // namespace o2::tpc diff --git a/Detectors/TPC/workflow/src/TPCRefitter.cxx b/Detectors/TPC/workflow/src/TPCRefitter.cxx index cdc4234e6a2cc..7c14c8cd7d973 100644 --- a/Detectors/TPC/workflow/src/TPCRefitter.cxx +++ b/Detectors/TPC/workflow/src/TPCRefitter.cxx @@ -9,29 +9,32 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include #include #include +#include "CommonConstants/LHCConstants.h" #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "SimulationDataFormat/MCCompLabel.h" #include "TPCCalibration/VDriftHelper.h" #include "TPCCalibration/CorrectionMapsLoader.h" #include "ReconstructionDataFormats/GlobalTrackID.h" #include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "SimulationDataFormat/MCEventLabel.h" -#include "SimulationDataFormat/MCUtils.h" -#include "CommonUtils/NameConf.h" #include "Framework/ConfigParamRegistry.h" -#include "Framework/CCDBParamSpec.h" #include "Framework/ControlService.h" #include "Framework/Task.h" +#include "MathUtils/Tsallis.h" #include "DetectorsCommonDataFormats/DetID.h" +#include "ReconstructionDataFormats/TrackCosmics.h" +#include "DataFormatsTPC/Constants.h" #include "DetectorsBase/GRPGeomHelper.h" #include "TPCWorkflow/TPCRefitter.h" +#include "GPUTPCGMMergedTrackHit.h" #include "GPUO2InterfaceRefit.h" #include "TPCBase/ParameterElectronics.h" #include "CommonUtils/TreeStreamRedirector.h" #include "Steer/MCKinematicsReader.h" +#include "DetectorsRaw/HBFUtils.h" namespace o2::trackstudy { @@ -51,6 +54,15 @@ using timeEst = o2::dataformats::TimeStampWithError; class TPCRefitterSpec final : public Task { public: + enum StudyType { + TPC = 0x1, ///< TPConly + ITSTPC = 0x2, ///< TPC + ITS matched tracks + Cosmics = 0x4, ///< Cosmics + }; + enum WriterType { + Streamer = 0x1, ///< Write per track streamer information + TFVectors = 0x2, ///< Writer vectors per TF + }; TPCRefitterSpec(std::shared_ptr dr, std::shared_ptr gr, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, GTrackID::mask_t src, bool useMC) : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src), mUseMC(useMC) { @@ -79,23 +91,51 @@ class TPCRefitterSpec final : public Task int mTFEnd = 999999999; int mTFCount = -1; int mDCAMinNCl = 80; + int mStudyType = 0; ///< Bitmask of 'StudyType' + int mWriterType = 0; ///< Bitmask of 'WriterType' + float mSqrt{13600}; ///< centre of mass energy + float mSamplingFactor{0.1}; ///< sampling factor in case sampling is used for unbinned data bool mUseR = false; bool mEnableDCA = false; - bool mWriteTrackClusters = false; - std::unique_ptr mDBGOut; - std::unique_ptr mDBGOutCl; + int mWriteTrackClusters = 0; ///< bitmask of which cluster information to dump to the tree: 0x1 = cluster native, 0x2 = corrected cluster positions, 0x4 = uncorrected cluster positions, 0x8 occupancy info + bool mDoSampling{false}; ///< perform sampling of unbinned data + bool mDoRefit{true}; ///< perform refit of TPC track + std::vector mClusterOccupancy; ///< binned occupancy of all clusters + std::vector mITSTPCTrackOccupanyTPCTime; ///< binned occupancy for ITS-TPC matched tracks using the TPC track time + std::vector mITSTPCTrackOccupanyCombinedTime; ///< binned occupancy for ITS-TPC matched tracks using the combined track time + std::unique_ptr mDBGOutTPC; ///< per track streamer for TPC tracks + std::unique_ptr mDBGOutITSTPC; ///< per track streamer for ITS-TPC tracks + std::unique_ptr mDBGOutTPCTF; ///< per TF streamer for TPC tracks + std::unique_ptr mDBGOutITSTPCTF; ///< per TF streamer for ITS-TPC tracks + std::unique_ptr mDBGOutCosmics; ///< per track streamer for TPC tracks + std::unique_ptr mDBGOutCl; ///< TPC cluster streamer float mITSROFrameLengthMUS = 0.; GTrackID::mask_t mTracksSrc{}; - o2::steer::MCKinematicsReader mcReader; // reader of MC information + o2::steer::MCKinematicsReader mcReader; ///< reader of MC information + std::mt19937 mGenerator; ///< random generator for sampling + float mVdriftTB; ///< VDrift expressed in cm/TimeBin + float mTPCTBBias; ///< Time bin bias + uint32_t mTimeBinsPerTF{}; ///< number of time bins in TF + uint32_t mOccupancyBinsPerTF{}; ///< number of time bins in TF + uint32_t mTimeBinsPerDrift{500}; ///< number of time bins assumed in one drift + // + // Input data // - // TPC data gsl::span mTPCTrackClusIdx; ///< input TPC track cluster indices span gsl::span mTPCTracksArray; ///< input TPC tracks span + gsl::span mITSTPCTracksArray; ///< input TPC-ITS tracks span + gsl::span mITSTracksArray; ///< input ITS tracks span + gsl::span mCosmics; ///< input ITS tracks span gsl::span mTPCRefitterShMap; ///< externally set TPC clusters sharing map gsl::span mTPCRefitterOccMap; ///< externally set TPC clusters occupancy map const o2::tpc::ClusterNativeAccess* mTPCClusterIdxStruct = nullptr; ///< struct holding the TPC cluster indices gsl::span mTPCTrkLabels; ///< input TPC Track MC labels std::unique_ptr mTPCRefitter; ///< TPC refitter used for TPC tracks refit during the reconstruction + std::vector mIntRecs; + + void fillOccupancyVectors(o2::globaltracking::RecoContainer& recoData); + bool processTPCTrack(o2::tpc::TrackTPC tr, o2::MCCompLabel lbl, o2::utils::TreeStreamRedirector* streamer, const o2::its::TrackITS* its = nullptr, const o2::dataformats::TrackTPCITS* itstpc = nullptr, bool outward = false, float time0custom = -1); + void processCosmics(o2::globaltracking::RecoContainer& recoData); }; void TPCRefitterSpec::init(InitContext& ic) @@ -109,20 +149,46 @@ void TPCRefitterSpec::init(InitContext& ic) mTFEnd = ic.options().get("tf-end"); mDCAMinPt = ic.options().get("dcaMinPt"); mDCAMinNCl = ic.options().get("dcaMinNCl"); - if (mXRef < 0.) { - mXRef = 0.; + mSqrt = ic.options().get("sqrts"); + mSamplingFactor = ic.options().get("sampling-factor"); + mDoSampling = ic.options().get("do-sampling"); + mDoRefit = ic.options().get("do-refit"); + mStudyType = ic.options().get("study-type"); + mWriterType = ic.options().get("writer-type"); + mWriteTrackClusters = ic.options().get("write-track-clusters"); + const auto occBinsPerDrift = ic.options().get("occupancy-bins-per-drift"); + mTimeBinsPerTF = (o2::raw::HBFUtils::Instance().nHBFPerTF * o2::constants::lhc::LHCMaxBunches) / 8 + 2 * mTimeBinsPerDrift; // add one drift before and after the TF + mOccupancyBinsPerTF = static_cast(std::ceil(float(mTimeBinsPerTF * occBinsPerDrift) / mTimeBinsPerDrift)); + mClusterOccupancy.resize(mOccupancyBinsPerTF); + mITSTPCTrackOccupanyTPCTime.resize(mOccupancyBinsPerTF); + mITSTPCTrackOccupanyCombinedTime.resize(mOccupancyBinsPerTF); + LOGP(info, "Using {} bins for the occupancy per TF", mOccupancyBinsPerTF); + + if ((mWriterType & WriterType::Streamer) == WriterType::Streamer) { + if ((mStudyType & StudyType::TPC) == StudyType::TPC) { + mDBGOutTPC = std::make_unique("tpctracks-study-streamer.root", "recreate"); + } + if ((mStudyType & StudyType::ITSTPC) == StudyType::ITSTPC) { + mDBGOutITSTPC = std::make_unique("itstpctracks-study-streamer.root", "recreate"); + } + if ((mStudyType & StudyType::Cosmics) == StudyType::Cosmics) { + mDBGOutCosmics = std::make_unique("cosmics-study-streamer.root", "recreate"); + } } - mTPCCorrMapsLoader.init(ic); - mDBGOut = std::make_unique("tpctracks-refitted.root", "recreate"); - mWriteTrackClusters = ic.options().get("dump-clusters"); if (ic.options().get("dump-clusters")) { mDBGOutCl = std::make_unique("tpc-trackStudy-cl.root", "recreate"); } + + if (mXRef < 0.) { + mXRef = 0.; + } + mGenerator = std::mt19937(std::random_device{}()); + mTPCCorrMapsLoader.init(ic); } void TPCRefitterSpec::run(ProcessingContext& pc) { - mTFCount++; + ++mTFCount; if (mTFCount < mTFStart || mTFCount > mTFEnd) { LOGP(info, "Skipping TF {}", mTFCount); return; @@ -131,9 +197,10 @@ void TPCRefitterSpec::run(ProcessingContext& pc) o2::globaltracking::RecoContainer recoData; recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions + fillOccupancyVectors(recoData); process(recoData); - if (mTFCount > mTFEnd) { + if (mTFCount >= mTFEnd) { LOGP(info, "Stopping processing after TF {}", mTFCount); pc.services().get().endOfStream(); return; @@ -169,36 +236,109 @@ void TPCRefitterSpec::updateTimeDependentParams(ProcessingContext& pc) } } +void TPCRefitterSpec::fillOccupancyVectors(o2::globaltracking::RecoContainer& recoData) +{ + // reset counters + std::fill(mClusterOccupancy.begin(), mClusterOccupancy.end(), 0u); + std::fill(mITSTPCTrackOccupanyTPCTime.begin(), mITSTPCTrackOccupanyTPCTime.end(), 0u); + std::fill(mITSTPCTrackOccupanyCombinedTime.begin(), mITSTPCTrackOccupanyCombinedTime.end(), 0u); + + // fill cluster occupancy + const auto& clusterIndex = recoData.inputsTPCclusters->clusterIndex; + using namespace o2::tpc::constants; + for (int sector = 0; sector < MAXSECTOR; ++sector) { + for (int padrow = 0; padrow < MAXGLOBALPADROW; ++padrow) { + for (size_t icl = 0; icl < clusterIndex.nClusters[sector][padrow]; ++icl) { + const auto& cl = clusterIndex.clusters[sector][padrow][icl]; + // shift by one TPC drift to allow seeing pile-up + const auto tpcTime = cl.getTime() + mTimeBinsPerDrift; + const uint32_t clOccPos = static_cast(tpcTime * mOccupancyBinsPerTF / mTimeBinsPerTF); + if (clOccPos >= mOccupancyBinsPerTF) { + LOGP(error, "cluster with time {} outside TPC acceptanc", cl.getTime()); + } else { + ++mClusterOccupancy[clOccPos]; + } + } + } + } + + // fill track occupancy for its-tpc matched tracks + auto tpcTracks = recoData.getTPCTracks(); + auto itstpcTracks = recoData.getTPCITSTracks(); + const auto& paramEle = o2::tpc::ParameterElectronics::Instance(); + + for (const auto& tpcitsTrack : itstpcTracks) { + const auto idxTPC = tpcitsTrack.getRefTPC().getIndex(); + if (idxTPC >= tpcTracks.size()) { + LOGP(fatal, "TPC index {} out of array size {}", idxTPC, tpcTracks.size()); + } + const auto& tpcTrack = tpcTracks[idxTPC]; + // shift by one TPC drift to allow seeing pile-up + const auto tpcTime = tpcTrack.getTime0() + mTimeBinsPerDrift; + if (tpcTime >= 0) { + const uint32_t clOccPosTPC = static_cast(tpcTime * mOccupancyBinsPerTF / mTimeBinsPerTF); + if (clOccPosTPC < mITSTPCTrackOccupanyTPCTime.size()) { + ++mITSTPCTrackOccupanyTPCTime[clOccPosTPC]; + } else { + LOGP(warn, "TF {}: TPC occupancy index {} out of range {}", mTFCount, clOccPosTPC, mITSTPCTrackOccupanyTPCTime.size()); + } + } + // convert mus to time bins + // shift by one TPC drift to allow seeing pile-up + const auto tpcitsTime = tpcitsTrack.getTimeMUS().getTimeStamp() / paramEle.ZbinWidth + mTimeBinsPerDrift; + if (tpcitsTime > 0) { + const uint32_t clOccPosITSTPC = static_cast(tpcitsTime * mOccupancyBinsPerTF / mTimeBinsPerTF); + if (clOccPosITSTPC < mITSTPCTrackOccupanyCombinedTime.size()) { + ++mITSTPCTrackOccupanyCombinedTime[clOccPosITSTPC]; + } + } + } + + auto fillDebug = [this](o2::utils::TreeStreamRedirector* streamer) { + if (streamer) { + *streamer << "occupancy" + << "tfCounter=" << mTFCount + << "clusterOcc=" << mClusterOccupancy + << "tpcTrackTimeOcc=" << mITSTPCTrackOccupanyTPCTime + << "itstpcTrackTimeOcc=" << mITSTPCTrackOccupanyCombinedTime + << "\n"; + } + }; + + fillDebug(mDBGOutTPC.get()); + fillDebug(mDBGOutITSTPC.get()); +} + void TPCRefitterSpec::process(o2::globaltracking::RecoContainer& recoData) { - static long counter = -1; auto prop = o2::base::Propagator::Instance(); + mITSTracksArray = recoData.getITSTracks(); mTPCTracksArray = recoData.getTPCTracks(); + mITSTPCTracksArray = recoData.getTPCITSTracks(); + mCosmics = recoData.getCosmicTracks(); + mTPCTrackClusIdx = recoData.getTPCTracksClusterRefs(); mTPCClusterIdxStruct = &recoData.inputsTPCclusters->clusterIndex; mTPCRefitterShMap = recoData.clusterShMapTPC; mTPCRefitterOccMap = recoData.occupancyMapTPC; - std::vector intRecs; + LOGP(info, "Processing TF {} with {} its, {} tpc, {} its-tpc tracks and {} comsmics", mTFCount, mITSTracksArray.size(), mTPCTracksArray.size(), mITSTPCTracksArray.size(), mCosmics.size()); if (mUseMC) { // extract MC tracks const o2::steer::DigitizationContext* digCont = nullptr; if (!mcReader.initFromDigitContext("collisioncontext.root")) { throw std::invalid_argument("initialization of MCKinematicsReader failed"); } digCont = mcReader.getDigitizationContext(); - intRecs = digCont->getEventRecords(); + mIntRecs = digCont->getEventRecords(); mTPCTrkLabels = recoData.getTPCTracksMCLabels(); } mTPCRefitter = std::make_unique(mTPCClusterIdxStruct, &mTPCCorrMapsLoader, prop->getNominalBz(), mTPCTrackClusIdx.data(), 0, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size(), nullptr, prop); mTPCRefitter->setTrackReferenceX(900); // disable propagation after refit by setting reference to value > 500 - float vdriftTB = mTPCVDriftHelper.getVDriftObject().getVDrift() * o2::tpc::ParameterElectronics::Instance().ZbinWidth; // VDrift expressed in cm/TimeBin - float tpcTBBias = mTPCVDriftHelper.getVDriftObject().getTimeOffset() / (8 * o2::constants::lhc::LHCBunchSpacingMUS); - std::vector clSector, clRow; - std::vector clX, clY, clZ, clXI, clYI, clZI; // *I are the uncorrected cluster positions - float dcar, dcaz, dcarRef, dcazRef; + mVdriftTB = mTPCVDriftHelper.getVDriftObject().getVDrift() * o2::tpc::ParameterElectronics::Instance().ZbinWidth; // VDrift expressed in cm/TimeBin + mTPCTBBias = mTPCVDriftHelper.getVDriftObject().getTimeOffset() / (8 * o2::constants::lhc::LHCBunchSpacingMUS); auto dumpClusters = [this] { static int tf = 0; @@ -229,190 +369,39 @@ void TPCRefitterSpec::process(o2::globaltracking::RecoContainer& recoData) dumpClusters(); } - for (size_t itr = 0; itr < mTPCTracksArray.size(); itr++) { - auto tr = mTPCTracksArray[itr]; // create track copy - if (tr.hasBothSidesClusters()) { - continue; + if ((mStudyType & StudyType::TPC) == StudyType::TPC) { + for (size_t itr = 0; itr < mTPCTracksArray.size(); itr++) { + processTPCTrack(mTPCTracksArray[itr], mUseMC ? mTPCTrkLabels[itr] : o2::MCCompLabel{}, mDBGOutTPC.get()); } + } - //========================================================================= - // create refitted copy - auto trackRefit = [itr, this](o2::track::TrackParCov& trc, float t, float chi2refit) -> bool { - int retVal = mUseGPUModel ? this->mTPCRefitter->RefitTrackAsGPU(trc, this->mTPCTracksArray[itr].getClusterRef(), t, &chi2refit, false, true) - : this->mTPCRefitter->RefitTrackAsTrackParCov(trc, this->mTPCTracksArray[itr].getClusterRef(), t, &chi2refit, false, true); - if (retVal < 0) { - LOGP(warn, "Refit failed ({}) with time={}: track#{}[{}]", retVal, t, counter, trc.asString()); - return false; - } - return true; - }; - - auto trackProp = [&tr, itr, prop, this](o2::track::TrackParCov& trc) -> bool { - if (!trc.rotate(tr.getAlpha())) { - LOGP(warn, "Rotation to original track alpha {} failed, track#{}[{}]", tr.getAlpha(), counter, trc.asString()); - return false; - } - float xtgt = this->mXRef; - if (mUseR && !trc.getXatLabR(this->mXRef, xtgt, prop->getNominalBz(), o2::track::DirInward)) { - xtgt = 0; - return false; - } - if (!prop->PropagateToXBxByBz(trc, xtgt)) { - LOGP(warn, "Propagation to X={} failed, track#{}[{}]", xtgt, counter, trc.asString()); - return false; - } - return true; - }; - - auto prepClus = [this, &tr, &clSector, &clRow, &clX, &clY, &clZ, &clXI, &clYI, &clZI](float t) { // extract cluster info - clSector.clear(); - clRow.clear(); - clXI.clear(); - clYI.clear(); - clZI.clear(); - clX.clear(); - clY.clear(); - clZ.clear(); - int count = tr.getNClusters(); - const auto* corrMap = this->mTPCCorrMapsLoader.getCorrMap(); - const o2::tpc::ClusterNative* cl = nullptr; - for (int ic = count; ic--;) { - uint8_t sector, row; - cl = &tr.getCluster(this->mTPCTrackClusIdx, ic, *this->mTPCClusterIdxStruct, sector, row); - clSector.push_back(sector); - clRow.push_back(row); - float x, y, z; - // ideal transformation without distortions - corrMap->TransformIdeal(sector, row, cl->getPad(), cl->getTime(), x, y, z, t); // nominal time of the track - clXI.push_back(x); - clYI.push_back(y); - clZI.push_back(z); - - // transformation without distortions - mTPCCorrMapsLoader.Transform(sector, row, cl->getPad(), cl->getTime(), x, y, z, t); // nominal time of the track - clX.push_back(x); - clY.push_back(y); - clZ.push_back(z); + if ((mStudyType & StudyType::ITSTPC) == StudyType::ITSTPC) { + for (const auto& tpcitsTrack : mITSTPCTracksArray) { + const auto idxTPC = tpcitsTrack.getRefTPC().getIndex(); + const auto idxITS = tpcitsTrack.getRefITS().getIndex(); + if (idxITS >= mITSTracksArray.size()) { + LOGP(fatal, "ITS index {} out of array size {}", idxITS, mITSTracksArray.size()); } - }; - - //========================================================================= - - auto trf = tr.getOuterParam(); // we refit inward original track - float chi2refit = 0; - if (!trackRefit(trf, tr.getTime0(), chi2refit) || !trackProp(trf)) { - continue; - } - - // propagate original track - if (!trackProp(tr)) { - continue; - } - - if (mWriteTrackClusters) { - prepClus(tr.getTime0()); // original clusters - } - - if (mEnableDCA) { - dcar = dcaz = dcarRef = dcazRef = 9999.f; - if ((trf.getPt() > mDCAMinPt) && (tr.getNClusters() > mDCAMinNCl)) { - getDCAs(trf, dcarRef, dcazRef); - getDCAs(tr, dcar, dcaz); + if (idxTPC >= mTPCTracksArray.size()) { + LOGP(fatal, "TPC index {} out of array size {}", idxTPC, mTPCTracksArray.size()); } + processTPCTrack(mTPCTracksArray[idxTPC], mUseMC ? mTPCTrkLabels[idxTPC] : o2::MCCompLabel{}, mDBGOutITSTPC.get(), &mITSTracksArray[idxITS], &tpcitsTrack); } + } - counter++; - // store results - (*mDBGOut) << "tpcIni" - << "counter=" << counter - << "iniTrack=" << tr - << "iniTrackRef=" << trf - << "time=" << tr.getTime0() - << "chi2refit=" << chi2refit; - - if (mWriteTrackClusters) { - (*mDBGOut) << "tpcIni" - << "clSector=" << clSector - << "clRow=" << clRow - << "clX=" << clX - << "clY=" << clY - << "clZ=" << clZ - << "clXI=" << clXI // ideal (uncorrected) cluster positions - << "clYI=" << clYI // ideal (uncorrected) cluster positions - << "clZI=" << clZI; // ideal (uncorrected) cluster positions - } - - if (mEnableDCA) { - (*mDBGOut) << "tpcIni" - << "dcar=" << dcar - << "dcaz=" << dcaz - << "dcarRef=" << dcarRef - << "dcazRef=" << dcazRef; - } - - (*mDBGOut) << "tpcIni" - << "\n"; - - float dz = 0; - - if (mUseMC) { // impose MC time in TPC timebin and refit inward after resetted covariance - // extract MC truth - const o2::MCTrack* mcTrack = nullptr; - auto lbl = mTPCTrkLabels[itr]; - if (!lbl.isValid() || !(mcTrack = mcReader.getTrack(lbl))) { - break; - } - long bc = intRecs[lbl.getEventID()].toLong(); // bunch crossing of the interaction - float bcTB = bc / 8. + tpcTBBias; // the same in TPC timebins, accounting for the TPC time bias - // create MC truth track in O2 format - std::array xyz{(float)mcTrack->GetStartVertexCoordinatesX(), (float)mcTrack->GetStartVertexCoordinatesY(), (float)mcTrack->GetStartVertexCoordinatesZ()}, - pxyz{(float)mcTrack->GetStartVertexMomentumX(), (float)mcTrack->GetStartVertexMomentumY(), (float)mcTrack->GetStartVertexMomentumZ()}; - TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrack->GetPdgCode()); - if (!pPDG) { - break; - } - o2::track::TrackPar mctrO2(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); - // - // propagate it to the alpha/X of the reconstructed track - if (!mctrO2.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(mctrO2, tr.getX())) { - break; - } - // now create a properly refitted track with correct time and distortions correction - { - auto trfm = tr.getOuterParam(); // we refit inward - // impose MC time in TPC timebin and refit inward after resetted covariance - float chi2refit = 0; - if (!trackRefit(trfm, bcTB, chi2refit) || !trfm.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(trfm, tr.getX())) { - LOGP(warn, "Failed to propagate MC-time refitted track#{} [{}] to X/alpha of original track [{}]", counter, trfm.asString(), tr.asString()); - break; - } - // estimate Z shift in case of no-distortions - dz = (tr.getTime0() - bcTB) * vdriftTB; - if (tr.hasCSideClustersOnly()) { - dz = -dz; - } - // - prepClus(bcTB); // clusters for MC time - (*mDBGOut) << "tpcMC" - << "counter=" << counter - << "movTrackRef=" << trfm - << "mcTrack=" << mctrO2 - << "imposedTB=" << bcTB - << "chi2refit=" << chi2refit - << "dz=" << dz - << "clX=" << clX - << "clY=" << clY - << "clZ=" << clZ - << "\n"; - } - break; - } + if (mCosmics.size() > 0) { + LOGP(info, "Procssing {} cosmics", mCosmics.size()); + processCosmics(recoData); } } void TPCRefitterSpec::endOfStream(EndOfStreamContext& ec) { - mDBGOut.reset(); + mDBGOutTPC.reset(); + mDBGOutITSTPC.reset(); + mDBGOutTPCTF.reset(); + mDBGOutITSTPCTF.reset(); + mDBGOutCosmics.reset(); mDBGOutCl.reset(); } @@ -445,25 +434,336 @@ bool TPCRefitterSpec::getDCAs(const o2::track::TrackPar& track, float& dcar, flo return ok; } -DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) +bool TPCRefitterSpec::processTPCTrack(o2::tpc::TrackTPC tr, o2::MCCompLabel lbl, o2::utils::TreeStreamRedirector* streamer, const o2::its::TrackITS* its, const o2::dataformats::TrackTPCITS* itstpc, bool outward, float time0custom) +{ + auto prop = o2::base::Propagator::Instance(); + static long counter = -1; + + struct ClusterData { + std::vector occCl; + std::vector clSector, clRow; + std::vector clX, clY, clZ, clXI, clYI, clZI; // *I are the uncorrected cluster positions + std::vector clNative; + } clData; + float dcar, dcaz, dcarRef, dcazRef; + + // auto tr = mTPCTracksArray[itr]; // create track copy + if (tr.hasBothSidesClusters()) { + return false; + } + + bool sampleTsallis = false; + bool sampleMB = false; + float tsallisWeight = 0; + if (mDoSampling) { + std::uniform_real_distribution<> distr(0., 1.); + if (o2::math_utils::Tsallis::downsampleTsallisCharged(tr.getPt(), mSamplingFactor, mSqrt, tsallisWeight, distr(mGenerator))) { + sampleTsallis = true; + } + if (distr(mGenerator) < mSamplingFactor) { + sampleMB = true; + } + + if (!sampleMB && !sampleTsallis) { + return false; + } + } + //========================================================================= + // create refitted copy + auto trackRefit = [&tr, this](o2::track::TrackParCov& trc, float t, float chi2refit, bool outward = false) -> bool { + int retVal = mUseGPUModel ? this->mTPCRefitter->RefitTrackAsGPU(trc, tr.getClusterRef(), t, &chi2refit, outward, true) + : this->mTPCRefitter->RefitTrackAsTrackParCov(trc, tr.getClusterRef(), t, &chi2refit, outward, true); + if (retVal < 0) { + LOGP(warn, "Refit failed ({}) with time={}: track#{}[{}]", retVal, t, counter, trc.asString()); + return false; + } + return true; + }; + + auto trackProp = [&tr, prop, this](o2::track::TrackParCov& trc) -> bool { + if (!trc.rotate(tr.getAlpha())) { + LOGP(warn, "Rotation to original track alpha {} failed, track#{}[{}]", tr.getAlpha(), counter, trc.asString()); + return false; + } + float xtgt = this->mXRef; + if (mUseR && !trc.getXatLabR(this->mXRef, xtgt, prop->getNominalBz(), o2::track::DirInward)) { + xtgt = 0; + return false; + } + if (!prop->PropagateToXBxByBz(trc, xtgt)) { + LOGP(warn, "Propagation to X={} failed, track#{}[{}]", xtgt, counter, trc.asString()); + return false; + } + return true; + }; + + // auto prepClus = [this, &tr, &clSector, &clRow, &clX, &clY, &clZ, &clXI, &clYI, &clZI, &clNative](float t) { // extract cluster info + auto prepClus = [this, &tr, &clData](float t) { // extract cluster info + int count = tr.getNClusters(); + const auto* corrMap = this->mTPCCorrMapsLoader.getCorrMap(); + const o2::tpc::ClusterNative* cl = nullptr; + for (int ic = count; ic--;) { + uint8_t sector, row; + uint32_t clusterIndex; + o2::tpc::TrackTPC::getClusterReference(mTPCTrackClusIdx, ic, sector, row, clusterIndex, tr.getClusterRef()); + unsigned int absoluteIndex = mTPCClusterIdxStruct->clusterOffset[sector][row] + clusterIndex; + cl = &mTPCClusterIdxStruct->clusters[sector][row][clusterIndex]; + uint8_t clflags = cl->getFlags(); + if (mTPCRefitterShMap[absoluteIndex] & GPUCA_NAMESPACE::gpu::GPUTPCGMMergedTrackHit::flagShared) { + clflags |= 0x10; + } + clData.clSector.emplace_back(sector); + clData.clRow.emplace_back(row); + auto& clCopy = clData.clNative.emplace_back(*cl); + clCopy.setFlags(clflags); + + float x, y, z; + // ideal transformation without distortions + corrMap->TransformIdeal(sector, row, cl->getPad(), cl->getTime(), x, y, z, t); // nominal time of the track + clData.clXI.emplace_back(x); + clData.clYI.emplace_back(y); + clData.clZI.emplace_back(z); + + // transformation without distortions + mTPCCorrMapsLoader.Transform(sector, row, cl->getPad(), cl->getTime(), x, y, z, t); // nominal time of the track + clData.clX.emplace_back(x); + clData.clY.emplace_back(y); + clData.clZ.emplace_back(z); + + // occupancy estimator + const auto tpcTime = cl->getTime() + mTimeBinsPerDrift; + const uint32_t clOccPosTPC = static_cast(tpcTime * mOccupancyBinsPerTF / mTimeBinsPerTF); + clData.occCl.emplace_back((clOccPosTPC < mClusterOccupancy.size()) ? mClusterOccupancy[clOccPosTPC] : -1); + } + }; + + //========================================================================= + + auto trf = tr.getOuterParam(); // we refit inward original track + float chi2refit = 0; + float time0 = tr.getTime0(); + if (time0custom > 0) { + time0 = time0custom; + } + if (mDoRefit) { + if (!trackRefit(trf, time0, chi2refit) || !trackProp(trf)) { + return false; + } + } + + // propagate original track + if (!trackProp(tr)) { + return false; + } + + if (mWriteTrackClusters) { + prepClus(time0); // original clusters + } + + if (mEnableDCA) { + dcar = dcaz = dcarRef = dcazRef = 9999.f; + if ((trf.getPt() > mDCAMinPt) && (tr.getNClusters() > mDCAMinNCl)) { + getDCAs(trf, dcarRef, dcazRef); + getDCAs(tr, dcar, dcaz); + } + } + + counter++; + // store results + if (streamer) { + (*streamer) << "tpc" + << "counter=" << counter + << "tfCounter=" << mTFCount + << "tpc=" << tr; + + if (mDoRefit) { + (*streamer) << "tpc" + << "tpcRF=" << trf + << "time0=" << time0 + << "chi2refit=" << chi2refit; + } + + if (mDoSampling) { + (*streamer) << "tpc" + << "tsallisWeight=" << tsallisWeight + << "sampleTsallis=" << sampleTsallis + << "sampleMB=" << sampleMB; + } + + if (mWriteTrackClusters) { + (*streamer) << "tpc" + << "clSector=" << clData.clSector + << "clRow=" << clData.clRow; + + if ((mWriteTrackClusters & 0x1) == 0x1) { + (*streamer) << "tpc" + << "cl=" << clData.clNative; + } + + if ((mWriteTrackClusters & 0x2) == 0x2) { + (*streamer) << "tpc" + << "clX=" << clData.clX + << "clY=" << clData.clY + << "clZ=" << clData.clZ; + } + + if ((mWriteTrackClusters & 0x4) == 0x4) { + (*streamer) << "tpc" + << "clXI=" << clData.clXI // ideal (uncorrected) cluster positions + << "clYI=" << clData.clYI // ideal (uncorrected) cluster positions + << "clZI=" << clData.clZI; // ideal (uncorrected) cluster positions + } + + if ((mWriteTrackClusters & 0x8) == 0x8) { + (*streamer) << "tpc" + << "clOcc=" << clData.occCl; + } + } + + if (its) { + (*streamer) << "tpc" + << "its=" << *its; + } + if (itstpc) { + (*streamer) << "tpc" + << "itstpc=" << *itstpc; + } + + if (mEnableDCA) { + (*streamer) << "tpc" + << "dcar=" << dcar + << "dcaz=" << dcaz + << "dcarRef=" << dcarRef + << "dcazRef=" << dcazRef; + } + + (*streamer) << "tpc" + << "\n"; + } + + float dz = 0; + + if (mUseMC) { // impose MC time in TPC timebin and refit inward after resetted covariance + // extract MC truth + const o2::MCTrack* mcTrack = nullptr; + if (!lbl.isValid() || !(mcTrack = mcReader.getTrack(lbl))) { + return false; + } + long bc = mIntRecs[lbl.getEventID()].toLong(); // bunch crossing of the interaction + float bcTB = bc / 8. + mTPCTBBias; // the same in TPC timebins, accounting for the TPC time bias + // create MC truth track in O2 format + std::array xyz{(float)mcTrack->GetStartVertexCoordinatesX(), (float)mcTrack->GetStartVertexCoordinatesY(), (float)mcTrack->GetStartVertexCoordinatesZ()}, + pxyz{(float)mcTrack->GetStartVertexMomentumX(), (float)mcTrack->GetStartVertexMomentumY(), (float)mcTrack->GetStartVertexMomentumZ()}; + TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrack->GetPdgCode()); + if (!pPDG) { + return false; + } + o2::track::TrackPar mctrO2(xyz, pxyz, TMath::Nint(pPDG->Charge() / 3), false); + // + // propagate it to the alpha/X of the reconstructed track + if (!mctrO2.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(mctrO2, tr.getX())) { + return false; + } + // now create a properly refitted track with correct time and distortions correction + { + auto trfm = tr.getOuterParam(); // we refit inward + // impose MC time in TPC timebin and refit inward after resetted covariance + float chi2refit = 0; + if (!trackRefit(trfm, bcTB, chi2refit) || !trfm.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(trfm, tr.getX())) { + LOGP(warn, "Failed to propagate MC-time refitted track#{} [{}] to X/alpha of original track [{}]", counter, trfm.asString(), tr.asString()); + return false; + } + // estimate Z shift in case of no-distortions + dz = (tr.getTime0() - bcTB) * mVdriftTB; + if (tr.hasCSideClustersOnly()) { + dz = -dz; + } + // + prepClus(bcTB); // clusters for MC time + if (streamer) { + (*streamer) << "tpcMC" + << "counter=" << counter + << "movTrackRef=" << trfm + << "mcTrack=" << mctrO2 + << "imposedTB=" << bcTB + << "chi2refit=" << chi2refit + << "dz=" << dz + << "clX=" << clData.clX + << "clY=" << clData.clY + << "clZ=" << clData.clZ + << "\n"; + } + } + return false; + } + + return true; +} + +void TPCRefitterSpec::processCosmics(o2::globaltracking::RecoContainer& recoData) +{ + auto tof = recoData.getTOFClusters(); + const auto& par = o2::tpc::ParameterElectronics::Instance(); + const auto invBinWidth = 1.f / par.ZbinWidth; + + for (const auto& cosmic : mCosmics) { + // + const auto& gidtop = cosmic.getRefTop(); + const auto& gidbot = cosmic.getRefBottom(); + + // LOGP(info, "Sources: {} - {}", o2::dataformats::GlobalTrackID::getSourceName(gidtop.getSource()), o2::dataformats::GlobalTrackID::getSourceName(gidbot.getSource())); + + std::array contributorsGID[2] = {recoData.getSingleDetectorRefs(cosmic.getRefTop()), recoData.getSingleDetectorRefs(cosmic.getRefBottom())}; + const auto trackTime = cosmic.getTimeMUS().getTimeStamp() * invBinWidth; + + // check if track has TPC & TOF for top and bottom part + // loop over both parts + for (const auto& comsmicInfo : contributorsGID) { + auto& tpcGlobal = comsmicInfo[GTrackID::TPC]; + auto& tofGlobal = comsmicInfo[GTrackID::TOF]; + if (tpcGlobal.isIndexSet() && tofGlobal.isIndexSet()) { + const auto itrTPC = tpcGlobal.getIndex(); + const auto itrTOF = tofGlobal.getIndex(); + const auto& tofCl = tof[itrTOF]; + const auto tofTime = tofCl.getTime() * 1e-6 * invBinWidth; // ps -> us -> time bins + const auto tofTimeRaw = tofCl.getTimeRaw() * 1e-6 * invBinWidth; // ps -> us -> time bins + const auto& trackTPC = mTPCTracksArray[itrTPC]; + // LOGP(info, "Cosmic time: {}, TOF time: {}, TOF time raw: {}, TPC time: {}", trackTime, tofTime, tofTimeRaw, trackTPC.getTime0()); + processTPCTrack(trackTPC, mUseMC ? mTPCTrkLabels[itrTPC] : o2::MCCompLabel{}, mDBGOutCosmics.get(), nullptr, nullptr, false, tofTime); + } + } + } +} + +DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool requestCosmics) { std::vector outputs; Options opts{ {"target-x", VariantType::Float, 83.f, {"Try to propagate to this radius"}}, {"dump-clusters", VariantType::Bool, false, {"dump all clusters"}}, - {"write-track-clusters", VariantType::Bool, false, {"write clusters associated to the track, uncorrected and corrected positions"}}, + {"write-track-clusters", VariantType::Int, 3, {"Bitmask write clusters associated to the track, full native cluster (0x1), corrected (0x2) and uncorrected (0x4) positions, (0x8) occupancy info"}}, {"tf-start", VariantType::Int, 0, {"1st TF to process"}}, {"tf-end", VariantType::Int, 999999999, {"last TF to process"}}, {"use-gpu-fitter", VariantType::Bool, false, {"use GPU track model for refit instead of TrackParCov"}}, + {"do-refit", VariantType::Bool, false, {"do refitting of TPC track"}}, {"use-r-as-x", VariantType::Bool, false, {"Use radius instead of target sector X"}}, {"enable-dcas", VariantType::Bool, false, {"Propagate to DCA and add it to the tree"}}, {"dcaMinPt", VariantType::Float, 1.f, {"Min pT of tracks propagated to DCA"}}, {"dcaMinNCl", VariantType::Int, 80, {"Min number of clusters for tracks propagated to DCA"}}, + {"sqrts", VariantType::Float, 13600.f, {"Centre of mass energy used for downsampling"}}, + {"do-sampling", VariantType::Bool, false, {"Perform sampling, min. bias and on Tsallis function, using 'sampling-factor'"}}, + {"sampling-factor", VariantType::Float, 0.1f, {"Sampling factor in case sample-unbinned-tsallis is used"}}, + {"study-type", VariantType::Int, 1, {"Bitmask of study type: 0x1 = TPC only, 0x2 = TPC + ITS, 0x4 = Cosmics"}}, + {"writer-type", VariantType::Int, 1, {"Bitmask of writer type: 0x1 = per track streamer, 0x2 = per TF vectors"}}, + {"occupancy-bins-per-drift", VariantType::UInt32, 31u, {"number of bin for occupancy histogram per drift time (500tb)"}}, }; auto dataRequest = std::make_shared(); dataRequest->requestTracks(srcTracks, useMC); dataRequest->requestClusters(srcClusters, useMC); + if (requestCosmics) { + dataRequest->requestCoscmicTracks(useMC); + } auto ggRequest = std::make_shared(false, // orbitResetTime true, // GRPECS=true false, // GRPLHCIF diff --git a/Detectors/TPC/workflow/src/tpc-miptrack-filter.cxx b/Detectors/TPC/workflow/src/tpc-miptrack-filter.cxx index d4c311edac19c..112e8ff2cd3a4 100644 --- a/Detectors/TPC/workflow/src/tpc-miptrack-filter.cxx +++ b/Detectors/TPC/workflow/src/tpc-miptrack-filter.cxx @@ -49,10 +49,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) auto logger = BranchDefinition::Spectator([](TrackOutputType const& tracks) { LOG(info) << "writing " << tracks.size() << " track(s)"; }); - auto tracksdef = BranchDefinition{InputSpec{"inputTracks", "TPC", "MIPS", 0}, // - "TPCTracks", "track-branch-name", // - 1, // - logger}; // + auto tracksdef = BranchDefinition{InputSpec{"inputTracks", "TPC", "MIPS", 0, Lifetime::Sporadic}, // + "TPCTracks", "track-branch-name", // + 1, // + logger}; // workflow.push_back(MakeRootTreeWriterSpec(processName, defaultFileName, defaultTreeName, std::move(tracksdef))()); diff --git a/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx b/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx index 9a0fdc0e26b53..264e7d8a98c60 100644 --- a/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx +++ b/Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx @@ -39,6 +39,7 @@ void customize(std::vector& workflowOptions) // option allowing to set parameters std::vector options{ {"enable-mc", o2::framework::VariantType::Bool, false, {"enable MC propagation"}}, + {"enable-cosmics", o2::framework::VariantType::Bool, false, {"enable reading cosmics"}}, {"track-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of track sources to use"}}, {"cluster-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of cluster sources to use"}}, {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, @@ -58,19 +59,25 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) { WorkflowSpec specs; - GID::mask_t allowedSourcesTrc = GID::getSourcesMask("TPC"); - GID::mask_t allowedSourcesClus = GID::getSourcesMask("TPC"); - // Update the (declared) parameters if changed from the command line o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); auto useMC = configcontext.options().get("enable-mc"); auto sclOpt = o2::tpc::CorrectionMapsLoader::parseGlobalOptions(configcontext.options()); + const auto enableCosmics = configcontext.options().get("enable-cosmics"); + + GID::mask_t allowedSourcesTrc = GID::getSourcesMask("ITS,TPC,ITS-TPC,TPC-TOF"); + GID::mask_t allowedSourcesClus = GID::getSourcesMask("TPC,TOF"); + if (enableCosmics) { + allowedSourcesTrc = allowedSourcesTrc | GID::getSourcesMask("ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF"); + } + GID::mask_t srcTrc = allowedSourcesTrc & GID::getSourcesMask(configcontext.options().get("track-sources")); GID::mask_t srcCls = allowedSourcesClus & GID::getSourcesMask(configcontext.options().get("cluster-sources")); if (sclOpt.requestCTPLumi) { srcTrc = srcTrc | GID::getSourcesMask("CTP"); srcCls = srcCls | GID::getSourcesMask("CTP"); } + if (sclOpt.lumiType == 2) { const auto enableMShape = configcontext.options().get("enable-M-shape-correction"); const auto enableIDCs = !configcontext.options().get("disable-IDC-scalers"); @@ -79,7 +86,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); // P-vertex is always needed - specs.emplace_back(o2::trackstudy::getTPCRefitterSpec(srcTrc, srcCls, useMC, sclOpt)); + if (enableCosmics) { + o2::globaltracking::InputHelper::addInputSpecsCosmics(configcontext, specs, useMC); + } + specs.emplace_back(o2::trackstudy::getTPCRefitterSpec(srcTrc, srcCls, useMC, sclOpt, enableCosmics)); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); From 373f80882c030819a0021e20535acffa672193b9 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Mon, 23 Sep 2024 20:39:42 +0100 Subject: [PATCH 0277/2205] Ctpdev: print input and class rates in case of big payload (#13518) * dev: decoder prints input and class rates and exit in case of big payload size * clang * fix: typos * clang * andrea suggestions --- .../CTPReconstruction/RawDataDecoder.h | 1 + .../CTP/reconstruction/src/RawDataDecoder.cxx | 163 ++++++++++++++++++ Detectors/CTP/workflow/src/RawDecoderSpec.cxx | 18 +- 3 files changed, 177 insertions(+), 5 deletions(-) diff --git a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h index e38e1fb027362..c50079f9f8717 100644 --- a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h +++ b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h @@ -35,6 +35,7 @@ class RawDataDecoder static void makeGBTWordInverse(std::vector& diglets, gbtword80_t& GBTWord, gbtword80_t& remnant, uint32_t& size_gbt, uint32_t Npld); int addCTPDigit(uint32_t linkCRU, uint32_t triggerOrbit, gbtword80_t& diglet, gbtword80_t& pldmask, std::map& digits); int decodeRaw(o2::framework::InputRecord& inputs, std::vector& filter, o2::pmr::vector& digits, std::vector& lumiPointsHBF1); + int decodeRawFatal(o2::framework::InputRecord& inputs, std::vector& filter); int decodeRaw(o2::framework::InputRecord& inputs, std::vector& filter, std::vector& digits, std::vector& lumiPointsHBF1); void setDecodeInps(bool decodeinps) { mDecodeInps = decodeinps; } void setDoLumi(bool lumi) { mDoLumi = lumi; } diff --git a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx index 88bf5ecf798af..4e3d480e463cd 100644 --- a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx +++ b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx @@ -17,6 +17,8 @@ #include "DataFormatsCTP/TriggerOffsetsParam.h" #include "CTPReconstruction/RawDataDecoder.h" #include "DataFormatsCTP/Configuration.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include using namespace o2::ctp; @@ -174,6 +176,7 @@ int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector> 8; + // LOG(info) << "CRU link:" << linkCRU; if (linkCRU == o2::ctp::GBTLinkIDIntRec) { payloadCTP = o2::ctp::NIntRecPayload; } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) { @@ -319,6 +322,166 @@ int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector& filter) +{ + o2::framework::DPLRawParser parser(inputs, filter); + uint32_t payloadCTP = 0; + gbtword80_t remnant = 0; + uint32_t size_gbt = 0; + mTFOrbit = 0; + uint32_t orbit0 = 0; + std::array rates{}; + std::array ratesC{}; + for (auto it = parser.begin(); it != parser.end(); ++it) { + const o2::header::RDHAny* rdh = nullptr; + try { + rdh = reinterpret_cast(it.raw()); + mPadding = (o2::raw::RDHUtils::getDataFormat(rdh) == 0); + } catch (std::exception& e) { + LOG(error) << "Failed to extract RDH, abandoning TF sending dummy output, exception was: " << e.what(); + // dummyOutput(); + return 1; + } + // auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(rdh); + uint32_t stopBit = o2::raw::RDHUtils::getStop(rdh); + uint32_t packetCounter = o2::raw::RDHUtils::getPageCounter(rdh); + uint32_t version = o2::raw::RDHUtils::getVersion(rdh); + uint32_t rdhOrbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdh); + uint32_t triggerType = o2::raw::RDHUtils::getTriggerType(rdh); + // std::cout << "diff orbits:" << triggerOrbit - rdhOrbit << std::endl; + bool tf = (triggerType & TF_TRIGGERTYPE_MASK) && (packetCounter == 0); + bool hb = (triggerType & HB_TRIGGERTYPE_MASK) && (packetCounter == 0); + if (tf) { + mTFOrbit = rdhOrbit; + // std::cout << "tforbit==================>" << mTFOrbit << " " << std::hex << mTFOrbit << std::endl; + mTFOrbits.push_back(mTFOrbit); + } + static bool prt = true; + if (prt) { + LOG(info) << "RDH version:" << version << " Padding:" << mPadding; + prt = false; + } + auto feeID = o2::raw::RDHUtils::getFEEID(rdh); // 0 = IR, 1 = TCR + auto linkCRU = (feeID & 0xf00) >> 8; + // LOG(info) << "CRU link:" << linkCRU; + if (linkCRU == o2::ctp::GBTLinkIDIntRec) { + payloadCTP = o2::ctp::NIntRecPayload; + } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) { + payloadCTP = o2::ctp::NClassPayload; + } else { + LOG(error) << "Unxpected CTP CRU link:" << linkCRU; + } + LOG(debug) << "RDH FEEid: " << feeID << " CTP CRU link:" << linkCRU << " Orbit:" << rdhOrbit << " triggerType:" << triggerType; + // LOG(info) << "remnant :" << remnant.count(); + gbtword80_t pldmask = 0; + for (uint32_t i = 0; i < payloadCTP; i++) { + pldmask[12 + i] = 1; + } + // std::cout << (orbit0 != rdhOrbit) << " comp " << (mTFOrbit==rdhOrbit) << std::endl; + // if(orbit0 != rdhOrbit) { + if (hb) { + remnant = 0; + size_gbt = 0; + orbit0 = rdhOrbit; + // std::cout << "orbit0============>" << std::dec << orbit0 << " " << std::hex << orbit0 << std::endl; + } + // Create 80 bit words + gsl::span payload(it.data(), it.size()); + gbtword80_t gbtWord80; + gbtWord80.set(); + int wordCount = 0; + int wordSize = 10; + std::vector gbtwords80; + // mPadding = 0; + if (mPadding == 1) { + wordSize = 16; + } + // LOG(info) << ii << " payload size:" << payload.size(); + gbtword80_t bcmask = std::bitset<80>("111111111111"); + for (auto payloadWord : payload) { + int wc = wordCount % wordSize; + // LOG(info) << wordCount << ":" << wc << " payload:" << int(payloadWord); + if ((wc == 0) && (wordCount != 0)) { + if (gbtWord80.count() != 80) { + gbtwords80.push_back(gbtWord80); + } + gbtWord80.set(); + } + if (wc < 10) { + for (int i = 0; i < 8; i++) { + gbtWord80[wc * 8 + i] = bool(int(payloadWord) & (1 << i)); + } + } + wordCount++; + } + if ((gbtWord80.count() != 80) && (gbtWord80.count() > 0)) { + gbtwords80.push_back(gbtWord80); + } + // decode 80 bits payload + for (auto word : gbtwords80) { + std::vector diglets; + gbtword80_t gbtWord = word; + makeGBTWordInverse(diglets, gbtWord, remnant, size_gbt, payloadCTP); + for (auto diglet : diglets) { + int nbits = payloadCTP - 12; + for (int i = 0; i < nbits; i++) { + gbtword80_t mask = 1ull << i; + gbtword80_t pld = (diglet >> 12) & mask; + // LOG(info) << "diglet:" << diglet << " pld:" << pld; + if (pld.count() != 0) { + if (linkCRU == o2::ctp::GBTLinkIDIntRec) { + rates[i]++; + } else { + ratesC[i]++; + } + } + } + // LOG(debug) << "diglet:" << diglet << " " << (diglet & bcmask).to_ullong(); + } + } + if ((remnant.count() > 0) && stopBit) { + int nbits = payloadCTP - 12; + for (int i = 0; i < nbits; i++) { + gbtword80_t mask = 1ull << i; + gbtword80_t pld = (remnant >> 12) & mask; + // LOG(info) << "diglet:" << remnant << " pld:" << pld; + if (pld.count() != 0) { + if (linkCRU == o2::ctp::GBTLinkIDIntRec) { + rates[i]++; + } else { + ratesC[i]++; + } + } + } + remnant = 0; + } + } + // print max rates + std::map ratesmap; + std::map ratesmapC; + for (int i = 0; i < o2::ctp::CTP_NCLASSES; i++) { + if (rates[i]) { + ratesmap[rates[i]] = i; + } + if (ratesC[i]) { + ratesmapC[ratesC[i]] = i; + } + } + auto nhb = o2::base::GRPGeomHelper::getNHBFPerTF(); + std::string message = "Ringing inputs [MHz]:"; + for (auto const& r : boost::adaptors::reverse(ratesmap)) { + // LOG(error) << r.second; + message += " " + o2::ctp::CTPInputsConfiguration::getInputNameFromIndex(r.second + 1) + ":" + std::to_string(r.first / 32. / o2::constants::lhc::LHCOrbitMUS); + } + std::string messageC = "Ringing classes [MHz]:"; + for (auto const& r : boost::adaptors::reverse(ratesmapC)) { + messageC += " class" + std::to_string(r.second) + ":" + std::to_string(r.first / 32. / o2::constants::lhc::LHCOrbitMUS); + } + LOG(error) << messageC; + LOG(fatal) << message; + return 0; +} +// int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector& filter, std::vector& digits, std::vector& lumiPointsHBF1) { o2::pmr::vector pmrdigits; diff --git a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx index df0988c871196..415dbe2a1ffe3 100644 --- a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx +++ b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx @@ -112,6 +112,7 @@ void RawDecoderSpec::run(framework::ProcessingContext& ctx) // std::vector lumiPointsHBF1; std::vector filter{InputSpec{"filter", ConcreteDataTypeMatcher{"CTP", "RAWDATA"}, Lifetime::Timeframe}}; + bool fatal_flag = 0; if (mMaxInputSize > 0) { size_t payloadSize = 0; for (const auto& ref : o2::framework::InputRecordWalker(inputs, filter)) { @@ -120,15 +121,22 @@ void RawDecoderSpec::run(framework::ProcessingContext& ctx) } if (payloadSize > (size_t)mMaxInputSize) { if (mMaxInputSizeFatal) { - LOG(fatal) << "Input data size:" << payloadSize; + fatal_flag = 1; + LOG(error) << "Input data size bigger than threshold: " << mMaxInputSize << " < " << payloadSize << " decoding TF and exiting."; + // LOG(fatal) << "Input data size:" << payloadSize; - fatal issued in decoder } else { - LOG(error) << "Input data size:" << payloadSize; + LOG(error) << "Input data size:" << payloadSize << " sending dummy output"; + dummyOutput(); + return; } - dummyOutput(); - return; } } - int ret = mDecoder.decodeRaw(inputs, filter, mOutputDigits, lumiPointsHBF1); + int ret = 0; + if (fatal_flag) { + ret = mDecoder.decodeRawFatal(inputs, filter); + } else { + ret = mDecoder.decodeRaw(inputs, filter, mOutputDigits, lumiPointsHBF1); + } if (ret == 1) { dummyOutput(); return; From 4fb71e581a2315ac52a0c1235d6beb05516f2fc6 Mon Sep 17 00:00:00 2001 From: noferini <9963644+noferini@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:09:03 +0200 Subject: [PATCH 0278/2205] fix bad truncation when filling TOF dia --- Detectors/TOF/base/src/WindowFiller.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Detectors/TOF/base/src/WindowFiller.cxx b/Detectors/TOF/base/src/WindowFiller.cxx index 829fd05f97629..0362222b55bf5 100644 --- a/Detectors/TOF/base/src/WindowFiller.cxx +++ b/Detectors/TOF/base/src/WindowFiller.cxx @@ -196,13 +196,14 @@ void WindowFiller::fillOutputContainer(std::vector& digits) // check if patterns are in the current row unsigned int initrow = mFirstIR.orbit * Geo::NWINDOW_IN_ORBIT; for (std::vector::reverse_iterator it = mCratePatterns.rbegin(); it != mCratePatterns.rend(); ++it) { - //printf("pattern row=%ld current=%ld\n",it->row - initrow,mReadoutWindowCurrent); + unsigned int irow = it->row; + // printf("pattern row=%ld (%u - %u) current=%ld\n",irow - initrow,irow,initrow,mReadoutWindowCurrent); - if (it->row - initrow > mReadoutWindowCurrent) { + if (irow - initrow > mReadoutWindowCurrent) { break; } - if (it->row - initrow < mReadoutWindowCurrent) { // this should not happen + if (irow - initrow < mReadoutWindowCurrent) { // this should not happen LOG(error) << "One pattern skipped because appears to occur early of the current row " << it->row << " < " << mReadoutWindowCurrent << " ?!"; } else { uint32_t cpatt = it->pattern; From c5fbdd22c10f1c867b4d9f74d91ce9b41e4efd4b Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 24 Sep 2024 21:09:56 +0200 Subject: [PATCH 0279/2205] ITS: Track Follower changes + study (#13536) * ITS: Track Follower changes Signed-off-by: Felix Schlepper * ITS: Add Extension Study Signed-off-by: Felix Schlepper --------- Signed-off-by: Felix Schlepper --- .../ITS/include/DataFormatsITS/TrackITS.h | 7 +- .../Detectors/ITSMFT/ITS/src/TrackITS.cxx | 10 +- .../ITS/postprocessing/studies/CMakeLists.txt | 3 +- .../include/ITSStudies/TrackExtension.h | 31 ++ .../studies/src/TrackExtension.cxx | 475 ++++++++++++++++++ .../standalone-postprocessing-workflow.cxx | 22 +- .../tracking/include/ITStracking/TimeFrame.h | 4 + .../include/ITStracking/TrackerTraits.h | 4 +- Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx | 7 +- .../ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 27 +- 10 files changed, 553 insertions(+), 37 deletions(-) create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx diff --git a/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h b/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h index a6772751e04b5..e9931b89ecd4a 100644 --- a/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h +++ b/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h @@ -101,8 +101,9 @@ class TrackITS : public o2::track::TrackParCov GPUhdi() void setPattern(uint32_t p) { mPattern = p; } GPUhdi() uint32_t getPattern() const { return mPattern; } - bool hasHitOnLayer(int i) const { return mPattern & (0x1 << i); } - bool isFakeOnLayer(int i) const { return !(mPattern & (0x1 << (16 + i))); } + bool hasHitOnLayer(uint32_t i) const { return mPattern & (0x1 << i); } + bool isFakeOnLayer(uint32_t i) const { return !(mPattern & (0x1 << (16 + i))); } + bool isExtendedOnLayer(uint32_t i) const { return (mPattern & (0x1 << (24 + i))); } // only correct if getNClusters <= 8 on layers <= 8 uint32_t getLastClusterLayer() const { uint32_t r{0}, v{mPattern & ((1 << 16) - 1)}; @@ -119,7 +120,7 @@ class TrackITS : public o2::track::TrackParCov } return s; } - int getNFakeClusters(); + int getNFakeClusters() const; void setNextROFbit(bool toggle = true) { mClusterSizes = toggle ? (mClusterSizes | kNextROF) : (mClusterSizes & ~kNextROF); } bool hasHitInNextROF() const { return mClusterSizes & kNextROF; } diff --git a/DataFormats/Detectors/ITSMFT/ITS/src/TrackITS.cxx b/DataFormats/Detectors/ITSMFT/ITS/src/TrackITS.cxx index 61080ba7261a1..0244756647120 100644 --- a/DataFormats/Detectors/ITSMFT/ITS/src/TrackITS.cxx +++ b/DataFormats/Detectors/ITSMFT/ITS/src/TrackITS.cxx @@ -107,15 +107,15 @@ bool TrackITS::isBetter(const TrackITS& best, float maxChi2) const return false; } -int TrackITS::getNFakeClusters() +int TrackITS::getNFakeClusters() const { int nFake{0}; - int firstClus = getFirstClusterLayer(); - int lastClus = firstClus + getNClusters(); - for (int iCl{firstClus}; iCl < lastClus; ++iCl) { + auto firstClus = getFirstClusterLayer(); + auto lastClus = firstClus + getNClusters(); + for (auto iCl{firstClus}; iCl < lastClus; ++iCl) { if (hasHitOnLayer(iCl) && isFakeOnLayer(iCl)) { ++nFake; } } return nFake; -} \ No newline at end of file +} diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt index fd9074d5b6b6a..d1205aebbccfc 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt @@ -16,6 +16,7 @@ o2_add_library(ITSPostprocessing src/ITSStudiesConfigParam.cxx src/AnomalyStudy.cxx src/TrackCheck.cxx + src/TrackExtension.cxx src/Helpers.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTracking O2::GlobalTrackingWorkflowReaders @@ -28,4 +29,4 @@ o2_target_root_dictionary(ITSPostprocessing HEADERS include/ITSStudies/ITSStudiesConfigParam.h include/ITSStudies/TrackCuts.h include/ITSStudies/TrackMethods.h - LINKDEF src/ITSStudiesLinkDef.h) \ No newline at end of file + LINKDEF src/ITSStudiesLinkDef.h) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h new file mode 100644 index 0000000000000..2567000746559 --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_TRACK_EXTENSION_STUDY_H +#define O2_TRACK_EXTENSION_STUDY_H + +#include "Framework/DataProcessorSpec.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" + +namespace o2 +{ +namespace steer +{ +class MCKinematicsReader; +} +namespace its::study +{ +using mask_t = o2::dataformats::GlobalTrackID::mask_t; +o2::framework::DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader); +} // namespace its::study + +} // namespace o2 +#endif diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx new file mode 100644 index 0000000000000..364a354c700b6 --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx @@ -0,0 +1,475 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "CommonUtils/TreeStreamRedirector.h" +#include "DataFormatsGlobalTracking/RecoContainer.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/Task.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITSStudies/Helpers.h" +#include "ITSStudies/TrackExtension.h" +#include "SimulationDataFormat/MCTrack.h" +#include "Steer/MCKinematicsReader.h" + +#include + +#include "TFile.h" + +namespace o2::its::study +{ +using namespace o2::framework; +using namespace o2::globaltracking; + +using GTrackID = o2::dataformats::GlobalTrackID; +using o2::steer::MCKinematicsReader; +class TrackExtensionStudy : public Task +{ + struct ParticleInfo { + int event; + int pdg; + float pt; + float eta; + float phi; + int mother; + int first; + float vx; + float vy; + float vz; + uint8_t clusters = 0u; + uint8_t fakeClusters = 0u; + uint8_t isReco = 0u; + uint8_t isFake = 0u; + bool isPrimary = false; + unsigned char storedStatus = 2; /// not stored = 2, fake = 1, good = 0 + int prodProcess; + o2::its::TrackITS track; + MCTrack mcTrack; + }; + + public: + TrackExtensionStudy(std::shared_ptr dr, + mask_t src, + bool useMC, + std::shared_ptr kineReader, + std::shared_ptr gr) : mDataRequest(dr), mTracksSrc(src), mKineReader(kineReader), mGGCCDBRequest(gr) + { + if (useMC) { + LOGP(info, "Read MCKine reader with {} sources", mKineReader->getNSources()); + } + } + + ~TrackExtensionStudy() final = default; + void init(InitContext& /*ic*/) final; + void run(ProcessingContext& /*pc*/) final; + void endOfStream(EndOfStreamContext& /*ec*/) final; + void process(); + + private: + static constexpr std::array mBitPatternsBefore{15, 30, 31, 60, 62, 63, 120, 124, 126}; + static constexpr std::array mBitPatternsAfter{31, 47, 61, 62, 63, 79, 94, 95, 111, 121, 122, 123, 124, 125, 126, 127}; + + void updateTimeDependentParams(ProcessingContext& pc); + std::string mOutFileName = "TrackExtensionStudy.root"; + std::shared_ptr mKineReader; + GeometryTGeo* mGeometry{}; + + gsl::span mTracksROFRecords; + gsl::span mTracks; + gsl::span mTracksMCLabels; + gsl::span mClusters; + gsl::span mInputITSidxs; + const o2::dataformats::MCLabelContainer* mClustersMCLCont{}; + + GTrackID::mask_t mTracksSrc{}; + std::shared_ptr mDataRequest; + std::vector>> mParticleInfo; // src/event/track + unsigned short mMask = 0x7f; + + std::shared_ptr mGGCCDBRequest; + std::unique_ptr mStream; + bool mWithTree{false}; + + std::unique_ptr mHTrackCounts; + std::unique_ptr mHClustersCounts; + std::unique_ptr mHLengthAny, mHLengthGood, mHLengthFake; + std::unique_ptr mHChi2Any, mHChi2Good, mHChi2Fake; + std::unique_ptr mHPtAny, mHPtGood, mHPtFake; + std::unique_ptr mHExtensionAny, mHExtensionGood, mHExtensionFake; + std::unique_ptr mHExtensionPatternsAny, mHExtensionPatternsGood, mHExtensionPatternsFake; +}; + +void TrackExtensionStudy::init(InitContext& ic) +{ + o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); + mWithTree = ic.options().get("with-tree"); + + constexpr size_t effHistBins = 100; + constexpr float effPtCutLow = 0.01; + constexpr float effPtCutHigh = 10.; + auto xbins = helpers::makeLogBinning(effHistBins, effPtCutLow, effPtCutHigh); + + // Track Counting + mHTrackCounts = std::make_unique("hTrackCounts", "Track Stats", 10, 0, 10); + mHTrackCounts->GetXaxis()->SetBinLabel(1, "Total Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(2, "Normal ANY Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(3, "Normal GOOD Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(4, "Normal FAKE Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(5, "Extended ANY Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(6, "Extended GOOD Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(7, "Extended FAKE Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(8, "Extended FAKE BEFORE Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(9, "Extended FAKE AFTER Tracks"); + mHTrackCounts->GetXaxis()->SetBinLabel(10, "Extended FAKE BEFORE&AFTER Tracks"); + + // Cluster Counting + mHClustersCounts = std::make_unique("hClusterCounts", "Cluster Stats", 5, 0, 5); + mHClustersCounts->GetXaxis()->SetBinLabel(1, "Total Clusters"); + mHClustersCounts->GetXaxis()->SetBinLabel(2, "Tracking"); + mHClustersCounts->GetXaxis()->SetBinLabel(3, "Extension"); + mHClustersCounts->GetXaxis()->SetBinLabel(4, "Good Extension"); + mHClustersCounts->GetXaxis()->SetBinLabel(5, "Fake Extension"); + + // Length + mHLengthAny = std::make_unique("hLengthAny", "Extended Tracks Length (ANY);NCluster;Entries", 5, 3, 8); + mHLengthGood = std::make_unique("hLengthGood", "Extended Tracks Length (GOOD);NCluster;Entries", 5, 3, 8); + mHLengthFake = std::make_unique("hLengthFake", "Extended Tracks Length (FAKE);NCluster;Entries", 5, 3, 8); + + // Chi2 + mHChi2Any = std::make_unique("hChi2Any", "Extended Tracks Length (ANY);#chi^{2};Entries", 50, 0, 100); + mHChi2Good = std::make_unique("hChi2Good", "Extended Tracks Length (GOOD);#chi^{2};Entries", 50, 0, 100); + mHChi2Fake = std::make_unique("hChi2Fake", "Extended Tracks Length (FAKE);#chi^{2};Entries", 50, 0, 100); + + // Pt + mHPtAny = std::make_unique("hPtAny", "Extended Tracks Length (ANY);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); + mHPtGood = std::make_unique("hPtGood", "Extended Tracks Length (GOOD);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); + mHPtFake = std::make_unique("hPtFake", "Extended Tracks Length (FAKE);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); + + // Length + mHExtensionAny = std::make_unique("hExtensionAny", "Extended Tracks Length (ANY);Extended Layer;Entries", 7, 0, 7); + mHExtensionGood = std::make_unique("hExtensionGood", "Extended Tracks Length (GOOD);Extended Layer;Entries", 7, 0, 7); + mHExtensionFake = std::make_unique("hExtensionFake", "Extended Tracks Length (FAKE);Extended Layer;Entries", 7, 0, 7); + + // Patterns + auto makePatternAxisLabels = [&](TH1* h) { + for (int i{1}; i <= h->GetXaxis()->GetNbins(); ++i) { + h->GetXaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsBefore[i - 1]).c_str()); + } + for (int i{1}; i <= h->GetYaxis()->GetNbins(); ++i) { + h->GetYaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsAfter[i - 1]).c_str()); + } + }; + mHExtensionPatternsAny = std::make_unique("hExtensionPatternsAny", "Extended Tracks Pattern (ANY);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + makePatternAxisLabels(mHExtensionPatternsAny.get()); + mHExtensionPatternsGood = std::make_unique("hExtensionPatternsGood", "Extended Tracks Pattern (GOOD);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + makePatternAxisLabels(mHExtensionPatternsGood.get()); + mHExtensionPatternsFake = std::make_unique("hExtensionPatternsFake", "Extended Tracks Pattern (FAKE);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + makePatternAxisLabels(mHExtensionPatternsFake.get()); + + mStream = std::make_unique(mOutFileName.c_str(), "RECREATE"); +} + +void TrackExtensionStudy::run(ProcessingContext& pc) +{ + o2::globaltracking::RecoContainer recoData; + recoData.collectData(pc, *mDataRequest); + updateTimeDependentParams(pc); + + mTracksROFRecords = recoData.getITSTracksROFRecords(); + mTracks = recoData.getITSTracks(); + mTracksMCLabels = recoData.getITSTracksMCLabels(); + mClusters = recoData.getITSClusters(); + mClustersMCLCont = recoData.getITSClustersMCLabels(); + mInputITSidxs = recoData.getITSTracksClusterRefs(); + + mHClustersCounts->SetBinContent(1, mClusters.size()); + + LOGP(info, "** Found in {} rofs:\n\t- {} clusters with {} labels\n\t- {} tracks with {} labels", + mTracksROFRecords.size(), mClusters.size(), mClustersMCLCont->getIndexedSize(), mTracks.size(), mTracksMCLabels.size()); + LOGP(info, "** Found {} sources from kinematic files", mKineReader->getNSources()); + + process(); +} + +void TrackExtensionStudy::process() +{ + LOGP(info, "** Filling particle table ... "); + mParticleInfo.resize(mKineReader->getNSources()); // sources + for (int iSource{0}; iSource < mKineReader->getNSources(); ++iSource) { + mParticleInfo[iSource].resize(mKineReader->getNEvents(iSource)); // events + for (int iEvent{0}; iEvent < mKineReader->getNEvents(iSource); ++iEvent) { + mParticleInfo[iSource][iEvent].resize(mKineReader->getTracks(iSource, iEvent).size()); // tracks + for (auto iPart{0}; iPart < mKineReader->getTracks(iEvent).size(); ++iPart) { + auto& part = mKineReader->getTracks(iSource, iEvent)[iPart]; + mParticleInfo[iSource][iEvent][iPart].event = iEvent; + mParticleInfo[iSource][iEvent][iPart].pdg = part.GetPdgCode(); + mParticleInfo[iSource][iEvent][iPart].pt = part.GetPt(); + mParticleInfo[iSource][iEvent][iPart].phi = part.GetPhi(); + mParticleInfo[iSource][iEvent][iPart].eta = part.GetEta(); + mParticleInfo[iSource][iEvent][iPart].vx = part.Vx(); + mParticleInfo[iSource][iEvent][iPart].vy = part.Vy(); + mParticleInfo[iSource][iEvent][iPart].vz = part.Vz(); + mParticleInfo[iSource][iEvent][iPart].isPrimary = part.isPrimary(); + mParticleInfo[iSource][iEvent][iPart].mother = part.getMotherTrackId(); + mParticleInfo[iSource][iEvent][iPart].prodProcess = part.getProcess(); + } + } + } + LOGP(info, "** Creating particle/clusters correspondance ... "); + for (auto iSource{0}; iSource < mParticleInfo.size(); ++iSource) { + for (auto iCluster{0}; iCluster < mClusters.size(); ++iCluster) { + auto labs = mClustersMCLCont->getLabels(iCluster); // ideally I can have more than one label per cluster + for (auto& lab : labs) { + if (!lab.isValid()) { + continue; // We want to skip channels related to noise, e.g. sID = 99: QED + } + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + auto& cluster = mClusters[iCluster]; + auto layer = mGeometry->getLayer(cluster.getSensorID()); + mParticleInfo[srcID][evID][trackID].clusters |= (1 << layer); + if (fake) { + mParticleInfo[srcID][evID][trackID].fakeClusters |= (1 << layer); + } + } + } + } + + LOGP(info, "** Analysing tracks ... "); + int unaccounted{0}, good{0}, fakes{0}, extended{0}; + for (auto iTrack{0}; iTrack < mTracks.size(); ++iTrack) { + const auto& lab = mTracksMCLabels[iTrack]; + if (!lab.isValid()) { + unaccounted++; + continue; + } + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + + if (srcID == 99) { // skip QED + unaccounted++; + continue; + } + + for (int iLayer{0}; iLayer < 7; ++iLayer) { + if (mTracks[iTrack].isExtendedOnLayer(iLayer)) { + ++extended; + break; + } + } + + mParticleInfo[srcID][evID][trackID].isReco += !fake; + mParticleInfo[srcID][evID][trackID].isFake += fake; + if (mTracks[iTrack].isBetter(mParticleInfo[srcID][evID][trackID].track, 1.e9)) { + mParticleInfo[srcID][evID][trackID].storedStatus = fake; + mParticleInfo[srcID][evID][trackID].track = mTracks[iTrack]; + mParticleInfo[srcID][evID][trackID].mcTrack = *mKineReader->getTrack(lab); + } + fakes += fake; + good += !fake; + } + LOGP(info, "** Some statistics:"); + LOGP(info, "\t- Total number of tracks: {}", mTracks.size()); + LOGP(info, "\t- Total number of tracks not corresponding to particles: {} ({:.2f} %)", unaccounted, unaccounted * 100. / mTracks.size()); + LOGP(info, "\t- Total number of fakes: {} ({:.2f} %)", fakes, fakes * 100. / mTracks.size()); + LOGP(info, "\t- Total number of good: {} ({:.2f} %)", good, good * 100. / mTracks.size()); + LOGP(info, "\t- Total number of extensions: {} ({:.2f} %)", extended, extended * 100. / mTracks.size()); + + LOGP(info, "** Filling histograms ... "); + for (auto iTrack{0}; iTrack < mTracks.size(); ++iTrack) { + auto& lab = mTracksMCLabels[iTrack]; + if (!lab.isValid()) { + unaccounted++; + continue; + } + int trackID, evID, srcID; + bool fake; + lab.get(trackID, evID, srcID, fake); + const auto& part = mParticleInfo[srcID][evID][trackID]; + if (!part.isPrimary) { + continue; + } + const auto& trk = part.track; + mHTrackCounts->Fill(0); + + std::bitset<7> extPattern{0}; + for (int iLayer{0}; iLayer < 7; ++iLayer) { + if (trk.isExtendedOnLayer(iLayer)) { + extPattern.set(iLayer); + } + } + + if (!extPattern.any()) { + mHTrackCounts->Fill(1); + if (part.isReco || !part.isFake) { + mHTrackCounts->Fill(2); + } else { + mHTrackCounts->Fill(3); + } + continue; + } + + if (mWithTree) { + std::array xyz{(float)part.mcTrack.GetStartVertexCoordinatesX(), (float)part.mcTrack.GetStartVertexCoordinatesY(), (float)part.mcTrack.GetStartVertexCoordinatesZ()}; + std::array pxyz{(float)part.mcTrack.GetStartVertexMomentumX(), (float)part.mcTrack.GetStartVertexMomentumY(), (float)part.mcTrack.GetStartVertexMomentumZ()}; + auto pdg = O2DatabasePDG::Instance()->GetParticle(part.pdg); + if (pdg == nullptr) { + LOGP(fatal, "MC info not available"); + } + auto mcTrk = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pdg->Charge() / 3.), true); + (*mStream) << "tree" + << "trk=" << trk + << "mcTrk=" << mcTrk + << "\n"; + } + + mHTrackCounts->Fill(4); + mHLengthAny->Fill(trk.getNClusters()); + mHChi2Any->Fill(trk.getChi2()); + mHPtAny->Fill(trk.getPt()); + if (part.isReco || !part.isFake) { + mHTrackCounts->Fill(5); + mHLengthGood->Fill(trk.getNClusters()); + mHChi2Good->Fill(trk.getChi2()); + mHPtGood->Fill(trk.getPt()); + } else { + mHTrackCounts->Fill(6); + mHLengthFake->Fill(trk.getNClusters()); + mHChi2Fake->Fill(trk.getChi2()); + mHPtFake->Fill(trk.getPt()); + } + + std::bitset<7> clusPattern{static_cast(trk.getPattern())}; + for (int iLayer{0}; iLayer < 7; ++iLayer) { + if (extPattern.test(iLayer)) { + extPattern.set(iLayer); + mHExtensionAny->Fill(iLayer); + if (part.isReco || !part.isFake) { + mHExtensionGood->Fill(iLayer); + } else { + mHExtensionFake->Fill(iLayer); + } + + if ((part.fakeClusters & (0x1 << iLayer)) == 0) { + mHClustersCounts->Fill(4); + } else { + mHClustersCounts->Fill(5); + } + } + } + std::bitset<7> oldPattern{clusPattern & ~extPattern}; + auto clusN = clusPattern.to_ulong(); + auto clusIdx = std::distance(std::begin(mBitPatternsAfter), std::find(std::begin(mBitPatternsAfter), std::end(mBitPatternsAfter), clusN)); + auto oldN = oldPattern.to_ulong(); + auto oldIdx = std::distance(std::begin(mBitPatternsBefore), std::find(std::begin(mBitPatternsBefore), std::end(mBitPatternsBefore), oldN)); + mHExtensionPatternsAny->Fill(oldIdx, clusIdx); + if (part.isReco || !part.isFake) { + mHExtensionPatternsGood->Fill(oldIdx, clusIdx); + } else { + mHExtensionPatternsFake->Fill(oldIdx, clusIdx); + } + + // old pattern + bool oldFake{false}, newFake{false}; + for (int iLayer{0}; iLayer < 7; ++iLayer) { + if (trk.isFakeOnLayer(iLayer)) { + if (oldPattern.test(iLayer)) { + oldFake = true; + } else if (extPattern.test(iLayer)) { + newFake = true; + } + } + } + + if (oldFake && newFake) { + mHTrackCounts->Fill(9); + } else if (oldFake) { + mHTrackCounts->Fill(7); + } else if (newFake) { + mHTrackCounts->Fill(8); + } + + mHClustersCounts->SetBinContent(2, mHClustersCounts->GetBinContent(2) + oldPattern.count()); + mHClustersCounts->SetBinContent(3, mHClustersCounts->GetBinContent(3) + extPattern.count()); + } +} + +void TrackExtensionStudy::updateTimeDependentParams(ProcessingContext& pc) +{ + static bool initOnceDone = false; + o2::base::GRPGeomHelper::instance().checkUpdates(pc); + if (!initOnceDone) { // this params need to be queried only once + initOnceDone = true; + mGeometry = GeometryTGeo::Instance(); + mGeometry->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); + } +} + +void TrackExtensionStudy::endOfStream(EndOfStreamContext& ec) +{ + LOGP(info, "Writing results to {}", mOutFileName); + mStream->GetFile()->cd(); + + mHTrackCounts->Write(); + mHClustersCounts->Write(); + + mHLengthAny->Write(); + mHLengthGood->Write(); + mHLengthFake->Write(); + + mHChi2Any->Write(); + mHChi2Good->Write(); + mHChi2Fake->Write(); + + mHPtAny->Write(); + mHPtGood->Write(); + mHPtFake->Write(); + + mHExtensionAny->Write(); + mHExtensionGood->Write(); + mHExtensionFake->Write(); + + mHExtensionPatternsAny->Write(); + mHExtensionPatternsGood->Write(); + mHExtensionPatternsFake->Write(); + + mStream->Close(); +} + +DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader) +{ + std::vector outputs; + auto dataRequest = std::make_shared(); + dataRequest->requestTracks(srcTracksMask, useMC); + dataRequest->requestClusters(srcClustersMask, useMC); + + auto ggRequest = std::make_shared(false, // orbitResetTime + true, // GRPECS=true + false, // GRPLHCIF + true, // GRPMagField + true, // askMatLUT + o2::base::GRPGeomRequest::Aligned, // geometry + dataRequest->inputs, + true); + + return DataProcessorSpec{ + "its-study-track-extension", + dataRequest->inputs, + outputs, + AlgorithmSpec{adaptFromTask(dataRequest, srcTracksMask, useMC, kineReader, ggRequest)}, + Options{{"with-tree", o2::framework::VariantType::Bool, false, {"Produce in addition a tree"}}}}; +} + +} // namespace o2::its::study diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx index 5a6975df35472..66844255536a1 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx @@ -23,6 +23,7 @@ #include "ITSStudies/PIDStudy.h" #include "ITSStudies/AnomalyStudy.h" #include "ITSStudies/TrackCheck.h" +#include "ITSStudies/TrackExtension.h" #include "Steer/MCKinematicsReader.h" using namespace o2::framework; @@ -49,6 +50,7 @@ void customize(std::vector& workflowOptions) {"track-study", VariantType::Bool, false, {"Perform the track study"}}, {"impact-parameter-study", VariantType::Bool, false, {"Perform the impact parameter study"}}, {"anomaly-study", VariantType::Bool, false, {"Perform the anomaly study"}}, + {"track-extension-study", VariantType::Bool, false, {"Perform the track extension study"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; o2::raw::HBFUtilsInitializer::addConfigOption(options, "o2_tfidinfo.root"); std::swap(workflowOptions, options); @@ -75,8 +77,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); srcCls = GID::getSourcesMask(configcontext.options().get("cluster-sources")); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); - // o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); - // o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); specs.emplace_back(o2::its::study::getImpactParameterStudy(srcTrc, srcCls, useMC)); } if (configcontext.options().get("cluster-size-study")) { @@ -84,8 +84,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); srcCls = GID::getSourcesMask(configcontext.options().get("cluster-sources")); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); - // o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); - // o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); specs.emplace_back(o2::its::study::getAvgClusSizeStudy(srcTrc, srcCls, useMC, mcKinematicsReader)); } if (configcontext.options().get("pid-study")) { @@ -93,8 +91,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); srcCls = GID::getSourcesMask(configcontext.options().get("cluster-sources")); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); - // o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); - // o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); specs.emplace_back(o2::its::study::getPIDStudy(srcTrc, srcCls, useMC, mcKinematicsReader)); } if (configcontext.options().get("track-study")) { @@ -105,20 +101,22 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); } specs.emplace_back(o2::its::study::getTrackCheckStudy(GID::getSourcesMask("ITS"), GID::getSourcesMask("ITS"), useMC, mcKinematicsReader)); - // o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); - // o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); } if (configcontext.options().get("anomaly-study")) { anyStudy = true; - // srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); srcCls = GID::getSourcesMask(configcontext.options().get("cluster-sources")); if (!configcontext.options().get("input-from-upstream")) { o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); } - // o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); - // o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); specs.emplace_back(o2::its::study::getAnomalyStudy(srcCls, useMC)); } + if (configcontext.options().get("track-extension-study")) { + anyStudy = true; + srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); + srcCls = GID::getSourcesMask("ITS"); + o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); + specs.emplace_back(o2::its::study::getTrackExtensionStudy(srcTrc, srcCls, useMC, mcKinematicsReader)); + } if (!anyStudy) { LOGP(info, "No study selected, dryrunning"); } @@ -128,4 +126,4 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::conf::ConfigurableParam::writeINI("o2_its_standalone_configuration.ini"); return std::move(specs); -} \ No newline at end of file +} diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index 6f960aa251432..08e50cf9ea824 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -173,6 +173,8 @@ class TimeFrame int getNumberOfNeighbours() const; size_t getNumberOfTracks() const; size_t getNumberOfUsedClusters() const; + auto getNumberOfExtendedTracks() const { return mNExtendedTracks; } + auto getNumberOfUsedExtendedClusters() const { return mNExtendedUsedClusters; } bool checkMemory(unsigned long max) { return getArtefactsMemory() < max; } unsigned long getArtefactsMemory(); @@ -270,6 +272,8 @@ class TimeFrame std::vector> mTrackletsLookupTable; std::vector> mUsedClusters; int mNrof = 0; + int mNExtendedTracks{0}; + int mNExtendedUsedClusters{0}; std::vector mROFramesPV = {0}; std::vector mPrimaryVertices; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h index 1930bc8761c66..207dd5d3d50f5 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h @@ -142,9 +142,9 @@ inline const int4 TrackerTraits::getBinsRect(const int layerIndex, float phi, fl float z1, float z2, float maxdeltaz) { const float zRangeMin = o2::gpu::GPUCommonMath::Min(z1, z2) - maxdeltaz; - const float phiRangeMin = phi - maxdeltaphi; + const float phiRangeMin = (maxdeltaphi > constants::math::Pi) ? 0.f : phi - maxdeltaphi; const float zRangeMax = o2::gpu::GPUCommonMath::Max(z1, z2) + maxdeltaz; - const float phiRangeMax = phi + maxdeltaphi; + const float phiRangeMax = (maxdeltaphi > constants::math::Pi) ? constants::math::TwoPi : phi + maxdeltaphi; if (zRangeMax < -mTrkParams[0].LayerZ[layerIndex + 1] || zRangeMin > mTrkParams[0].LayerZ[layerIndex + 1] || zRangeMin > zRangeMax) { diff --git a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx index 8676de0c980cd..9a43402a2e93a 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx @@ -109,7 +109,12 @@ void Tracker::clustersToTracks(std::function logger, std::f logger(fmt::format(" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours)); logger(fmt::format(" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->getNumberOfTracks(), timeRoads)); total += timeTracklets + timeCells + timeNeighbours + timeRoads; - total += evaluateTask(&Tracker::extendTracks, "Extending tracks", logger, iteration); + if (mTrkParams[iteration].UseTrackFollower) { + int nExtendedTracks{-mTimeFrame->mNExtendedTracks}, nExtendedClusters{-mTimeFrame->mNExtendedUsedClusters}; + auto timeExtending = evaluateTask(&Tracker::extendTracks, "Extending tracks", [](const std::string&) {}, iteration); + total += timeExtending; + logger(fmt::format(" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->mNExtendedTracks, nExtendedClusters + mTimeFrame->mNExtendedUsedClusters, timeExtending)); + } } total += evaluateTask(&Tracker::findShortPrimaries, "Short primaries finding", logger); diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index 4ea39e29310bf..4763508adc003 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -675,16 +675,11 @@ void TrackerTraits::findRoads(const int iteration) void TrackerTraits::extendTracks(const int iteration) { - if (!mTrkParams.back().UseTrackFollower) { - return; - } for (int rof{0}; rof < mTimeFrame->getNrof(); ++rof) { for (auto& track : mTimeFrame->getTracks(rof)) { - /// TODO: track refitting is missing! - int ncl{track.getNClusters()}; auto backup{track}; bool success{false}; - if (track.getLastClusterLayer() != mTrkParams[0].NLayers - 1) { + if (track.getLastClusterLayer() != mTrkParams[iteration].NLayers - 1) { success = success || trackFollowing(&track, rof, true, iteration); } if (track.getFirstClusterLayer() != 0) { @@ -694,7 +689,7 @@ void TrackerTraits::extendTracks(const int iteration) /// We have to refit the track track.resetCovariance(); track.setChi2(0); - bool fitSuccess = fitTrack(track, 0, mTrkParams[0].NLayers, 1, mTrkParams[0].MaxChi2ClusterAttachment, mTrkParams[0].MaxChi2NDF); + bool fitSuccess = fitTrack(track, 0, mTrkParams[iteration].NLayers, 1, mTrkParams[iteration].MaxChi2ClusterAttachment, mTrkParams[0].MaxChi2NDF); if (!fitSuccess) { track = backup; continue; @@ -702,13 +697,19 @@ void TrackerTraits::extendTracks(const int iteration) track.getParamOut() = track; track.resetCovariance(); track.setChi2(0); - fitSuccess = fitTrack(track, mTrkParams[0].NLayers - 1, -1, -1, mTrkParams[0].MaxChi2ClusterAttachment, mTrkParams[0].MaxChi2NDF, 50.); + fitSuccess = fitTrack(track, mTrkParams[iteration].NLayers - 1, -1, -1, mTrkParams[iteration].MaxChi2ClusterAttachment, mTrkParams[0].MaxChi2NDF, 50.); if (!fitSuccess) { track = backup; continue; } + mTimeFrame->mNExtendedTracks++; + mTimeFrame->mNExtendedUsedClusters += track.getNClusters() - backup.getNClusters(); + auto pattern = track.getPattern(); + auto diff = (pattern & ~backup.getPattern()) & 0xff; + pattern |= (diff << 24); + track.setPattern(pattern); /// Make sure that the newly attached clusters get marked as used - for (int iLayer{0}; iLayer < mTrkParams[0].NLayers; ++iLayer) { + for (int iLayer{0}; iLayer < mTrkParams[iteration].NLayers; ++iLayer) { if (track.getClusterIndex(iLayer) == constants::its::UnusedIndex) { continue; } @@ -859,12 +860,12 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co int iLayer = outward ? track->getLastClusterLayer() : track->getFirstClusterLayer(); while (iLayer != end) { iLayer += step; - const float& r = mTrkParams[iteration].LayerRadii[iLayer]; - float x; - if (!hypo.getXatLabR(r, x, mTimeFrame->getBz(), o2::track::DirAuto)) { + const float r = mTrkParams[iteration].LayerRadii[iLayer]; + float x{-999}; + if (!hypo.getXatLabR(r, x, mTimeFrame->getBz(), o2::track::DirAuto) || x <= 0.f) { continue; } - bool success{false}; + auto& hypoParam{outward ? hypo.getParamOut() : hypo.getParamIn()}; if (!propInstance->propagateToX(hypoParam, x, mTimeFrame->getBz(), PropagatorF::MAX_SIN_PHI, PropagatorF::MAX_STEP, mTrkParams[iteration].CorrType)) { From 05e0d455cc538f5c53b36292b311f0649fc9df30 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 25 Sep 2024 16:57:31 +0400 Subject: [PATCH 0280/2205] Demote to info the log about missing RCTInfo in ITS DCS agent --- Detectors/ITSMFT/ITS/workflow/src/DCSParserSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/ITS/workflow/src/DCSParserSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/DCSParserSpec.cxx index 533592df20f23..a9e1121077f02 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/DCSParserSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/DCSParserSpec.cxx @@ -475,7 +475,7 @@ void ITSDCSParser::pushToCCDB(ProcessingContext& pc) cdbman.setFatalWhenNull(false); auto ts = o2::ccdb::BasicCCDBManager::instance().getRunDuration(mRunNumber, false); if (ts.first < 0 || ts.second < 0) { - LOGP(error, "Failed to retrieve headers from CCDB with run number {}, << this->mRunNumber, will default to using the current time for timestamp information", mRunNumber); + LOGP(info, "Failed to retrieve headers from CCDB with run number {}, << this->mRunNumber, will default to using the current time for timestamp information", mRunNumber); tstart = o2::ccdb::getCurrentTimestamp(); tend = tstart + 365L * 24 * 3600 * 1000; } else { From fac9d914a6a4397fce594fb3bf080eda13ffa9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 26 Sep 2024 11:33:04 +0200 Subject: [PATCH 0281/2205] [HistogramRegistry] add string handling for template form (#13538) --- Framework/Core/include/Framework/HistogramRegistry.h | 8 ++++++++ Framework/Core/src/HistogramRegistry.cxx | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/HistogramRegistry.h b/Framework/Core/include/Framework/HistogramRegistry.h index c88525368e88a..f11fd3f263e9d 100644 --- a/Framework/Core/include/Framework/HistogramRegistry.h +++ b/Framework/Core/include/Framework/HistogramRegistry.h @@ -104,6 +104,8 @@ class HistogramRegistry std::shared_ptr add(char const* const name, char const* const title, const HistogramConfigSpec& histConfigSpec, bool callSumw2 = false); template std::shared_ptr add(char const* const name, char const* const title, HistType histType, const std::vector& axes, bool callSumw2 = false); + template + std::shared_ptr add(const std::string& name, char const* const title, HistType histType, const std::vector& axes, bool callSumw2 = false); void addClone(const std::string& source, const std::string& target); @@ -369,6 +371,12 @@ std::shared_ptr HistogramRegistry::add(char const* const name, char const* co } } +template +std::shared_ptr HistogramRegistry::add(const std::string& name, char const* const title, HistType histType, const std::vector& axes, bool callSumw2) +{ + return add(name.c_str(), title, histType, axes, callSumw2); +} + template std::shared_ptr HistogramRegistry::get(const HistName& histName) { diff --git a/Framework/Core/src/HistogramRegistry.cxx b/Framework/Core/src/HistogramRegistry.cxx index 806aae93be95e..c246fd752e5a1 100644 --- a/Framework/Core/src/HistogramRegistry.cxx +++ b/Framework/Core/src/HistogramRegistry.cxx @@ -121,7 +121,7 @@ HistPtr HistogramRegistry::add(char const* const name, char const* const title, HistPtr HistogramRegistry::add(const std::string& name, char const* const title, HistType histType, const std::vector& axes, bool callSumw2) { - return insert({name.c_str(), title, {histType, axes}, callSumw2}); + return add(name.c_str(), title, histType, axes, callSumw2); } // store a copy of an existing histogram (or group of histograms) under a different name From 0618a4a1c988589f121593c834a0fd92e3346138 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 26 Sep 2024 19:03:29 +0200 Subject: [PATCH 0282/2205] o2-sim: More universal timestamp setup This matters for workflows using o2sim_grp to pickup timestamps (like sim_challenge) and only changes the behaviour of o2-sim-serial. Fixes https://its.cern.ch/jira/browse/O2-5377 Also adding some notes in sim_challenge.sh --- macro/o2sim.C | 17 ++++++++++++++--- prodtests/sim_challenge.sh | 7 ++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/macro/o2sim.C b/macro/o2sim.C index 44db30293bb73..4bd2ff4e4d9cb 100644 --- a/macro/o2sim.C +++ b/macro/o2sim.C @@ -65,6 +65,17 @@ FairRunSim* o2sim_init(bool asservice, bool evalmat = false) auto& ccdbmgr = o2::ccdb::BasicCCDBManager::instance(); // fix the timestamp early uint64_t timestamp = confref.getTimestamp(); + // see if we have a run number but not a timestamp + auto run_number = confref.getRunNumber(); + if (run_number != -1) { + if (confref.getConfigData().mTimestampMode == o2::conf::TimeStampMode::kNow) { + // fix the time by talking to CCDB + auto [sor, eor] = ccdbmgr.getRunDuration(run_number); + LOG(info) << "Have run number. Fixing timestamp to " << sor; + timestamp = sor; + } + } + ccdbmgr.setTimestamp(timestamp); ccdbmgr.setURL(confref.getConfigData().mCCDBUrl); // try to verify connection @@ -163,12 +174,12 @@ FairRunSim* o2sim_init(bool asservice, bool evalmat = false) // add ALICE particles to TDatabasePDG singleton o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance()); - long runStart = confref.getTimestamp(); // this will signify "time of this MC" (might not coincide with start of Run) + long runStart = timestamp; { // store GRPobject o2::parameters::GRPObject grp; - if (confref.getRunNumber() != -1) { - grp.setRun(confref.getRunNumber()); + if (run_number != -1) { + grp.setRun(run_number); } else { grp.setRun(run->GetRunId()); } diff --git a/prodtests/sim_challenge.sh b/prodtests/sim_challenge.sh index 4de3b2902fc39..c879156195075 100755 --- a/prodtests/sim_challenge.sh +++ b/prodtests/sim_challenge.sh @@ -1,6 +1,11 @@ #!/bin/bash -# A simple chain of algorithms from MC to reco (and analysis) +# A linearized and simplified chain of algorithms from MC to reco (and analysis) for ALICE Run3. +# Please note that this script was originally provided as first and quick integration of +# algorithms in the MC pipeline (mainly for testing purposes). +# The script does, however, not represent a production setup and it is not maintained actively. +# The official MC configs and production system is maintained in O2DPG (https://github.com/AliceO2Group/O2DPG) +# and it is advised to use that one. Some documentation can be found here: https://aliceo2group.github.io/simulation/docs/o2dpgworkflow/ # ------------ LOAD UTILITY FUNCTIONS ---------------------------- . ${O2_ROOT}/share/scripts/jobutils.sh From 2d48d1b12f1d8d0e34fc359f9b5c57931f6ae6a3 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 27 Sep 2024 10:55:10 +0200 Subject: [PATCH 0283/2205] white space --- prodtests/sim_challenge.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prodtests/sim_challenge.sh b/prodtests/sim_challenge.sh index c879156195075..8c7cfb1a024b0 100755 --- a/prodtests/sim_challenge.sh +++ b/prodtests/sim_challenge.sh @@ -3,8 +3,8 @@ # A linearized and simplified chain of algorithms from MC to reco (and analysis) for ALICE Run3. # Please note that this script was originally provided as first and quick integration of # algorithms in the MC pipeline (mainly for testing purposes). -# The script does, however, not represent a production setup and it is not maintained actively. -# The official MC configs and production system is maintained in O2DPG (https://github.com/AliceO2Group/O2DPG) +# The script does, however, not represent a production setup and it is not maintained actively. +# The official MC configs and production system is maintained in O2DPG (https://github.com/AliceO2Group/O2DPG) # and it is advised to use that one. Some documentation can be found here: https://aliceo2group.github.io/simulation/docs/o2dpgworkflow/ # ------------ LOAD UTILITY FUNCTIONS ---------------------------- From 813cce4df34ae92bf84ffeebd3bd34f90e06fd40 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 27 Sep 2024 11:02:59 +0200 Subject: [PATCH 0284/2205] Added examples to run EPOS4 on-the-fly (#13543) * Added examples to run EPOS4 on-the-fly --- run/SimExamples/HepMC_EPOS4/README.md | 67 +++++++++++ run/SimExamples/HepMC_EPOS4/epos.sh | 30 +++++ run/SimExamples/HepMC_EPOS4/example.optns | 32 ++++++ run/SimExamples/HepMC_EPOS4/rundpg.sh | 132 ++++++++++++++++++++++ run/SimExamples/HepMC_EPOS4/rundpl.sh | 119 +++++++++++++++++++ run/SimExamples/HepMC_EPOS4/runo2sim.sh | 117 +++++++++++++++++++ 6 files changed, 497 insertions(+) create mode 100644 run/SimExamples/HepMC_EPOS4/README.md create mode 100755 run/SimExamples/HepMC_EPOS4/epos.sh create mode 100644 run/SimExamples/HepMC_EPOS4/example.optns create mode 100644 run/SimExamples/HepMC_EPOS4/rundpg.sh create mode 100755 run/SimExamples/HepMC_EPOS4/rundpl.sh create mode 100644 run/SimExamples/HepMC_EPOS4/runo2sim.sh diff --git a/run/SimExamples/HepMC_EPOS4/README.md b/run/SimExamples/HepMC_EPOS4/README.md new file mode 100644 index 0000000000000..94c50572cff9f --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/README.md @@ -0,0 +1,67 @@ + + +The usage of EPOS4 with the O2 machinery is presented in this short manual. +An in-depth explanation of the mechanisms behind the HepMC(3) data handling can be found in the +HepMC_fifo folder of the MC examples. The scripts use the `cmd` parameter of `GeneratorHepMC` +to spawn the EPOS4 generation via the `epos.sh` script. + +EPOS4 uses the outdated HepMC2 libraries, so this had to be specified in the steering scripts +of the generators configuration. If `HepMC.version=2` is removed then the scripts will not work +anymore. This is to say that the balance achieved with the configurations provided is easily +destroyed if the user base edits parts that are not understood completely. + +# Scripts description + +Four scripts are available to run the simulations +- **epos.sh** → starts the actual EPOS4 generation +- **runo2sim.sh** → allows the generation of events using o2-sim +- **rundpg.sh** → starts the DPG machinery for event generation +- **rundpl.sh** → starts the event generation with DPL + +In addition an example.optns file is provided to start EPOS4, but more can be found in the generator example folder +or in the website [epos4learn.web.cern.ch](https://epos4learn.docs.cern.ch/) where an extensive tutorial on the generator is provided. + +## epos.sh + +It can be run without the help of the other scripts to simply generate an .hepmc file or print +to the stdout the HepMC results. It it worth nothing though that EPOS4 must be loaded (via cvmfs through AliGenerators or O2sim for example) or installed. In this case the user should simply redirect the stdout to a file: +``` +./epos.sh -i test -s 234345 > test.hepmc +``` +This example shows all the functionalities of the script (which are implemented in a similar way inside +the generation steering scripts). In particular the `-i` flag allows to provide .optns parameters to EPOS4, +`-s` feeds the generator with a user seed, and the HepMC output is given by test.hepmc by redirecting the +stdout which will contain only the HepMC data thanks to the `-hepstd` flag set automatically in epos.sh and +the `set ihepmc 2` option which **MUST** be set in the option file (otherwise either an hepmc file will be created - ihepmc 1 - or nothing will be generated - missing ihepmc or != 1|2 ). + +It is important to note that setting an empty/null seed in the generator out of the box makes EPOS4 crash, so a protection was added in our steering epos.sh script which now generates a random number if 0 is provided. + +## runo2sim.sh, rundpg.sh and rundpl.sh + +The three scripts have little differences (especially in the first part), so they will be described together. They work after loading any O2sim version after the 20/09/2024 (included), since multiple modifications had to be performed on both EPOS4 and the introduction of AliGenO2 in order to be able to load both O2sim and EPOS4 simultaneously. + +If no parameters are provided to the scripts, they will run with default values (energy and nevents provided in the example.optns file), but few flags are available to change the settings of the generation: +- **-m , --more** → feeds the simulation with advanced parameters provided to the configuration key flags +- **-n , --nevents** → changes the number of events in the .optns file or gets the one in the file if no events are provided +- **-i , --input** → .optns filename to feed EPOS4, no extension must be set in the filename +- **-j , --jobs** → sets the number of workers (jobs) +- **-h , --help** → prints usage instructions +- **-e , --ecm** → sets the center-of-mass energy in the options file + +In the `rundpg.sh` script an additional flag is available +- **-t , --tf** → number of timeframes to be generated + +In this case the options file will be copied in each tf$n folder, otherwise the epos script won't be able to run with multiple timeframes. +In o2sim and DPG scripts the randomly generated seed is set directly, instead this is not feasible with the DPL one, given that the --seed option is not able to redirect this number to GeneratorHepMC. So a seed 0 is automatically given to epos.sh which generates a random number in return. + +Now the three scripts start to differ: + +- **runo2sim.sh** → o2-sim is launched +- **rundpg.sh** → first the o2dpg_sim_workflow.py script will be launched generating the json configuration, then the o2_dpg_workflow_runner.py script will start the workflow +- **rundpl.sh** → o2-sim-dpl-eventgen is executed piping its results to o2-sim-mctracks-to-aod and afterwards to o2-analysis-mctracks-to-aod-simple-task + +The last few lines of the scripts contain the execution of o2-sim, DPG worflow creator/runner and DPL software respectively, so this part can be modified by the users following their requirements. It's important not to delete from the configuration keys `GeneratorFileOrCmd.cmd=$cmd -i $optns;GeneratorFileOrCmd.bMaxSwitch=none;HepMC.version=2;` and it would be better to provide additional configurations via the -m flag. EPOS4 cannot set a maximum impact parameter value, so it's better to leave the bMaxSwitch to none, while the others serve the sole purpose of running successfully the generator using auto generated FIFOs. + + diff --git a/run/SimExamples/HepMC_EPOS4/epos.sh b/run/SimExamples/HepMC_EPOS4/epos.sh new file mode 100755 index 0000000000000..46a7dbfa27e5c --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/epos.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Script based on CRMC example +# EPOS4 option files must contain ihepmc set to 2 to print HepMC +# data on stdout. -hepmc flag is not needed anymore, but -hepstd is fundamental +# in order not to print useless information on stdout (a z-*optns*.mtr file will be created) + +optns="example" +seed=$RANDOM + +while test $# -gt 0 ; do + case $1 in + -i|--input) optns=$2 ; shift ;; + -s|--seed) seed=$2 ; shift ;; + -h|--help) usage; exit 0 ;; + esac + shift +done + +if [ ! -f $optns.optns ]; then + echo "Error: Options file $optns.optns not found" + exit 1 +fi + +if [ $seed -eq 0 ]; then + echo "Seed can't be 0, random number will be used" + seed=$RANDOM +fi + +# Or filters the stdout with only HepMC2 useful data +$EPOS4_ROOT/epos4/scripts/epos -hepstd -s $seed $optns | sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p' diff --git a/run/SimExamples/HepMC_EPOS4/example.optns b/run/SimExamples/HepMC_EPOS4/example.optns new file mode 100644 index 0000000000000..c2b067941e4e8 --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/example.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collision no hydro no hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 7000 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core off !core/corona not activated +hydro off !hydro not activated +eos off !eos not activated +hacas off !hadronic cascade not activated +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/run/SimExamples/HepMC_EPOS4/rundpg.sh b/run/SimExamples/HepMC_EPOS4/rundpg.sh new file mode 100644 index 0000000000000..93993f66bfbd6 --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/rundpg.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# +# This script shows how to start the DPG simulation machinery starting EPOS4 +# automatically while using the FIFOs generated internally by GeneratorHepMC + +# This script works only with O2sim version starting from the 20/09/2024 + +set -x +if [ ! "${EPOS4_ROOT}" ]; then + echo "This needs EPOS4 loaded; alienv enter ..." + exit 1 +fi + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + + +cmd="$PWD/epos.sh" +NEV=-1 +more="" +optns="example" +TF=1 +eCM=-1 +JOBS=2 + +usage() +{ + cat </dev/stderr + exit 3 + ;; + esac + shift +done + +echo "Options file: $optns" + +if [ ! -f $optns.optns ]; then + echo "Error: Options file $optns.optns not found" + exit 4 +fi + +# Set number of events in optns file +if [ ! $NEV -eq -1 ]; then + echo "Setting number of events to $NEV" + if grep -Fq "nfull" $optns.optns; then + sed -i "/nfull/c\set nfull $NEV" $optns.optns + else + echo "set nfull $NEV" >> $optns.optns + fi +else + echo "Number of events not set, checking optns file..." + if grep -Fq "nfull" $optns.optns; then + NEV=$(grep -F "nfull" $optns.optns | awk '{print $3}') + echo "Number of events set to $NEV" + else + echo "Error: Number of events not set in EPOS4" + exit 5 + fi +fi + +# Set ECM + +if [ ! $eCM -eq -1 ]; then + echo "Setting eCM to $eCM" + if grep -Fq "ecms" $optns.optns; then + sed -i "/ecms/c\set ecms $eCM" $optns.optns + else + echo "set ecms $eCM" >> $optns.optns + fi +else + echo "Energy not set, checking optns file..." + if grep -Fq "ecms" $optns.optns; then + eCM=$(grep -F "ecms" $optns.optns | awk '{print $3}') + echo "Energy set to $eCM" + else + echo "Error: eCM not set in EPOS4" + exit 6 + fi +fi + +# Copy options file in each timeframe folder +for i in $(seq 1 $TF); do + if [ ! -d tf$i ]; then + mkdir tf$i + fi + cp $optns.optns tf$i/$optns.optns +done + +# create workflow + +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM $eCM -ns $NEV -gen hepmc -tf $TF -j $JOBS \ + -interactionRate 500000 -confKey "GeneratorFileOrCmd.cmd=$cmd -i $optns;GeneratorFileOrCmd.bMaxSwitch=none;HepMC.version=2;${more}" + +# Run workflow +${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt aod --stdout-on-failure diff --git a/run/SimExamples/HepMC_EPOS4/rundpl.sh b/run/SimExamples/HepMC_EPOS4/rundpl.sh new file mode 100755 index 0000000000000..c3851175d08f4 --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/rundpl.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# +# This is a simple simulation example showing how to +# start EPOS4 generation automatically using cmd with hepmc output on FIFO +# and simultaneosly use o2-sim for transport + +# This script works only with O2sim version starting from the 20/09/2024 + +# EPOS4 and O2 must be loaded +set -x +if [ ! "${EPOS4_ROOT}" ]; then + echo "This needs EPOS4 loaded; alienv enter ..." + exit 1 +fi + +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 2 + +cmd="$PWD/epos.sh" +NEV=-1 +more="" +optns="example" +eCM=-1 +JOBS=2 + +usage() +{ + cat </dev/stderr + exit 3 + ;; + esac + shift +done + +echo "Options file: $optns" + +if [ ! -f $optns.optns ]; then + echo "Error: Options file $optns.optns not found" + exit 4 +fi + +# Set number of events in optns file +if [ ! $NEV -eq -1 ]; then + echo "Setting number of events to $NEV" + if grep -Fq "nfull" $optns.optns; then + sed -i "/nfull/c\set nfull $NEV" $optns.optns + else + echo "set nfull $NEV" >> $optns.optns + fi +else + echo "Number of events not set, checking optns file..." + if grep -Fq "nfull" $optns.optns; then + NEV=$(grep -F "nfull" $optns.optns | awk '{print $3}') + echo "Number of events set to $NEV" + else + echo "Error: Number of events not set in EPOS4" + exit 5 + fi +fi + +# Set ECM + +if [ ! $eCM -eq -1 ]; then + echo "Setting eCM to $eCM" + if grep -Fq "ecms" $optns.optns; then + sed -i "/ecms/c\set ecms $eCM" $optns.optns + else + echo "set ecms $eCM" >> $optns.optns + fi +else + echo "Energy not set, checking optns file..." + if grep -Fq "ecms" $optns.optns; then + eCM=$(grep -F "ecms" $optns.optns | awk '{print $3}') + echo "Energy set to $eCM" + else + echo "Error: eCM not set in EPOS4" + exit 6 + fi +fi + +# Starting simulation => seed is fed automatically to epos with the --seed flag. HepMC.version = 2 is mandatory +# otherwise the simulation won't work. +# Seed is automatically set to Random by the epos.sh script because the --seed option with o2-sim-dpl-eventgen does not feed the number to GeneratorHepMC + +o2-sim-dpl-eventgen -b --nEvents ${NEV} --generator hepmc --configKeyValues "GeneratorFileOrCmd.cmd=$cmd -i $optns;GeneratorFileOrCmd.bMaxSwitch=none;HepMC.version=2;${more}" |\ + o2-sim-mctracks-to-aod -b | o2-analysis-mctracks-to-aod-simple-task -b diff --git a/run/SimExamples/HepMC_EPOS4/runo2sim.sh b/run/SimExamples/HepMC_EPOS4/runo2sim.sh new file mode 100644 index 0000000000000..31698f39a87f0 --- /dev/null +++ b/run/SimExamples/HepMC_EPOS4/runo2sim.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +# +# This is a simple simulation example showing how to +# start EPOS4 generation automatically using cmd with hepmc output on FIFO +# and simultaneosly use o2-sim for transport + +# This script works only with O2sim version starting from the 20/09/2024 + +# EPOS4 and O2 must be loaded +set -x +if [ ! "${EPOS4_ROOT}" ]; then + echo "This needs EPOS4 loaded; alienv enter ..." + exit 1 +fi + +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 2 + +cmd="$PWD/epos.sh" +NEV=-1 +more="" +optns="example" +eCM=-1 +JOBS=2 + +usage() +{ + cat </dev/stderr + exit 3 + ;; + esac + shift +done + +echo "Options file: $optns" + +if [ ! -f $optns.optns ]; then + echo "Error: Options file $optns.optns not found" + exit 4 +fi + +# Set number of events in optns file +if [ ! $NEV -eq -1 ]; then + echo "Setting number of events to $NEV" + if grep -Fq "nfull" $optns.optns; then + sed -i "/nfull/c\set nfull $NEV" $optns.optns + else + echo "set nfull $NEV" >> $optns.optns + fi +else + echo "Number of events not set, checking optns file..." + if grep -Fq "nfull" $optns.optns; then + NEV=$(grep -F "nfull" $optns.optns | awk '{print $3}') + echo "Number of events set to $NEV" + else + echo "Error: Number of events not set in EPOS4" + exit 5 + fi +fi + +# Set ECM + +if [ ! $eCM -eq -1 ]; then + echo "Setting eCM to $eCM" + if grep -Fq "ecms" $optns.optns; then + sed -i "/ecms/c\set ecms $eCM" $optns.optns + else + echo "set ecms $eCM" >> $optns.optns + fi +else + echo "Energy not set, checking optns file..." + if grep -Fq "ecms" $optns.optns; then + eCM=$(grep -F "ecms" $optns.optns | awk '{print $3}') + echo "Energy set to $eCM" + else + echo "Error: eCM not set in EPOS4" + exit 6 + fi +fi + +# Starting simulation => seed is fed automatically to epos with the --seed flag. HepMC.version = 2 is mandatory +# otherwise the simulation won't work +o2-sim -j $JOBS -n ${NEV} -g hepmc --seed $RANDOM \ + --configKeyValues "GeneratorFileOrCmd.cmd=$cmd -i $optns;GeneratorFileOrCmd.bMaxSwitch=none;HepMC.version=2;${more}" From aa884647d60822c07f60430adfb9ce7f38ab2959 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:56:30 +0200 Subject: [PATCH 0285/2205] DPL: introduce a --data-processing-timeout (#13542) Used to force stop the data processing and start the calibration. In case it is larger than the exit-transition-timeout, the two will be coalesced into a single transition. For the time being the only side effect is to set the DeviceState::allowedProcessing and to terminate the source devices earlier than the data processing ones. Next PR will make sure that only calibrations are treated when DeviceState::allowedProcessing is set to ProcessingType::Calibration. --- .../Core/include/Framework/DeviceContext.h | 2 + .../Core/include/Framework/DeviceState.h | 10 +++++ Framework/Core/src/DataProcessingDevice.cxx | 43 ++++++++++++++++++- Framework/Core/src/DeviceSpecHelpers.cxx | 2 + Framework/Core/src/O2ControlHelpers.cxx | 9 +++- Framework/Core/src/runDataProcessing.cxx | 20 +++++---- .../test_FrameworkDataFlowToO2Control.cxx | 14 +++++- 7 files changed, 87 insertions(+), 13 deletions(-) diff --git a/Framework/Core/include/Framework/DeviceContext.h b/Framework/Core/include/Framework/DeviceContext.h index 3777e7f608b75..4593e5e819ccf 100644 --- a/Framework/Core/include/Framework/DeviceContext.h +++ b/Framework/Core/include/Framework/DeviceContext.h @@ -28,9 +28,11 @@ struct ComputingQuotaStats; struct DeviceContext { ComputingQuotaStats* quotaStats = nullptr; uv_timer_t* gracePeriodTimer = nullptr; + uv_timer_t* dataProcessingGracePeriodTimer = nullptr; uv_signal_t* sigusr1Handle = nullptr; int expectedRegionCallbacks = 0; int exitTransitionTimeout = 0; + int dataProcessingTimeout = 0; }; } // namespace o2::framework diff --git a/Framework/Core/include/Framework/DeviceState.h b/Framework/Core/include/Framework/DeviceState.h index f6d863064ee66..5644d85a904d4 100644 --- a/Framework/Core/include/Framework/DeviceState.h +++ b/Framework/Core/include/Framework/DeviceState.h @@ -68,8 +68,18 @@ struct DeviceState { STREAM_CONTEXT_LOG = 1 << 4, // Log for the StreamContext callbacks }; + enum ProcessingType : int { + Any, // Any kind of processing is allowed + CalibrationOnly, // Only calibrations are allowed to be processed / produced + }; + std::vector inputChannelInfos; StreamingState streaming = StreamingState::Streaming; + // What kind of processing is allowed. By default we allow any. + // If we are past the data processing timeout, this will be + // CalibrationOnly. We need to reset it at every start. + ProcessingType allowedProcessing = ProcessingType::Any; + bool quitRequested = false; std::atomic cleanupCount = -1; diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index 169613b18a2ee..fe594bdeb7ed1 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -142,11 +142,28 @@ void on_transition_requested_expired(uv_timer_t* handle) if (hasOnlyGenerated(spec)) { O2_SIGNPOST_EVENT_EMIT_INFO(calibration, cid, "callback", "Grace period for source expired. Exiting."); } else { - O2_SIGNPOST_EVENT_EMIT_WARN(calibration, cid, "callback", "Grace period for data / calibration expired. Exiting."); + O2_SIGNPOST_EVENT_EMIT_INFO(calibration, cid, "callback", "Grace period for %{public}s expired. Exiting.", + state.allowedProcessing == DeviceState::CalibrationOnly ? "calibration" : "data & calibration"); } state.transitionHandling = TransitionHandlingState::Expired; } +void on_data_processing_expired(uv_timer_t* handle) +{ + auto* ref = (ServiceRegistryRef*)handle->data; + auto& state = ref->get(); + state.loopReason |= DeviceState::TIMER_EXPIRED; + + // Check if this is a source device + O2_SIGNPOST_ID_FROM_POINTER(cid, device, handle); + + // Source devices should never end up in this callback, since the exitTransitionTimeout should + // be reset to the dataProcessingTimeout and the timers cohalesced. + assert(hasOnlyGenerated(ref->get()) == false); + O2_SIGNPOST_EVENT_EMIT_INFO(calibration, cid, "callback", "Grace period for data processing expired. Only calibrations from this point onwards."); + state.allowedProcessing = DeviceState::CalibrationOnly; +} + void on_communication_requested(uv_async_t* s) { auto* state = (DeviceState*)s->data; @@ -949,6 +966,10 @@ void DataProcessingDevice::startPollers() deviceContext.gracePeriodTimer = (uv_timer_t*)malloc(sizeof(uv_timer_t)); deviceContext.gracePeriodTimer->data = new ServiceRegistryRef(mServiceRegistry); uv_timer_init(state.loop, deviceContext.gracePeriodTimer); + + deviceContext.dataProcessingGracePeriodTimer = (uv_timer_t*)malloc(sizeof(uv_timer_t)); + deviceContext.dataProcessingGracePeriodTimer->data = new ServiceRegistryRef(mServiceRegistry); + uv_timer_init(state.loop, deviceContext.dataProcessingGracePeriodTimer); } void DataProcessingDevice::stopPollers() @@ -980,6 +1001,11 @@ void DataProcessingDevice::stopPollers() delete (ServiceRegistryRef*)deviceContext.gracePeriodTimer->data; free(deviceContext.gracePeriodTimer); deviceContext.gracePeriodTimer = nullptr; + + uv_timer_stop(deviceContext.dataProcessingGracePeriodTimer); + delete (ServiceRegistryRef*)deviceContext.dataProcessingGracePeriodTimer->data; + free(deviceContext.dataProcessingGracePeriodTimer); + deviceContext.dataProcessingGracePeriodTimer = nullptr; } void DataProcessingDevice::InitTask() @@ -1015,6 +1041,7 @@ void DataProcessingDevice::InitTask() deviceContext.expectedRegionCallbacks = std::stoi(fConfig->GetValue("expected-region-callbacks")); deviceContext.exitTransitionTimeout = std::stoi(fConfig->GetValue("exit-transition-timeout")); + deviceContext.dataProcessingTimeout = std::stoi(fConfig->GetValue("data-processing-timeout")); for (auto& channel : GetChannels()) { channel.second.at(0).Transport()->SubscribeToRegionEvents([&context = deviceContext, @@ -1209,6 +1236,7 @@ void DataProcessingDevice::PreRun() O2_SIGNPOST_START(device, cid, "PreRun", "Entering PreRun callback."); state.quitRequested = false; state.streaming = StreamingState::Streaming; + state.allowedProcessing = DeviceState::Any; for (auto& info : state.inputChannelInfos) { if (info.state != InputChannelState::Pull) { info.state = InputChannelState::Running; @@ -1339,6 +1367,19 @@ void DataProcessingDevice::Run() state.streaming = StreamingState::EndOfStreaming; } + // If this is a source device, dataTransitionTimeout and dataProcessingTimeout are effectively + // the same (because source devices are not allowed to produce any calibration). + // should be the same. + if (hasOnlyGenerated(spec) && deviceContext.dataProcessingTimeout > 0) { + deviceContext.exitTransitionTimeout = deviceContext.dataProcessingTimeout; + } + + // We do not do anything in particular if the data processing timeout would go past the exitTransitionTimeout + if (deviceContext.dataProcessingTimeout > 0 && deviceContext.dataProcessingTimeout < deviceContext.exitTransitionTimeout) { + uv_update_time(state.loop); + O2_SIGNPOST_EVENT_EMIT(calibration, lid, "timer_setup", "Starting %d s timer for dataProcessingTimeout.", deviceContext.dataProcessingTimeout); + uv_timer_start(deviceContext.dataProcessingGracePeriodTimer, on_data_processing_expired, deviceContext.dataProcessingTimeout * 1000, 0); + } if (deviceContext.exitTransitionTimeout != 0 && state.streaming != StreamingState::Idle) { state.transitionHandling = TransitionHandlingState::Requested; ref.get().call(ServiceRegistryRef{ref}); diff --git a/Framework/Core/src/DeviceSpecHelpers.cxx b/Framework/Core/src/DeviceSpecHelpers.cxx index 8076242bd274e..d1fad2bb66f8b 100644 --- a/Framework/Core/src/DeviceSpecHelpers.cxx +++ b/Framework/Core/src/DeviceSpecHelpers.cxx @@ -1537,6 +1537,7 @@ void DeviceSpecHelpers::prepareArguments(bool defaultQuiet, bool defaultStopped, realOdesc.add_options()("child-driver", bpo::value()); realOdesc.add_options()("rate", bpo::value()); realOdesc.add_options()("exit-transition-timeout", bpo::value()); + realOdesc.add_options()("data-processing-timeout", bpo::value()); realOdesc.add_options()("expected-region-callbacks", bpo::value()); realOdesc.add_options()("timeframes-rate-limit", bpo::value()); realOdesc.add_options()("environment", bpo::value()); @@ -1723,6 +1724,7 @@ boost::program_options::options_description DeviceSpecHelpers::getForwardedDevic ("control-port", bpo::value(), "Utility port to be used by O2 Control") // ("rate", bpo::value(), "rate for a data source device (Hz)") // ("exit-transition-timeout", bpo::value(), "timeout before switching to READY state") // + ("data-processing-timeout", bpo::value(), "timeout after which only calibration can happen") // ("expected-region-callbacks", bpo::value(), "region callbacks to expect before starting") // ("timeframes-rate-limit", bpo::value()->default_value("0"), "how many timeframes can be in fly") // ("shm-monitor", bpo::value(), "whether to use the shared memory monitor") // diff --git a/Framework/Core/src/O2ControlHelpers.cxx b/Framework/Core/src/O2ControlHelpers.cxx index ad539dc4af03f..46b1eb12ea26a 100644 --- a/Framework/Core/src/O2ControlHelpers.cxx +++ b/Framework/Core/src/O2ControlHelpers.cxx @@ -262,6 +262,8 @@ void dumpCommand(std::ostream& dumpOut, const DeviceExecution& execution, std::s dumpOut << indLevel << indScheme << "- \"-b\"\n"; dumpOut << indLevel << indScheme << "- \"--exit-transition-timeout\"\n"; dumpOut << indLevel << indScheme << "- \"'{{ exit_transition_timeout }}'\"\n"; + dumpOut << indLevel << indScheme << "- \"--data-processing-timeout\"\n"; + dumpOut << indLevel << indScheme << "- \"'{{ data_processing_timeout }}'\"\n"; dumpOut << indLevel << indScheme << "- \"--monitoring-backend\"\n"; dumpOut << indLevel << indScheme << "- \"'{{ monitoring_dpl_url }}'\"\n"; dumpOut << indLevel << indScheme << "- \"--session\"\n"; @@ -393,15 +395,20 @@ void dumpTask(std::ostream& dumpOut, const DeviceSpec& spec, const DeviceExecuti dumpOut << indLevel << "defaults:\n"; dumpOut << indLevel << indScheme << "log_task_stdout: none\n"; dumpOut << indLevel << indScheme << "log_task_stderr: none\n"; - std::string exitTransitionTimeout = "15"; + std::string exitTransitionTimeout = "15"; // Allow 15 seconds to finish processing and calibrations + std::string dataProcessingTimeout = "10"; // Allow only ten seconds to finish processing if (execution.args.size() > 2) { for (size_t i = 0; i < execution.args.size() - 1; ++i) { if (strcmp(execution.args[i], "--exit-transition-timeout") == 0) { exitTransitionTimeout = execution.args[i + 1]; } + if (strcmp(execution.args[i], "--data-processing-timeout") == 0) { + dataProcessingTimeout = execution.args[i + 1]; + } } } dumpOut << indLevel << indScheme << "exit_transition_timeout: " << exitTransitionTimeout << "\n"; + dumpOut << indLevel << indScheme << "data_processing_timeout: " << dataProcessingTimeout << "\n"; if (bfs::path(execution.args[0]).filename().string() != execution.args[0]) { LOG(warning) << "The workflow template generation was started with absolute or relative executables paths." diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 7d298998d0563..0cf775a33de18 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -1036,6 +1036,7 @@ int doChild(int argc, char** argv, ServiceRegistry& serviceRegistry, // declared in the workflow definition are allowed. runner.AddHook([&spec, driverConfig, defaultDriverClient](fair::mq::DeviceRunner& r) { std::string defaultExitTransitionTimeout = "0"; + std::string defaultDataProcessingTimeout = "0"; std::string defaultInfologgerMode = ""; o2::framework::DeploymentMode deploymentMode = o2::framework::DefaultsHelpers::deploymentMode(); if (deploymentMode == o2::framework::DeploymentMode::OnlineDDS) { @@ -1047,15 +1048,16 @@ int doChild(int argc, char** argv, ServiceRegistry& serviceRegistry, boost::program_options::options_description optsDesc; ConfigParamsHelper::populateBoostProgramOptions(optsDesc, spec.options, gHiddenDeviceOptions); char const* defaultSignposts = getenv("DPL_SIGNPOSTS"); - optsDesc.add_options()("monitoring-backend", bpo::value()->default_value("default"), "monitoring backend info") // - ("driver-client-backend", bpo::value()->default_value(defaultDriverClient), "backend for device -> driver communicataon: stdout://: use stdout, ws://: use websockets") // - ("infologger-severity", bpo::value()->default_value(""), "minimum FairLogger severity to send to InfoLogger") // - ("dpl-tracing-flags", bpo::value()->default_value(""), "pipe `|` separate list of events to be traced") // - ("signposts", bpo::value()->default_value(defaultSignposts ? defaultSignposts : ""), "comma separated list of signposts to enable") // - ("expected-region-callbacks", bpo::value()->default_value("0"), "how many region callbacks we are expecting") // - ("exit-transition-timeout", bpo::value()->default_value(defaultExitTransitionTimeout), "how many second to wait before switching from RUN to READY") // - ("timeframes-rate-limit", bpo::value()->default_value("0"), "how many timeframe can be in fly at the same moment (0 disables)") // - ("configuration,cfg", bpo::value()->default_value("command-line"), "configuration backend") // + optsDesc.add_options()("monitoring-backend", bpo::value()->default_value("default"), "monitoring backend info") // + ("driver-client-backend", bpo::value()->default_value(defaultDriverClient), "backend for device -> driver communicataon: stdout://: use stdout, ws://: use websockets") // + ("infologger-severity", bpo::value()->default_value(""), "minimum FairLogger severity to send to InfoLogger") // + ("dpl-tracing-flags", bpo::value()->default_value(""), "pipe `|` separate list of events to be traced") // + ("signposts", bpo::value()->default_value(defaultSignposts ? defaultSignposts : ""), "comma separated list of signposts to enable") // + ("expected-region-callbacks", bpo::value()->default_value("0"), "how many region callbacks we are expecting") // + ("exit-transition-timeout", bpo::value()->default_value(defaultExitTransitionTimeout), "how many second to wait before switching from RUN to READY") // + ("data-processing-timeout", bpo::value()->default_value(defaultDataProcessingTimeout), "how many second to wait before stopping data processing and allowing data calibration") // + ("timeframes-rate-limit", bpo::value()->default_value("0"), "how many timeframe can be in fly at the same moment (0 disables)") // + ("configuration,cfg", bpo::value()->default_value("command-line"), "configuration backend") // ("infologger-mode", bpo::value()->default_value(defaultInfologgerMode), "O2_INFOLOGGER_MODE override"); r.fConfig.AddToCmdLineOptions(optsDesc, true); }); diff --git a/Framework/Core/test/test_FrameworkDataFlowToO2Control.cxx b/Framework/Core/test/test_FrameworkDataFlowToO2Control.cxx index 4cda5fd76336a..d5f402aa16caa 100644 --- a/Framework/Core/test/test_FrameworkDataFlowToO2Control.cxx +++ b/Framework/Core/test/test_FrameworkDataFlowToO2Control.cxx @@ -15,10 +15,8 @@ #include "../src/DeviceSpecHelpers.h" #include "../src/SimpleResourceManager.h" #include "../src/ComputingResourceHelpers.h" -#include "Framework/DataAllocator.h" #include "Framework/DeviceControl.h" #include "Framework/DeviceSpec.h" -#include "Framework/ProcessingContext.h" #include "Framework/WorkflowSpec.h" #include "Framework/DriverConfig.h" #include "Framework/O2ControlParameters.h" @@ -141,6 +139,7 @@ const std::vector expectedTasks{ log_task_stdout: none log_task_stderr: none exit_transition_timeout: 15 + data_processing_timeout: 10 _module_cmdline: >- source /etc/profile.d/modules.sh && MODULEPATH={{ modulepath }} module load O2 QualityControl Control-OCCPlugin && {{ dpl_command }} | bcsadc/foo @@ -173,6 +172,8 @@ const std::vector expectedTasks{ - "-b" - "--exit-transition-timeout" - "'{{ exit_transition_timeout }}'" + - "--data-processing-timeout" + - "'{{ data_processing_timeout }}'" - "--monitoring-backend" - "'{{ monitoring_dpl_url }}'" - "--session" @@ -236,6 +237,7 @@ const std::vector expectedTasks{ log_task_stdout: none log_task_stderr: none exit_transition_timeout: 15 + data_processing_timeout: 10 _module_cmdline: >- source /etc/profile.d/modules.sh && MODULEPATH={{ modulepath }} module load O2 QualityControl Control-OCCPlugin && {{ dpl_command }} | foo @@ -270,6 +272,8 @@ const std::vector expectedTasks{ - "-b" - "--exit-transition-timeout" - "'{{ exit_transition_timeout }}'" + - "--data-processing-timeout" + - "'{{ data_processing_timeout }}'" - "--monitoring-backend" - "'{{ monitoring_dpl_url }}'" - "--session" @@ -333,6 +337,7 @@ const std::vector expectedTasks{ log_task_stdout: none log_task_stderr: none exit_transition_timeout: 15 + data_processing_timeout: 10 _module_cmdline: >- source /etc/profile.d/modules.sh && MODULEPATH={{ modulepath }} module load O2 QualityControl Control-OCCPlugin && {{ dpl_command }} | foo @@ -367,6 +372,8 @@ const std::vector expectedTasks{ - "-b" - "--exit-transition-timeout" - "'{{ exit_transition_timeout }}'" + - "--data-processing-timeout" + - "'{{ data_processing_timeout }}'" - "--monitoring-backend" - "'{{ monitoring_dpl_url }}'" - "--session" @@ -430,6 +437,7 @@ const std::vector expectedTasks{ log_task_stdout: none log_task_stderr: none exit_transition_timeout: 15 + data_processing_timeout: 10 _module_cmdline: >- source /etc/profile.d/modules.sh && MODULEPATH={{ modulepath }} module load O2 QualityControl Control-OCCPlugin && {{ dpl_command }} | foo @@ -461,6 +469,8 @@ const std::vector expectedTasks{ - "-b" - "--exit-transition-timeout" - "'{{ exit_transition_timeout }}'" + - "--data-processing-timeout" + - "'{{ data_processing_timeout }}'" - "--monitoring-backend" - "'{{ monitoring_dpl_url }}'" - "--session" From 1de0de370a5770df562e5b5534c4e84ded929c70 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 20 Sep 2024 09:18:45 +0200 Subject: [PATCH 0286/2205] GPU Interface: provide setter for external occuapancy map --- .../Interface/GPUO2InterfaceRefit.cxx | 21 ++++++------------- .../Interface/GPUO2InterfaceUtils.cxx | 18 ++++++++++++++++ .../Interface/GPUO2InterfaceUtils.h | 1 + 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx index f81da3b52ad1b..55122b7de4af6 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx @@ -99,35 +99,26 @@ size_t GPUO2InterfaceRefit::fillOccupancyMapGetSize(unsigned int nHbfPerTf, cons GPUO2InterfaceRefit::GPUO2InterfaceRefit(const ClusterNativeAccess* cl, const CorrectionMapsHelper* trans, float bzNominalGPU, const TPCClRefElem* trackRef, unsigned int nHbfPerTf, const unsigned char* sharedmap, const unsigned int* occupancymap, int occupancyMapSize, const std::vector* trks, o2::base::Propagator* p) { mParam = GPUO2InterfaceUtils::getFullParam(bzNominalGPU, nHbfPerTf); - size_t expectedSharedMapSize = nHbfPerTf ? fillOccupancyMapGetSize(nHbfPerTf, mParam.get()) : 0; + size_t expectedOccMapSize = nHbfPerTf ? fillOccupancyMapGetSize(nHbfPerTf, mParam.get()) : 0; if (cl->nClustersTotal) { if (sharedmap == nullptr && trks == nullptr) { throw std::runtime_error("Must provide either shared cluster map or vector of tpc tracks to build the map"); } - if ((sharedmap == nullptr) ^ (expectedSharedMapSize && occupancymap == nullptr)) { + if ((sharedmap == nullptr) ^ (expectedOccMapSize && occupancymap == nullptr)) { throw std::runtime_error("Must provide either both shared cluster map and occupancy map or none of them"); } if (sharedmap == nullptr) { mSharedMap.resize(cl->nClustersTotal); sharedmap = mSharedMap.data(); - mOccupancyMap.resize(expectedSharedMapSize / sizeof(*mOccupancyMap.data())); + mOccupancyMap.resize(expectedOccMapSize / sizeof(*mOccupancyMap.data())); occupancymap = mOccupancyMap.data(); + occupancyMapSize = expectedOccMapSize; fillSharedClustersAndOccupancyMap(cl, *trks, trackRef, mSharedMap.data(), mOccupancyMap.data(), nHbfPerTf, mParam.get()); } } - if (occupancymap && occupancyMapSize > sizeof(*occupancymap) && occupancymap[1] != (mParam->rec.tpc.occupancyMapTimeBins * 0x10000 + mParam->rec.tpc.occupancyMapTimeBinsAverage)) { - throw std::runtime_error("Occupancy map has invalid paramters occupancyMapTimeBins and occupancyMapTimeBinsAverage"); - } - if (occupancyMapSize != -1 && nHbfPerTf && (size_t)occupancyMapSize != expectedSharedMapSize) { - throw std::runtime_error("Received occupancy map of wrong size, most likely --configKeyValues or HBperTF of map creator and map consumer are different"); - } + GPUO2InterfaceUtils::paramUseExternalOccupancyMap(mParam.get(), nHbfPerTf, occupancymap, occupancyMapSize); + mRefit = std::make_unique(); - if (occupancymap) { - mParam->occupancyTotal = *occupancymap; - if (mParam->rec.tpc.occupancyMapTimeBins) { - mParam->occupancyMap = occupancymap + 2; - } - } mRefit->SetGPUParam(mParam.get()); mRefit->SetClusterStateArray(sharedmap); mRefit->SetPropagator(p); diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index f56e3dde1ea48..bb9c38c291fe2 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -14,6 +14,7 @@ #include "GPUO2InterfaceUtils.h" #include "GPUO2InterfaceConfiguration.h" +#include "GPUO2InterfaceRefit.h" #include "TPCPadGainCalib.h" #include "CalibdEdxContainer.h" #include "TPCBase/Sector.h" @@ -115,3 +116,20 @@ std::shared_ptr GPUO2InterfaceUtils::getFullParamShared(float solenoid { return std::move(getFullParam(solenoidBz, nHbfPerTf, pConfiguration, pO2Settings, autoMaxTimeBin)); } + +void GPUO2InterfaceUtils::paramUseExternalOccupancyMap(GPUParam* param, unsigned int nHbfPerTf, const unsigned int* occupancymap, int occupancyMapSize) +{ + size_t expectedOccMapSize = nHbfPerTf ? GPUO2InterfaceRefit::fillOccupancyMapGetSize(nHbfPerTf, param) : 0; + if (occupancyMapSize != -1 && nHbfPerTf && (size_t)occupancyMapSize != expectedOccMapSize) { + throw std::runtime_error("Received occupancy map of wrong size, most likely --configKeyValues or HBperTF of map creator and map consumer are different"); + } + if (occupancymap && occupancyMapSize > sizeof(*occupancymap) && occupancymap[1] != (param->rec.tpc.occupancyMapTimeBins * 0x10000 + param->rec.tpc.occupancyMapTimeBinsAverage)) { + throw std::runtime_error("Occupancy map has invalid paramters occupancyMapTimeBins and occupancyMapTimeBinsAverage"); + } + if (occupancymap) { + param->occupancyTotal = *occupancymap; + if (param->rec.tpc.occupancyMapTimeBins) { + param->occupancyMap = occupancymap + 2; + } + } +} diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h index c375f4d646a00..d2c3ee495c9ea 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h @@ -57,6 +57,7 @@ class GPUO2InterfaceUtils } static std::unique_ptr getFullParam(float solenoidBz, unsigned int nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); static std::shared_ptr getFullParamShared(float solenoidBz, unsigned int nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); // Return owning pointer + static void paramUseExternalOccupancyMap(GPUParam* param, unsigned int nHbfPerTf, const unsigned int* occupancymap, int occupancyMapSize); class GPUReconstructionZSDecoder { From 253c99be3fa6de6f241e68aee8da08761873072b Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:35:49 +0200 Subject: [PATCH 0287/2205] DPL: drop incoming non-calibration data when we process calibration only (#13544) --- .../Core/include/Framework/DeviceState.h | 2 -- Framework/Core/src/DataProcessingDevice.cxx | 11 +++----- Framework/Core/src/DataRelayer.cxx | 27 ++++++++++++++++--- Framework/Core/test/test_DataRelayer.cxx | 3 +++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Framework/Core/include/Framework/DeviceState.h b/Framework/Core/include/Framework/DeviceState.h index 5644d85a904d4..4a080e72907f6 100644 --- a/Framework/Core/include/Framework/DeviceState.h +++ b/Framework/Core/include/Framework/DeviceState.h @@ -17,8 +17,6 @@ #include #include -#include -#include #include typedef struct uv_loop_s uv_loop_t; diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index fe594bdeb7ed1..f4123de250e79 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -10,7 +10,6 @@ // or submit itself to any jurisdiction. #include "Framework/AsyncQueue.h" #include "Framework/DataProcessingDevice.h" -#include "Framework/ChannelMatching.h" #include "Framework/ControlService.h" #include "Framework/ComputingQuotaEvaluator.h" #include "Framework/DataProcessingHeader.h" @@ -28,7 +27,6 @@ #include "ConfigurationOptionsRetriever.h" #include "Framework/FairMQDeviceProxy.h" #include "Framework/CallbackService.h" -#include "Framework/TMessageSerializer.h" #include "Framework/InputRecord.h" #include "Framework/InputSpan.h" #if defined(__APPLE__) || defined(NDEBUG) @@ -37,23 +35,20 @@ #include "Framework/Signpost.h" #include "Framework/TimingHelpers.h" #include "Framework/SourceInfoHeader.h" -#include "Framework/Logger.h" #include "Framework/DriverClient.h" -#include "Framework/Monitoring.h" #include "Framework/TimesliceIndex.h" #include "Framework/VariableContextHelpers.h" #include "Framework/DataProcessingContext.h" +#include "Framework/DataProcessingHeader.h" #include "Framework/DeviceContext.h" #include "Framework/RawDeviceService.h" #include "Framework/StreamContext.h" #include "Framework/DefaultsHelpers.h" +#include "Framework/ServiceRegistryRef.h" -#include "PropertyTreeHelpers.h" -#include "DataProcessingStatus.h" #include "DecongestionService.h" #include "Framework/DataProcessingHelpers.h" #include "DataRelayerHelpers.h" -#include "ProcessingPoliciesHelpers.h" #include "Headers/DataHeader.h" #include "Headers/DataHeaderHelpers.h" @@ -66,6 +61,7 @@ #include #include #include +#include #include #include @@ -74,7 +70,6 @@ #include #include #include -#include #include #include #include diff --git a/Framework/Core/src/DataRelayer.cxx b/Framework/Core/src/DataRelayer.cxx index ad085afac0b03..c2ae459aace38 100644 --- a/Framework/Core/src/DataRelayer.cxx +++ b/Framework/Core/src/DataRelayer.cxx @@ -402,6 +402,12 @@ void DataRelayer::pruneCache(TimesliceSlot slot, OnDropCallback onDrop) pruneCache(slot); } +bool isCalibrationData(std::unique_ptr& first) +{ + auto* dh = o2::header::get(first->GetData()); + return dh->flagsDerivedHeader & DataProcessingHeader::KEEP_AT_EOS_FLAG; +} + DataRelayer::RelayChoice DataRelayer::relay(void const* rawHeader, std::unique_ptr* messages, @@ -456,7 +462,7 @@ DataRelayer::RelayChoice &nPayloads, &cache = mCache, &services = mContext, - numInputTypes = mDistinctRoutesIndex.size()](TimesliceId timeslice, int input, TimesliceSlot slot, InputInfo const& info) { + numInputTypes = mDistinctRoutesIndex.size()](TimesliceId timeslice, int input, TimesliceSlot slot, InputInfo const& info) -> size_t { O2_SIGNPOST_ID_GENERATE(aid, data_relayer); O2_SIGNPOST_EVENT_EMIT(data_relayer, aid, "saveInSlot", "saving %{public}s@%zu in slot %zu from %{public}s", fmt::format("{:x}", *o2::header::get(messages[0]->GetData())).c_str(), @@ -468,11 +474,20 @@ DataRelayer::RelayChoice // TODO: make sure that multiple parts can only be added within the same call of // DataRelayer::relay assert(nPayloads > 0); + size_t saved = 0; for (size_t mi = 0; mi < nMessages; ++mi) { assert(mi + nPayloads < nMessages); + // We are in calibration mode and the data does not have the calibration bit set. + // We do not store it. + if (services.get().allowedProcessing == DeviceState::ProcessingType::CalibrationOnly && !isCalibrationData(messages[mi])) { + mi += nPayloads; + continue; + } target.add([&messages, &mi](size_t i) -> fair::mq::MessagePtr& { return messages[mi + i]; }, nPayloads + 1); mi += nPayloads; + saved += nPayloads; } + return saved; }; auto updateStatistics = [ref = mContext](TimesliceIndex::ActionTaken action) { @@ -551,7 +566,10 @@ DataRelayer::RelayChoice this->pruneCache(slot, onDrop); mPruneOps.erase(std::remove_if(mPruneOps.begin(), mPruneOps.end(), [slot](const auto& x) { return x.slot == slot; }), mPruneOps.end()); } - saveInSlot(timeslice, input, slot, info); + size_t saved = saveInSlot(timeslice, input, slot, info); + if (saved == 0) { + return RelayChoice{.type = RelayChoice::Type::Dropped, .timeslice = timeslice}; + } index.publishSlot(slot); index.markAsDirty(slot, true); stats.updateStats({static_cast(ProcessingStatsId::RELAYED_MESSAGES), DataProcessingStats::Op::Add, (int)1}); @@ -633,7 +651,10 @@ DataRelayer::RelayChoice // cache still holds the old data, so we prune it. this->pruneCache(slot, onDrop); mPruneOps.erase(std::remove_if(mPruneOps.begin(), mPruneOps.end(), [slot](const auto& x) { return x.slot == slot; }), mPruneOps.end()); - saveInSlot(timeslice, input, slot, info); + size_t saved = saveInSlot(timeslice, input, slot, info); + if (saved == 0) { + return RelayChoice{.type = RelayChoice::Type::Dropped, .timeslice = timeslice}; + } index.publishSlot(slot); index.markAsDirty(slot, true); return RelayChoice{.type = RelayChoice::Type::WillRelay}; diff --git a/Framework/Core/test/test_DataRelayer.cxx b/Framework/Core/test/test_DataRelayer.cxx index d112e8736399a..ec5d48fbd78da 100644 --- a/Framework/Core/test/test_DataRelayer.cxx +++ b/Framework/Core/test/test_DataRelayer.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. #include +#include "Framework/DeviceState.h" #include "Headers/DataHeader.h" #include "Headers/Stack.h" #include "MemoryResources/MemoryResources.h" @@ -60,10 +61,12 @@ TEST_CASE("DataRelayer") stats.registerMetric(spec); } + DeviceState state; ref.registerService(ServiceRegistryHelpers::handleForService(&monitoring)); ref.registerService(ServiceRegistryHelpers::handleForService(&stats)); ref.registerService(ServiceRegistryHelpers::handleForService(&states)); ref.registerService(ServiceRegistryHelpers::handleForService(&driverConfig)); + ref.registerService(ServiceRegistryHelpers::handleForService(&state)); // A simple test where an input is provided // and the subsequent InputRecord is immediately requested. SECTION("TestNoWait") From 993746fb3793de032eda84dc2846c9ac5ac01cb2 Mon Sep 17 00:00:00 2001 From: tubagundem Date: Mon, 30 Sep 2024 17:11:17 +0200 Subject: [PATCH 0288/2205] TPC: simulation toyCluster.C macro fix --- Detectors/TPC/simulation/macro/toyCluster.C | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Detectors/TPC/simulation/macro/toyCluster.C b/Detectors/TPC/simulation/macro/toyCluster.C index b7c5f74633cfc..d60e5a7c0f94e 100644 --- a/Detectors/TPC/simulation/macro/toyCluster.C +++ b/Detectors/TPC/simulation/macro/toyCluster.C @@ -404,8 +404,12 @@ void createDigitsFromSim(const char* inpFileSim = "o2sim_HitsTPC.root", const st gRandom->Gaus(0, std::abs(posEle.X() - posEleDiff.X())) + posEle.X(), gRandom->Gaus(0, std::abs(posEle.Y() - posEleDiff.Y())) + posEle.Y(), gRandom->Gaus(0, std::abs(posEle.Z() - posEleDiff.Z())) + posEle.Z())); - // auto posEleTmp = posTotElectrons[j]; - const float driftTime = (detParam.TPClength - posTotElectrons.at(isec).Z()) / gasParam.DriftV; + } + + // loop over all electrons + for (unsigned int j = 0; j < posTotElectrons.size(); ++j) { + auto posEleTmp = posTotElectrons[j]; + const float driftTime = (detParam.TPClength - posEleTmp.Z()) / gasParam.DriftV; if ((driftTime + hitTime) > maxEleTime) { LOG(warning) << "Skipping electron with driftTime " << driftTime << " from hit at time " << hitTime; @@ -418,13 +422,13 @@ void createDigitsFromSim(const char* inpFileSim = "o2sim_HitsTPC.root", const st } // Remove electrons that end up outside the active volume - if (std::abs(posTotElectrons.at(isec).Z()) > detParam.TPClength) { + if (std::abs(posEleTmp.Z()) > detParam.TPClength) { continue; } // When the electron is not in the mSector we're processing, abandon // create dummy pos at A-Side - auto posEleTmpTmp = posTotElectrons.at(isec); + auto posEleTmpTmp = posEleTmp; posEleTmpTmp.SetZ(1); if (mapper.isOutOfSector(posEleTmpTmp, mSector)) { continue; @@ -451,10 +455,10 @@ void createDigitsFromSim(const char* inpFileSim = "o2sim_HitsTPC.root", const st for (int i = 0; i < nShapedPoints; ++i) { digitContainer.addDigit(label, cru, driftTime / eleParam.ZbinWidth + i, globalPad, signalArray[i]); } - } // secondary loop - } // electron loop - } // hit loop - } // track loop + } + } // electron loop + } // hit loop + } // track loop // dump digits for each event to a file dumpDigits(digitContainer, 0.l, digits, labels, commonMode, brdigits, brlabel, brmCommon); From d9e8f0474b784a01ab70c51c5360f770b1a0fd3e Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 1 Oct 2024 10:24:25 +0200 Subject: [PATCH 0289/2205] ITS digi: Ability to process events before the first RO This commit makes it possible to inject events/hits into the ITS digitizer which happen in time before the "first interaction sampled" (start of the first readout-frame given by HBFUtils). The commit avoids/fixes a segmenation fault which, so far, occurs in these situations (because of overflow of unsigned int32 newROFrame) The commit allows to reduce "startup" effects in a timeframe by capturing hits that come from events before data taking starts. This makes MC more realistic. With these "startup effects" removed, one could now play with short timeframe lengths for skimming studies. --- .../include/ITSMFTSimulation/Digitizer.h | 1 + .../common/simulation/src/Digitizer.cxx | 25 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Digitizer.h b/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Digitizer.h index e3e16f15586ee..e3995068c52cf 100644 --- a/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Digitizer.h +++ b/Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Digitizer.h @@ -118,6 +118,7 @@ class Digitizer : public TObject uint32_t mROFrameMin = 0; ///< lowest RO frame of current digits uint32_t mROFrameMax = 0; ///< highest RO frame of current digits uint32_t mNewROFrame = 0; ///< ROFrame corresponding to provided time + bool mIsBeforeFirstRO = false; uint32_t mEventROFrameMin = 0xffffffff; ///< lowest RO frame for processed events (w/o automatic noise ROFs) uint32_t mEventROFrameMax = 0; ///< highest RO frame forfor processed events (w/o automatic noise ROFs) diff --git a/Detectors/ITSMFT/common/simulation/src/Digitizer.cxx b/Detectors/ITSMFT/common/simulation/src/Digitizer.cxx index 2464f03a6005e..382fa769a94c7 100644 --- a/Detectors/ITSMFT/common/simulation/src/Digitizer.cxx +++ b/Detectors/ITSMFT/common/simulation/src/Digitizer.cxx @@ -102,6 +102,10 @@ void Digitizer::init() } mParams.print(); mIRFirstSampledTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); + + // + LOG(info) << "First IR sampled in digitization is: " << mIRFirstSampledTF; + LOG(info) << "First IR ns " << mIRFirstSampledTF.bc2ns(); } auto Digitizer::getChipResponse(int chipID) @@ -167,7 +171,19 @@ void Digitizer::setEventTime(const o2::InteractionTimeRecord& irt) if (mCollisionTimeWrtROF < 0 && nbc > 0) { nbc--; } - mNewROFrame = nbc / mParams.getROFrameLengthInBC(); + + // we might get interactions to digitize from before + // the first sampled IR + if (nbc < 0) { + mNewROFrame = 0; + // this event is before the first RO + mIsBeforeFirstRO = true; + } else { + mNewROFrame = nbc / mParams.getROFrameLengthInBC(); + mIsBeforeFirstRO = false; + } + LOG(info) << " NewROFrame " << mNewROFrame << " nbc " << nbc; + // in continuous mode depends on starts of periodic readout frame mCollisionTimeWrtROF += (nbc % mParams.getROFrameLengthInBC()) * o2::constants::lhc::LHCBunchSpacingNS; } else { @@ -275,6 +291,11 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID if (isContinuous()) { timeInROF += mCollisionTimeWrtROF; } + if (mIsBeforeFirstRO && timeInROF < 0) { + // disregard this hit because it comes from an event before readout starts and it does not effect this RO + return; + } + // calculate RO Frame for this hit if (timeInROF < 0) { timeInROF = 0.; @@ -290,7 +311,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID maxFr = roFrameMax; // if signal extends beyond current maxFrame, increase the latter } - // here we start stepping in the depth of the sensor to generate charge diffision + // here we start stepping in the depth of the sensor to generate charge diffusion float nStepsInv = mParams.getNSimStepsInv(); int nSteps = mParams.getNSimSteps(); const auto& matrix = mGeometry->getMatrixL2G(hit.GetDetectorID()); From 7380cae49bf0ae5092c75d7f2661ac84d0dbfb55 Mon Sep 17 00:00:00 2001 From: Piotr Konopka Date: Tue, 1 Oct 2024 15:41:38 +0200 Subject: [PATCH 0290/2205] DPL: Remove use of obsolete reconfiguration mechanism in ECS (#13539) --- .../Core/include/Framework/O2ControlLabels.h | 4 --- Framework/Core/src/O2ControlHelpers.cxx | 30 ------------------- Framework/Core/src/O2ControlLabels.cxx | 1 - 3 files changed, 35 deletions(-) diff --git a/Framework/Core/include/Framework/O2ControlLabels.h b/Framework/Core/include/Framework/O2ControlLabels.h index 2d4ea7c66cc3a..eb05f156cf58d 100644 --- a/Framework/Core/include/Framework/O2ControlLabels.h +++ b/Framework/Core/include/Framework/O2ControlLabels.h @@ -31,10 +31,6 @@ const extern DataProcessorLabel uniqueProxyLabel; // Thus, AliECS will not perform host and port allocation automatically. It takes priority over `uniqueProxyLabel`. const extern DataProcessorLabel preserveRawChannelsLabel; -// This label makes AliECS templates add the property `qcConfiguration` to the tasks, allowing them -// to reconfigure in init with a freshly templated config. -const extern DataProcessorLabel qcReconfigurable; - } // namespace ecs } // namespace o2::framework diff --git a/Framework/Core/src/O2ControlHelpers.cxx b/Framework/Core/src/O2ControlHelpers.cxx index 46b1eb12ea26a..48d564e4ee4f0 100644 --- a/Framework/Core/src/O2ControlHelpers.cxx +++ b/Framework/Core/src/O2ControlHelpers.cxx @@ -207,11 +207,6 @@ bool shouldPreserveRawChannels(const DeviceSpec& spec) return std::find(spec.labels.begin(), spec.labels.end(), ecs::preserveRawChannelsLabel) != spec.labels.end(); } -bool isQcReconfigurable(const DeviceSpec& spec) -{ - return std::find(spec.labels.begin(), spec.labels.end(), ecs::qcReconfigurable) != spec.labels.end(); -} - bool isCritical(const DeviceSpec& spec) { // DPL's expendable Data Processor corresponds to a non-critical task in ECS @@ -220,27 +215,6 @@ bool isCritical(const DeviceSpec& spec) return std::find(spec.labels.begin(), spec.labels.end(), DataProcessorLabel{"expendable"}) == spec.labels.end(); } -void dumpProperties(std::ostream& dumpOut, const DeviceExecution& execution, const DeviceSpec& spec, const std::string& indLevel) -{ - // get the argument `--config` - std::string configPath; - auto it = std::find_if(execution.args.begin(), execution.args.end(), [](char* v) { return v != nullptr && strcmp(v, "--config") == 0; }); - - // get the next argument and find `/o2/components/` in it, then take what comes after in the string. - if (it != execution.args.end()) { - std::string configParam = *(++it); - std::string prefix = "/o2/components/"; // keep only the path to the config file, i.e. stuff after "/o2/components/" - size_t pos = configParam.find(prefix); - if (pos != std::string::npos) { - configPath = configParam.substr(pos + prefix.length()); - } - } - - dumpOut << indLevel << "properties:\n"; - std::string qcConfigFullCommand = configPath.empty() ? "\"\"" : "\"{{ ToPtree(config.Get('" + configPath + "'), 'json') }}\""; - dumpOut << indLevel << indScheme << "qcConfiguration: " << qcConfigFullCommand << "\n"; -} - void dumpCommand(std::ostream& dumpOut, const DeviceExecution& execution, std::string indLevel) { dumpOut << indLevel << "shell: true\n"; @@ -461,10 +435,6 @@ void dumpTask(std::ostream& dumpOut, const DeviceSpec& spec, const DeviceExecuti } } - if (implementation::isQcReconfigurable(spec)) { - implementation::dumpProperties(dumpOut, execution, spec, indLevel); - } - dumpOut << indLevel << "command:\n"; implementation::dumpCommand(dumpOut, execution, indLevel + indScheme); } diff --git a/Framework/Core/src/O2ControlLabels.cxx b/Framework/Core/src/O2ControlLabels.cxx index 9c0b4dbd96d41..aa22d858f6e44 100644 --- a/Framework/Core/src/O2ControlLabels.cxx +++ b/Framework/Core/src/O2ControlLabels.cxx @@ -16,5 +16,4 @@ namespace o2::framework::ecs const DataProcessorLabel uniqueProxyLabel = {"ecs-unique-proxy"}; const DataProcessorLabel preserveRawChannelsLabel = {"ecs-preserve-raw-channels"}; -const DataProcessorLabel qcReconfigurable = {"qc-reconfigurable"}; } \ No newline at end of file From f49a578291a078b018f17819067e161286c2a6b8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 2 Oct 2024 00:35:26 +0200 Subject: [PATCH 0291/2205] DCAFitterGPU: add asynch batching + benchmarking (#13553) --- .../GPU/DeviceInterface/GPUInterface.h | 71 ++++++++ Common/DCAFitter/GPU/cuda/CMakeLists.txt | 3 + Common/DCAFitter/GPU/cuda/DCAFitterN.cu | 163 +++++++++++++----- Common/DCAFitter/GPU/cuda/GPUInterface.cu | 108 ++++++++++++ .../GPU/cuda/test/testDCAFitterNGPU.cxx | 120 +++++++------ Common/DCAFitter/GPU/hip/CMakeLists.txt | 3 +- .../DCAFitter/include/DCAFitter/DCAFitterN.h | 2 +- .../ITS/tracking/GPU/ITStrackingGPU/Stream.h | 2 +- 8 files changed, 374 insertions(+), 98 deletions(-) create mode 100644 Common/DCAFitter/GPU/DeviceInterface/GPUInterface.h create mode 100644 Common/DCAFitter/GPU/cuda/GPUInterface.cu diff --git a/Common/DCAFitter/GPU/DeviceInterface/GPUInterface.h b/Common/DCAFitter/GPU/DeviceInterface/GPUInterface.h new file mode 100644 index 0000000000000..3aa5ead805acd --- /dev/null +++ b/Common/DCAFitter/GPU/DeviceInterface/GPUInterface.h @@ -0,0 +1,71 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \brief Helper interface to the GPU device, meant to be compatible with manual allocation/streams and GPUReconstruction ones. +/// \author matteo.concas@cern.ch + +#ifndef DCAFITTER_GPU_INTERFACE +#define DCAFITTER_GPU_INTERFACE + +#include +#include +#include + +namespace o2 +{ +namespace vertexing +{ +namespace device +{ + +#if !defined(__HIPCC__) && !defined(__CUDACC__) +typedef struct _dummyStream { +} Stream; +#else +#ifdef __HIPCC__ +typedef hipStream_t Stream; +#else +typedef cudaStream_t Stream; +#endif +#endif + +class GPUInterface +{ + public: + GPUInterface(GPUInterface& other) = delete; + void operator=(const GPUInterface&) = delete; + + static GPUInterface* Instance(); + + // APIs + void registerBuffer(void*, size_t); + void unregisterBuffer(void* addr); + void allocDevice(void**, size_t); + void freeDevice(void*); + Stream& getStream(unsigned short N = 0); + Stream& getNextStream(); + + protected: + GPUInterface(size_t N = 1); + ~GPUInterface(); + + void resize(size_t); + + std::atomic mLastUsedStream{0}; + static GPUInterface* sGPUInterface; + std::vector mPool{}; + std::vector mStreams{}; +}; + +} // namespace device +} // namespace vertexing +} // namespace o2 +#endif diff --git a/Common/DCAFitter/GPU/cuda/CMakeLists.txt b/Common/DCAFitter/GPU/cuda/CMakeLists.txt index a498d0c350202..ddc1d09445d7f 100644 --- a/Common/DCAFitter/GPU/cuda/CMakeLists.txt +++ b/Common/DCAFitter/GPU/cuda/CMakeLists.txt @@ -12,12 +12,15 @@ o2_add_library(DCAFitterCUDA TARGETVARNAME targetName SOURCES DCAFitterN.cu + GPUInterface.cu PUBLIC_INCLUDE_DIRECTORIES ../../include + PUBLIC_INCLUDE_DIRECTORIES ../ PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ReconstructionDataFormats O2::DetectorsBase PRIVATE_LINK_LIBRARIES O2::GPUTrackingCUDAExternalProvider) set_property(TARGET ${targetName} PROPERTY CUDA_SEPARABLE_COMPILATION ON) +# add_compile_options(-lineinfo) o2_add_test(DCAFitterNCUDA SOURCES test/testDCAFitterNGPU.cxx diff --git a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu index 5cb93d474eb86..ab53ae25d7548 100644 --- a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu +++ b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu @@ -15,9 +15,11 @@ #include #endif +#include + #include "GPUCommonDef.h" #include "DCAFitter/DCAFitterN.h" -// #include "MathUtils/SMatrixGPU.h" +#include "DeviceInterface/GPUInterface.h" #define gpuCheckError(x) \ { \ @@ -61,10 +63,10 @@ GPUg() void processKernel(Fitter* fitter, int* res, Tr*... tracks) } template -GPUg() void processBulkKernel(Fitter* fitters, int* results, unsigned int N, Tr*... tracks) +GPUg() void processBatchKernel(Fitter* fitters, int* results, size_t off, size_t N, Tr*... tracks) { for (auto iThread{blockIdx.x * blockDim.x + threadIdx.x}; iThread < N; iThread += blockDim.x * gridDim.x) { - results[iThread] = fitters[iThread].process(tracks[iThread]...); + results[iThread + off] = fitters[iThread + off].process(tracks[iThread + off]...); } } @@ -131,64 +133,137 @@ int process(const int nBlocks, } template -std::vector processBulk(const int nBlocks, - const int nThreads, - std::vector& fitters, - std::vector
&... args) +void processBulk(const int nBlocks, + const int nThreads, + const int nBatches, + std::vector& fitters, + std::vector& results, + std::vector
&... args) { - kernel::warmUpGpuKernel<<<1, 1>>>(); + auto* gpuInterface = GPUInterface::Instance(); + kernel::warmUpGpuKernel<<<1, 1, 0, gpuInterface->getNextStream()>>>(); - cudaEvent_t start, stop; - gpuCheckError(cudaEventCreate(&start)); - gpuCheckError(cudaEventCreate(&stop)); - const auto nFits{fitters.size()}; // for clarity: size of all the vectors needs to be equal, not enforcing it here yet. - std::vector results(nFits); - int* results_device; - Fitter* fitters_device; - std::array tracks_device; + // Benchmarking events + std::vector ioUp(nBatches), ioDown(nBatches), kerElapsed(nBatches); + std::vector startIOUp(nBatches), endIOUp(nBatches), startIODown(nBatches), endIODown(nBatches), startKer(nBatches), endKer(nBatches); + for (int iBatch{0}; iBatch < nBatches; ++iBatch) { + gpuCheckError(cudaEventCreate(&startIOUp[iBatch])); + gpuCheckError(cudaEventCreate(&endIOUp[iBatch])); + gpuCheckError(cudaEventCreate(&startIODown[iBatch])); + gpuCheckError(cudaEventCreate(&endIODown[iBatch])); + gpuCheckError(cudaEventCreate(&startKer[iBatch])); + gpuCheckError(cudaEventCreate(&endKer[iBatch])); + } + // Tracks + std::array tracks_device; int iArg{0}; ([&] { - gpuCheckError(cudaMalloc(reinterpret_cast(&(tracks_device[iArg])), sizeof(Tr) * args.size())); - gpuCheckError(cudaMemcpy(tracks_device[iArg], args.data(), sizeof(Tr) * args.size(), cudaMemcpyHostToDevice)); + gpuInterface->registerBuffer(reinterpret_cast(args.data()), sizeof(Tr) * args.size()); + gpuInterface->allocDevice(reinterpret_cast(&(tracks_device[iArg])), sizeof(Tr) * args.size()); ++iArg; }(), ...); - gpuCheckError(cudaMalloc(reinterpret_cast(&results_device), sizeof(int) * nFits)); - gpuCheckError(cudaMalloc(reinterpret_cast(&fitters_device), sizeof(Fitter) * nFits)); - gpuCheckError(cudaMemcpy(fitters_device, fitters.data(), sizeof(Fitter) * nFits, cudaMemcpyHostToDevice)); - gpuCheckError(cudaEventRecord(start)); - std::apply([&](auto&&... args) { kernel::processBulkKernel<<>>(fitters_device, results_device, nFits, args...); }, tracks_device); - gpuCheckError(cudaEventRecord(stop)); + // Fitters + gpuInterface->registerBuffer(reinterpret_cast(fitters.data()), sizeof(Fitter) * fitters.size()); + Fitter* fitters_device; + gpuInterface->allocDevice(reinterpret_cast(&fitters_device), sizeof(Fitter) * fitters.size()); - gpuCheckError(cudaPeekAtLastError()); - gpuCheckError(cudaDeviceSynchronize()); + // Results + gpuInterface->registerBuffer(reinterpret_cast(results.data()), sizeof(int) * fitters.size()); + int* results_device; + gpuInterface->allocDevice(reinterpret_cast(&results_device), sizeof(int) * fitters.size()); - gpuCheckError(cudaMemcpy(results.data(), results_device, sizeof(int) * results.size(), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaMemcpy(fitters.data(), fitters_device, sizeof(Fitter) * nFits, cudaMemcpyDeviceToHost)); + // R.R. Computation + int totalSize = fitters.size(); + int batchSize = totalSize / nBatches; + int remainder = totalSize % nBatches; - iArg = 0; - ([&] { - gpuCheckError(cudaMemcpy(args.data(), tracks_device[iArg], sizeof(Tr) * args.size(), cudaMemcpyDeviceToHost)); - gpuCheckError(cudaFree(tracks_device[iArg])); - ++iArg; - }(), - ...); + for (int iBatch{0}; iBatch < nBatches; ++iBatch) { + auto& stream = gpuInterface->getNextStream(); + auto offset = iBatch * batchSize + std::min(iBatch, remainder); + auto nFits = batchSize + (iBatch < remainder ? 1 : 0); + + gpuCheckError(cudaEventRecord(startIOUp[iBatch], stream)); + gpuCheckError(cudaMemcpyAsync(fitters_device + offset, fitters.data() + offset, sizeof(Fitter) * nFits, cudaMemcpyHostToDevice, stream)); + iArg = 0; + ([&] { + gpuCheckError(cudaMemcpyAsync(tracks_device[iArg] + offset, args.data() + offset, sizeof(Tr) * nFits, cudaMemcpyHostToDevice, stream)); + ++iArg; + }(), + ...); + gpuCheckError(cudaEventRecord(endIOUp[iBatch], stream)); + + gpuCheckError(cudaEventRecord(startKer[iBatch], stream)); + std::apply([&](auto&&... args) { kernel::processBatchKernel<<>>(fitters_device, results_device, offset, nFits, args...); }, tracks_device); + gpuCheckError(cudaEventRecord(endKer[iBatch], stream)); + + gpuCheckError(cudaPeekAtLastError()); + iArg = 0; + gpuCheckError(cudaEventRecord(startIODown[iBatch], stream)); + ([&] { + gpuCheckError(cudaMemcpyAsync(args.data() + offset, tracks_device[iArg] + offset, sizeof(Tr) * nFits, cudaMemcpyDeviceToHost, stream)); + ++iArg; + }(), + ...); + + gpuCheckError(cudaMemcpyAsync(fitters.data() + offset, fitters_device + offset, sizeof(Fitter) * nFits, cudaMemcpyDeviceToHost, stream)); + gpuCheckError(cudaMemcpyAsync(results.data() + offset, results_device + offset, sizeof(int) * nFits, cudaMemcpyDeviceToHost, stream)); + gpuCheckError(cudaEventRecord(endIODown[iBatch], stream)); + } - gpuCheckError(cudaFree(fitters_device)); - gpuCheckError(cudaFree(results_device)); - gpuCheckError(cudaEventSynchronize(stop)); + ([&] { gpuInterface->unregisterBuffer(args.data()); }(), ...); - float milliseconds = 0; - gpuCheckError(cudaEventElapsedTime(&milliseconds, start, stop)); + for (auto* tracksD : tracks_device) { + gpuInterface->freeDevice(tracksD); + } + + gpuInterface->freeDevice(fitters_device); + gpuInterface->freeDevice(results_device); + gpuInterface->unregisterBuffer(fitters.data()); + gpuInterface->unregisterBuffer(results.data()); - LOGP(info, "Kernel run in: {} ms using {} blocks and {} threads.", milliseconds, nBlocks, nThreads); - return results; + // Do benchmarks + gpuCheckError(cudaDeviceSynchronize()); + for (int iBatch{0}; iBatch < nBatches; ++iBatch) { + gpuCheckError(cudaEventElapsedTime(&ioUp[iBatch], startIOUp[iBatch], endIOUp[iBatch])); + gpuCheckError(cudaEventElapsedTime(&kerElapsed[iBatch], startKer[iBatch], endKer[iBatch])); + gpuCheckError(cudaEventElapsedTime(&ioDown[iBatch], startIODown[iBatch], endIODown[iBatch])); + } + + float totalUp = std::accumulate(ioUp.begin(), ioUp.end(), 0.f); + float totalDown = std::accumulate(ioDown.begin(), ioDown.end(), 0.f); + float totalKernels = std::accumulate(kerElapsed.begin(), kerElapsed.end(), 0.f); + LOGP(info, "Config: {} batches, {} blocks, {} threads", nBatches, nBlocks, nThreads); + LOGP(info, "Total I/O time: Up {} ms Avg {} ms, Down {} ms Avg {} ms", totalUp, totalUp / float(nBatches), totalDown, totalDown / (float)nBatches); + LOGP(info, "Total Kernel time: {} ms Avg {} ms", totalKernels, totalKernels / (float)nBatches); + + for (int iBatch{0}; iBatch < nBatches; ++iBatch) { + gpuCheckError(cudaEventDestroy(startIOUp[iBatch])); + gpuCheckError(cudaEventDestroy(endIOUp[iBatch])); + gpuCheckError(cudaEventDestroy(startIODown[iBatch])); + gpuCheckError(cudaEventDestroy(endIODown[iBatch])); + gpuCheckError(cudaEventDestroy(startKer[iBatch])); + gpuCheckError(cudaEventDestroy(endKer[iBatch])); + } } -template std::vector processBulk(const int, const int, std::vector>&, std::vector&, std::vector&); -template std::vector processBulk(const int, const int, std::vector>&, std::vector&, std::vector&, std::vector&); +template void processBulk(const int, + const int, + const int, + std::vector>&, + std::vector&, + std::vector&, + std::vector&); +template void processBulk(const int, + const int, + const int, + std::vector>&, + std::vector&, + std::vector&, + std::vector&, + std::vector&); template int process(const int, const int, o2::vertexing::DCAFitterN<2>&, o2::track::TrackParCov&, o2::track::TrackParCov&); template int process(const int, const int, o2::vertexing::DCAFitterN<3>&, o2::track::TrackParCov&, o2::track::TrackParCov&, o2::track::TrackParCov&); template void print(const int, const int, o2::vertexing::DCAFitterN<2>&); diff --git a/Common/DCAFitter/GPU/cuda/GPUInterface.cu b/Common/DCAFitter/GPU/cuda/GPUInterface.cu new file mode 100644 index 0000000000000..09f9cdc595dcd --- /dev/null +++ b/Common/DCAFitter/GPU/cuda/GPUInterface.cu @@ -0,0 +1,108 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \brief Helper interface to the GPU device, meant to be compatible with manual allocation/streams and GPUReconstruction ones. +/// \author matteo.concas@cern.ch + +#ifdef __HIPCC__ +#include "hip/hip_runtime.h" +#else +#include +#endif + +#include +#include + +#include "DeviceInterface/GPUInterface.h" + +#define gpuCheckError(x) \ + { \ + gpuAssert((x), __FILE__, __LINE__); \ + } +#define gpuCheckErrorSoft(x) \ + { \ + gpuAssert((x), __FILE__, __LINE__, false); \ + } +inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort = true) +{ + if (code != cudaSuccess) { + std::cerr << "GPUassert: " << cudaGetErrorString(code) << " " << file << " " << line << std::endl; + if (abort) { + throw std::runtime_error("GPU assert failed."); + } + } +} + +namespace o2::vertexing::device +{ + +GPUInterface::GPUInterface(size_t N) +{ + resize(N); + for (auto& st : mStreams) { + gpuCheckError(cudaStreamCreate(&st)); + } +} + +GPUInterface::~GPUInterface() +{ + for (auto& st : mStreams) { + gpuCheckError(cudaStreamDestroy(st)); + } +} + +void GPUInterface::resize(size_t N) +{ + mPool.resize(N); + mStreams.resize(N); +} + +void GPUInterface::registerBuffer(void* addr, size_t bufferSize) +{ + gpuCheckError(cudaHostRegister(addr, bufferSize, cudaHostRegisterDefault)); +} + +void GPUInterface::unregisterBuffer(void* addr) +{ + gpuCheckError(cudaHostUnregister(addr)); +} + +GPUInterface* GPUInterface::sGPUInterface = nullptr; +GPUInterface* GPUInterface::Instance() +{ + if (sGPUInterface == nullptr) { + const auto* envValue = std::getenv("GPUINTERFACE_NSTREAMS"); + sGPUInterface = new GPUInterface(envValue == nullptr ? 8 : std::stoi(envValue)); + } + return sGPUInterface; +} + +void GPUInterface::allocDevice(void** addrPtr, size_t bufferSize) +{ + gpuCheckError(cudaMalloc(addrPtr, bufferSize)); +} + +void GPUInterface::freeDevice(void* addr) +{ + gpuCheckError(cudaFree(addr)); +} + +Stream& GPUInterface::getStream(unsigned short N) +{ + return mStreams[N % mStreams.size()]; +} + +Stream& GPUInterface::getNextStream() +{ + unsigned short next = mLastUsedStream.fetch_add(1) % mStreams.size(); // wrap-around + automatic wrap-around beyond 65535 + return mStreams[next]; +} +} // namespace o2::vertexing::device \ No newline at end of file diff --git a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx index ff4f12827f1e8..a7254931737cb 100644 --- a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx +++ b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx @@ -23,10 +23,6 @@ #include #include -#define nBlocks 60 -#define nThreads 1024 -#define NTest 1000000 - namespace o2 { namespace vertexing @@ -231,11 +227,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) meanDAW /= nfoundAW ? nfoundA : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundA) / NTest << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAW) / NTest << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); @@ -309,11 +305,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) meanDAW /= nfoundA ? nfoundA : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices Helix : Helix from gamma conversion"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundA) / NTest << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAW) / NTest << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); @@ -387,11 +383,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Helix : Line"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundA) / NTest << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAW) / NTest << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); @@ -464,11 +460,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 2-prong vertices: Line : Line"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundA) / NTest << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAW) / NTest << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); @@ -540,11 +536,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) meanDAW /= nfoundAW ? nfoundAW : 1; meanDW /= nfoundW ? nfoundW : 1; LOG(info) << "Processed " << NTest << " 3-prong vertices"; - LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundA) / NTest + LOG(info) << "3-prongs with abs.dist minimization: eff = " << float(nfoundA) / NTest << " mean.dist to truth: " << meanDA << " Total time: " << swA.CpuTime(); - LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAW) / NTest + LOG(info) << "3-prongs with abs.dist but wghPCA: eff = " << float(nfoundAW) / NTest << " mean.dist to truth: " << meanDAW << " Total time: " << swAW.CpuTime(); - LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundW) / NTest + LOG(info) << "3-prongs with wgh.dist minimization: eff = " << float(nfoundW) / NTest << " mean.dist to truth: " << meanDW << " Total time: " << swW.CpuTime(); BOOST_CHECK(nfoundA > 0.99 * NTest); BOOST_CHECK(nfoundAW > 0.99 * NTest); @@ -560,8 +556,15 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs) BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) { - // gRandom->Delete(); - // gRandom = new TRandom(42); + const char* nThreadsEnvVarName = "DCAFITTERGPU_TEST_NTHREADS"; + const char* nBlocksEnvVarName = "DCAFITTERGPU_TEST_NBLOCKS"; + const char* nBatchesEnvVarName = "DCAFITTERGPU_TEST_NBATCHES"; + const char* nTestsEnvVarName = "DCAFITTERGPU_TEST_NTESTS"; + int nBlocks = std::getenv(nThreadsEnvVarName) == nullptr ? 30 : std::stoi(std::getenv(nThreadsEnvVarName)); + int nThreads = std::getenv(nBlocksEnvVarName) == nullptr ? 256 : std::stoi(std::getenv(nBlocksEnvVarName)); + int nBatches = std::getenv(nBatchesEnvVarName) == nullptr ? 8 : std::stoi(std::getenv(nBatchesEnvVarName)); + int NTest = std::getenv(nTestsEnvVarName) == nullptr ? 100001 : std::stoi(std::getenv(nTestsEnvVarName)); + o2::utils::TreeStreamRedirector outStreamB("dcafitterNTestBulk.root"); TGenPhaseSpace genPHS; @@ -612,7 +615,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) } swAb.Start(false); - auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -628,7 +632,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(true); std::fill(fitters_host.begin(), fitters_host.end(), ft); swAWb.Start(false); - auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -644,7 +649,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(false); std::fill(fitters_host.begin(), fitters_host.end(), ft); swWb.Start(false); - auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -660,11 +666,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) meanDAWb /= nfoundAWb ? nfoundAWb : 1; meanDWb /= nfoundWb ? nfoundWb : 1; LOGP(info, "Bulk-processed {} 2-prong vertices Helix : Helix", NTest); - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundAb) / NTest << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAWb) / NTest << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundWb) / NTest << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundAb > 0.99 * NTest); BOOST_CHECK(nfoundAWb > 0.99 * NTest); @@ -708,7 +714,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) } swAb.Start(false); - auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -724,7 +731,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(true); std::fill(fitters_host.begin(), fitters_host.end(), ft); swAWb.Start(false); - auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -740,7 +748,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(false); std::fill(fitters_host.begin(), fitters_host.end(), ft); swWb.Start(false); - auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -757,11 +766,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) meanDAWb /= nfoundAWb ? nfoundAWb : 1; meanDWb /= nfoundWb ? nfoundWb : 1; LOGP(info, "Bulk-processed {} 2-prong vertices Helix : Helix from gamma conversion", NTest); - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundAb) / NTest << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAWb) / NTest << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundWb) / NTest << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundAb > 0.99 * NTest); BOOST_CHECK(nfoundAWb > 0.99 * NTest); @@ -806,7 +815,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) std::fill(fitters_host.begin(), fitters_host.end(), ft); swAb.Start(false); - auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -822,7 +832,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(true); std::fill(fitters_host.begin(), fitters_host.end(), ft); swAWb.Start(false); - auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -838,7 +849,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(false); std::fill(fitters_host.begin(), fitters_host.end(), ft); swWb.Start(false); - auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -855,11 +867,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) meanDAWb /= nfoundAWb ? nfoundAWb : 1; meanDWb /= nfoundWb ? nfoundWb : 1; LOG(info) << "Bulk-processed " << NTest << " 2-prong vertices: Helix : Line"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundAb) / NTest << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAWb) / NTest << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundWb) / NTest << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundAb > 0.99 * NTest); BOOST_CHECK(nfoundAWb > 0.99 * NTest); @@ -903,7 +915,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) std::fill(fitters_host.begin(), fitters_host.end(), ft); swAb.Start(false); - auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -919,7 +932,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setWeightedFinalPCA(true); std::fill(fitters_host.begin(), fitters_host.end(), ft); swAWb.Start(false); - auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncAWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swAWb.Stop(); for (int iev = 0; iev < NTest; iev++) { LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); @@ -935,7 +949,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) std::fill(fitters_host.begin(), fitters_host.end(), ft); swWb.Start(false); - auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES + std::vector ncWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncWb, vctracks[0], vctracks[1]); // HERE WE FIT THE VERTICES swWb.Stop(); for (int iev = 0; iev < NTest; iev++) { @@ -951,11 +966,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) meanDAWb /= nfoundAWb ? nfoundAWb : 1; meanDWb /= nfoundWb ? nfoundWb : 1; LOG(info) << "Bulk-processed " << NTest << " 2-prong vertices: Line : Line"; - LOG(info) << "2-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + LOG(info) << "2-prongs with abs.dist minimization: eff = " << float(nfoundAb) / NTest << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + LOG(info) << "2-prongs with abs.dist but wghPCA: eff = " << float(nfoundAWb) / NTest << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; - LOG(info) << "2-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + LOG(info) << "2-prongs with wgh.dist minimization: eff = " << float(nfoundWb) / NTest << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundAb > 0.99 * NTest); BOOST_CHECK(nfoundAWb > 0.99 * NTest); @@ -1000,7 +1015,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) ft.setUseAbsDCA(true); std::fill(fitters_host.begin(), fitters_host.end(), ft); swAb.Start(false); - auto ncAb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + std::vector ncAb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAb, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES swAb.Stop(); for (int iev = 0; iev < NTest; iev++) { LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAb[iev] << " Chi2: " << (ncAb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); @@ -1016,7 +1032,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) std::fill(fitters_host.begin(), fitters_host.end(), ft); swAWb.Start(false); - auto ncAWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + std::vector ncAWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncAWb, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES swAWb.Stop(); for (int iev = 0; iev < NTest; iev++) { LOG(debug) << "fit abs.dist " << iev << " NC: " << ncAWb[iev] << " Chi2: " << (ncAWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); @@ -1032,7 +1049,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) std::fill(fitters_host.begin(), fitters_host.end(), ft); swWb.Start(false); - auto ncWb = device::processBulk(nBlocks, nThreads, fitters_host, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES + std::vector ncWb(NTest, 0); + device::processBulk(nBlocks, nThreads, nBatches, fitters_host, ncWb, vctracks[0], vctracks[1], vctracks[2]); // HERE WE FIT THE VERTICES swWb.Stop(); for (int iev = 0; iev < NTest; iev++) { LOG(debug) << "fit wgh.dist " << iev << " NC: " << ncWb[iev] << " Chi2: " << (ncWb[iev] ? fitters_host[iev].getChi2AtPCACandidate(0) : -1); @@ -1048,11 +1066,11 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) meanDAWb /= nfoundAWb ? nfoundAWb : 1; meanDWb /= nfoundWb ? nfoundWb : 1; LOG(info) << "Bulk-processed " << NTest << " 3-prong vertices"; - LOG(info) << "3-prongs with abs.dist minization: eff= " << float(nfoundAb) / NTest + LOG(info) << "3-prongs with abs.dist minimization: eff = " << float(nfoundAb) / NTest << " mean.dist to truth: " << meanDAb << " Total time: " << swAb.CpuTime() * 1000 << " ms"; - LOG(info) << "3-prongs with abs.dist but wghPCA: eff= " << float(nfoundAWb) / NTest + LOG(info) << "3-prongs with abs.dist but wghPCA: eff = " << float(nfoundAWb) / NTest << " mean.dist to truth: " << meanDAWb << " Total time: " << swAWb.CpuTime() * 1000 << " ms"; - LOG(info) << "3-prongs with wgh.dist minization: eff= " << float(nfoundWb) / NTest + LOG(info) << "3-prongs with wgh.dist minimization: eff = " << float(nfoundWb) / NTest << " mean.dist to truth: " << meanDWb << " Total time: " << swWb.CpuTime() * 1000 << " ms"; BOOST_CHECK(nfoundAb > 0.99 * NTest); BOOST_CHECK(nfoundAWb > 0.99 * NTest); diff --git a/Common/DCAFitter/GPU/hip/CMakeLists.txt b/Common/DCAFitter/GPU/hip/CMakeLists.txt index 272d18a81bab4..f62759bb6ea2c 100644 --- a/Common/DCAFitter/GPU/hip/CMakeLists.txt +++ b/Common/DCAFitter/GPU/hip/CMakeLists.txt @@ -12,7 +12,8 @@ set(CMAKE_HIP_FLAGS "${CMAKE_HIP_FLAGS} -fgpu-rdc") o2_add_hipified_library(DCAFitterHIP SOURCES ../cuda/DCAFitterN.cu - PUBLIC_INCLUDE_DIRECTORIES ../../include + ../cuda/GPUInterface.cu + PUBLIC_INCLUDE_DIRECTORIES ../../include ../ PUBLIC_LINK_LIBRARIES O2::MathUtils O2::ReconstructionDataFormats O2::DetectorsBase diff --git a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h index 5a89597ad379a..2e36f7588e8be 100644 --- a/Common/DCAFitter/include/DCAFitter/DCAFitterN.h +++ b/Common/DCAFitter/include/DCAFitter/DCAFitterN.h @@ -1142,7 +1142,7 @@ template int process(const int nBlocks, const int nThreads, Fitter&, Tr&... args); template -std::vector processBulk(const int nBlocks, const int nThreads, std::vector& fitters, std::vector
&... args); +void processBulk(const int nBlocks, const int nThreads, const int nBatches, std::vector& fitters, std::vector& results, std::vector
&... args); } // namespace device } // namespace vertexing diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Stream.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Stream.h index b6fbbe166cafe..20744b47cd9b5 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Stream.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Stream.h @@ -32,7 +32,7 @@ class Stream final Stream(); ~Stream(); - const GPUStream& get() const; + [[nodiscard]] const GPUStream& get() const; private: GPUStream mStream; From 4138bafcdd629bf889d92e3b50d6330459810294 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 2 Oct 2024 06:49:37 +0200 Subject: [PATCH 0292/2205] DPL Analysis: add option to artificially slow down AOD reader (#13549) --- .../src/AODJAlienReaderHelpers.cxx | 19 +++++++++++++++++-- Framework/Core/src/WorkflowHelpers.cxx | 4 +++- Framework/Core/src/runDataProcessing.cxx | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx index 5ce2eca49c07b..a8b708668dae1 100644 --- a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx +++ b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx @@ -41,8 +41,6 @@ #include #include -#include - using namespace o2; using namespace o2::aod; @@ -140,6 +138,8 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback() auto filename = options.get("aod-file-private"); + auto maxRate = options.get("aod-max-io-rate"); + std::string parentFileReplacement; if (options.isSet("aod-parent-base-path-replacement")) { parentFileReplacement = options.get("aod-parent-base-path-replacement"); @@ -192,6 +192,7 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback() fileCounter, numTF, watchdog, + maxRate, didir, reportTFN, reportTFFileName](Monitoring& monitoring, DataAllocator& outputs, ControlService& control, DeviceSpec const& device) { // Each parallel reader device.inputTimesliceId reads the files fileCounter*device.maxInputTimeslices+device.inputTimesliceId // the TF to read is numTF @@ -222,6 +223,8 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback() return; } + int64_t startTime = uv_hrtime(); + int64_t startSize = totalSizeCompressed; for (auto& route : requestedTables) { if ((device.inputTimesliceId % route.maxTimeslices) != route.timeslice) { continue; @@ -278,6 +281,18 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback() } first = false; } + int64_t stopSize = totalSizeCompressed; + int64_t bytesDelta = stopSize - startSize; + int64_t stopTime = uv_hrtime(); + float currentDelta = float(stopTime - startTime) / 1000000000; // in s + if (ceil(maxRate) > 0.) { + float extraTime = (bytesDelta / 1000000 - currentDelta * maxRate) / maxRate; + // We only sleep if we read faster than the max-read-rate. + if (extraTime > 0.) { + LOGP(info, "Read {} MB in {} s. Sleeping for {} seconds to stay within {} MB/s limit.", bytesDelta / 1000000, currentDelta, extraTime, maxRate); + uv_sleep(extraTime * 1000); // in milliseconds + } + } totalDFSent++; monitoring.send(Metric{(uint64_t)totalDFSent, "df-sent"}.addTag(Key::Subsystem, monitoring::tags::Value::DPL)); monitoring.send(Metric{(uint64_t)totalSizeUncompressed / 1000, "aod-bytes-read-uncompressed"}.addTag(Key::Subsystem, monitoring::tags::Value::DPL)); diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 30246492b8b65..6349bd5889eba 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -12,6 +12,7 @@ #include "AnalysisSupportHelpers.h" #include "Framework/AlgorithmSpec.h" #include "Framework/AODReaderHelpers.h" +#include "Framework/ConfigParamSpec.h" #include "Framework/ConfigParamsHelper.h" #include "Framework/CommonDataProcessors.h" #include "Framework/ConfigContext.h" @@ -27,6 +28,7 @@ #include "Framework/DefaultsHelpers.h" #include "Framework/Signpost.h" +#include "Framework/Variant.h" #include "Headers/DataHeader.h" #include #include @@ -34,7 +36,6 @@ #include #include #include -#include O2_DECLARE_DYNAMIC_LOG(workflow_helpers); @@ -213,6 +214,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext aodLifetime}}, .algorithm = AlgorithmSpec::dummyAlgorithm(), .options = {ConfigParamSpec{"aod-file-private", VariantType::String, ctx.options().get("aod-file"), {"AOD file"}}, + ConfigParamSpec{"aod-max-io-rate", VariantType::Float, 0.f, {"Maximum I/O rate in MB/s"}}, ConfigParamSpec{"aod-reader-json", VariantType::String, {"json configuration file"}}, ConfigParamSpec{"aod-parent-access-level", VariantType::String, {"Allow parent file access up to specified level. Default: no (0)"}}, ConfigParamSpec{"aod-parent-base-path-replacement", VariantType::String, {R"(Replace base path of parent files. Syntax: FROM;TO. E.g. "alien:///path/in/alien;/local/path". Enclose in "" on the command line.)"}}, diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 0cf775a33de18..d4d0c836aa925 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -2026,6 +2026,7 @@ int runStateMachine(DataProcessorSpecs const& workflow, "--aod-writer-resmode", "--aod-writer-maxfilesize", "--aod-writer-keep", + "--aod-max-io-rate", "--aod-parent-access-level", "--aod-parent-base-path-replacement", "--driver-client-backend", From 8572af89aca1d47d47a245a7279d7ae842641ec8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 2 Oct 2024 13:30:40 +0200 Subject: [PATCH 0293/2205] Add quiet predictedChi2 call (#13548) --- .../TrackParametrizationWithError.h | 9 +++++---- .../src/TrackParametrizationWithError.cxx | 2 +- Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h index 0f01713d50beb..536bacf1a6a70 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h @@ -93,9 +93,9 @@ class TrackParametrizationWithError : public TrackParametrization GPUd() bool propagateToDCA(const o2::dataformats::VertexBase& vtx, value_t b, o2::dataformats::DCA* dca = nullptr, value_t maxD = 999.f); GPUd() void invert(); GPUd() value_t getPredictedChi2(const dim2_t& p, const dim3_t& cov) const; - GPUd() value_t getPredictedChi2Unchecked(const dim2_t& p, const dim3_t& cov) const; + GPUd() value_t getPredictedChi2Quiet(const dim2_t& p, const dim3_t& cov) const; GPUd() value_t getPredictedChi2(const value_t* p, const value_t* cov) const; - GPUd() value_t getPredictedChi2Unchecked(const value_t* p, const value_t* cov) const; + GPUd() value_t getPredictedChi2Quiet(const value_t* p, const value_t* cov) const; template GPUd() value_t getPredictedChi2(const BaseCluster& p) const; @@ -103,6 +103,7 @@ class TrackParametrizationWithError : public TrackParametrization void buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const; value_t getPredictedChi2(const TrackParametrizationWithError& rhs, MatrixDSym5& covToSet) const; GPUd() value_t getPredictedChi2(const TrackParametrizationWithError& rhs) const; + GPUd() value_t getPredictedChi2Quiet(const TrackParametrizationWithError& rhs) const; bool update(const TrackParametrizationWithError& rhs, const MatrixDSym5& covInv); bool update(const TrackParametrizationWithError& rhs); @@ -322,9 +323,9 @@ GPUdi() auto TrackParametrizationWithError::getPredictedChi2(const dim2 //______________________________________________ template -GPUdi() auto TrackParametrizationWithError::getPredictedChi2Unchecked(const dim2_t& p, const dim3_t& cov) const -> value_t +GPUdi() auto TrackParametrizationWithError::getPredictedChi2Quiet(const dim2_t& p, const dim3_t& cov) const -> value_t { - return getPredictedChi2Unchecked(p.data(), cov.data()); + return getPredictedChi2Quiet(p.data(), cov.data()); } //______________________________________________ diff --git a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx index da15aefcf958f..e56830deace14 100644 --- a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx @@ -736,7 +736,7 @@ GPUd() auto TrackParametrizationWithError::getPredictedChi2(const value //______________________________________________ template -GPUd() auto TrackParametrizationWithError::getPredictedChi2Unchecked(const value_t* p, const value_t* cov) const -> value_t +GPUd() auto TrackParametrizationWithError::getPredictedChi2Quiet(const value_t* p, const value_t* cov) const -> value_t { // Estimate the chi2 of the space point "p" with the cov. matrix "cov" auto sdd = static_cast(getSigmaY2()) + static_cast(cov[0]); diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index 4763508adc003..4457d4515e0a6 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -355,7 +355,7 @@ void TrackerTraits::computeLayerCells(const int iteration) break; } - auto predChi2{track.getPredictedChi2(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; + auto predChi2{track.getPredictedChi2Quiet(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; if (!track.o2::track::TrackParCov::update(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)) { break; } @@ -536,7 +536,7 @@ void TrackerTraits::processNeighbours(int iLayer, int iLevel, const std::vector< } } - auto predChi2{seed.getPredictedChi2(trHit.positionTrackingFrame, trHit.covarianceTrackingFrame)}; + auto predChi2{seed.getPredictedChi2Quiet(trHit.positionTrackingFrame, trHit.covarianceTrackingFrame)}; if ((predChi2 > mTrkParams[0].MaxChi2ClusterAttachment) || predChi2 < 0.f) { CA_DEBUGGER(failed[3]++); continue; @@ -781,7 +781,7 @@ void TrackerTraits::findShortPrimaries() float pvRes{mTrkParams[0].PVres / o2::gpu::CAMath::Sqrt(float(pvs[iV].getNContributors()))}; const float posVtx[2]{0.f, pvs[iV].getZ()}; const float covVtx[3]{pvRes, 0.f, pvRes}; - float chi2 = temporaryTrack.getPredictedChi2(posVtx, covVtx); + float chi2 = temporaryTrack.getPredictedChi2Quiet(posVtx, covVtx); if (chi2 < bestChi2) { if (!temporaryTrack.track::TrackParCov::update(posVtx, covVtx)) { continue; @@ -837,7 +837,7 @@ bool TrackerTraits::fitTrack(TrackITSExt& track, int start, int end, int step, f } } - auto predChi2{track.getPredictedChi2(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; + auto predChi2{track.getPredictedChi2Quiet(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; if ((nCl >= 3 && predChi2 > chi2clcut) || predChi2 < 0.f) { return false; } @@ -932,7 +932,7 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co continue; } - auto predChi2{tbuParams.getPredictedChi2(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; + auto predChi2{tbuParams.getPredictedChi2Quiet(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; if (predChi2 >= track->getChi2() * mTrkParams[iteration].NSigmaCut) { continue; } From 0a1fe0eb75e68b3f823550f854c785a2e752a1cb Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Thu, 26 Sep 2024 19:36:43 +0200 Subject: [PATCH 0294/2205] TPC: Optimising scaling of distortions in MC - Making simulation of scaled distortions in the digitizer fully consistent with the scaled corrections in the reconstruction - cleaning some old code --- Detectors/TPC/simulation/src/Digitizer.cxx | 2 +- .../include/TPCSpaceCharge/SpaceCharge.h | 15 ++ Detectors/TPC/spacecharge/src/SpaceCharge.cxx | 192 ++++++++++++++++-- 3 files changed, 193 insertions(+), 16 deletions(-) diff --git a/Detectors/TPC/simulation/src/Digitizer.cxx b/Detectors/TPC/simulation/src/Digitizer.cxx index 290cd84df9a6b..15cc86edaecab 100644 --- a/Detectors/TPC/simulation/src/Digitizer.cxx +++ b/Detectors/TPC/simulation/src/Digitizer.cxx @@ -257,7 +257,7 @@ void Digitizer::recalculateDistortions() mSpaceChargeDer->calcGlobalCorrWithGlobalDistIterative(side, nullptr, 0); LOGP(info, "Calculating scaled distortions with scaling factor {}", mLumiScaleFactor); - mSpaceCharge->calcGlobalDistWithGlobalCorrIterative(side, mSpaceChargeDer.get(), mLumiScaleFactor); + mSpaceCharge->calcGlobalDistWithGlobalCorrIterativeLinearCartesian(side, mSpaceChargeDer.get(), mLumiScaleFactor); } // set new lumi of avg map mSpaceCharge->setMeanLumi(CorrMapParam::Instance().lumiInst); diff --git a/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h b/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h index 4362d95738692..ad76ec2b6da5b 100644 --- a/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h +++ b/Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h @@ -369,6 +369,20 @@ class SpaceCharge void calcGlobalCorrWithGlobalDistIterative(const Side side, const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); void calcGlobalCorrWithGlobalDistIterative(const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6); + /// Calculate global distortions using the global corrections by scaling with second distortion object, which will be consistent with scaled corrections in cartesian coordinates (as done in the tracking) + /// \param side Side of the TPC + /// \param scSCale possible second sc object + /// \param scale scaling for second sc object + void calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const Side side, const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6); + void calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6); + + /// Calculate global corrections using the global distortions by scaling with second distortion object, which will be consistent with scaled corrections in cartesian coordinates + /// \param side Side of the TPC + /// \param scSCale possible second sc object + /// \param scale scaling for second sc object + void calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const Side side, const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6); + void calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const SpaceCharge* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6); + /// \return returns number of vertices in z direction unsigned short getNZVertices() const { return mParamGrid.NZVertices; } @@ -1373,6 +1387,7 @@ class SpaceCharge void initRodAlignmentVoltages(const MisalignmentType misalignmentType, const FCType fcType, const int sector, const Side side, const float deltaPot); void calcGlobalDistCorrIterative(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr, const SpaceCharge* scSCale, float scale, const Type type); + void calcGlobalDistCorrIterativeLinearCartesian(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr, const SpaceCharge* scSCale, float scale, const Type type); ClassDefNV(SpaceCharge, 6); }; diff --git a/Detectors/TPC/spacecharge/src/SpaceCharge.cxx b/Detectors/TPC/spacecharge/src/SpaceCharge.cxx index 6748de7ae9916..07101bac15c23 100644 --- a/Detectors/TPC/spacecharge/src/SpaceCharge.cxx +++ b/Detectors/TPC/spacecharge/src/SpaceCharge.cxx @@ -757,15 +757,6 @@ void SpaceCharge::calcGlobalDistCorrIterative(const DistCorrInterpolator< const DataT radius = getRVertex(iR, side); for (unsigned int iZ = 1; iZ < mParamGrid.NZVertices; ++iZ) { const DataT z = getZVertex(iZ, side); - - unsigned int nearestiZ = iZ; - unsigned int nearestiR = iR; - unsigned int nearestiPhi = iPhi; - - DataT nearestZ = getZVertex(nearestiZ, side); - DataT nearestR = getRVertex(nearestiR, side); - DataT nearestPhi = getPhiVertex(nearestiPhi, side); - // //========================================================================================== //==== start algorithm: use tricubic upsampling to numerically approach the query point ==== @@ -774,9 +765,9 @@ void SpaceCharge::calcGlobalDistCorrIterative(const DistCorrInterpolator< // 1. calculate difference from nearest point to query point with stepwidth factor x // and approach the new point // - DataT stepR = (radius - nearestR) * approachR; - DataT stepZ = (z - nearestZ) * approachZ; - DataT stepPhi = (phi - nearestPhi) * approachPhi; + DataT stepR = 0; + DataT stepZ = 0; + DataT stepPhi = 0; // needed to check for convergence DataT lastCorrdR = std::numeric_limits::max(); @@ -790,9 +781,9 @@ void SpaceCharge::calcGlobalDistCorrIterative(const DistCorrInterpolator< for (int iter = 0; iter < maxIter; ++iter) { // 2. get new point coordinates - const DataT rCurrPos = getRVertex(nearestiR, side) + stepR; - const DataT zCurrPos = getZVertex(nearestiZ, side) + stepZ; - const DataT phiCurrPos = getPhiVertex(nearestiPhi, side) + stepPhi; + const DataT rCurrPos = radius + stepR; + const DataT zCurrPos = z + stepZ; + const DataT phiCurrPos = phi + stepPhi; // abort calculation of drift path if electron reached inner/outer field cage or central electrode if (rCurrPos <= getRMinSim(side) || rCurrPos >= getRMaxSim(side) || getSide(zCurrPos) != side) { @@ -867,6 +858,177 @@ void SpaceCharge::calcGlobalDistCorrIterative(const DistCorrInterpolator< } } +template +void SpaceCharge::calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const Side side, const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr) +{ + calcGlobalDistCorrIterativeLinearCartesian(getGlobalCorrInterpolator(side), maxIter, approachX, approachY, approachZ, diffCorr, scSCale, scale, Type::Distortions); +} + +template +void SpaceCharge::calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr) +{ +#pragma omp parallel for num_threads(sNThreads) + for (int iside = 0; iside < FNSIDES; ++iside) { + const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C; + calcGlobalDistWithGlobalCorrIterativeLinearCartesian(side, scSCale, scale, maxIter, approachX, approachY, approachZ, diffCorr); + } +} + +template +void SpaceCharge::calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const Side side, const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr) +{ + calcGlobalDistCorrIterativeLinearCartesian(getGlobalDistInterpolator(side), maxIter, approachX, approachY, approachZ, diffCorr, scSCale, scale, Type::Corrections); +} + +template +void SpaceCharge::calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const SpaceCharge* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr) +{ +#pragma omp parallel for num_threads(sNThreads) + for (int iside = 0; iside < FNSIDES; ++iside) { + const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C; + calcGlobalCorrWithGlobalDistIterativeLinearCartesian(side, scSCale, scale, maxIter, approachX, approachY, approachZ, diffCorr); + } +} + +template +void SpaceCharge::calcGlobalDistCorrIterativeLinearCartesian(const DistCorrInterpolator& globCorr, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr, const SpaceCharge* scSCale, float scale, const Type type) +{ + const Side side = globCorr.getSide(); + if (type == Type::Distortions) { + initContainer(mGlobalDistdR[side], true); + initContainer(mGlobalDistdZ[side], true); + initContainer(mGlobalDistdRPhi[side], true); + } else { + initContainer(mGlobalCorrdR[side], true); + initContainer(mGlobalCorrdZ[side], true); + initContainer(mGlobalCorrdRPhi[side], true); + } + + const auto& scSCaleInterpolator = (type == Type::Distortions) ? scSCale->mInterpolatorGlobalCorr[side] : scSCale->mInterpolatorGlobalDist[side]; + +#pragma omp parallel for num_threads(sNThreads) + for (unsigned int iPhi = 0; iPhi < mParamGrid.NPhiVertices; ++iPhi) { + const DataT phi = getPhiVertex(iPhi, side); + for (unsigned int iR = 0; iR < mParamGrid.NRVertices; ++iR) { + const DataT radius = getRVertex(iR, side); + const DataT x = getXFromPolar(radius, phi); + const DataT y = getYFromPolar(radius, phi); + + for (unsigned int iZ = 1; iZ < mParamGrid.NZVertices; ++iZ) { + const DataT z = getZVertex(iZ, side); + + DataT stepX = 0; + DataT stepY = 0; + DataT stepZ = 0; + + // needed to check for convergence + DataT lastCorrX = std::numeric_limits::max(); + DataT lastCorrY = std::numeric_limits::max(); + DataT lastCorrZ = std::numeric_limits::max(); + DataT lastX = std::numeric_limits::max(); + DataT lastY = std::numeric_limits::max(); + DataT lastZ = std::numeric_limits::max(); + + for (int iter = 0; iter < maxIter; ++iter) { + const DataT xCurrPos = x + stepX; + const DataT yCurrPos = y + stepY; + const DataT zCurrPos = z + stepZ; + + // abort calculation of drift path if electron reached inner/outer field cage or central electrode + const DataT rCurrPos = getRadiusFromCartesian(xCurrPos, yCurrPos); + if (rCurrPos <= getRMinSim(side) || rCurrPos >= getRMaxSim(side) || getSide(zCurrPos) != side) { + break; + } + + // interpolate global correction at new point and calculate position of global correction + DataT corrX = 0; + DataT corrY = 0; + DataT corrZ = 0; + (type == Type::Distortions) ? getCorrections(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ) : getDistortions(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ); + + if (scSCale && scale != 0) { + DataT corrXScale = 0; + DataT corrYScale = 0; + DataT corrZScale = 0; + (type == Type::Distortions) ? scSCale->getCorrections(xCurrPos, yCurrPos, zCurrPos, side, corrXScale, corrYScale, corrZScale) : getDistortions(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ); + corrX += scale * corrXScale; + corrY += scale * corrYScale; + corrZ += scale * corrZScale; + } + + // check for convergence + const DataT diffCorrX = std::abs(corrX - lastCorrX); + const DataT diffCorrY = std::abs(corrY - lastCorrY); + const DataT diffCorrZ = std::abs(corrZ - lastCorrZ); + + lastCorrX = corrX; + lastCorrY = corrY; + lastCorrZ = corrZ; + lastX = xCurrPos; + lastY = yCurrPos; + lastZ = zCurrPos; + + // stop algorithm if converged + if ((diffCorrX < diffCorr) && (diffCorrY < diffCorr) && (diffCorrZ < diffCorr)) { + break; + } + + const DataT xNewPos = xCurrPos + corrX; + const DataT yNewPos = yCurrPos + corrY; + const DataT zNewPos = zCurrPos + corrZ; + + // approach desired coordinate + stepX += (x - xNewPos) * approachX; + stepY += (y - yNewPos) * approachY; + stepZ += (z - zNewPos) * approachZ; + } + + const DataT xNew = lastX + lastCorrX; + const DataT yNew = lastY + lastCorrY; + const DataT radiusNew = getRadiusFromCartesian(xNew, yNew); + const DataT corrdR = -(radiusNew - getRadiusFromCartesian(lastX, lastY)); + + float phiNew = getPhiFromCartesian(xNew, yNew); + o2::math_utils::bringTo02PiGen(phiNew); + + float phiLast = getPhiFromCartesian(lastX, lastY); + o2::math_utils::bringTo02PiGen(phiLast); + + DataT deltaPhi = (phiNew - phiLast); + // handle edge cases + if (deltaPhi > PI) { + deltaPhi -= 2 * PI; + } else if (deltaPhi < -PI) { + deltaPhi += 2 * PI; + } + const DataT corrdRPhi = -deltaPhi * radiusNew; + + // set global distortions if algorithm converged or iterations exceed max numbers of iterations + if (type == Type::Distortions) { + mGlobalDistdR[side](iZ, iR, iPhi) = corrdR; + mGlobalDistdRPhi[side](iZ, iR, iPhi) = corrdRPhi; + mGlobalDistdZ[side](iZ, iR, iPhi) = -lastCorrZ; + } else { + mGlobalCorrdR[side](iZ, iR, iPhi) = corrdR; + mGlobalCorrdRPhi[side](iZ, iR, iPhi) = corrdRPhi; + mGlobalCorrdZ[side](iZ, iR, iPhi) = -lastCorrZ; + } + } + } + for (unsigned int iR = 0; iR < mParamGrid.NRVertices; ++iR) { + if (type == Type::Distortions) { + mGlobalDistdR[side](0, iR, iPhi) = 3 * (mGlobalDistdR[side](1, iR, iPhi) - mGlobalDistdR[side](2, iR, iPhi)) + mGlobalDistdR[side](3, iR, iPhi); + mGlobalDistdRPhi[side](0, iR, iPhi) = 3 * (mGlobalDistdRPhi[side](1, iR, iPhi) - mGlobalDistdRPhi[side](2, iR, iPhi)) + mGlobalDistdRPhi[side](3, iR, iPhi); + mGlobalDistdZ[side](0, iR, iPhi) = 3 * (mGlobalDistdZ[side](1, iR, iPhi) - mGlobalDistdZ[side](2, iR, iPhi)) + mGlobalDistdZ[side](3, iR, iPhi); + } else { + mGlobalCorrdR[side](0, iR, iPhi) = 3 * (mGlobalCorrdR[side](1, iR, iPhi) - mGlobalCorrdR[side](2, iR, iPhi)) + mGlobalCorrdR[side](3, iR, iPhi); + mGlobalCorrdRPhi[side](0, iR, iPhi) = 3 * (mGlobalCorrdRPhi[side](1, iR, iPhi) - mGlobalCorrdRPhi[side](2, iR, iPhi)) + mGlobalCorrdRPhi[side](3, iR, iPhi); + mGlobalCorrdZ[side](0, iR, iPhi) = 3 * (mGlobalCorrdZ[side](1, iR, iPhi) - mGlobalCorrdZ[side](2, iR, iPhi)) + mGlobalCorrdZ[side](3, iR, iPhi); + } + } + } +} + template NumericalFields SpaceCharge::getElectricFieldsInterpolator(const Side side) const { From 8957bd649d190097d6ebd5afa2d67132ca090568 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner <48915672+matthias-kleiner@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:12:07 +0200 Subject: [PATCH 0295/2205] TPC: adding dEdx space-charge correction (#13557) * TPC: adding dEdx space-charge correction - adding check for shared clusters - adding cluster occupancy * Adding missing include --- Detectors/TPC/calibration/CMakeLists.txt | 4 +- .../include/TPCCalibration/CalculatedEdx.h | 20 +- .../TPCCalibration/CorrectdEdxDistortions.h | 101 ++++++++++ .../TPC/calibration/src/CalculatedEdx.cxx | 63 ++++++- .../src/CorrectdEdxDistortions.cxx | 174 ++++++++++++++++++ 5 files changed, 358 insertions(+), 4 deletions(-) create mode 100644 Detectors/TPC/calibration/include/TPCCalibration/CorrectdEdxDistortions.h create mode 100644 Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx diff --git a/Detectors/TPC/calibration/CMakeLists.txt b/Detectors/TPC/calibration/CMakeLists.txt index 4e569774c86a5..0ec62e5f323b3 100644 --- a/Detectors/TPC/calibration/CMakeLists.txt +++ b/Detectors/TPC/calibration/CMakeLists.txt @@ -56,6 +56,7 @@ o2_add_library(TPCCalibration src/CorrMapParam.cxx src/TPCMShapeCorrection.cxx src/DigitAdd.cxx + src/CorrectdEdxDistortions.cxx PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBase O2::TPCReconstruction ROOT::Minuit Microsoft.GSL::GSL @@ -111,7 +112,8 @@ o2_target_root_dictionary(TPCCalibration include/TPCCalibration/TPCScaler.h include/TPCCalibration/CorrMapParam.h include/TPCCalibration/TPCMShapeCorrection.h - include/TPCCalibration/DigitAdd.h) + include/TPCCalibration/DigitAdd.h + include/TPCCalibration/CorrectdEdxDistortions.h) o2_add_test_root_macro(macro/comparePedestalsAndNoise.C PUBLIC_LINK_LIBRARIES O2::TPCBase diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h index e5889cc302b38..701c840e060eb 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h @@ -24,6 +24,7 @@ #include "CalibdEdxContainer.h" #include "CorrectionMapsHelper.h" #include "CommonUtils/TreeStreamRedirector.h" +#include "TPCCalibration/CorrectdEdxDistortions.h" #include @@ -55,6 +56,7 @@ enum class CorrectionFlags : unsigned short { GainFull = 1 << 2, ///< flag for full gain map from calibration container GainResidual = 1 << 3, ///< flag for residuals gain map from calibration container dEdxResidual = 1 << 4, ///< flag for residual dEdx correction + dEdxSC = 1 << 5, ///< flag for space-charge dEdx correction }; enum class ClusterFlags : unsigned short { @@ -64,6 +66,7 @@ enum class ClusterFlags : unsigned short { ExcludeEdgeCl = 1 << 2, ///< flag to exclude sector edge clusters in dEdx calculation ExcludeSubthresholdCl = 1 << 3, ///< flag to exclude subthreshold clusters in dEdx calculation ExcludeSectorBoundaries = 1 << 4, ///< flag to exclude sector boundary clusters in subthreshold cluster treatment + ExcludeSharedCl = 1 << 5, ///< flag to exclude clusters shared between tracks }; inline CorrectionFlags operator&(CorrectionFlags a, CorrectionFlags b) { return static_cast(static_cast(a) & static_cast(b)); } @@ -111,6 +114,9 @@ class CalculatedEdx /// set the debug streamer void setStreamer(const char* debugRootFile) { mStreamer = std::make_unique(debugRootFile, "recreate"); }; + /// set the debug streamer of the space-charge dedx correction + void setSCStreamer(const char* debugRootFile = "debug_sc_corrections.root") { mSCdEdxCorrection.setStreamer(debugRootFile); } + /// \return returns magnetic field in kG float getFieldNominalGPUBz() { return mFieldNominalGPUBz; } @@ -160,7 +166,8 @@ class CalculatedEdx /// load calibration objects from CCDB /// \param runNumberOrTimeStamp run number or time stamp - void loadCalibsFromCCDB(long runNumberOrTimeStamp); + /// \param isMC set if dEdx space-charge corrections will be loaded for MC or real data + void loadCalibsFromCCDB(long runNumberOrTimeStamp, const bool isMC = false); /// load calibration objects from local CCDB folder /// \param localCCDBFolder local CCDB folder @@ -208,6 +215,15 @@ class CalculatedEdx /// \param object name of the object to load void setPropagatorFromFile(const char* folder, const char* file, const char* object); + /// \param lumi set luminosity for space-charge correction map scaling + void setLumi(const float lumi) { mSCdEdxCorrection.setLumi(lumi); } + + /// \return returns space-charge dedx correctin + auto& getSCCorrection() { return mSCdEdxCorrection; } + + /// \return returns cluster occupancy for given cluster + unsigned int getOccupancy(const o2::tpc::ClusterNative& cl) const; + private: std::vector* mTracks{nullptr}; ///< vector containing the tpc tracks which will be processed std::vector* mTPCTrackClIdxVecInput{nullptr}; ///< input vector with TPC tracks cluster indicies @@ -228,6 +244,8 @@ class CalculatedEdx std::array, 5> mChargeTotROC; std::array, 5> mChargeMaxROC; + + CorrectdEdxDistortions mSCdEdxCorrection; ///< for space-charge correction of dE/dx }; } // namespace o2::tpc diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CorrectdEdxDistortions.h b/Detectors/TPC/calibration/include/TPCCalibration/CorrectdEdxDistortions.h new file mode 100644 index 0000000000000..74e4e58fb5bf8 --- /dev/null +++ b/Detectors/TPC/calibration/include/TPCCalibration/CorrectdEdxDistortions.h @@ -0,0 +1,101 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// @file CorrectdEdxDistortions.h +/// @author Matthias Kleiner, mkleiner@ikf.uni-frankfurt.de +/// + +#ifndef ALICEO2_TPC_CORRECTDEDXDISTORTIONS_H +#define ALICEO2_TPC_CORRECTDEDXDISTORTIONS_H + +#include "GPUTPCGeometry.h" +#include + +// forward declare classes +namespace o2::gpu +{ +class TPCFastTransform; +} + +namespace o2::utils +{ +class TreeStreamRedirector; +} + +namespace o2::tpc +{ + +class CorrectdEdxDistortions +{ + public: + /// Default constructor + CorrectdEdxDistortions(); + + /// Default destructor + ~CorrectdEdxDistortions(); + + /// setting the space-charge corrections from local file + /// \param scAvgFile average space-charge correction map + /// \param scDerFile derivative space-charge correction map + /// \param lumi luminosity which is used for scaling the correction map + void setSCCorrFromFile(const char* scAvgFile, const char* scDerFile, const float lumi = -1); + + /// setting the space-charge corrections + /// \param avg average space-charge correction map + /// \param der derivative space-charge correction map + /// \param lumi luminosity which is used for scaling the correction map + void setCorrectionMaps(o2::gpu::TPCFastTransform* avg, o2::gpu::TPCFastTransform* der, const float lumi); + + /// setting the space-charge corrections + /// \param avg average space-charge correction map + /// \param der derivative space-charge correction map + void setCorrectionMaps(o2::gpu::TPCFastTransform* avg, o2::gpu::TPCFastTransform* der); + + /// \param lumi luminosity which is used for scaling the correction map + void setLumi(float lumi); + + /// enable the debug streamer + void setStreamer(const char* debugRootFile = "debug_sc_corrections.root"); + + /// \return getting the correction value for the cluster charge + /// \param time true time information of the cluster + /// \param sector TPC sector of the cluster + /// \param padrow global padrow + /// \param pad pad number in the padrow + float getCorrection(const float time, unsigned char sector, unsigned char padrow, int pad) const; + + /// set minimum allowed lx correction at lower pad + void setMinLX0(const float minLX) { mLX0Min = minLX; } + + /// set minimum allowed lx correction upper lower pad + void setMinLX1(const float minLX) { mLX1Min = minLX; } + + /// set minimum allowed correction value + void setMinCorr(const float minCorr) { mScCorrMin = minCorr; } + + /// set maximum allowed correction value + void setMaxCorr(const float maxCorr) { mScCorrMax = maxCorr; } + + private: + float mScaleDer = 0; + std::unique_ptr mCorrAvg{nullptr}; ///< correction map for average distortions + std::unique_ptr mCorrDer{nullptr}; ///< correction map for distortions + o2::gpu::GPUTPCGeometry mTPCGeometry; ///< geometry information of TPC + std::unique_ptr mStreamer{nullptr}; ///< debug streamer + float mLX0Min{82}; ///< minimum allowed lx position after correction at position of the bottom pad + float mLX1Min{82}; ///< minimum allowed lx position after correction at position of the top pad + float mScCorrMin{0.7}; ///< minimum allowed correction values + float mScCorrMax{1.6}; ///< maximum allowed correction values +}; +} // namespace o2::tpc + +#endif diff --git a/Detectors/TPC/calibration/src/CalculatedEdx.cxx b/Detectors/TPC/calibration/src/CalculatedEdx.cxx index 00c8a4c8aa743..9809cc454e94f 100644 --- a/Detectors/TPC/calibration/src/CalculatedEdx.cxx +++ b/Detectors/TPC/calibration/src/CalculatedEdx.cxx @@ -26,6 +26,7 @@ #include "CalibdEdxTrackTopologyPol.h" #include "DataFormatsParameters/GRPMagField.h" #include "GPUO2InterfaceUtils.h" +#include "GPUTPCGMMergedTrackHit.h" using namespace o2::tpc; @@ -111,9 +112,12 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl std::vector gainResidualVector; std::vector residualCorrTotVector; std::vector residualCorrMaxVector; + std::vector scCorrVector; std::vector trackVector; std::vector clVector; + std::vector occupancyVector; + std::vector isClusterShared; if (mDebug) { excludeClVector.reserve(nClusters); @@ -134,6 +138,9 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl residualCorrMaxVector.reserve(nClusters); trackVector.reserve(nClusters); clVector.reserve(nClusters); + scCorrVector.reserve(nClusters); + occupancyVector.reserve(nClusters); + isClusterShared.reserve(nClusters); } // for missing clusters @@ -154,6 +161,10 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // set sectorIndex, rowIndex, clusterIndexNumb track.getClusterReference(*mTPCTrackClIdxVecInput, iCl, sectorIndex, rowIndex, clusterIndexNumb); + // check if the cluster is shared + const unsigned int absoluteIndex = mClusterIndex->clusterOffset[sectorIndex][rowIndex] + clusterIndexNumb; + const bool isShared = mRefit ? (mTPCRefitterShMap[absoluteIndex] & GPUCA_NAMESPACE::gpu::GPUTPCGMMergedTrackHit::flagShared) : 0; + // get region, pad, stack and stack ID const int region = Mapper::REGION[rowIndex]; const unsigned char pad = std::clamp(static_cast(cl.getPad() + 0.5f), static_cast(0), Mapper::PADSPERROW[region][Mapper::getLocalRowFromGlobalRow(rowIndex)] - 1); // the left side of the pad is defined at e.g. 3.5 and the right side at 4.5 @@ -179,6 +190,9 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl if (((clusterMask & ClusterFlags::ExcludeEdgeCl) == ClusterFlags::ExcludeEdgeCl) && ((flagsCl & ClusterNative::flagEdge) == ClusterNative::flagEdge)) { excludeCl += 0b100; // 4 for edge cluster } + if (((clusterMask & ClusterFlags::ExcludeSharedCl) == ClusterFlags::ExcludeSharedCl) && isShared) { + excludeCl += 0b10000; // for shared cluster + } // get the x position of the track const float xPosition = Mapper::instance().getPadCentre(PadPos(rowIndex, 0)).X(); @@ -214,6 +228,8 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl offsPadVector.emplace_back(offsPad); trackVector.emplace_back(track); clVector.emplace_back(cl); + occupancyVector.emplace_back(getOccupancy(cl)); + isClusterShared.emplace_back(isShared); topologyCorrVector.emplace_back(-999.f); topologyCorrTotVector.emplace_back(-999.f); @@ -222,6 +238,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl gainResidualVector.emplace_back(-999.f); residualCorrTotVector.emplace_back(-999.f); residualCorrMaxVector.emplace_back(-999.f); + scCorrVector.emplace_back(-999.f); } // to avoid counting the skipped cluster as a subthreshold cluster rowIndexOld = rowIndex; @@ -325,6 +342,19 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl minChargeMax = chargeMax; }; + // space-charge dEdx corrections + const float time = cl.getTime() - track.getTime0(); // ToDo: get correct time from ITS-TPC track if possible + float scCorr = 1.0f; + if ((correctionMask & CorrectionFlags::dEdxSC) == CorrectionFlags::dEdxSC) { + scCorr = mSCdEdxCorrection.getCorrection(time, sectorIndex, rowIndex, pad); + if (scCorr > 0) { + chargeTot /= scCorr; + }; + if (corrMax > 0) { + chargeMax /= scCorr; + }; + } + if (stack == GEMstack::IROCgem) { mChargeTotROC[0].emplace_back(chargeTot); mChargeMaxROC[0].emplace_back(chargeMax); @@ -359,6 +389,8 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl offsPadVector.emplace_back(offsPad); trackVector.emplace_back(track); clVector.emplace_back(cl); + occupancyVector.emplace_back(getOccupancy(cl)); + isClusterShared.emplace_back(isShared); topologyCorrVector.emplace_back(effectiveLength); topologyCorrTotVector.emplace_back(effectiveLengthTot); @@ -367,6 +399,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl gainResidualVector.emplace_back(gainResidual); residualCorrTotVector.emplace_back(corrTot); residualCorrMaxVector.emplace_back(corrMax); + scCorrVector.emplace_back(scCorr); }; } @@ -394,6 +427,10 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl output.NHitsOROC3 = nClsROC[3]; } + // copy corrected cluster charges + auto chargeTotVector = mChargeTotROC[4]; + auto chargeMaxVector = mChargeMaxROC[4]; + // calculate dEdx output.dEdxTotIROC = getTruncMean(mChargeTotROC[0], low, high); output.dEdxTotOROC1 = getTruncMean(mChargeTotROC[1], low, high); @@ -428,6 +465,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl << "gainResidualVector=" << gainResidualVector << "residualCorrTotVector=" << residualCorrTotVector << "residualCorrMaxVector=" << residualCorrMaxVector + << "scCorrVector=" << scCorrVector << "localXVector=" << localXVector << "localYVector=" << localYVector << "offsPadVector=" << offsPadVector @@ -436,6 +474,10 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl << "minChargeTot=" << minChargeTot << "minChargeMax=" << minChargeMax << "output=" << output + << "occupancy=" << occupancyVector + << "chargeTotVector=" << chargeTotVector + << "chargeMaxVector=" << chargeMaxVector + << "isClusterShared=" << isClusterShared << "\n"; } } @@ -492,7 +534,7 @@ float CalculatedEdx::getTrackTopologyCorrectionPol(const o2::tpc::TrackTPC& trac return effectiveLength; } -void CalculatedEdx::loadCalibsFromCCDB(long runNumberOrTimeStamp) +void CalculatedEdx::loadCalibsFromCCDB(long runNumberOrTimeStamp, const bool isMC) { // setup CCDB manager auto& cm = o2::ccdb::BasicCCDBManager::instance(); @@ -542,6 +584,15 @@ void CalculatedEdx::loadCalibsFromCCDB(long runNumberOrTimeStamp) auto propagator = o2::base::Propagator::Instance(); const o2::base::MatLayerCylSet* matLut = o2::base::MatLayerCylSet::rectifyPtrFromFile(cm.get("GLO/Param/MatLUT")); propagator->setMatLUT(matLut); + + // load sc correction maps + auto avgMap = isMC ? cm.getForTimeStamp(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalCorrMapMC), tRun) : cm.getForTimeStamp(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalCorrMap), tRun); + avgMap->rectifyAfterReadingFromFile(); + + auto derMap = isMC ? cm.getForTimeStamp(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalCorrDerivMapMC), tRun) : cm.getForTimeStamp(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalCorrDerivMap), tRun); + derMap->rectifyAfterReadingFromFile(); + + mSCdEdxCorrection.setCorrectionMaps(avgMap, derMap); } void CalculatedEdx::loadCalibsFromLocalCCDBFolder(const char* localCCDBFolder) @@ -624,4 +675,12 @@ void CalculatedEdx::setPropagatorFromFile(const char* folder, const char* file, o2::base::MatLayerCylSet* matLut = o2::base::MatLayerCylSet::rectifyPtrFromFile((o2::base::MatLayerCylSet*)matLutFile->Get(object)); propagator->setMatLUT(matLut); } -} \ No newline at end of file +} + +unsigned int CalculatedEdx::getOccupancy(const o2::tpc::ClusterNative& cl) const +{ + const int nTimeBinsPerOccupBin = 16; + const int iBinOcc = cl.getTime() / nTimeBinsPerOccupBin + 2; + const unsigned int occupancy = mTPCRefitterOccMap.empty() ? -1 : mTPCRefitterOccMap[iBinOcc]; + return occupancy; +} diff --git a/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx b/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx new file mode 100644 index 0000000000000..e5d1f32ad5661 --- /dev/null +++ b/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx @@ -0,0 +1,174 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// @file CorrectdEdxDistortions.cxx +/// @author Matthias Kleiner, mkleiner@ikf.uni-frankfurt.de +/// + +#include "TPCCalibration/CorrectdEdxDistortions.h" +#include "TPCFastTransform.h" +#include "CommonUtils/TreeStreamRedirector.h" + +o2::tpc::CorrectdEdxDistortions::~CorrectdEdxDistortions() = default; + +o2::tpc::CorrectdEdxDistortions::CorrectdEdxDistortions() = default; + +void o2::tpc::CorrectdEdxDistortions::setStreamer(const char* debugRootFile) +{ + mStreamer = std::make_unique(debugRootFile, "recreate"); +}; + +void o2::tpc::CorrectdEdxDistortions::setSCCorrFromFile(const char* scAvgFile, const char* scDerFile, const float lumi) +{ + auto avg = o2::gpu::TPCFastTransform::loadFromFile(scAvgFile, "ccdb_object"); + auto der = o2::gpu::TPCFastTransform::loadFromFile(scDerFile, "ccdb_object"); + if (!avg || !der) { + LOGP(warn, "Couldnt load all sc correction objects from local file"); + return; + } + avg->rectifyAfterReadingFromFile(); + der->rectifyAfterReadingFromFile(); + setCorrectionMaps(avg, der, lumi); +} + +void o2::tpc::CorrectdEdxDistortions::setCorrectionMaps(o2::gpu::TPCFastTransform* avg, o2::gpu::TPCFastTransform* der) +{ + if (!avg || !der) { + LOGP(warn, "Nullptr detected in setting the correction maps"); + return; + } + mCorrAvg = std::unique_ptr(new o2::gpu::TPCFastTransform); + mCorrAvg->cloneFromObject(*avg, nullptr); + mCorrAvg->rectifyAfterReadingFromFile(); + + mCorrDer = std::unique_ptr(new o2::gpu::TPCFastTransform); + mCorrDer->cloneFromObject(*der, nullptr); + mCorrDer->rectifyAfterReadingFromFile(); + + mCorrAvg->setApplyCorrectionOn(); + mCorrDer->setApplyCorrectionOn(); +} + +void o2::tpc::CorrectdEdxDistortions::setCorrectionMaps(o2::gpu::TPCFastTransform* avg, o2::gpu::TPCFastTransform* der, const float lumi) +{ + setCorrectionMaps(avg, der); + setLumi(lumi); +} + +void o2::tpc::CorrectdEdxDistortions::setLumi(float lumi) +{ + if (!mCorrAvg || !mCorrDer) { + LOGP(warn, "Nullptr detected in accessing the correction maps"); + return; + } + const float lumiAvg = mCorrAvg->getLumi(); + const float lumiDer = mCorrDer->getLumi(); + mScaleDer = (lumi - lumiAvg) / lumiDer; + LOGP(info, "Setting mScaleDer: {} for inst lumi: {} avg lumi: {} deriv. lumi: {}", mScaleDer, lumi, lumiAvg, lumiDer); +} + +float o2::tpc::CorrectdEdxDistortions::getCorrection(const float time, unsigned char sector, unsigned char padrow, int pad) const +{ + // + // Get the corrections at the previous and next padrow and interpolate them to the start and end position of current pad + // Calculate from corrected position the radial distortions and compare the effective length of distorted electrons with pad length + // + + // localY of current pad + const float ly = mTPCGeometry.LinearPad2Y(sector, padrow, pad); + + // get correction at "pad + 0.5*padlength" pos1 and dont extrapolate/interpolate across GEM gaps + const int row1 = ((padrow == mTPCGeometry.EndIROC() - 1) || (padrow == mTPCGeometry.EndOROC1() - 1) || (padrow == mTPCGeometry.EndOROC2() - 1)) ? padrow : std::clamp(padrow + 1, 0, GPUCA_ROW_COUNT - 1); + + float lxT_1 = 0; + float lyT_1 = 0; + float lzT_1 = 0; + mCorrAvg->Transform(sector, row1, pad, time, lxT_1, lyT_1, lzT_1, 0, mCorrDer.get(), nullptr, mScaleDer, 0, 1); + + // correct for different localY position of pads + lyT_1 += ly - mTPCGeometry.LinearPad2Y(sector, row1, pad); + + // get radius of upper pad + const float r_1_f = std::sqrt(lxT_1 * lxT_1 + lyT_1 * lyT_1); + + // get correction at "pad - 0.5*padlength" pos0 and dont extrapolate/interpolate across GEM gaps + const int row0 = ((padrow == mTPCGeometry.EndIROC()) || (padrow == mTPCGeometry.EndOROC1()) || (padrow == mTPCGeometry.EndOROC2())) ? padrow : std::clamp(padrow - 1, 0, GPUCA_ROW_COUNT - 1); + + // check if previous pad row has enough pads + const unsigned char pad0 = std::clamp(static_cast(pad), 0, mTPCGeometry.NPads(row0) - 1); + float lxT_0 = 0; + float lyT_0 = 0; + float lzT_0 = 0; + mCorrAvg->Transform(sector, row0, pad0, time, lxT_0, lyT_0, lzT_0, 0, mCorrDer.get(), nullptr, mScaleDer, 0, 1); + + // correct for different localY position of pads + lyT_0 += ly - mTPCGeometry.LinearPad2Y(sector, row0, pad0); + + // get radius of lower pad + const float r_0_f = std::sqrt(lxT_0 * lxT_0 + lyT_0 * lyT_0); + + // effective radial length of electrons + const float dr_f = r_1_f - r_0_f; + + // position of upper and lower pad edge + const float x_0 = padrow - 0.5; + const float x_1 = padrow + 0.5; + + // interpolate corrections to upper and lower pad edge + const int deltaRow = (row1 - row0); + const float d_StartPad = (r_0_f * (row1 - x_0) + r_1_f * (x_0 - row0)) / deltaRow; + const float d_EndPad = (r_0_f * (row1 - x_1) + r_1_f * (x_1 - row0)) / deltaRow; + const float scCorr = (d_EndPad - d_StartPad) / mTPCGeometry.PadHeight(padrow); + + // check if corrected position is still reasonable + const bool isOk = ((lxT_1 < mLX0Min) || (lxT_0 < mLX1Min) || (scCorr < mScCorrMin) || (scCorr > mScCorrMax)) ? false : true; + + // store debug informations + if (mStreamer) { + const float lx = mTPCGeometry.Row2X(padrow); + + // original correction + float lxT = 0; + float lyT = 0; + float lzT = 0; + mCorrAvg->Transform(sector, padrow, pad, time, lxT, lyT, lzT, 0, mCorrDer.get(), nullptr, mScaleDer, 0, 1); + + (*mStreamer) << "tree" + << "sector=" << sector + << "padrow=" << padrow + << "row0=" << row0 + << "row1=" << row1 + << "pad0=" << pad0 + << "pad=" << pad + << "time=" << time + << "lx=" << lx + << "lxT=" << lxT + << "lyT=" << lyT + << "lzT=" << lzT + << "lxT_0=" << lxT_0 + << "lxT_1=" << lxT_1 + << "ly=" << ly + << "lyT_0=" << lyT_0 + << "lyT_1=" << lyT_1 + << "lzT_0=" << lzT_0 + << "lzT_1=" << lzT_1 + << "d_StartPad=" << d_StartPad + << "d_EndPad=" << d_EndPad + << "r_0_f=" << r_0_f + << "r_1_f=" << r_1_f + << "scCorr=" << scCorr + << "isOk=" << isOk + << "\n"; + } + + return isOk ? scCorr : 1; +} From c0c70ae617dce32393427c4c5c714b29e03ec948 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 3 Oct 2024 05:16:40 +0200 Subject: [PATCH 0296/2205] DCAFitterGPU: reduce I/O overhead by copying elements using a kernel (#13556) --- Common/DCAFitter/GPU/cuda/DCAFitterN.cu | 13 +++++++++++-- .../DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu index ab53ae25d7548..ed7e8acba5397 100644 --- a/Common/DCAFitter/GPU/cuda/DCAFitterN.cu +++ b/Common/DCAFitter/GPU/cuda/DCAFitterN.cu @@ -56,6 +56,14 @@ GPUg() void printKernel(Fitter* fitter) } } +template +GPUg() void initFitters(Fitter* fitters, unsigned int off, unsigned int N) +{ + for (auto iThread{blockIdx.x * blockDim.x + threadIdx.x + 1}; iThread < N; iThread += blockDim.x * gridDim.x) { + fitters[iThread + off] = fitters[off]; + } +} + template GPUg() void processKernel(Fitter* fitter, int* res, Tr*... tracks) { @@ -63,7 +71,7 @@ GPUg() void processKernel(Fitter* fitter, int* res, Tr*... tracks) } template -GPUg() void processBatchKernel(Fitter* fitters, int* results, size_t off, size_t N, Tr*... tracks) +GPUg() void processBatchKernel(Fitter* fitters, int* results, unsigned int off, unsigned int N, Tr*... tracks) { for (auto iThread{blockIdx.x * blockDim.x + threadIdx.x}; iThread < N; iThread += blockDim.x * gridDim.x) { results[iThread + off] = fitters[iThread + off].process(tracks[iThread + off]...); @@ -186,7 +194,7 @@ void processBulk(const int nBlocks, auto nFits = batchSize + (iBatch < remainder ? 1 : 0); gpuCheckError(cudaEventRecord(startIOUp[iBatch], stream)); - gpuCheckError(cudaMemcpyAsync(fitters_device + offset, fitters.data() + offset, sizeof(Fitter) * nFits, cudaMemcpyHostToDevice, stream)); + gpuCheckError(cudaMemcpyAsync(fitters_device + offset, fitters.data() + offset, sizeof(Fitter) /* * nFits */, cudaMemcpyHostToDevice, stream)); // copying just the first element of the buffer iArg = 0; ([&] { gpuCheckError(cudaMemcpyAsync(tracks_device[iArg] + offset, args.data() + offset, sizeof(Tr) * nFits, cudaMemcpyHostToDevice, stream)); @@ -196,6 +204,7 @@ void processBulk(const int nBlocks, gpuCheckError(cudaEventRecord(endIOUp[iBatch], stream)); gpuCheckError(cudaEventRecord(startKer[iBatch], stream)); + kernel::initFitters<<>>(fitters_device, offset, nFits); std::apply([&](auto&&... args) { kernel::processBatchKernel<<>>(fitters_device, results_device, offset, nFits, args...); }, tracks_device); gpuCheckError(cudaEventRecord(endKer[iBatch], stream)); diff --git a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx index a7254931737cb..e3f882dc755cb 100644 --- a/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx +++ b/Common/DCAFitter/GPU/cuda/test/testDCAFitterNGPU.cxx @@ -560,8 +560,8 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngsBulk) const char* nBlocksEnvVarName = "DCAFITTERGPU_TEST_NBLOCKS"; const char* nBatchesEnvVarName = "DCAFITTERGPU_TEST_NBATCHES"; const char* nTestsEnvVarName = "DCAFITTERGPU_TEST_NTESTS"; - int nBlocks = std::getenv(nThreadsEnvVarName) == nullptr ? 30 : std::stoi(std::getenv(nThreadsEnvVarName)); - int nThreads = std::getenv(nBlocksEnvVarName) == nullptr ? 256 : std::stoi(std::getenv(nBlocksEnvVarName)); + int nBlocks = std::getenv(nBlocksEnvVarName) == nullptr ? 30 : std::stoi(std::getenv(nBlocksEnvVarName)); + int nThreads = std::getenv(nThreadsEnvVarName) == nullptr ? 256 : std::stoi(std::getenv(nThreadsEnvVarName)); int nBatches = std::getenv(nBatchesEnvVarName) == nullptr ? 8 : std::stoi(std::getenv(nBatchesEnvVarName)); int NTest = std::getenv(nTestsEnvVarName) == nullptr ? 100001 : std::stoi(std::getenv(nTestsEnvVarName)); From dbfe3c61771ae1d53da9db6e0c56208a34c42e47 Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 2 Oct 2024 13:53:30 +0200 Subject: [PATCH 0297/2205] AggregatedRunInfo struct proposal We are often in the need to collect global properties of a run like run-duration, run-start, firstOrbit, lastOrbit, ... No single CCDB source delivers all of these information. Moreover we sometimes have multiple sources for the same information (GRPECS, RCT/Info/RunInformation) which may not be at sync. The proposal of this commit is to: (a) introduce an aggregator struct "AggregatedRunInfo" in which we can deliver all important information describing a Run. (b) implement an authoritative and agreed-on method to fill this struct. The goal is to set everyone (reco, MC, analysis) on the same foot/contract. For now the struct is minimal for demonstration purposes. --- DataFormats/Parameters/CMakeLists.txt | 4 +- .../DataFormatsParameters/AggregatedRunInfo.h | 46 ++++++++++++++++ .../Parameters/src/AggregatedRunInfo.cxx | 54 +++++++++++++++++++ .../Parameters/src/ParametersDataLinkDef.h | 1 + 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h create mode 100644 DataFormats/Parameters/src/AggregatedRunInfo.cxx diff --git a/DataFormats/Parameters/CMakeLists.txt b/DataFormats/Parameters/CMakeLists.txt index 3539e9e11fd1e..ed137a42f6565 100644 --- a/DataFormats/Parameters/CMakeLists.txt +++ b/DataFormats/Parameters/CMakeLists.txt @@ -14,7 +14,8 @@ o2_add_library(DataFormatsParameters src/GRPLHCIFData.cxx src/GRPECSObject.cxx src/GRPMagField.cxx - PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants + src/AggregatedRunInfo.cxx + PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants O2::CommonTypes O2::CCDB O2::DetectorsCommonDataFormats) @@ -24,6 +25,7 @@ o2_target_root_dictionary(DataFormatsParameters include/DataFormatsParameters/GRPLHCIFData.h include/DataFormatsParameters/GRPECSObject.h include/DataFormatsParameters/GRPMagField.h + include/DataFormatsParameters/AggregatedRunInfo.h LINKDEF src/ParametersDataLinkDef.h) o2_add_executable(simgrp-tool diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h new file mode 100644 index 0000000000000..91b9491124b77 --- /dev/null +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -0,0 +1,46 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GRPECSObject.h +/// \brief Header of the AggregatedRunInfo struct +/// \author ruben.shahoyan@cern.ch sandro.wenzel@cern.ch + +#ifndef ALICEO2_DATA_AGGREGATEDRUNINFO_H_ +#define ALICEO2_DATA_AGGREGATEDRUNINFO_H_ + +#include +#include "CCDB/BasicCCDBManager.h" + +namespace o2::parameters +{ + +/// Composite struct where one may collect important global properties of data "runs" +/// aggregated from various sources (GRPECS, RunInformation CCDB entries, etc.). +/// Also offers the authoritative algorithms to collect these information for easy reuse +/// across various algorithms (anchoredMC, analysis, ...) +struct AggregatedRunInfo { + int runNumber; // run number + uint64_t sor; // best known timestamp for the start of run + uint64_t eor; // best known timestamp for end of run + uint64_t orbitsPerTF; // number of orbits per TF + uint64_t orbitReset; // timestamp of orbit reset before run + uint64_t orbitSOR; // orbit when run starts after orbit reset + uint64_t orbitEOR; // orbit when run ends after orbit reset + + // we may have pointers to actual data source objects GRPECS, ... + + // fills and returns AggregatedRunInfo for a given run number. + static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); +}; + +} // namespace o2::parameters + +#endif \ No newline at end of file diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx new file mode 100644 index 0000000000000..77c8a332c13b2 --- /dev/null +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -0,0 +1,54 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file AggregatedRunInfo.cxx +/// \author sandro.wenzel@cern.ch + +#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "CommonConstants/LHCConstants.h" +#include "Framework/Logger.h" + +using namespace o2::parameters; + +o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber) +{ + // TODO: could think about caching results per runnumber to + // avoid going to CCDB multiple times ---> but should be done inside the CCDBManagerInstance + + // we calculate the first orbit of a run based on sor (start-of-run) and eor + // we obtain these by calling getRunDuration + auto [sor, eor] = ccdb.getRunDuration(runnumber); + + // determine a good timestamp to query OrbitReset for this run + // --> the middle of the run is very appropriate and safer than just sor + auto run_mid_timestamp = sor + (eor - sor) / 2; + + // query the time of the orbit reset (when orbit is defined to be 0) + auto ctpx = ccdb.getForTimeStamp>("CTP/Calib/OrbitReset", run_mid_timestamp); + int64_t tsOrbitReset = (*ctpx)[0]; // us + + // get timeframe length from GRPECS + std::map metadata; + metadata["runNumber"] = Form("%d", runnumber); + auto grpecs = ccdb.getSpecific("GLO/Config/GRPECS", run_mid_timestamp, metadata); + auto nOrbitsPerTF = grpecs->getNHBFPerTF(); + + // calculate SOR orbit + int64_t orbitSOR = (sor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; + int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; + + // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) + orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; + + return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; +} diff --git a/DataFormats/Parameters/src/ParametersDataLinkDef.h b/DataFormats/Parameters/src/ParametersDataLinkDef.h index e4817bd443302..d2cbee2049c52 100644 --- a/DataFormats/Parameters/src/ParametersDataLinkDef.h +++ b/DataFormats/Parameters/src/ParametersDataLinkDef.h @@ -30,5 +30,6 @@ #pragma link C++ class o2::parameters::GRPMagField + ; #pragma link C++ class std::unordered_map < unsigned int, unsigned int> + ; #pragma link C++ class std::pair < unsigned long, std::string> + ; +#pragma link C++ struct o2::parameters::AggregatedRunInfo + ; #endif From 3b4c9cfbf667a2c9f33aa6319b4ac2a90b0a55ff Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Thu, 3 Oct 2024 13:45:33 +0200 Subject: [PATCH 0298/2205] feat(CCDB): add getForRunMiddleTimeStamp method Adds a new method `getForRunMiddleTimeStamp` to the `CCDBManagerInstance` class. This method retrieves an object of type `T` from the CCDB using the path and the middle timestamp of the given run number. This is a useful utility method for cases where the exact timestamp does not matter and the run number is available. Optionally use metadata in the query Rename the function Fix setting of the metadata --- CCDB/include/CCDB/BasicCCDBManager.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CCDB/include/CCDB/BasicCCDBManager.h b/CCDB/include/CCDB/BasicCCDBManager.h index 7994c60448121..5295062de4022 100644 --- a/CCDB/include/CCDB/BasicCCDBManager.h +++ b/CCDB/include/CCDB/BasicCCDBManager.h @@ -102,6 +102,10 @@ class CCDBManagerInstance template T* getForTimeStamp(std::string const& path, long timestamp); + /// retrieve an object of type T from CCDB as stored under path and using the timestamp in the middle of the run + template + T* getForRun(std::string const& path, int runNumber, bool setRunMetadata = false); + /// retrieve an object of type T from CCDB as stored under path, timestamp and metaData template T* getSpecific(std::string const& path, long timestamp = -1, MD metaData = MD()) @@ -311,6 +315,20 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp) return ptr; } +template +T* CCDBManagerInstance::getForRun(std::string const& path, int runNumber, bool setRunMetadata) +{ + auto [start, stop] = getRunDuration(runNumber); + if (start < 0 || stop < 0) { + if (mFatalWhenNull) { + reportFatal(std::string("Failed to get run duration for run ") + std::to_string(runNumber)); + } + return nullptr; + } + mMetaData = setRunMetadata ? MD{{"runNumber", std::to_string(runNumber)}} : MD{}; + return getForTimeStamp(path, start / 2 + stop / 2); +} + class BasicCCDBManager : public CCDBManagerInstance { public: From f15bb280744cfd097e46aa1fb43a57905f85f483 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 3 Oct 2024 15:06:09 +0200 Subject: [PATCH 0299/2205] Revert "AggregatedRunInfo struct proposal" This reverts commit dbfe3c61771ae1d53da9db6e0c56208a34c42e47. (Compilation broken) --- DataFormats/Parameters/CMakeLists.txt | 4 +- .../DataFormatsParameters/AggregatedRunInfo.h | 46 ---------------- .../Parameters/src/AggregatedRunInfo.cxx | 54 ------------------- .../Parameters/src/ParametersDataLinkDef.h | 1 - 4 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h delete mode 100644 DataFormats/Parameters/src/AggregatedRunInfo.cxx diff --git a/DataFormats/Parameters/CMakeLists.txt b/DataFormats/Parameters/CMakeLists.txt index ed137a42f6565..3539e9e11fd1e 100644 --- a/DataFormats/Parameters/CMakeLists.txt +++ b/DataFormats/Parameters/CMakeLists.txt @@ -14,8 +14,7 @@ o2_add_library(DataFormatsParameters src/GRPLHCIFData.cxx src/GRPECSObject.cxx src/GRPMagField.cxx - src/AggregatedRunInfo.cxx - PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants + PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants O2::CommonTypes O2::CCDB O2::DetectorsCommonDataFormats) @@ -25,7 +24,6 @@ o2_target_root_dictionary(DataFormatsParameters include/DataFormatsParameters/GRPLHCIFData.h include/DataFormatsParameters/GRPECSObject.h include/DataFormatsParameters/GRPMagField.h - include/DataFormatsParameters/AggregatedRunInfo.h LINKDEF src/ParametersDataLinkDef.h) o2_add_executable(simgrp-tool diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h deleted file mode 100644 index 91b9491124b77..0000000000000 --- a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file GRPECSObject.h -/// \brief Header of the AggregatedRunInfo struct -/// \author ruben.shahoyan@cern.ch sandro.wenzel@cern.ch - -#ifndef ALICEO2_DATA_AGGREGATEDRUNINFO_H_ -#define ALICEO2_DATA_AGGREGATEDRUNINFO_H_ - -#include -#include "CCDB/BasicCCDBManager.h" - -namespace o2::parameters -{ - -/// Composite struct where one may collect important global properties of data "runs" -/// aggregated from various sources (GRPECS, RunInformation CCDB entries, etc.). -/// Also offers the authoritative algorithms to collect these information for easy reuse -/// across various algorithms (anchoredMC, analysis, ...) -struct AggregatedRunInfo { - int runNumber; // run number - uint64_t sor; // best known timestamp for the start of run - uint64_t eor; // best known timestamp for end of run - uint64_t orbitsPerTF; // number of orbits per TF - uint64_t orbitReset; // timestamp of orbit reset before run - uint64_t orbitSOR; // orbit when run starts after orbit reset - uint64_t orbitEOR; // orbit when run ends after orbit reset - - // we may have pointers to actual data source objects GRPECS, ... - - // fills and returns AggregatedRunInfo for a given run number. - static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); -}; - -} // namespace o2::parameters - -#endif \ No newline at end of file diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx deleted file mode 100644 index 77c8a332c13b2..0000000000000 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file AggregatedRunInfo.cxx -/// \author sandro.wenzel@cern.ch - -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPECSObject.h" -#include "CommonConstants/LHCConstants.h" -#include "Framework/Logger.h" - -using namespace o2::parameters; - -o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber) -{ - // TODO: could think about caching results per runnumber to - // avoid going to CCDB multiple times ---> but should be done inside the CCDBManagerInstance - - // we calculate the first orbit of a run based on sor (start-of-run) and eor - // we obtain these by calling getRunDuration - auto [sor, eor] = ccdb.getRunDuration(runnumber); - - // determine a good timestamp to query OrbitReset for this run - // --> the middle of the run is very appropriate and safer than just sor - auto run_mid_timestamp = sor + (eor - sor) / 2; - - // query the time of the orbit reset (when orbit is defined to be 0) - auto ctpx = ccdb.getForTimeStamp>("CTP/Calib/OrbitReset", run_mid_timestamp); - int64_t tsOrbitReset = (*ctpx)[0]; // us - - // get timeframe length from GRPECS - std::map metadata; - metadata["runNumber"] = Form("%d", runnumber); - auto grpecs = ccdb.getSpecific("GLO/Config/GRPECS", run_mid_timestamp, metadata); - auto nOrbitsPerTF = grpecs->getNHBFPerTF(); - - // calculate SOR orbit - int64_t orbitSOR = (sor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; - int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; - - // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) - orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; - - return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; -} diff --git a/DataFormats/Parameters/src/ParametersDataLinkDef.h b/DataFormats/Parameters/src/ParametersDataLinkDef.h index d2cbee2049c52..e4817bd443302 100644 --- a/DataFormats/Parameters/src/ParametersDataLinkDef.h +++ b/DataFormats/Parameters/src/ParametersDataLinkDef.h @@ -30,6 +30,5 @@ #pragma link C++ class o2::parameters::GRPMagField + ; #pragma link C++ class std::unordered_map < unsigned int, unsigned int> + ; #pragma link C++ class std::pair < unsigned long, std::string> + ; -#pragma link C++ struct o2::parameters::AggregatedRunInfo + ; #endif From c2ff3e0077fac6a43cd0e0d14ec3899da1ad8cd9 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 3 Oct 2024 15:42:03 +0200 Subject: [PATCH 0300/2205] Unconditionally load PVs if requested --- .../Detectors/GlobalTracking/src/RecoContainer.cxx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx index e634395f6d723..60c18b966abed 100644 --- a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx +++ b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx @@ -833,13 +833,11 @@ void RecoContainer::addSVertices(ProcessingContext& pc, bool) //____________________________________________________________ void RecoContainer::addPVertices(ProcessingContext& pc, bool mc) { - if (!pvtxPool.isLoaded(PVTX)) { // in case was loaded via addPVerticesTMP - pvtxPool.registerContainer(pc.inputs().get>("pvtx"), PVTX); - } + pvtxPool.registerContainer(pc.inputs().get>("pvtx"), PVTX); pvtxPool.registerContainer(pc.inputs().get>("pvtx_trmtc"), PVTX_TRMTC); pvtxPool.registerContainer(pc.inputs().get>("pvtx_tref"), PVTX_TRMTCREFS); - if (mc && !pvtxPool.isLoaded(PVTX_MCTR)) { // in case was loaded via addPVerticesTMP + if (mc) { // in case was loaded via addPVerticesTMP pvtxPool.registerContainer(pc.inputs().get>("pvtx_mc"), PVTX_MCTR); } } @@ -856,13 +854,11 @@ void RecoContainer::addStrangeTracks(ProcessingContext& pc, bool mc) //____________________________________________________________ void RecoContainer::addPVerticesTMP(ProcessingContext& pc, bool mc) { - if (!pvtxPool.isLoaded(PVTX)) { // in case was loaded via addPVertices - pvtxPool.registerContainer(pc.inputs().get>("pvtx"), PVTX); - } + pvtxPool.registerContainer(pc.inputs().get>("pvtx"), PVTX); pvtxPool.registerContainer(pc.inputs().get>("pvtx_cont"), PVTX_CONTID); pvtxPool.registerContainer(pc.inputs().get>("pvtx_contref"), PVTX_CONTIDREFS); - if (mc && !pvtxPool.isLoaded(PVTX_MCTR)) { // in case was loaded via addPVertices + if (mc) { // in case was loaded via addPVertices pvtxPool.registerContainer(pc.inputs().get>("pvtx_mc"), PVTX_MCTR); } } From 0b014090d245a3ac7b23dfaa6640ff3bd91cc512 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:20:08 +0200 Subject: [PATCH 0301/2205] DPL Analysis: re-enable prefetching (#13559) Now that ROOT supports prefetching with bulk reading, we can reenable this which should cut in half the number of IOPS for the general case. --- Framework/Core/src/TableTreeHelpers.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index 14e4a43ea6cba..780126c89dd85 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -547,14 +547,14 @@ void TreeToTable::addAllColumns(TTree* tree, std::vector&& names) if (mBranchReaders.empty()) { throw runtime_error("No columns will be read"); } - //tree->SetCacheSize(50000000); - // FIXME: see https://github.com/root-project/root/issues/8962 and enable - // again once fixed. - //tree->SetClusterPrefetch(true); - //for (auto& reader : mBranchReaders) { - // tree->AddBranchToCache(reader->branch()); - //} - //tree->StopCacheLearningPhase(); + // Was affected by https://github.com/root-project/root/issues/8962 + // Re-enabling this seems to cut the number of IOPS in half + tree->SetCacheSize(25000000); + tree->SetClusterPrefetch(true); + for (auto& reader : mBranchReaders) { + tree->AddBranchToCache(reader->branch()); + } + tree->StopCacheLearningPhase(); } void TreeToTable::setLabel(const char* label) From 362c300e363cc0fc67897c0c4eca870e0c26a74a Mon Sep 17 00:00:00 2001 From: Paul Buehler Date: Fri, 4 Oct 2024 12:51:34 +0200 Subject: [PATCH 0302/2205] Make sure that the string 'using' in a text is NOT interpreted as the using keyword. (#13546) --- scripts/datamodel-doc/ALICEO2includeFile.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/datamodel-doc/ALICEO2includeFile.py b/scripts/datamodel-doc/ALICEO2includeFile.py index 680beaa684cc1..0d99f6e3aad07 100644 --- a/scripts/datamodel-doc/ALICEO2includeFile.py +++ b/scripts/datamodel-doc/ALICEO2includeFile.py @@ -1078,15 +1078,15 @@ def condition(s): if len(iend) == 0: print(nslevel) sys.exit('Ending ; not found in using declaration! EXIT -->') - cont = words[icol:icol+iend[0]+1] - name = fullDataModelName(nslevel, words[icol+1].txt) + # make sure that using is not part of a text, like ".... PID using TPC ..." or similar definition = O2DMT.block(words[icol+3:icol+iend[0]], False) - - # namespace, name, cont - use = using(nslevel, name, definition, O2DMT.block(cont)) - - usings.append(use) + if ('"' not in definition and "'" not in definition): + # namespace, name, cont + name = fullDataModelName(nslevel, words[icol+1].txt) + cont = words[icol:icol+iend[0]+1] + use = using(nslevel, name, definition, O2DMT.block(cont)) + usings.append(use) return usings From 23360e93169206b7e08d7b7eb11404f67c81ff92 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:50:48 +0200 Subject: [PATCH 0303/2205] Revert "DPL Analysis: re-enable prefetching (#13559)" (#13566) --- Framework/Core/src/TableTreeHelpers.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index 780126c89dd85..14e4a43ea6cba 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -547,14 +547,14 @@ void TreeToTable::addAllColumns(TTree* tree, std::vector&& names) if (mBranchReaders.empty()) { throw runtime_error("No columns will be read"); } - // Was affected by https://github.com/root-project/root/issues/8962 - // Re-enabling this seems to cut the number of IOPS in half - tree->SetCacheSize(25000000); - tree->SetClusterPrefetch(true); - for (auto& reader : mBranchReaders) { - tree->AddBranchToCache(reader->branch()); - } - tree->StopCacheLearningPhase(); + //tree->SetCacheSize(50000000); + // FIXME: see https://github.com/root-project/root/issues/8962 and enable + // again once fixed. + //tree->SetClusterPrefetch(true); + //for (auto& reader : mBranchReaders) { + // tree->AddBranchToCache(reader->branch()); + //} + //tree->StopCacheLearningPhase(); } void TreeToTable::setLabel(const char* label) From 53682be6d3d7ea56568c2355d411fa0aba8b07b8 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 20 Sep 2024 01:29:20 +0400 Subject: [PATCH 0304/2205] Reader-driver can be used to skim MC input from root files --- .../common/include/CommonDataFormat/IRFrame.h | 15 +- .../src/ReaderDriverSpec.cxx | 18 +- .../DetectorsRaw/HBFUtilsInitializer.h | 12 +- Detectors/Raw/src/HBFUtilsInitializer.cxx | 195 ++++++++++++++---- cmake/O2RootMacroExclusionList.cmake | 1 + macro/CMakeLists.txt | 1 + macro/CreateSampleIRFrames.C | 38 ++++ 7 files changed, 231 insertions(+), 49 deletions(-) create mode 100644 macro/CreateSampleIRFrames.C diff --git a/DataFormats/common/include/CommonDataFormat/IRFrame.h b/DataFormats/common/include/CommonDataFormat/IRFrame.h index 26b1e33f17e50..d404a9538306a 100644 --- a/DataFormats/common/include/CommonDataFormat/IRFrame.h +++ b/DataFormats/common/include/CommonDataFormat/IRFrame.h @@ -28,9 +28,22 @@ namespace dataformats // We could just alias it to the bracket specialization, but this would create // problems with fwd.declaration struct IRFrame : public o2::math_utils::detail::Bracket { + static constexpr uint64_t LastIRFrame = uint64_t(0x1) << 63; + using o2::math_utils::detail::Bracket::Bracket; - uint64_t info = 0; + uint64_t info = uint64_t(0); + + void setLast(bool v = true) + { + if (v) { + info |= LastIRFrame; + } else { + v &= ~LastIRFrame; + } + } + + bool isLast() const { return (info & LastIRFrame) != 0UL; } ClassDefNV(IRFrame, 2); }; diff --git a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx index 0ab7a69dc5363..f8fd91418c04e 100644 --- a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx @@ -23,6 +23,7 @@ #include "GlobalTrackingWorkflow/ReaderDriverSpec.h" #include "DetectorsRaw/HBFUtilsInitializer.h" #include "CommonUtils/StringUtils.h" +#include "CommonDataFormat/IRFrame.h" #include "TFile.h" #include "TTree.h" @@ -32,6 +33,7 @@ namespace o2 { namespace globaltracking { +using HBFINI = o2::raw::HBFUtilsInitializer; class ReadeDriverSpec : public o2::framework::Task { @@ -60,16 +62,20 @@ void ReadeDriverSpec::run(ProcessingContext& pc) static RateLimiter limiter; static int count = 0; if (!count) { - if (o2::raw::HBFUtilsInitializer::NTFs < 0) { + if (HBFINI::NTFs < 0) { LOGP(fatal, "Number of TFs to process was not initizalized in the HBFUtilsInitializer"); } - mNTF = (mNTF > 0 && mNTF < o2::raw::HBFUtilsInitializer::NTFs) ? mNTF : o2::raw::HBFUtilsInitializer::NTFs; + mNTF = (mNTF > 0 && mNTF < HBFINI::NTFs) ? mNTF : HBFINI::NTFs; } else { // check only for count > 0 limiter.check(pc, mTFRateLimit, mMinSHM); } - std::vector v{}; - pc.outputs().snapshot(Output{"GLO", "READER_DRIVER", 0}, v); - if (++count >= mNTF) { + auto& v = pc.outputs().make>(Output{"GLO", "READER_DRIVER", 0}); + if (!HBFINI::IRFrameSel.getMin().isDummy() && !HBFINI::IRFrameSel.getMax().isDummy()) { + v.push_back(HBFINI::IRFrameSel); + LOGP(debug, "OUTVEC {}/{}", v.back().getMin().asString(), v.back().getMax().asString()); + } + count++; + if ((HBFINI::LastIRFrameIndex == -1 && count == HBFINI::NTFs) || (v.size() && v.back().isLast())) { pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); } @@ -84,7 +90,7 @@ DataProcessorSpec getReaderDriverSpec(const std::string& metricChannel, size_t m options.emplace_back(ConfigParamSpec{"channel-config", VariantType::String, metricChannel, {"Out-of-band channel config for TF throttling"}}); } return DataProcessorSpec{ - o2::raw::HBFUtilsInitializer::ReaderDriverDevice, + HBFINI::ReaderDriverDevice, Inputs{}, Outputs{{"GLO", "READER_DRIVER", 0, Lifetime::Timeframe}}, AlgorithmSpec{adaptFromTask(minSHM)}, diff --git a/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h b/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h index 439b53371b336..895eff097e7a0 100644 --- a/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h +++ b/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h @@ -18,6 +18,7 @@ #include #include #include "CommonDataFormat/TFIDInfo.h" +#include "CommonDataFormat/IRFrame.h" #include "CommonUtils/NameConf.h" namespace o2 @@ -50,16 +51,25 @@ struct HBFUtilsInitializer { static constexpr char DelayOpt[] = "reader-delay"; static constexpr char HBFConfOpt[] = "hbfutils-config"; static constexpr char HBFTFInfoOpt[] = "tf-info-source"; + static constexpr char HBFIRFrameOpt[] = "irframes-info-source"; + static constexpr char IgnoreIRFramesOpt[] = "ignore-irframes"; static constexpr char HBFUSrc[] = "hbfutils"; static constexpr char ReaderDriverDevice[] = "reader-driver"; static constexpr char UpstreamOpt[] = "upstream"; static int NTFs; + static long LastIRFrameIndex; // index of the last used entry in the optional IRFrame vector + static bool LastIRFrameSplit; // flag that the last IRFrame was split between two TFs + static std::vector IRFrames; + static o2::dataformats::IRFrame IRFrameSel; // IRFrame selected for the current TF HBFUtilsInitializer(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& wf); static HBFOpt getOptType(const std::string& optString); static std::vector readTFIDInfoVector(const std::string& fname); - static void assignDataHeader(const std::vector& tfinfoVec, o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph); + static void readIRFramesVector(const std::string& fname); + static void assignDataHeaderFromTFIDInfo(const std::vector& tfinfoVec, o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph); + static void assignDataHeaderFromHBFUtils(o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph); + static void assignDataHeaderFromHBFUtilWithIRFrames(o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph); static void addNewTimeSliceCallback(std::vector& policies); static void addConfigOption(std::vector& opts, const std::string& defOpt = std::string(o2::base::NameConf::DIGITIZATIONCONFIGFILE)); }; diff --git a/Detectors/Raw/src/HBFUtilsInitializer.cxx b/Detectors/Raw/src/HBFUtilsInitializer.cxx index 967cb843eb9ff..dc46b9baeabc9 100644 --- a/Detectors/Raw/src/HBFUtilsInitializer.cxx +++ b/Detectors/Raw/src/HBFUtilsInitializer.cxx @@ -27,6 +27,7 @@ #include "Framework/CallbackService.h" #include "Framework/Logger.h" #include "Framework/DataProcessingHeader.h" +#include #include #include @@ -39,20 +40,23 @@ namespace o2f = o2::framework; /// (only those fields of HBFUtils which were not modified before, e.g. by ConfigurableParam::updateFromString) int HBFUtilsInitializer::NTFs = 0; +long HBFUtilsInitializer::LastIRFrameIndex = -1; +bool HBFUtilsInitializer::LastIRFrameSplit = false; +std::vector HBFUtilsInitializer::IRFrames = {}; +o2::dataformats::IRFrame HBFUtilsInitializer::IRFrameSel = {}; //_________________________________________________________ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext, o2f::WorkflowSpec& wf) { bool upstream = false; // timing info will be provided from upstream readers-driver, just subscribe to it + std::string rootFileInput{}; + std::string hbfuInput{}; - auto updateHBFUtils = [&configcontext, &upstream]() -> std::string { + auto updateHBFUtils = [&configcontext, &upstream, &hbfuInput, &rootFileInput]() { static bool done = false; - static std::string confTFInfo{}; if (!done) { bool helpasked = configcontext.helpOnCommandLine(); // if help is asked, don't take for granted that the ini file is there, don't produce an error if it is not! auto conf = configcontext.options().isSet(HBFConfOpt) ? configcontext.options().get(HBFConfOpt) : ""; - HBFOpt opt = HBFOpt::NONE; - upstream = false; if (!conf.empty()) { auto vopts = o2::utils::Str::tokenize(conf, ','); for (const auto& optStr : vopts) { @@ -60,37 +64,30 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext upstream = true; continue; } - if (!confTFInfo.empty()) { - throw std::runtime_error(fmt::format("too many options in {} {}", HBFConfOpt, conf)); - } - opt = getOptType(optStr); - if ((opt == HBFOpt::INI || opt == HBFOpt::JSON) && (!(helpasked && !o2::conf::ConfigurableParam::configFileExists(confTFInfo)))) { + HBFOpt opt = getOptType(optStr); + if ((opt == HBFOpt::INI || opt == HBFOpt::JSON) && !helpasked) { o2::conf::ConfigurableParam::updateFromFile(optStr, "HBFUtils", true); // update only those values which were not touched yet (provenance == kCODE) const auto& hbfu = o2::raw::HBFUtils::Instance(); hbfu.checkConsistency(); - confTFInfo = HBFUSrc; + hbfuInput = optStr; } else if (opt == HBFOpt::HBFUTILS) { const auto& hbfu = o2::raw::HBFUtils::Instance(); hbfu.checkConsistency(); - confTFInfo = HBFUSrc; + hbfuInput = optStr; } else if (opt == HBFOpt::ROOT) { - confTFInfo = optStr; + rootFileInput = optStr; } } } done = true; - if (opt != HBFOpt::NONE) { - if (upstream) { - if (opt != HBFOpt::ROOT) { - throw std::runtime_error(fmt::format("invalid option {}: upstream can be used only with root file providing TFIDInfo", conf)); - } - } - } else if (upstream) { - confTFInfo = "o2_tfidinfo.root"; - LOGP(debug, "--hbfutils-config input type is not provided but upstream keyword is found: assume {}", confTFInfo); + /* RSS + if (upstream) { + if (rootFileInput.empty()) { + throw std::runtime_error(fmt::format("invalid option {}: upstream can be used only with root file providing TFIDInfo or IRFrames", conf)); + } } + */ } - return confTFInfo; }; if (configcontext.options().hasOption("disable-root-input") && configcontext.options().get("disable-root-input")) { @@ -99,12 +96,22 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext const auto& hbfu = o2::raw::HBFUtils::Instance(); for (auto& spec : wf) { if (spec.inputs.empty()) { - auto conf = updateHBFUtils(); + updateHBFUtils(); if (!upstream || spec.name == ReaderDriverDevice) { - o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{HBFTFInfoOpt, o2f::VariantType::String, conf, {"root file with per-TF info"}}); + if (!hbfuInput.empty()) { // MC timing coming from the HBFUtils configurable + o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{HBFTFInfoOpt, o2f::VariantType::String, HBFUSrc, {"HBFUtils input"}}); + if (!rootFileInput.empty() && spec.name == ReaderDriverDevice) { // this is IRFrame file passed to reader driver + o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{HBFIRFrameOpt, o2f::VariantType::String, rootFileInput, {"root file with selected IR-frames"}}); + } + } else { + o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{HBFTFInfoOpt, o2f::VariantType::String, rootFileInput, {"root file with per-TF info"}}); + } o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{DelayOpt, o2f::VariantType::Float, 0.f, {"delay in seconds between consecutive TFs sending"}}); } else { // subsribe to upstream timing info from readers-driver spec.inputs.emplace_back(o2f::InputSpec{"driverInfo", "GLO", "READER_DRIVER", 0, o2f::Lifetime::Timeframe}); + if (!hbfuInput.empty() && !rootFileInput.empty()) { // flag that the READER_DRIVER is not dummy but contains IRFrames + o2f::ConfigParamsHelper::addOptionIfMissing(spec.options, o2f::ConfigParamSpec{IgnoreIRFramesOpt, o2f::VariantType::Bool, false, {"ignore IR-frames info"}}); + } } } } @@ -148,7 +155,24 @@ std::vector HBFUtilsInitializer::readTFIDInfoVector(c } //_________________________________________________________ -void HBFUtilsInitializer::assignDataHeader(const std::vector& tfinfoVec, o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) +void HBFUtilsInitializer::readIRFramesVector(const std::string& fname) +{ + if (o2::utils::Str::beginsWith(fname, "alien://") && !gGrid && !TGrid::Connect("alien://")) { + LOGP(fatal, "could not open alien connection to read {}", fname); + } + std::unique_ptr fl(TFile::Open(fname.c_str())); + auto vptr = (std::vector*)fl->GetObjectChecked("irframes", "std::vector"); + if (!vptr) { + throw std::runtime_error(fmt::format("Failed to read irframes vector from {}", fname)); + } + std::vector v(*vptr); + NTFs = vptr->size(); + LastIRFrameIndex = -1; + IRFrames.swap(*vptr); +} + +//_________________________________________________________ +void HBFUtilsInitializer::assignDataHeaderFromTFIDInfo(const std::vector& tfinfoVec, o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { const auto tfinf = tfinfoVec[dh.tfCounter % tfinfoVec.size()]; LOGP(debug, "Setting DH for {}/{} from tfCounter={} firstTForbit={} runNumber={} to tfCounter={} firstTForbit={} runNumber={}", @@ -159,6 +183,81 @@ void HBFUtilsInitializer::assignDataHeader(const std::vector(), dh.dataDescription.as(), dh.tfCounter, dh.firstTForbit, dh.runNumber); +} + +//_________________________________________________________ +void HBFUtilsInitializer::assignDataHeaderFromHBFUtilWithIRFrames(o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) +{ + const auto& hbfu = o2::raw::HBFUtils::Instance(); + static int64_t offset = hbfu.getFirstIRofTF({0, hbfu.orbitFirstSampled}).orbit; + dh.runNumber = hbfu.runNumber; + dh.firstTForbit = offset + hbfu.nHBFPerTF * dh.tfCounter; // fallback settings + IRFrameSel.getMin().clear(); // invalidate + if (LastIRFrameSplit) { // previously sent IRFrame has a continuation in the next TF + LastIRFrameIndex--; + LastIRFrameSplit = false; + } + o2::InteractionRecord ir0Mn, ir0Mx; + while (++LastIRFrameIndex < NTFs) { + IRFrameSel = IRFrames[LastIRFrameIndex]; // copy! + ir0Mn = hbfu.getFirstIRofTF(IRFrameSel.getMin()); + ir0Mx = hbfu.getFirstIRofTF(IRFrameSel.getMax()); + if (ir0Mn.orbit < offset) { + if (ir0Mx.orbit < offset) { + LOGP(warn, "IRFrame#{} ({}-{}) precedes 1st sampled TF {}, skipping", + LastIRFrameIndex, + IRFrameSel.getMin().asString(), + IRFrameSel.getMax().asString(), + hbfu.getFirstIRofTF({0, hbfu.orbitFirstSampled}).asString()); + IRFrameSel.getMin().clear(); + continue; + } else { + LOGP(warn, "IRFrame#{} ({}-{}) start precedes 1st sampled TF {}, overriding start", LastIRFrameIndex, + IRFrameSel.getMin().asString(), + IRFrameSel.getMax().asString(), + hbfu.getFirstIRofTF({0, hbfu.orbitFirstSampled}).asString()); + ir0Mn = hbfu.getFirstIRofTF({0, hbfu.orbitFirstSampled}); + IRFrameSel.setMin(ir0Mn); + } + } + if (IRFrameSel.getMax().orbit >= ir0Mn.orbit + hbfu.nHBFPerTF) { + ir0Mx = ir0Mn + int64_t(hbfu.nHBFPerTF) * o2::constants::lhc::LHCMaxBunches - 1; + LOGP(warn, "IRFrame#{} ({}-{}) is split to ({}-{}) and ({}-{})", + LastIRFrameIndex, + IRFrameSel.getMin().asString(), IRFrameSel.getMax().asString(), + IRFrameSel.getMin().asString(), ir0Mx.asString(), + (ir0Mx + 1).asString(), IRFrameSel.getMax().asString()); + IRFrameSel.setMax(ir0Mx); + IRFrames[LastIRFrameIndex].setMin(ir0Mx + 1); + LastIRFrameSplit = true; + } + break; + } + if (IRFrameSel.getMin().isDummy() || IRFrameSel.getMax().isDummy()) { + LOGP(warn, "Failed to define IRFrame"); + } else { + dh.tfCounter = (ir0Mn.orbit - offset) / hbfu.nHBFPerTF; + dh.firstTForbit = ir0Mn.orbit; + if (LastIRFrameIndex == NTFs - 1 && !LastIRFrameSplit) { + IRFrameSel.setLast(); + } + } + dph.creation = hbfu.startTime + (dh.firstTForbit - hbfu.orbitFirst) * o2::constants::lhc::LHCOrbitMUS * 1.e-3; + LOGP(debug, "SETTING DH for {}/{} from tfCounter={} firstTForbit={} runNumber={} and IRFrame ({}-{})", + dh.dataOrigin.as(), dh.dataDescription.as(), dh.tfCounter, dh.firstTForbit, dh.runNumber, + IRFrameSel.getMin().asString(), IRFrameSel.getMax().asString()); +} + //_________________________________________________________ void HBFUtilsInitializer::addNewTimeSliceCallback(std::vector& policies) { @@ -167,29 +266,43 @@ void HBFUtilsInitializer::addNewTimeSliceCallback(std::vector(HBFTFInfoOpt); - uint32_t delay = context.options().isSet(DelayOpt) ? uint32_t(1e6 * context.options().get(DelayOpt)) : 0; - if (!fname.empty()) { - if (fname == HBFUSrc) { // simple linear enumeration from already updated HBFUtils - const auto& hbfu = o2::raw::HBFUtils::Instance(); - service.set( - [offset = int64_t(hbfu.getFirstIRofTF({0, hbfu.orbitFirstSampled}).orbit), increment = int64_t(hbfu.nHBFPerTF), - startTime = hbfu.startTime, orbitFirst = hbfu.orbitFirst, runNumber = hbfu.runNumber, delay](o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { - dh.firstTForbit = offset + increment * dh.tfCounter; - dh.runNumber = runNumber; - dph.creation = startTime + (dh.firstTForbit - orbitFirst) * o2::constants::lhc::LHCOrbitMUS * 1.e-3; + std::string irFrames, tfInput = context.options().get(HBFTFInfoOpt); + if (context.options().hasOption(HBFIRFrameOpt)) { + irFrames = context.options().get(HBFIRFrameOpt); + } + uint32_t delay = context.options().hasOption(DelayOpt) && context.options().isSet(DelayOpt) ? uint32_t(1e6 * context.options().get(DelayOpt)) : 0; + if (!tfInput.empty()) { + if (tfInput == HBFUSrc) { // simple linear enumeration from already updated HBFUtils + if (irFrames.empty()) { // push the whole TF + NTFs = 1; + service.set([delay](o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { + assignDataHeaderFromHBFUtils(dh, dph); static size_t tfcount = 0; if (tfcount++ && delay > 0) { usleep(delay); } }); - } else if (o2::utils::Str::endsWith(fname, ".root")) { // read TFIDinfo from file - if (!o2::utils::Str::pathExists(fname)) { - throw std::runtime_error(fmt::format("file {} does not exist", fname)); + } else { // linear enumeration with IRFrames selection (skimming) + if (!o2::utils::Str::pathExists(irFrames)) { + throw std::runtime_error(fmt::format("file {} does not exist", irFrames)); + } + readIRFramesVector(irFrames); + service.set( + [delay](o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { + assignDataHeaderFromHBFUtilWithIRFrames(dh, dph); + static size_t tfcount = 0; + if (tfcount++ && delay > 0) { + usleep(delay); + } + }); + } + } else if (o2::utils::Str::endsWith(tfInput, ".root")) { // read TFIDinfo from file + if (!o2::utils::Str::pathExists(tfInput)) { + throw std::runtime_error(fmt::format("file {} does not exist", tfInput)); } service.set( - [tfidinfo = readTFIDInfoVector(fname), delay](o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { - assignDataHeader(tfidinfo, dh, dph); + [tfidinfo = readTFIDInfoVector(tfInput), delay](o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph) { + assignDataHeaderFromTFIDInfo(tfidinfo, dh, dph); static size_t tfcount = 0; if (tfcount++ && delay > 0) { usleep(delay); diff --git a/cmake/O2RootMacroExclusionList.cmake b/cmake/O2RootMacroExclusionList.cmake index 137b449cba509..6d286df72b12f 100644 --- a/cmake/O2RootMacroExclusionList.cmake +++ b/cmake/O2RootMacroExclusionList.cmake @@ -60,6 +60,7 @@ list(APPEND O2_ROOT_MACRO_EXCLUSION_LIST macro/load_all_libs.C macro/putCondition.C macro/rootlogon.C + macro/CreateSampleIRFrames.C Detectors/Upgrades/ALICE3/macros/ALICE3Field.C) diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt index ac50fd5775875..843ad4a3be0ab 100644 --- a/macro/CMakeLists.txt +++ b/macro/CMakeLists.txt @@ -57,6 +57,7 @@ install(FILES CheckDigits_mft.C CreateGRPMagFieldObject.C CreateGRPLHCIFObject.C getTimeStamp.C + CreateSampleIRFrames.C DESTINATION share/macro/) # FIXME: a lot of macros that are here should really be elsewhere. Those which diff --git a/macro/CreateSampleIRFrames.C b/macro/CreateSampleIRFrames.C new file mode 100644 index 0000000000000..fb1a3f2a29c65 --- /dev/null +++ b/macro/CreateSampleIRFrames.C @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if defined(__CLING__) && !defined(__ROOTCLING__) + +// create IRFrames of length frLengthBC, starting from the beginning of simulated data + offBC, separated by gapBC +void CreateSampleIRFrames(size_t offsBC = 0, size_t frLengthBC = int(1.5 * 3564), size_t gapBC = 0, + const char* iniFile = "o2simdigitizerworkflow_configuration.ini", + const char* digiCtx = "collisioncontext.root", + const char* outFile = "irframes.root") +{ + o2::conf::ConfigurableParam::updateFromFile(iniFile, "HBFUtils", true); + const auto& hbfu = o2::raw::HBFUtils::Instance(); + hbfu.print(); + auto dc = o2::steer::DigitizationContext::loadFromFile(digiCtx); + const auto& evr = dc->getEventRecords(); + std::vector irFrames; + o2::InteractionRecord ir0 = hbfu.getFirstSampledTFIR() + offsBC; + while (ir0 < evr.back()) { + irFrames.emplace_back(ir0, ir0 + frLengthBC); + ir0 += frLengthBC + gapBC; + std::cout << "Added IRFrame# " << irFrames.size() - 1 << " : " << irFrames.back().getMin() << " : " << irFrames.back().getMax() << "\n"; + } + std::string outfname{outFile}; + TFile outF(outfname.empty() ? "IRFrames.root" : outfname.c_str(), "recreate"); + outF.WriteObjectAny(&irFrames, "std::vector", "irframes"); + outF.Close(); +} + +#endif From 9d39dbc56748f775abc302459aa219f72af94a96 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 20 Sep 2024 01:29:39 +0400 Subject: [PATCH 0305/2205] Adapth ITS/MFT digit reader to IRFrames filtering --- .../include/ITSMFTWorkflow/DigitReaderSpec.h | 8 +- .../common/workflow/src/DigitReaderSpec.cxx | 189 +++++++++++++++--- 2 files changed, 167 insertions(+), 30 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DigitReaderSpec.h b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DigitReaderSpec.h index 3b462cd5d7594..e655e05842d71 100644 --- a/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DigitReaderSpec.h +++ b/Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/DigitReaderSpec.h @@ -24,6 +24,8 @@ #include "Headers/DataHeader.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DetectorsCommonDataFormats/DetID.h" +#include "SimulationDataFormat/IOMCTruthContainerView.h" +#include "SimulationDataFormat/ConstMCTruthContainer.h" using namespace o2::framework; @@ -48,7 +50,7 @@ class DigitReader : public Task std::vector mCalib, *mCalibPtr = &mCalib; std::vector mDigROFRec, *mDigROFRecPtr = &mDigROFRec; std::vector mDigMC2ROFs, *mDigMC2ROFsPtr = &mDigMC2ROFs; - + o2::dataformats::ConstMCTruthContainer mConstLabels; o2::header::DataOrigin mOrigin = o2::header::gDataOriginInvalid; std::unique_ptr mFile; @@ -56,6 +58,10 @@ class DigitReader : public Task bool mUseMC = true; // use MC truth bool mUseCalib = true; // send calib data bool mTriggerOut = true; // send dummy triggers vector + bool mUseIRFrames = false; // selected IRFrames modes + int mROFBiasInBC = 0; + int mROFLengthInBC = 0; + int mNRUs = 0; std::string mDetName = ""; std::string mDetNameLC = ""; std::string mFileName = ""; diff --git a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx index ef9494c85bf4b..fa634c9d6fc5f 100644 --- a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx @@ -19,11 +19,16 @@ #include "Framework/ConfigParamRegistry.h" #include "Framework/Logger.h" #include "ITSMFTWorkflow/DigitReaderSpec.h" +#include "ITSMFTBase/DPLAlpideParam.h" +#include "ITSMFTReconstruction/ChipMappingITS.h" +#include "ITSMFTReconstruction/ChipMappingMFT.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" -#include "SimulationDataFormat/IOMCTruthContainerView.h" #include "DataFormatsITSMFT/PhysTrigger.h" #include "CommonUtils/NameConf.h" +#include "CommonDataFormat/IRFrame.h" +#include "CommonUtils/IRFrameSelector.h" +#include "CCDB/BasicCCDBManager.h" #include using namespace o2::framework; @@ -56,43 +61,169 @@ void DigitReader::init(InitContext& ic) { mFileName = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), ic.options().get((mDetNameLC + "-digit-infile").c_str())); + if (ic.options().hasOption("ignore-irframes") && !ic.options().get("ignore-irframes")) { + mUseIRFrames = true; + } connectTree(mFileName); } void DigitReader::run(ProcessingContext& pc) { - auto ent = mTree->GetReadEntry() + 1; - assert(ent < mTree->GetEntries()); // this should not happen - - o2::dataformats::IOMCTruthContainerView* plabels = nullptr; - if (mUseMC) { - mTree->SetBranchAddress(mDigtMCTruthBranchName.c_str(), &plabels); - } - mTree->GetEntry(ent); - LOG(info) << mDetName << "DigitReader pushes " << mDigROFRec.size() << " ROFRecords, " - << mDigits.size() << " digits at entry " << ent; - - // This is a very ugly way of providing DataDescription, which anyway does not need to contain detector name. - // To be fixed once the names-definition class is ready - pc.outputs().snapshot(Output{mOrigin, "DIGITSROF", 0}, mDigROFRec); - pc.outputs().snapshot(Output{mOrigin, "DIGITS", 0}, mDigits); - if (mUseCalib) { - pc.outputs().snapshot(Output{mOrigin, "GBTCALIB", 0}, mCalib); + const auto& tinfo = pc.services().get(); + if (tinfo.globalRunNumberChanged) { // new run is starting: 1st call + // TODO: we have to find a way define CCDBInput for IRFrames mode only using DPL fetcher + auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); + auto rlim = ccdb.getRunDuration(tinfo.runNumber); + long ts = (rlim.first + rlim.second) / 2; + if (mOrigin == o2::header::gDataOriginITS) { + ccdb.getForTimeStamp>("ITS/Config/AlpideParam", ts); + const auto& alpideParam = o2::itsmft::DPLAlpideParam::Instance(); + mROFBiasInBC = alpideParam.roFrameBiasInBC; + mROFLengthInBC = alpideParam.roFrameLengthInBC; + mNRUs = o2::itsmft::ChipMappingITS::getNRUs(); + } else { + ccdb.getForTimeStamp>("MFT/Config/AlpideParam", ts); + const auto& alpideParam = o2::itsmft::DPLAlpideParam::Instance(); + mROFBiasInBC = alpideParam.roFrameBiasInBC; + mROFLengthInBC = alpideParam.roFrameLengthInBC; + mNRUs = o2::itsmft::ChipMappingMFT::getNRUs(); + } } - if (mTriggerOut) { - std::vector dummyTrig; - pc.outputs().snapshot(Output{mOrigin, "PHYSTRIG", 0}, dummyTrig); + gsl::span irFrames{}; + if (mUseIRFrames) { + irFrames = pc.inputs().get>("driverInfo"); } - if (mUseMC) { - auto& sharedlabels = pc.outputs().make>(Output{mOrigin, "DIGITSMCTR", 0}); - plabels->copyandflatten(sharedlabels); - delete plabels; - pc.outputs().snapshot(Output{mOrigin, "DIGITSMC2ROF", 0}, mDigMC2ROFs); + static o2::dataformats::IOMCTruthContainerView* plabels = nullptr; + if (mUseMC && !plabels) { + mTree->SetBranchAddress(mDigtMCTruthBranchName.c_str(), &plabels); } + auto ent = mTree->GetReadEntry(); - if (mTree->GetReadEntry() + 1 >= mTree->GetEntries()) { - pc.services().get().endOfStream(); - pc.services().get().readyToQuit(QuitRequest::Me); + if (!mUseIRFrames) { + ent++; + assert(ent < mTree->GetEntries()); // this should not happen + mTree->GetEntry(ent); + LOG(info) << mDetName << "DigitReader pushes " << mDigROFRec.size() << " ROFRecords, " << mDigits.size() << " digits at entry " << ent; + pc.outputs().snapshot(Output{mOrigin, "DIGITSROF", 0}, mDigROFRec); + pc.outputs().snapshot(Output{mOrigin, "DIGITS", 0}, mDigits); + if (mUseCalib) { + pc.outputs().snapshot(Output{mOrigin, "GBTCALIB", 0}, mCalib); + } + if (mTriggerOut) { + std::vector dummyTrig; + pc.outputs().snapshot(Output{mOrigin, "PHYSTRIG", 0}, dummyTrig); + } + if (mUseMC) { + auto& sharedlabels = pc.outputs().make>(Output{mOrigin, "DIGITSMCTR", 0}); + plabels->copyandflatten(sharedlabels); + delete plabels; + plabels = nullptr; + pc.outputs().snapshot(Output{mOrigin, "DIGITSMC2ROF", 0}, mDigMC2ROFs); + } + if (mTree->GetReadEntry() + 1 >= mTree->GetEntries()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } + } else { // need to select particulars IRs range, presumably from the same tree entry + std::vector digitsSel; + std::vector calibSel; + std::vector digROFRecSel; + std::vector digMC2ROFsSel; + o2::dataformats::MCTruthContainer digitLabelsSel; + + if (irFrames.size()) { // we assume the IRFrames are in the increasing order + if (ent < 0) { + ent++; + } + o2::utils::IRFrameSelector irfSel; + irfSel.setSelectedIRFrames(irFrames, 0, 0, mROFBiasInBC, true); + const auto irMin = irFrames.front().getMin(); + const auto irMax = irFrames.back().getMax(); + LOGP(info, "Selecting IRFrame {}-{}", irMin.asString(), irMax.asString()); + while (ent < mTree->GetEntries()) { + // do we need to read a new entry? + if (ent > mTree->GetReadEntry()) { + if (mUseMC) { + delete plabels; + plabels = nullptr; + mConstLabels.clear(); + mTree->SetBranchAddress(mDigtMCTruthBranchName.c_str(), &plabels); + } + mTree->GetEntry(ent); + if (mUseMC) { + plabels->copyandflatten(mConstLabels); + delete plabels; + plabels = nullptr; + } + } + std::vector rofOld2New; + rofOld2New.resize(mDigROFRec.size(), -1); + + if (mDigROFRec.front().getBCData() <= irMax && mDigROFRec.back().getBCData() >= irMin) { // there is an overlap + for (int irof = 0; irof < (int)mDigROFRec.size(); irof++) { + const auto& rof = mDigROFRec[irof]; + if (irfSel.check({rof.getBCData(), rof.getBCData() + mROFLengthInBC - 1}) != -1) { + rofOld2New[irof] = (int)digROFRecSel.size(); + LOGP(debug, "Adding selected ROF {}", rof.getBCData().asString()); + digROFRecSel.push_back(rof); + int offs = digitsSel.size(); + digROFRecSel.back().setFirstEntry(offs); + std::copy(mDigits.begin() + rof.getFirstEntry(), mDigits.begin() + rof.getFirstEntry() + rof.getNEntries(), std::back_inserter(digitsSel)); + for (int id = 0; id < rof.getNEntries(); id++) { // copy MC info + digitLabelsSel.addElements(id + offs, mConstLabels.getLabels(id + rof.getFirstEntry())); + } + if (mCalib.size() >= size_t((irof + 1) * mNRUs)) { + std::copy(mCalib.begin() + irof * mNRUs, mCalib.begin() + (irof + 1) * mNRUs, std::back_inserter(calibSel)); + } + } + } + } + if (mUseMC) { + digMC2ROFsSel = mDigMC2ROFs; + for (auto& mc2rof : digMC2ROFsSel) { + if (mc2rof.rofRecordID < 0) { + continue; // did not contribute even to the original data + } + unsigned int mn = 0xffff, mx = 0; + for (int ir = mc2rof.minROF; ir <= mc2rof.maxROF; ir++) { + if (rofOld2New[ir] >= 0) { // used + mx = rofOld2New[ir]; + if (mn > mx) { + mn = mx; + } + } + } + mc2rof.rofRecordID = mn == 0xffff ? -1 : int(mn); + mc2rof.minROF = mn; + mc2rof.maxROF = mx; + } + } + if (mDigROFRec.back().getBCData() < irMax) { // need to check the next entry + ent++; + continue; + } + break; // push collected data + } + } + pc.outputs().snapshot(Output{mOrigin, "DIGITSROF", 0}, digROFRecSel); + pc.outputs().snapshot(Output{mOrigin, "DIGITS", 0}, digitsSel); + if (mUseCalib) { + pc.outputs().snapshot(Output{mOrigin, "GBTCALIB", 0}, calibSel); + } + if (mTriggerOut) { + std::vector dummyTrig; + pc.outputs().snapshot(Output{mOrigin, "PHYSTRIG", 0}, dummyTrig); + } + if (mUseMC) { + auto& sharedlabels = pc.outputs().make>(Output{mOrigin, "DIGITSMCTR", 0}); + digitLabelsSel.flatten_to(sharedlabels); + pc.outputs().snapshot(Output{mOrigin, "DIGITSMC2ROF", 0}, digMC2ROFsSel); + } + + if (!irFrames.size() || irFrames.back().isLast()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } } } From 6fb976bb3a81e6c693688eed7bbc2fbd04108d11 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 4 Oct 2024 12:47:37 +0200 Subject: [PATCH 0306/2205] Fix compilation issue in AggregatedRunInfo Revert "Revert "AggregatedRunInfo struct proposal"" This reverts commit f15bb280744cfd097e46aa1fb43a57905f85f483. --- DataFormats/Parameters/CMakeLists.txt | 4 +- .../DataFormatsParameters/AggregatedRunInfo.h | 46 ++++++++++++++++ .../Parameters/src/AggregatedRunInfo.cxx | 55 +++++++++++++++++++ .../Parameters/src/ParametersDataLinkDef.h | 1 + 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h create mode 100644 DataFormats/Parameters/src/AggregatedRunInfo.cxx diff --git a/DataFormats/Parameters/CMakeLists.txt b/DataFormats/Parameters/CMakeLists.txt index 3539e9e11fd1e..ed137a42f6565 100644 --- a/DataFormats/Parameters/CMakeLists.txt +++ b/DataFormats/Parameters/CMakeLists.txt @@ -14,7 +14,8 @@ o2_add_library(DataFormatsParameters src/GRPLHCIFData.cxx src/GRPECSObject.cxx src/GRPMagField.cxx - PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants + src/AggregatedRunInfo.cxx + PUBLIC_LINK_LIBRARIES FairRoot::Base O2::CommonConstants O2::CommonTypes O2::CCDB O2::DetectorsCommonDataFormats) @@ -24,6 +25,7 @@ o2_target_root_dictionary(DataFormatsParameters include/DataFormatsParameters/GRPLHCIFData.h include/DataFormatsParameters/GRPECSObject.h include/DataFormatsParameters/GRPMagField.h + include/DataFormatsParameters/AggregatedRunInfo.h LINKDEF src/ParametersDataLinkDef.h) o2_add_executable(simgrp-tool diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h new file mode 100644 index 0000000000000..01d8057ed5cde --- /dev/null +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -0,0 +1,46 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GRPECSObject.h +/// \brief Header of the AggregatedRunInfo struct +/// \author ruben.shahoyan@cern.ch sandro.wenzel@cern.ch + +#ifndef ALICEO2_DATA_AGGREGATEDRUNINFO_H_ +#define ALICEO2_DATA_AGGREGATEDRUNINFO_H_ + +#include +#include "CCDB/BasicCCDBManager.h" + +namespace o2::parameters +{ + +/// Composite struct where one may collect important global properties of data "runs" +/// aggregated from various sources (GRPECS, RunInformation CCDB entries, etc.). +/// Also offers the authoritative algorithms to collect these information for easy reuse +/// across various algorithms (anchoredMC, analysis, ...) +struct AggregatedRunInfo { + int runNumber; // run number + int64_t sor; // best known timestamp for the start of run + int64_t eor; // best known timestamp for end of run + int64_t orbitsPerTF; // number of orbits per TF + int64_t orbitReset; // timestamp of orbit reset before run + int64_t orbitSOR; // orbit when run starts after orbit reset + int64_t orbitEOR; // orbit when run ends after orbit reset + + // we may have pointers to actual data source objects GRPECS, ... + + // fills and returns AggregatedRunInfo for a given run number. + static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); +}; + +} // namespace o2::parameters + +#endif diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx new file mode 100644 index 0000000000000..7a91b35fc494e --- /dev/null +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -0,0 +1,55 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file AggregatedRunInfo.cxx +/// \author sandro.wenzel@cern.ch + +#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "CommonConstants/LHCConstants.h" +#include "Framework/Logger.h" + +using namespace o2::parameters; + +o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber) +{ + // TODO: could think about caching results per runnumber to + // avoid going to CCDB multiple times ---> but should be done inside the CCDBManagerInstance + + // we calculate the first orbit of a run based on sor (start-of-run) and eor + // we obtain these by calling getRunDuration + auto [sor, eor] = ccdb.getRunDuration(runnumber); + + // determine a good timestamp to query OrbitReset for this run + // --> the middle of the run is very appropriate and safer than just sor + auto run_mid_timestamp = sor + (eor - sor) / 2; + + // query the time of the orbit reset (when orbit is defined to be 0) + auto ctpx = ccdb.getForTimeStamp>("CTP/Calib/OrbitReset", run_mid_timestamp); + int64_t tsOrbitReset = (*ctpx)[0]; // us + + // get timeframe length from GRPECS + std::map metadata; + metadata["runNumber"] = Form("%d", runnumber); + auto grpecs = ccdb.getSpecific("GLO/Config/GRPECS", run_mid_timestamp, metadata); + auto nOrbitsPerTF = grpecs->getNHBFPerTF(); + + // calculate SOR orbit + int64_t orbitSOR = (sor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; + int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; + + // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) + orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; + + + return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; +} diff --git a/DataFormats/Parameters/src/ParametersDataLinkDef.h b/DataFormats/Parameters/src/ParametersDataLinkDef.h index e4817bd443302..d2cbee2049c52 100644 --- a/DataFormats/Parameters/src/ParametersDataLinkDef.h +++ b/DataFormats/Parameters/src/ParametersDataLinkDef.h @@ -30,5 +30,6 @@ #pragma link C++ class o2::parameters::GRPMagField + ; #pragma link C++ class std::unordered_map < unsigned int, unsigned int> + ; #pragma link C++ class std::pair < unsigned long, std::string> + ; +#pragma link C++ struct o2::parameters::AggregatedRunInfo + ; #endif From 8a21520efe3449e7d83cf4e3e7bfc1e8e6c8eae4 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 4 Oct 2024 11:20:08 +0000 Subject: [PATCH 0307/2205] Please consider the following formatting changes --- .../include/DataFormatsParameters/AggregatedRunInfo.h | 2 +- DataFormats/Parameters/src/AggregatedRunInfo.cxx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h index 01d8057ed5cde..dc93ad46cc167 100644 --- a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -27,7 +27,7 @@ namespace o2::parameters /// Also offers the authoritative algorithms to collect these information for easy reuse /// across various algorithms (anchoredMC, analysis, ...) struct AggregatedRunInfo { - int runNumber; // run number + int runNumber; // run number int64_t sor; // best known timestamp for the start of run int64_t eor; // best known timestamp for end of run int64_t orbitsPerTF; // number of orbits per TF diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index 7a91b35fc494e..77c8a332c13b2 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -50,6 +50,5 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2:: // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; - return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; } From 1d16cac86f5ee57c3dedf7de2786c4be01024bf4 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:32:42 +0200 Subject: [PATCH 0308/2205] Drop non C++20 code (#13576) --- .../include/Framework/StructToTuple.h | 115 ------------------ 1 file changed, 115 deletions(-) diff --git a/Framework/Foundation/include/Framework/StructToTuple.h b/Framework/Foundation/include/Framework/StructToTuple.h index 0ef3be4efcb3c..becf22d01b8fe 100644 --- a/Framework/Foundation/include/Framework/StructToTuple.h +++ b/Framework/Foundation/include/Framework/StructToTuple.h @@ -124,7 +124,6 @@ struct is_braces_constructible : decltype(test(0)) { return d##0; \ } -#if __cplusplus >= 202002L struct UniversalType { template operator T() @@ -142,120 +141,6 @@ consteval auto brace_constructible_size(auto... Members) return brace_constructible_size(Members..., UniversalType{}); } } -#else -template -constexpr long brace_constructible_size() -{ - using A = any_type; - using type = std::decay_t; - // clang-format off - - if BRACE_CONSTRUCTIBLE_ENTRY (9, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (9, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (9) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (8, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (8) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (7, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (7) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (6, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (6) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (5, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (5) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (4, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (4) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (3, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (3) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (2, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (2) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 9) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 8) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 7) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 6) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 5) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 4) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 3) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 2) - else if BRACE_CONSTRUCTIBLE_ENTRY (1, 1) - else if BRACE_CONSTRUCTIBLE_ENTRY_TENS (1) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (9) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (8) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (7) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (6) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (5) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (4) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (3) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (2) - else if BRACE_CONSTRUCTIBLE_ENTRY_LOW (1) - else - { - return 0; - } - // clang-format on -} -#endif #define DPL_HOMOGENEOUS_APPLY_ENTRY_LOW(u) \ constexpr(numElements == u) \ From bb1000df7851affda1c7ecfc0b6f1c58e97bfb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Tue, 8 Oct 2024 14:48:06 +0200 Subject: [PATCH 0309/2205] [DM] Add expected time computation in Framework (#13528) * [DM] Add expected time computation in Framework - Use expected time functions in datamodel - add tofSignal computation in DM from ex. time - next: use utilities in AOD producer * Remove TOFValue and TOFExpTime --- .../include/Framework/AnalysisDataModel.h | 78 +++++++++++++------ Framework/Core/include/Framework/PID.h | 56 +++++++++++++ 2 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 Framework/Core/include/Framework/PID.h diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 9c939412cd941..2a1f9dbadf67f 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -24,6 +24,7 @@ #include "CommonConstants/GeomConstants.h" #include "CommonConstants/ZDCConstants.h" #include "SimulationDataFormat/MCGenProperties.h" +#include "Framework/PID.h" namespace o2 { @@ -266,39 +267,58 @@ DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector ma ifnode(aod::track::trdPattern > (uint8_t)0, static_cast(o2::aod::track::TRD), (uint8_t)0x0) | ifnode((aod::track::tofChi2 >= 0.f) && (aod::track::tofExpMom > 0.f), static_cast(o2::aod::track::TOF), (uint8_t)0x0)); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTime, tofExpTime, //! Expected time for the track to reach the TOF - [](float length, float tofExpMom, float mMassZSqared) -> float { - if (tofExpMom <= 0.f) { - return -999.f; - } - return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeEl, tofExpTimeEl, //! Expected time for the track to reach the TOF under the electron hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassElectron * o2::constants::physics::MassElectron; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeMu, tofExpTimeMu, //! Expected time for the track to reach the TOF under the muon hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassMuon * o2::constants::physics::MassMuon; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); }); DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimePi, tofExpTimePi, //! Expected time for the track to reach the TOF under the pion hypothesis [](float length, float tofExpMom) -> float { - if (tofExpMom <= 0.f) { - return -999.f; - } - constexpr float mMassZSqared = o2::constants::physics::MassPionCharged * o2::constants::physics::MassPionCharged; - return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + constexpr float massSquared = o2::constants::physics::MassPionCharged * o2::constants::physics::MassPionCharged; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); }); DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeKa, tofExpTimeKa, //! Expected time for the track to reach the TOF under the kaon hypothesis [](float length, float tofExpMom) -> float { - if (tofExpMom <= 0.f) { - return -999.f; - } - constexpr float mMassZSqared = o2::constants::physics::MassKaonCharged * o2::constants::physics::MassKaonCharged; - return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + constexpr float massSquared = o2::constants::physics::MassKaonCharged * o2::constants::physics::MassKaonCharged; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); }); DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimePr, tofExpTimePr, //! Expected time for the track to reach the TOF under the proton hypothesis [](float length, float tofExpMom) -> float { - if (tofExpMom <= 0.f) { - return -999.f; - } - constexpr float mMassZSqared = o2::constants::physics::MassProton * o2::constants::physics::MassProton; - return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); + constexpr float massSquared = o2::constants::physics::MassProton * o2::constants::physics::MassProton; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeDe, tofExpTimeDe, //! Expected time for the track to reach the TOF under the deuteron hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassDeuteron * o2::constants::physics::MassDeuteron; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeTr, tofExpTimeTr, //! Expected time for the track to reach the TOF under the triton hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassTriton * o2::constants::physics::MassTriton; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeHe, tofExpTimeHe, //! Expected time for the track to reach the TOF under the helium3 hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassHelium3 * o2::constants::physics::MassHelium3; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpTimeAl, tofExpTimeAl, //! Expected time for the track to reach the TOF under the helium4 hypothesis + [](float length, float tofExpMom) -> float { + constexpr float massSquared = o2::constants::physics::MassAlpha * o2::constants::physics::MassAlpha; + return o2::framework::pid::tof::MassToExpTime(tofExpMom, length, massSquared); }); namespace v001 @@ -338,7 +358,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(ITSNClsInnerBarrel, itsNClsInnerBarrel, //! Number of }); DECLARE_SOA_DYNAMIC_COLUMN(ITSClsSizeInLayer, itsClsSizeInLayer, //! Size of the ITS cluster in a given layer [](uint32_t itsClusterSizes, int layer) -> uint8_t { - if (layer >= 7) { + if (layer >= 7 || layer < 0) { return 0; } return (itsClusterSizes >> (layer * 4)) & 0xf; @@ -535,10 +555,15 @@ DECLARE_SOA_TABLE_FULL(StoredTracksExtra_000, "TracksExtra", "AOD", "TRACKEXTRA" track::HasTRD, track::HasTOF, track::TPCNClsFound, track::TPCNClsCrossedRows, - track::TOFExpTime, + track::TOFExpTimeEl, + track::TOFExpTimeMu, track::TOFExpTimePi, track::TOFExpTimeKa, track::TOFExpTimePr, + track::TOFExpTimeDe, + track::TOFExpTimeTr, + track::TOFExpTimeHe, + track::TOFExpTimeAl, track::ITSNCls, track::ITSNClsInnerBarrel, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, @@ -560,10 +585,15 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "T track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::v001::ITSClsSizeInLayer, track::v001::IsITSAfterburner, - track::TOFExpTime, + track::TOFExpTimeEl, + track::TOFExpTimeMu, track::TOFExpTimePi, track::TOFExpTimeKa, track::TOFExpTimePr, + track::TOFExpTimeDe, + track::TOFExpTimeTr, + track::TOFExpTimeHe, + track::TOFExpTimeAl, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, diff --git a/Framework/Core/include/Framework/PID.h b/Framework/Core/include/Framework/PID.h new file mode 100644 index 0000000000000..3c8c27b27bae6 --- /dev/null +++ b/Framework/Core/include/Framework/PID.h @@ -0,0 +1,56 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef o2_framework_PID_H_DEFINED +#define o2_framework_PID_H_DEFINED + +#include +#include "CommonConstants/PhysicsConstants.h" + +/// +/// \file PID.h +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \since 2024-09-11 +/// \brief TOF PID utilities to work with the information stored in the AO2D +/// + +namespace o2::framework::pid +{ + +namespace tof +{ + +/// @brief Compute the expected time of flight for a given momentum, length and massSquared +/// @param tofExpMom the expected momentum of the particle in GeV/c +/// @param length the track length in cm +/// @param massSquared the squared mass of the particle in GeV^2/c^4 +/// @return the expected time of flight of the particle in ps +inline float MassToExpTime(float tofExpMom, float length, float massSquared) +{ + if (tofExpMom <= 0.f) { + return -999.f; + } + return length * std::sqrt((massSquared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); +} + +/// @brief Compute the signal of the time of flight for a given track time and expected time of flight +/// @param tracktime the measured time of flight (at the vertex) in ps +/// @param exptime the expected time of flight in ps +/// @return the signal of the time of flight +inline float TrackTimeToTOFSignal(float tracktime, float exptime) +{ + return tracktime * 1000.f + exptime; +} +} // namespace tof + +} // namespace o2::framework::pid + +#endif // o2_framework_PID_H_DEFINED From 695a86482e741d3fe1fccd9fb16353211c22b5a5 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 8 Oct 2024 14:15:16 +0200 Subject: [PATCH 0310/2205] GPU TPC: Fix crash when TPC-CTF-decoding with no track model tracks --- .../Global/GPUChainTrackingCompression.cxx | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 83bcb20ff6e8b..69ce61f0d8b62 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -283,32 +283,34 @@ int GPUChainTracking::RunTPCDecompression() bool toGPU = true; runKernel({GetGridAutoStep(inputStream, RecoStep::TPCDecompression), krnlRunRangeNone, &mEvents->init}, DecompressorShadow.mNativeClustersIndex, NSLICES * GPUCA_ROW_COUNT * sizeof(DecompressorShadow.mNativeClustersIndex[0])); - std::exclusive_scan(cmprClsHost.nTrackClusters, cmprClsHost.nTrackClusters + cmprClsHost.nTracks, Decompressor.mAttachedClustersOffsets, 0u); // computing clusters offsets for first kernel int nStreams = doGPU ? mRec->NStreams() - 1 : 1; - for (int iStream = 0; iStream < nStreams; ++iStream) { - unsigned int startTrack = cmprClsHost.nTracks / nStreams * iStream; - unsigned int endTrack = cmprClsHost.nTracks / nStreams * (iStream + 1) + (iStream < nStreams - 1 ? 0 : cmprClsHost.nTracks % nStreams); // index of last track (excluded from computation) - unsigned int numTracks = endTrack - startTrack; - unsigned int* offsets = Decompressor.mAttachedClustersOffsets; - unsigned int numClusters = (endTrack == cmprClsHost.nTracks ? offsets[endTrack - 1] + cmprClsHost.nTrackClusters[endTrack - 1] : offsets[endTrack]) - offsets[startTrack]; - unsigned int numClustersRed = numClusters - numTracks; - GPUMemCpy(myStep, DecompressorShadow.mAttachedClustersOffsets + startTrack, Decompressor.mAttachedClustersOffsets + startTrack, numTracks * sizeof(Decompressor.mAttachedClustersOffsets[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.nTrackClusters + startTrack, cmprClsHost.nTrackClusters + startTrack, numTracks * sizeof(cmprClsHost.nTrackClusters[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.qTotA + offsets[startTrack], cmprClsHost.qTotA + offsets[startTrack], numClusters * sizeof(cmprClsHost.qTotA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.qMaxA + offsets[startTrack], cmprClsHost.qMaxA + offsets[startTrack], numClusters * sizeof(cmprClsHost.qMaxA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.flagsA + offsets[startTrack], cmprClsHost.flagsA + offsets[startTrack], numClusters * sizeof(cmprClsHost.flagsA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.rowDiffA + offsets[startTrack] - startTrack, cmprClsHost.rowDiffA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.rowDiffA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.sliceLegDiffA + offsets[startTrack] - startTrack, cmprClsHost.sliceLegDiffA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.sliceLegDiffA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.padResA + offsets[startTrack] - startTrack, cmprClsHost.padResA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.padResA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.timeResA + offsets[startTrack] - startTrack, cmprClsHost.timeResA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.timeResA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.sigmaPadA + offsets[startTrack], cmprClsHost.sigmaPadA + offsets[startTrack], numClusters * sizeof(cmprClsHost.sigmaPadA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.sigmaTimeA + offsets[startTrack], cmprClsHost.sigmaTimeA + offsets[startTrack], numClusters * sizeof(cmprClsHost.sigmaTimeA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.qPtA + startTrack, cmprClsHost.qPtA + startTrack, numTracks * sizeof(cmprClsHost.qPtA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.rowA + startTrack, cmprClsHost.rowA + startTrack, numTracks * sizeof(cmprClsHost.rowA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.sliceA + startTrack, cmprClsHost.sliceA + startTrack, numTracks * sizeof(cmprClsHost.sliceA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.timeA + startTrack, cmprClsHost.timeA + startTrack, numTracks * sizeof(cmprClsHost.timeA[0]), iStream, toGPU); - GPUMemCpy(myStep, inputGPUShadow.padA + startTrack, cmprClsHost.padA + startTrack, numTracks * sizeof(cmprClsHost.padA[0]), iStream, toGPU); - runKernel({GetGridAuto(iStream), krnlRunRangeNone, {&mEvents->stream[iStream], &mEvents->init}}, startTrack, endTrack); + if (cmprClsHost.nAttachedClusters != 0) { + std::exclusive_scan(cmprClsHost.nTrackClusters, cmprClsHost.nTrackClusters + cmprClsHost.nTracks, Decompressor.mAttachedClustersOffsets, 0u); // computing clusters offsets for first kernel + for (int iStream = 0; iStream < nStreams; ++iStream) { + unsigned int startTrack = cmprClsHost.nTracks / nStreams * iStream; + unsigned int endTrack = cmprClsHost.nTracks / nStreams * (iStream + 1) + (iStream < nStreams - 1 ? 0 : cmprClsHost.nTracks % nStreams); // index of last track (excluded from computation) + unsigned int numTracks = endTrack - startTrack; + unsigned int* offsets = Decompressor.mAttachedClustersOffsets; + unsigned int numClusters = (endTrack == cmprClsHost.nTracks ? offsets[endTrack - 1] + cmprClsHost.nTrackClusters[endTrack - 1] : offsets[endTrack]) - offsets[startTrack]; + unsigned int numClustersRed = numClusters - numTracks; + GPUMemCpy(myStep, DecompressorShadow.mAttachedClustersOffsets + startTrack, Decompressor.mAttachedClustersOffsets + startTrack, numTracks * sizeof(Decompressor.mAttachedClustersOffsets[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.nTrackClusters + startTrack, cmprClsHost.nTrackClusters + startTrack, numTracks * sizeof(cmprClsHost.nTrackClusters[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.qTotA + offsets[startTrack], cmprClsHost.qTotA + offsets[startTrack], numClusters * sizeof(cmprClsHost.qTotA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.qMaxA + offsets[startTrack], cmprClsHost.qMaxA + offsets[startTrack], numClusters * sizeof(cmprClsHost.qMaxA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.flagsA + offsets[startTrack], cmprClsHost.flagsA + offsets[startTrack], numClusters * sizeof(cmprClsHost.flagsA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.rowDiffA + offsets[startTrack] - startTrack, cmprClsHost.rowDiffA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.rowDiffA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.sliceLegDiffA + offsets[startTrack] - startTrack, cmprClsHost.sliceLegDiffA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.sliceLegDiffA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.padResA + offsets[startTrack] - startTrack, cmprClsHost.padResA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.padResA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.timeResA + offsets[startTrack] - startTrack, cmprClsHost.timeResA + offsets[startTrack] - startTrack, numClustersRed * sizeof(cmprClsHost.timeResA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.sigmaPadA + offsets[startTrack], cmprClsHost.sigmaPadA + offsets[startTrack], numClusters * sizeof(cmprClsHost.sigmaPadA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.sigmaTimeA + offsets[startTrack], cmprClsHost.sigmaTimeA + offsets[startTrack], numClusters * sizeof(cmprClsHost.sigmaTimeA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.qPtA + startTrack, cmprClsHost.qPtA + startTrack, numTracks * sizeof(cmprClsHost.qPtA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.rowA + startTrack, cmprClsHost.rowA + startTrack, numTracks * sizeof(cmprClsHost.rowA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.sliceA + startTrack, cmprClsHost.sliceA + startTrack, numTracks * sizeof(cmprClsHost.sliceA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.timeA + startTrack, cmprClsHost.timeA + startTrack, numTracks * sizeof(cmprClsHost.timeA[0]), iStream, toGPU); + GPUMemCpy(myStep, inputGPUShadow.padA + startTrack, cmprClsHost.padA + startTrack, numTracks * sizeof(cmprClsHost.padA[0]), iStream, toGPU); + runKernel({GetGridAuto(iStream), krnlRunRangeNone, {&mEvents->stream[iStream], &mEvents->init}}, startTrack, endTrack); + } } GPUMemCpy(myStep, inputGPUShadow.nSliceRowClusters, cmprClsHost.nSliceRowClusters, NSLICES * GPUCA_ROW_COUNT * sizeof(cmprClsHost.nSliceRowClusters[0]), unattachedStream, toGPU); GPUMemCpy(myStep, inputGPUShadow.qTotU, cmprClsHost.qTotU, cmprClsHost.nUnattachedClusters * sizeof(cmprClsHost.qTotU[0]), unattachedStream, toGPU); From 669d3bf8d65f37277d9e16d50d67fd2858ec980b Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 8 Oct 2024 18:00:06 +0200 Subject: [PATCH 0311/2205] Protection against ITS/MFT GBTTrailer packet status corruption --- .../reconstruction/include/ITSMFTReconstruction/GBTWord.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h index a0f758e5a5833..2efd1497c2e9e 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTWord.h @@ -243,7 +243,7 @@ struct GBTDataTrailer : public GBTWord { id = GBTFlagDataTrailer; } - uint8_t getPacketState() const { return data8[8]; } + uint8_t getPacketState() const { return data8[8] & (MaxStateCombinations - 1); } void setByte(uint8_t v, int which) = delete; From 9a4bbb7a442e8e446791d9a801ba2eaf4fe7edfb Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 11:10:08 +0200 Subject: [PATCH 0312/2205] GPU: Add debug output --- GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu index a51b3f9e2261f..11c40fed7b811 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu @@ -329,6 +329,9 @@ int GPUReconstructionCUDA::InitDevice_Runtime() mDeviceMemorySize = mDeviceMemorySize * 2 / 3; // Leave 1/3 of GPU memory for event display } + if (mProcessingSettings.debugLevel >= 3) { + GPUInfo("Allocating memory on GPU"); + } if (mDeviceMemorySize > deviceProp.totalGlobalMem || GPUFailedMsgI(cudaMalloc(&mDeviceMemoryBase, mDeviceMemorySize))) { size_t free, total; GPUFailedMsg(cudaMemGetInfo(&free, &total)); @@ -336,6 +339,9 @@ int GPUReconstructionCUDA::InitDevice_Runtime() GPUFailedMsgI(cudaDeviceReset()); return (1); } + if (mProcessingSettings.debugLevel >= 3) { + GPUInfo("Allocating memory on Host"); + } if (GPUFailedMsgI(cudaMallocHost(&mHostMemoryBase, mHostMemorySize))) { GPUError("Error allocating Page Locked Host Memory (trying %lld bytes)", (long long int)mHostMemorySize); GPUFailedMsgI(cudaDeviceReset()); @@ -611,6 +617,9 @@ int GPUReconstructionCUDA::GPUDebug(const char* state, int stream, bool force) int GPUReconstructionCUDA::registerMemoryForGPU_internal(const void* ptr, size_t size) { + if (mProcessingSettings.debugLevel >= 3) { + GPUInfo("Registering %zu bytes of memory for GPU", size); + } return GPUFailedMsgI(cudaHostRegister((void*)ptr, size, cudaHostRegisterDefault)); } From 63b9c7c0ab5de6842869bf52f6b328be3b38d9d6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 11:38:31 +0200 Subject: [PATCH 0313/2205] GPU: Get rid of all long long types --- GPU/Common/GPUCommonRtypes.h | 4 +-- GPU/GPUTracking/Base/GPUReconstruction.cxx | 18 +++++----- GPU/GPUTracking/Base/GPUReconstruction.h | 16 ++++----- .../Base/GPUReconstructionConvert.cxx | 20 +++++------ .../Base/GPUReconstructionConvert.h | 4 +-- .../Base/GPUReconstructionTimeframe.cxx | 8 ++--- .../Base/GPUReconstructionTimeframe.h | 4 +-- .../Base/cuda/GPUReconstructionCUDA.cu | 34 +++++++++---------- .../Base/cuda/GPUReconstructionCUDA.h | 4 +-- .../opencl-common/GPUReconstructionOCL.cxx | 24 ++++++------- .../Base/opencl-common/GPUReconstructionOCL.h | 4 +-- .../GPUReconstructionOCLInternals.h | 10 +++--- .../AliHLTTPCClusterStatComponent.cxx | 6 ++-- .../AliHLTTPCClusterStatComponent.h | 4 +-- .../GPUTPCClusterStatistics.cxx | 4 +-- .../GPUTPCCompressionKernels.h | 2 +- ...andalone-cluster-dump-entropy-analysed.cxx | 14 ++++---- GPU/GPUTracking/Global/GPUChainTracking.h | 2 +- .../Global/GPUChainTrackingClusterizer.cxx | 4 +-- .../Interface/GPUO2InterfaceUtils.cxx | 4 +-- .../Interface/GPUO2InterfaceUtils.h | 4 +-- GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx | 14 ++++---- GPU/GPUTracking/Merger/GPUTPCGMMerger.h | 4 +-- .../SliceTracker/GPUTPCSliceData.cxx | 2 +- .../SliceTracker/GPUTPCStartHitsFinder.cxx | 2 +- .../Standalone/Benchmark/standalone.cxx | 10 +++--- .../GPUTRDTrackletReaderComponent.cxx | 6 ++-- .../display/3rdparty/KHR/khrplatform.h | 24 ++++++------- GPU/GPUTracking/display/GPUDisplay.cxx | 2 +- GPU/GPUTracking/qa/GPUQA.cxx | 10 +++--- GPU/GPUTracking/qa/GPUQA.h | 10 +++--- GPU/GPUTracking/qa/GPUQAHelper.h | 2 +- GPU/GPUTracking/utils/opencl_obtain_program.h | 2 +- GPU/GPUbenchmark/cuda/Kernels.cu | 2 +- .../TPCFastSpaceChargeCorrection.h | 6 ++-- .../TPCFastTransform.cxx | 2 +- GPU/TPCFastTransformation/TPCFastTransform.h | 8 ++--- .../TPCFastTransformManager.cxx | 4 +-- .../alirootMacro/createTPCFastTransform.C | 2 +- .../generateTPCDistortionNTupleAliRoot.C | 2 +- .../alirootMacro/initTPCcalibration.C | 2 +- .../devtools/IrregularSpline1DTest.C | 2 +- .../devtools/IrregularSpline2D3DTest.C | 2 +- GPU/Workflow/src/GPUWorkflowSpec.cxx | 2 +- 44 files changed, 158 insertions(+), 158 deletions(-) diff --git a/GPU/Common/GPUCommonRtypes.h b/GPU/Common/GPUCommonRtypes.h index be1923d9b0e8b..31b655986673a 100644 --- a/GPU/Common/GPUCommonRtypes.h +++ b/GPU/Common/GPUCommonRtypes.h @@ -26,8 +26,8 @@ #define ClassImp(name) #define templateClassImp(name) #ifndef GPUCA_GPUCODE_DEVICE - typedef unsigned long long int ULong64_t; - typedef unsigned int UInt_t; +// typedef unsigned long long ULong64_t; +// typedef unsigned int UInt_t; #include #endif #endif diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index 23b00e7287401..2dd92862c0500 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -74,7 +74,7 @@ constexpr const char* const GPUReconstruction::GEOMETRY_TYPE_NAMES[]; constexpr const char* const GPUReconstruction::IOTYPENAMES[]; constexpr GPUReconstruction::GeometryType GPUReconstruction::geometryType; -static long long int ptrDiff(void* a, void* b) { return (long long int)((char*)a - (char*)b); } +static long ptrDiff(void* a, void* b) { return (long)((char*)a - (char*)b); } GPUReconstruction::GPUReconstruction(const GPUSettingsDeviceBackend& cfg) : mHostConstantMem(new GPUConstantMem), mDeviceBackendSettings(cfg) { @@ -600,7 +600,7 @@ void GPUReconstruction::AllocateRegisteredMemoryInternal(GPUMemoryResource* res, res->mSize = std::max((size_t)res->SetPointers((void*)1) - 1, res->mOverrideSize); if (res->mReuse >= 0) { if (res->mSize > mMemoryResources[res->mReuse].mSize) { - GPUError("Invalid reuse, insufficient size: %lld < %lld", (long long int)mMemoryResources[res->mReuse].mSize, (long long int)res->mSize); + GPUError("Invalid reuse, insufficient size: %ld < %ld", (long)mMemoryResources[res->mReuse].mSize, (long)res->mSize); throw std::bad_alloc(); } res->mPtrDevice = mMemoryResources[res->mReuse].mPtrDevice; @@ -834,9 +834,9 @@ void GPUReconstruction::PopNonPersistentMemory(RecoStep step, unsigned long tag) } if ((mProcessingSettings.debugLevel >= 3 || mProcessingSettings.allocDebugLevel) && (IsGPU() || mProcessingSettings.forceHostMemoryPoolSize)) { if (IsGPU()) { - printf("Allocated Device memory after %30s (%8s): %'13lld (non temporary %'13lld, blocked %'13lld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase), mDeviceMemoryPoolBlocked == nullptr ? 0ll : ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolBlocked)); + printf("Allocated Device memory after %30s (%8s): %'13ld (non temporary %'13ld, blocked %'13ld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase), mDeviceMemoryPoolBlocked == nullptr ? 0l : ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolBlocked)); } - printf("Allocated Host memory after %30s (%8s): %'13lld (non temporary %'13lld, blocked %'13lld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), ptrDiff(mHostMemoryPool, mHostMemoryBase), mHostMemoryPoolBlocked == nullptr ? 0ll : ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolBlocked)); + printf("Allocated Host memory after %30s (%8s): %'13ld (non temporary %'13ld, blocked %'13ld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), ptrDiff(mHostMemoryPool, mHostMemoryBase), mHostMemoryPoolBlocked == nullptr ? 0l : ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolBlocked)); printf("%16s", ""); PrintMemoryMax(); } @@ -904,15 +904,15 @@ void GPUReconstruction::UpdateMaxMemoryUsed() void GPUReconstruction::PrintMemoryMax() { - printf("Maximum Memory Allocation: Host %'lld / Device %'lld\n", (long long int)mHostMemoryUsedMax, (long long int)mDeviceMemoryUsedMax); + printf("Maximum Memory Allocation: Host %'ld / Device %'ld\n", (long)mHostMemoryUsedMax, (long)mDeviceMemoryUsedMax); } void GPUReconstruction::PrintMemoryOverview() { if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { - printf("Memory Allocation: Host %'lld / %'lld (Permanent %'lld), Device %'lld / %'lld, (Permanent %'lld) %d chunks\n", - ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), (long long int)mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), - ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), (long long int)mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), (int)mMemoryResources.size()); + printf("Memory Allocation: Host %'ld / %'ld (Permanent %'ld), Device %'ld / %'ld, (Permanent %'ld) %d chunks\n", + ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), (long)mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), + ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), (long)mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), (int)mMemoryResources.size()); } } @@ -937,7 +937,7 @@ void GPUReconstruction::PrintMemoryStatistics() } printf("%59s CPU / %9s GPU\n", "", ""); for (auto it = sizes.begin(); it != sizes.end(); it++) { - printf("Allocation %30s %s: Size %'14lld / %'14lld\n", it->first.c_str(), it->second[2] ? "P" : " ", (long long int)it->second[0], (long long int)it->second[1]); + printf("Allocation %30s %s: Size %'14ld / %'14ld\n", it->first.c_str(), it->second[2] ? "P" : " ", (long)it->second[0], (long)it->second[1]); } PrintMemoryOverview(); for (unsigned int i = 0; i < mChains.size(); i++) { diff --git a/GPU/GPUTracking/Base/GPUReconstruction.h b/GPU/GPUTracking/Base/GPUReconstruction.h index f1efff492d3df..3484fb65d0faa 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.h +++ b/GPU/GPUTracking/Base/GPUReconstruction.h @@ -414,7 +414,7 @@ inline T* GPUReconstruction::AllocateIOMemoryHelper(size_t n, const T*& ptr, std retVal = u.get(); if (mProcessingSettings.registerStandaloneInputMemory) { if (registerMemoryForGPU(u.get(), n * sizeof(T))) { - GPUError("Error registering memory for GPU: %p - %lld bytes\n", (void*)u.get(), (long long int)(n * sizeof(T))); + GPUError("Error registering memory for GPU: %p - %ld bytes\n", (void*)u.get(), (long)(n * sizeof(T))); throw std::bad_alloc(); } } @@ -505,7 +505,7 @@ inline unsigned int GPUReconstruction::DumpData(FILE* fp, const T* const* entrie } } if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Dumped %lld %s", (long long int)numTotal, IOTYPENAMES[type]); + GPUInfo("Dumped %ld %s", (long)numTotal, IOTYPENAMES[type]); } return numTotal; } @@ -539,7 +539,7 @@ inline size_t GPUReconstruction::ReadData(FILE* fp, const T** entries, S* num, s } (void)r; if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %lld %s", (long long int)numTotal, IOTYPENAMES[type]); + GPUInfo("Read %ld %s", (long)numTotal, IOTYPENAMES[type]); } return numTotal; } @@ -569,7 +569,7 @@ inline std::unique_ptr GPUReconstruction::ReadFlatObjectFromFile(const char* r = fread(size, sizeof(size[0]), 2, fp); if (r == 0 || size[0] != sizeof(T)) { fclose(fp); - GPUError("ERROR reading %s, invalid size: %lld (%lld expected)", file, (long long int)size[0], (long long int)sizeof(T)); + GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (long)size[0], (long)sizeof(T)); throw std::runtime_error("invalid size"); } std::unique_ptr retVal(new T); @@ -579,7 +579,7 @@ inline std::unique_ptr GPUReconstruction::ReadFlatObjectFromFile(const char* r = fread(buf, 1, size[1], fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %lld bytes from %s", (long long int)r, file); + GPUInfo("Read %ld bytes from %s", (long)r, file); } retVal->clearInternalBufferPtr(); retVal->setActualBufferAddress(buf); @@ -611,14 +611,14 @@ inline std::unique_ptr GPUReconstruction::ReadStructFromFile(const char* file r = fread(&size, sizeof(size), 1, fp); if (r == 0 || size != sizeof(T)) { fclose(fp); - GPUError("ERROR reading %s, invalid size: %lld (%lld expected)", file, (long long int)size, (long long int)sizeof(T)); + GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (long)size, (long)sizeof(T)); throw std::runtime_error("invalid size"); } std::unique_ptr newObj(new T); r = fread(newObj.get(), 1, size, fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %lld bytes from %s", (long long int)r, file); + GPUInfo("Read %ld bytes from %s", (long)r, file); } return newObj; } @@ -639,7 +639,7 @@ inline int GPUReconstruction::ReadStructFromFile(const char* file, T* obj) r = fread(obj, 1, size, fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %lld bytes from %s", (long long int)r, file); + GPUInfo("Read %ld bytes from %s", (long)r, file); } return 0; } diff --git a/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx b/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx index 18b661a0cdec1..7c8f3dc1cf1b3 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx @@ -195,7 +195,7 @@ namespace // anonymous // ------------------------------------------------- TPC ZS General ------------------------------------------------- -typedef std::array zsPage; +typedef std::array zsPage; struct zsEncoder { int curRegion = 0, outputRegion = 0; @@ -219,7 +219,7 @@ struct zsEncoder { unsigned int pageCounter = 0; void ZSfillEmpty(void* ptr, int shift, unsigned int feeId, int orbit, int linkid); static void ZSstreamOut(unsigned short* bufIn, unsigned int& lenIn, unsigned char* bufOut, unsigned int& lenOut, unsigned int nBits); - long int getHbf(long int timestamp) { return (timestamp * LHCBCPERTIMEBIN + bcShiftInFirstHBF) / o2::constants::lhc::LHCMaxBunches; } + long getHbf(long timestamp) { return (timestamp * LHCBCPERTIMEBIN + bcShiftInFirstHBF) / o2::constants::lhc::LHCMaxBunches; } }; inline void zsEncoder::ZSfillEmpty(void* ptr, int shift, unsigned int feeId, int orbit, int linkid) @@ -1325,7 +1325,7 @@ size_t zsEncoderRun::compare(std::vector* buffer, std::vector -void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) +void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) { // Pass in either outBuffer / outSizes, to fill standalone output buffers, or raw to use RawFileWriter // ir is the interaction record for time bin 0 @@ -1394,8 +1394,8 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptrreset(new unsigned long long int[totalPages * TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned long long int)]); - unsigned long long int offset = 0; + outBuffer->reset(new unsigned long[totalPages * TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned long)]); + unsigned long offset = 0; for (unsigned int i = 0; i < NSLICES; i++) { for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { memcpy((char*)outBuffer->get() + offset, buffer[i][j].data(), buffer[i][j].size() * TPCZSHDR::TPC_ZS_PAGE_SIZE); @@ -1405,7 +1405,7 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr(const GPUTrackingInOutDigits&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); +template void GPUReconstructionConvert::RunZSEncoder(const GPUTrackingInOutDigits&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); #ifdef GPUCA_O2_LIB -template void GPUReconstructionConvert::RunZSEncoder(const DigitArray&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); +template void GPUReconstructionConvert::RunZSEncoder(const DigitArray&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); #endif #endif -void GPUReconstructionConvert::RunZSEncoderCreateMeta(const unsigned long long int* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out) +void GPUReconstructionConvert::RunZSEncoderCreateMeta(const unsigned long* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out) { - unsigned long long int offset = 0; + unsigned long offset = 0; for (unsigned int i = 0; i < NSLICES; i++) { for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { ptrs[i * GPUTrackingInOutZS::NENDPOINTS + j] = (char*)buffer + offset; diff --git a/GPU/GPUTracking/Base/GPUReconstructionConvert.h b/GPU/GPUTracking/Base/GPUReconstructionConvert.h index 62f136015022c..8ff66491c947e 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionConvert.h +++ b/GPU/GPUTracking/Base/GPUReconstructionConvert.h @@ -54,8 +54,8 @@ class GPUReconstructionConvert static void ConvertNativeToClusterData(o2::tpc::ClusterNativeAccess* native, std::unique_ptr* clusters, unsigned int* nClusters, const TPCFastTransform* transform, int continuousMaxTimeBin = 0); static void ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess& native, std::unique_ptr& nativeBuffer, const AliHLTTPCRawCluster** rawClusters, unsigned int* nRawClusters); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); - static void RunZSEncoderCreateMeta(const unsigned long long int* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoderCreateMeta(const unsigned long* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out); static void RunZSFilter(std::unique_ptr* buffers, const o2::tpc::Digit* const* ptrs, size_t* nsb, const size_t* ns, const GPUParam& param, bool zs12bit, float threshold); static int GetMaxTimeBin(const o2::tpc::ClusterNativeAccess& native); static int GetMaxTimeBin(const GPUTrackingInOutDigits& digits); diff --git a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx index df7335495ab4b..cf26311da0966 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx @@ -231,9 +231,9 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) return (2); } - long long int nBunch = -DRIFT_TIME / config.bunchSpacing; - long long int lastBunch = config.timeFrameLen / config.bunchSpacing; - long long int lastTFBunch = lastBunch - DRIFT_TIME / config.bunchSpacing; + long nBunch = -DRIFT_TIME / config.bunchSpacing; + long lastBunch = config.timeFrameLen / config.bunchSpacing; + long lastTFBunch = lastBunch - DRIFT_TIME / config.bunchSpacing; int nCollisions = 0, nBorderCollisions = 0, nTrainCollissions = 0, nMultipleCollisions = 0, nTrainMultipleCollisions = 0; int nTrain = 0; int mcMin = -1, mcMax = -1; @@ -288,7 +288,7 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) return (1); } nTotalClusters += nClusters; - printf("Placing event %4d+%d (ID %4d) at z %7.3f (time %'dns) %s(collisions %4d, bunch %6lld, train %3d) (%'10d clusters, %'10d MC labels, %'10d track MC info)\n", nCollisions, nBorderCollisions, useEvent, shift, (int)(nBunch * config.bunchSpacing), inTF ? " inside" : "outside", + printf("Placing event %4d+%d (ID %4d) at z %7.3f (time %'dns) %s(collisions %4d, bunch %6ld, train %3d) (%'10d clusters, %'10d MC labels, %'10d track MC info)\n", nCollisions, nBorderCollisions, useEvent, shift, (int)(nBunch * config.bunchSpacing), inTF ? " inside" : "outside", nCollisions, nBunch, nTrain, nClusters, mChain->mIOPtrs.nMCLabelsTPC, mChain->mIOPtrs.nMCInfosTPC); nInBunchPileUp++; nCollisionsInTrain++; diff --git a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h index 5bab78e4d5099..e93f7234e7cdc 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h +++ b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h @@ -57,7 +57,7 @@ class GPUReconstructionTimeframe int mNEventsInDirectory; std::uniform_real_distribution mDisUniReal; - std::uniform_int_distribution mDisUniInt; + std::uniform_int_distribution mDisUniInt; std::mt19937_64 mRndGen1; std::mt19937_64 mRndGen2; @@ -68,7 +68,7 @@ class GPUReconstructionTimeframe int mNTotalCollisions = 0; - long long int mEventStride; + long mEventStride; int mSimBunchNoRepeatEvent; std::vector mEventUsed; std::vector> mShiftedEvents; diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu index 11c40fed7b811..52aad75f5c55d 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu @@ -62,17 +62,17 @@ GPUReconstructionCUDABackend::~GPUReconstructionCUDABackend() } } -int GPUReconstructionCUDABackend::GPUFailedMsgAI(const long long int error, const char* file, int line) +int GPUReconstructionCUDABackend::GPUFailedMsgAI(const long error, const char* file, int line) { // Check for CUDA Error and in the case of an error display the corresponding error string if (error == cudaSuccess) { return (0); } - GPUError("CUDA Error: %lld / %s (%s:%d)", error, cudaGetErrorString((cudaError_t)error), file, line); + GPUError("CUDA Error: %ld / %s (%s:%d)", error, cudaGetErrorString((cudaError_t)error), file, line); return 1; } -void GPUReconstructionCUDABackend::GPUFailedMsgA(const long long int error, const char* file, int line) +void GPUReconstructionCUDABackend::GPUFailedMsgA(const long error, const char* file, int line) { if (GPUFailedMsgAI(error, file, line)) { static bool runningCallbacks = false; @@ -203,7 +203,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() continue; } devicesOK[i] = true; - devMemory[i] = std::min(free, std::max(0, total - REQUIRE_MEMORY_RESERVED)); + devMemory[i] = std::min(free, std::max(0, total - REQUIRE_MEMORY_RESERVED)); if (deviceSpeed > bestDeviceSpeed) { bestDevice = i; bestDeviceSpeed = deviceSpeed; @@ -216,7 +216,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() bool noDevice = false; if (bestDevice == -1) { - GPUWarning("No %sCUDA Device available, aborting CUDA Initialisation (Required mem: %lld)", count ? "appropriate " : "", (long long int)mDeviceMemorySize); + GPUWarning("No %sCUDA Device available, aborting CUDA Initialisation (Required mem: %ld)", count ? "appropriate " : "", (long)mDeviceMemorySize); #ifndef __HIPCC__ GPUImportant("Requiring Revision %d.%d, Mem: %lu", reqVerMaj, reqVerMin, std::max(mDeviceMemorySize, REQUIRE_MIN_MEMORY)); #endif @@ -244,21 +244,21 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mProcessingSettings.debugLevel >= 2) { GPUInfo("Using CUDA Device %s with Properties:", deviceProp.name); - GPUInfo("\ttotalGlobalMem = %lld", (unsigned long long int)deviceProp.totalGlobalMem); - GPUInfo("\tsharedMemPerBlock = %lld", (unsigned long long int)deviceProp.sharedMemPerBlock); + GPUInfo("\ttotalGlobalMem = %ld", (unsigned long)deviceProp.totalGlobalMem); + GPUInfo("\tsharedMemPerBlock = %ld", (unsigned long)deviceProp.sharedMemPerBlock); GPUInfo("\tregsPerBlock = %d", deviceProp.regsPerBlock); GPUInfo("\twarpSize = %d", deviceProp.warpSize); - GPUInfo("\tmemPitch = %lld", (unsigned long long int)deviceProp.memPitch); + GPUInfo("\tmemPitch = %ld", (unsigned long)deviceProp.memPitch); GPUInfo("\tmaxThreadsPerBlock = %d", deviceProp.maxThreadsPerBlock); GPUInfo("\tmaxThreadsDim = %d %d %d", deviceProp.maxThreadsDim[0], deviceProp.maxThreadsDim[1], deviceProp.maxThreadsDim[2]); GPUInfo("\tmaxGridSize = %d %d %d", deviceProp.maxGridSize[0], deviceProp.maxGridSize[1], deviceProp.maxGridSize[2]); - GPUInfo("\ttotalConstMem = %lld", (unsigned long long int)deviceProp.totalConstMem); + GPUInfo("\ttotalConstMem = %ld", (unsigned long)deviceProp.totalConstMem); GPUInfo("\tmajor = %d", deviceProp.major); GPUInfo("\tminor = %d", deviceProp.minor); GPUInfo("\tclockRate = %d", deviceProp.clockRate); GPUInfo("\tmemoryClockRate = %d", deviceProp.memoryClockRate); GPUInfo("\tmultiProcessorCount = %d", deviceProp.multiProcessorCount); - GPUInfo("\ttextureAlignment = %lld", (unsigned long long int)deviceProp.textureAlignment); + GPUInfo("\ttextureAlignment = %ld", (unsigned long)deviceProp.textureAlignment); GPUInfo(" "); } if (deviceProp.warpSize != GPUCA_WARP_SIZE) { @@ -281,7 +281,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #ifdef GPUCA_USE_TEXTURES if (GPUCA_SLICE_DATA_MEMORY * NSLICES > (size_t)deviceProp.maxTexture1DLinear) { - GPUError("Invalid maximum texture size of device: %lld < %lld\n", (long long int)deviceProp.maxTexture1DLinear, (long long int)(GPUCA_SLICE_DATA_MEMORY * NSLICES)); + GPUError("Invalid maximum texture size of device: %ld < %ld\n", (long)deviceProp.maxTexture1DLinear, (long)(GPUCA_SLICE_DATA_MEMORY * NSLICES)); return (1); } #endif @@ -320,7 +320,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #endif if (mDeviceMemorySize == 1 || mDeviceMemorySize == 2) { - mDeviceMemorySize = std::max(0, devMemory[mDeviceId] - REQUIRE_FREE_MEMORY_RESERVED_PER_SM * deviceProp.multiProcessorCount); // Take all GPU memory but some reserve + mDeviceMemorySize = std::max(0, devMemory[mDeviceId] - REQUIRE_FREE_MEMORY_RESERVED_PER_SM * deviceProp.multiProcessorCount); // Take all GPU memory but some reserve if (mDeviceMemorySize >= RESERVE_EXTRA_MEM_THRESHOLD) { mDeviceMemorySize -= RESERVE_EXTRA_MEM_OFFSET; } @@ -335,7 +335,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mDeviceMemorySize > deviceProp.totalGlobalMem || GPUFailedMsgI(cudaMalloc(&mDeviceMemoryBase, mDeviceMemorySize))) { size_t free, total; GPUFailedMsg(cudaMemGetInfo(&free, &total)); - GPUError("CUDA Memory Allocation Error (trying %lld bytes, %lld available on GPU, %lld free)", (long long int)mDeviceMemorySize, (long long int)deviceProp.totalGlobalMem, (long long int)free); + GPUError("CUDA Memory Allocation Error (trying %ld bytes, %ld available on GPU, %ld free)", (long)mDeviceMemorySize, (long)deviceProp.totalGlobalMem, (long)free); GPUFailedMsgI(cudaDeviceReset()); return (1); } @@ -343,12 +343,12 @@ int GPUReconstructionCUDA::InitDevice_Runtime() GPUInfo("Allocating memory on Host"); } if (GPUFailedMsgI(cudaMallocHost(&mHostMemoryBase, mHostMemorySize))) { - GPUError("Error allocating Page Locked Host Memory (trying %lld bytes)", (long long int)mHostMemorySize); + GPUError("Error allocating Page Locked Host Memory (trying %ld bytes)", (long)mHostMemorySize); GPUFailedMsgI(cudaDeviceReset()); return (1); } if (mProcessingSettings.debugLevel >= 1) { - GPUInfo("Memory ptrs: GPU (%lld bytes): %p - Host (%lld bytes): %p", (long long int)mDeviceMemorySize, mDeviceMemoryBase, (long long int)mHostMemorySize, mHostMemoryBase); + GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (long)mDeviceMemorySize, mDeviceMemoryBase, (long)mHostMemorySize, mHostMemoryBase); memset(mHostMemoryBase, 0xDD, mHostMemorySize); if (GPUFailedMsgI(cudaMemset(mDeviceMemoryBase, 0xDD, mDeviceMemorySize))) { GPUError("Error during CUDA memset"); @@ -405,7 +405,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #endif mDeviceConstantMem = (GPUConstantMem*)devPtrConstantMem; - GPUInfo("CUDA Initialisation successfull (Device %d: %s (Frequency %d, Cores %d), %lld / %lld bytes host / global memory, Stack frame %d, Constant memory %lld)", mDeviceId, deviceProp.name, deviceProp.clockRate, deviceProp.multiProcessorCount, (long long int)mHostMemorySize, (long long int)mDeviceMemorySize, (int)GPUCA_GPU_STACK_SIZE, (long long int)gGPUConstantMemBufferSize); + GPUInfo("CUDA Initialisation successfull (Device %d: %s (Frequency %d, Cores %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", mDeviceId, deviceProp.name, deviceProp.clockRate, deviceProp.multiProcessorCount, (long)mHostMemorySize, (long)mDeviceMemorySize, (int)GPUCA_GPU_STACK_SIZE, (long)gGPUConstantMemBufferSize); } else { GPUReconstructionCUDA* master = dynamic_cast(mMaster); mDeviceId = master->mDeviceId; @@ -531,7 +531,7 @@ size_t GPUReconstructionCUDA::TransferMemoryInternal(GPUMemoryResource* res, int return 0; } if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %lld bytes", toGPU ? "GPU" : "Host", res->Name(), (long long int)res->Size()); + GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (long)res->Size()); } return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); } diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h index 8a483adb3353a..acf4ffbcf2965 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h @@ -35,8 +35,8 @@ class GPUReconstructionCUDABackend : public GPUReconstructionDeviceBase { public: ~GPUReconstructionCUDABackend() override; - static int GPUFailedMsgAI(const long long int error, const char* file, int line); - void GPUFailedMsgA(const long long int error, const char* file, int line); + static int GPUFailedMsgAI(const long error, const char* file, int line); + void GPUFailedMsgA(const long error, const char* file, int line); protected: GPUReconstructionCUDABackend(const GPUSettingsDeviceBackend& cfg); diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx index 3d6d083f4a87e..abcde6766c00c 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx @@ -53,7 +53,7 @@ GPUReconstructionOCL::~GPUReconstructionOCL() } } -int GPUReconstructionOCL::GPUFailedMsgAI(const long int error, const char* file, int line) +int GPUReconstructionOCL::GPUFailedMsgAI(const long error, const char* file, int line) { // Check for OPENCL Error and in the case of an error display the corresponding error string if (error == CL_SUCCESS) { @@ -63,7 +63,7 @@ int GPUReconstructionOCL::GPUFailedMsgAI(const long int error, const char* file, return 1; } -void GPUReconstructionOCL::GPUFailedMsgA(const long int error, const char* file, int line) +void GPUReconstructionOCL::GPUFailedMsgA(const long error, const char* file, int line) { if (GPUFailedMsgAI(error, file, line)) { static bool runningCallbacks = false; @@ -182,7 +182,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() double bestDeviceSpeed = -1, deviceSpeed = (double)freq * (double)shaders; if (mProcessingSettings.debugLevel >= 2) { - GPUImportant("Device %s%2d: %s %s (Frequency %d, Shaders %d, %d bit) (Speed Value: %lld)%s %s", deviceOK ? " " : "[", i, device_vendor, device_name, (int)freq, (int)shaders, (int)nbits, (long long int)deviceSpeed, deviceOK ? " " : " ]", deviceOK ? "" : deviceFailure); + GPUImportant("Device %s%2d: %s %s (Frequency %d, Shaders %d, %d bit) (Speed Value: %ld)%s %s", deviceOK ? " " : "[", i, device_vendor, device_name, (int)freq, (int)shaders, (int)nbits, (long)deviceSpeed, deviceOK ? " " : " ]", deviceOK ? "" : deviceFailure); } if (!deviceOK) { continue; @@ -231,11 +231,11 @@ int GPUReconstructionOCL::InitDevice_Runtime() GPUInfo("\tVersion = %s", deviceVersion); GPUInfo("\tFrequency = %d", (int)freq); GPUInfo("\tShaders = %d", (int)shaders); - GPUInfo("\tGLobalMemory = %lld", (long long int)globalMem); - GPUInfo("\tContantMemoryBuffer = %lld", (long long int)constantBuffer); - GPUInfo("\tLocalMemory = %lld", (long long int)localMem); - GPUInfo("\tmaxThreadsPerBlock = %lld", (long long int)maxWorkGroup); - GPUInfo("\tmaxThreadsDim = %lld %lld %lld", (long long int)maxWorkItems[0], (long long int)maxWorkItems[1], (long long int)maxWorkItems[2]); + GPUInfo("\tGLobalMemory = %ld", (long)globalMem); + GPUInfo("\tContantMemoryBuffer = %ld", (long)constantBuffer); + GPUInfo("\tLocalMemory = %ld", (long)localMem); + GPUInfo("\tmaxThreadsPerBlock = %ld", (long)maxWorkGroup); + GPUInfo("\tmaxThreadsDim = %ld %ld %ld", (long)maxWorkItems[0], (long)maxWorkItems[1], (long)maxWorkItems[2]); GPUInfo(" "); } #ifndef GPUCA_NO_CONSTANT_MEMORY @@ -342,12 +342,12 @@ int GPUReconstructionOCL::InitDevice_Runtime() mDeviceConstantMem = (GPUConstantMem*)((void**)mHostMemoryBase)[1]; if (mProcessingSettings.debugLevel >= 1) { - GPUInfo("Memory ptrs: GPU (%lld bytes): %p - Host (%lld bytes): %p", (long long int)mDeviceMemorySize, mDeviceMemoryBase, (long long int)mHostMemorySize, mHostMemoryBase); + GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (long)mDeviceMemorySize, mDeviceMemoryBase, (long)mHostMemorySize, mHostMemoryBase); memset(mHostMemoryBase, 0xDD, mHostMemorySize); } - GPUInfo("OPENCL Initialisation successfull (%d: %s %s (Frequency %d, Shaders %d), %lld / %lld bytes host / global memory, Stack frame %d, Constant memory %lld)", bestDevice, device_vendor, device_name, (int)freq, (int)shaders, (long long int)mDeviceMemorySize, - (long long int)mHostMemorySize, -1, (long long int)gGPUConstantMemBufferSize); + GPUInfo("OPENCL Initialisation successfull (%d: %s %s (Frequency %d, Shaders %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", bestDevice, device_vendor, device_name, (int)freq, (int)shaders, (long)mDeviceMemorySize, + (long)mHostMemorySize, -1, (long)gGPUConstantMemBufferSize); } else { GPUReconstructionOCL* master = dynamic_cast(mMaster); mBlockCount = master->mBlockCount; @@ -423,7 +423,7 @@ size_t GPUReconstructionOCL::TransferMemoryInternal(GPUMemoryResource* res, int return 0; } if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %lld bytes", toGPU ? "GPU" : "Host", res->Name(), (long long int)res->Size()); + GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (long)res->Size()); } return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); } diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h index d5562e14a3577..98a0559c8f8a4 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h @@ -38,8 +38,8 @@ class GPUReconstructionOCL : public GPUReconstructionDeviceBase int ExitDevice_Runtime() override; void UpdateAutomaticProcessingSettings() override; - int GPUFailedMsgAI(const long int error, const char* file, int line); - void GPUFailedMsgA(const long int error, const char* file, int line); + int GPUFailedMsgAI(const long error, const char* file, int line); + void GPUFailedMsgA(const long error, const char* file, int line); void SynchronizeGPU() override; int DoStuckProtection(int stream, deviceEvent event) override; diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h index 2f8a70ec6b2b1..53ce88c0324ef 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h @@ -131,15 +131,15 @@ static const char* opencl_error_string(int errorcode) #define GPUFailedMsg(x) GPUFailedMsgA(x, __FILE__, __LINE__) #define GPUFailedMsgI(x) GPUFailedMsgAI(x, __FILE__, __LINE__) -static inline long int OCLsetKernelParameters_helper(cl_kernel& k, int i) +static inline long OCLsetKernelParameters_helper(cl_kernel& k, int i) { return 0; } template -static inline long int OCLsetKernelParameters_helper(cl_kernel& kernel, int i, const T& firstParameter, const Args&... restOfParameters) +static inline long OCLsetKernelParameters_helper(cl_kernel& kernel, int i, const T& firstParameter, const Args&... restOfParameters) { - long int retVal = clSetKernelArg(kernel, i, sizeof(T), &firstParameter); + long retVal = clSetKernelArg(kernel, i, sizeof(T), &firstParameter); if (retVal) { return retVal; } @@ -147,12 +147,12 @@ static inline long int OCLsetKernelParameters_helper(cl_kernel& kernel, int i, c } template -static inline long int OCLsetKernelParameters(cl_kernel& kernel, const Args&... args) +static inline long OCLsetKernelParameters(cl_kernel& kernel, const Args&... args) { return OCLsetKernelParameters_helper(kernel, 0, args...); } -static inline long int clExecuteKernelA(cl_command_queue queue, cl_kernel krnl, size_t local_size, size_t global_size, cl_event* pEvent, cl_event* wait = nullptr, cl_int nWaitEvents = 1) +static inline long clExecuteKernelA(cl_command_queue queue, cl_kernel krnl, size_t local_size, size_t global_size, cl_event* pEvent, cl_event* wait = nullptr, cl_int nWaitEvents = 1) { return clEnqueueNDRangeKernel(queue, krnl, 1, nullptr, &global_size, &local_size, wait == nullptr ? 0 : nWaitEvents, wait, pEvent); } diff --git a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx index 3891e72a97243..bbe4934de590d 100644 --- a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx +++ b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx @@ -478,7 +478,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa hitIndexCache[ip]->fAverageQMax = averageQMax; hitIndexCache[ip]->fAverageQTot = averageCharge; } - pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(UInt_t); + pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(unsigned int); } } @@ -507,7 +507,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa std::sort(sortedClusters, sortedClusters + clusters->fCount, AliHLTTPCClusterStat_sorthelper); } - for (UInt_t iCluster = 0; iCluster < clusters->fCount; iCluster++) { + for (unsigned int iCluster = 0; iCluster < clusters->fCount; iCluster++) { AliHLTTPCRawCluster& cluster = clusters->fClusters[iCluster]; AliHLTTPCClusterXYZ& clusterTransformed = clustersTransformed->fClusters[iCluster]; static AliHLTTPCTrackHelperStruct tmp; @@ -599,7 +599,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa PrintDumpClustersScaled(slice, patch, cluster, clusterTransformed, clusterTrack); } } - pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(UInt_t); + pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(unsigned int); } } diff --git a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h index 126c37eba1b05..5860fa44eff44 100644 --- a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h +++ b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h @@ -47,8 +47,8 @@ class AliHLTTPCClusterStatComponent : public AliHLTProcessor, public AliOptionPa float fResidualPad; float fResidualTime; bool fFirstHit; - long long int fAverageQMax; - long long int fAverageQTot; + long fAverageQMax; + long fAverageQTot; }; // interface methods of base class diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx index f050563645faf..9db4b9758dbce 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx @@ -225,7 +225,7 @@ void GPUTPCClusterStatistics::Finish() GPUInfo("Combined Sigma: %6.4f --> %6.4f (%6.4f%%)", eSigma, eSigmaCombined, eSigma > 1e-3 ? (100. * (eSigma - eSigmaCombined) / eSigma) : 0.f); GPUInfo("Combined Q: %6.4f --> %6.4f (%6.4f%%)", eQ, eQCombined, eQ > 1e-3 ? (100. * (eQ - eQCombined) / eQ) : 0.f); - printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'lld cluster)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, (long long int)mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); + printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'ld clusters)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, (long)mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); } float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bool count) @@ -265,7 +265,7 @@ float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bo mHuffman += huffmanSize * total; } } - GPUInfo("Size: %30s: Entropy %7.4f Huffman %7.4f (Count) %9lld", name, entropy, huffmanSize, (long long int)total); + GPUInfo("Size: %30s: Entropy %7.4f Huffman %7.4f (Count) %9ld", name, entropy, huffmanSize, (long)total); return entropy; } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h index b3d6212418c50..8cd29903dd00a 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h @@ -69,7 +69,7 @@ class GPUTPCCompressionGatherKernels : public GPUKernelTemplate using Vec16 = unsigned short; using Vec32 = unsigned int; - using Vec64 = unsigned long int; + using Vec64 = unsigned long; using Vec128 = uint4; struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { diff --git a/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx b/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx index 0996781533f02..d5aaa6c803069 100644 --- a/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx +++ b/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx @@ -323,15 +323,15 @@ int main(int argc, char** argv) fclose(fp); - long long int* histograms[nFields]; + long* histograms[nFields]; double* probabilities[nFields]; - long long int counts[nFields]; + long counts[nFields]; int used[nFields]; for (int i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID) { continue; } - histograms[i] = new long long int[1 << field_bits[i]]; + histograms[i] = new long[1 << field_bits[i]]; probabilities[i] = new double[1 << field_bits[i]]; } @@ -352,7 +352,7 @@ int main(int argc, char** argv) if (i == CLUSTER_ID || i == PATCH) { continue; } - memset(histograms[i], 0, sizeof(long long int) * (1 << field_bits[i])); + memset(histograms[i], 0, sizeof(long) * (1 << field_bits[i])); counts[i] = 0; used[i] = 0; } @@ -589,7 +589,7 @@ int main(int argc, char** argv) nClustersUsed++; } - printf("Clusters in block: %lld / %lld\n", nClustersUsed, nClusters); + printf("Clusters in block: %ld / %ld\n", nClustersUsed, nClusters); double log2 = log(2.); double entropies[nFields]; @@ -603,7 +603,7 @@ int main(int argc, char** argv) if (counts[i]) { for (int j = 0; j < (1 << field_bits[i]); j++) { - // printf("Field %d/%s Value %d Entries %lld\n", i, field_names[i], j, histograms[i][j]); + // printf("Field %d/%s Value %d Entries %ld\n", i, field_names[i], j, histograms[i][j]); probabilities[i][j] = (double)histograms[i][j] / (double)counts[i]; if (probabilities[i][j]) { @@ -670,7 +670,7 @@ int main(int argc, char** argv) if (counts[i] == 0) { continue; } - printf("Field %2d/%16s (count %10lld / used %1d) rawBits %2d huffman %9.6f entropy %9.6f\n", i, field_names[i], counts[i], used[i], field_bits[i], huffmanSizes[i], entropies[i]); + printf("Field %2d/%16s (count %10ld / used %1d) rawBits %2d huffman %9.6f entropy %9.6f\n", i, field_names[i], counts[i], used[i], field_bits[i], huffmanSizes[i], entropies[i]); } rawBits = 79; // Override incorrect calculation: Row is only 6 bit in raw format, and slice is not needed! printf("Raw Bits: %d - Total Size %f MB Clusters %d\n", rawBits, (double)rawBits * (double)nClustersUsed / 8. / 1.e6, nClustersUsed); diff --git a/GPU/GPUTracking/Global/GPUChainTracking.h b/GPU/GPUTracking/Global/GPUChainTracking.h index 4963aaf728a04..81ed442c11412 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.h +++ b/GPU/GPUTracking/Global/GPUChainTracking.h @@ -97,7 +97,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega InOutMemory(InOutMemory&&); InOutMemory& operator=(InOutMemory&&); - std::unique_ptr tpcZSpages; + std::unique_ptr tpcZSpages; std::unique_ptr tpcZSpagesChar; // Same as above, but as char (needed for reading dumps, but deprecated, since alignment can be wrong) // TODO: Fix alignment std::unique_ptr tpcCompressedClusters; // TODO: Fix alignment std::unique_ptr tpcZSmeta; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index bcf4310a333f6..43569fc9f1e60 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -532,9 +532,9 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) } if (mIOPtrs.tpcZS) { - GPUInfo("Event has %u 8kb TPC ZS pages (version %d), %lld digits", mCFContext->nPagesTotal, mCFContext->zsVersion, (long long int)mRec->MemoryScalers()->nTPCdigits); + GPUInfo("Event has %u 8kb TPC ZS pages (version %d), %ld digits", mCFContext->nPagesTotal, mCFContext->zsVersion, (long)mRec->MemoryScalers()->nTPCdigits); } else { - GPUInfo("Event has %lld TPC Digits", (long long int)mRec->MemoryScalers()->nTPCdigits); + GPUInfo("Event has %ld TPC Digits", (long)mRec->MemoryScalers()->nTPCdigits); } if (mCFContext->tpcMaxTimeBin > maxAllowedTimebin) { diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index bb9c38c291fe2..70c0600c355c2 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -48,14 +48,14 @@ std::unique_ptr GPUO2InterfaceUtils::getCalibdEdxCo } template <> -void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) +void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) { GPUParam param; param.SetDefaults(5.00668); o2::gpu::GPUReconstructionConvert::RunZSEncoder(in, outBuffer, outSizes, raw, ir, param, version, verify, threshold, padding, digitsFilter); } template <> -void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding, std::function&)> digitsFilter) +void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding, std::function&)> digitsFilter) { GPUParam param; param.SetDefaults(&config.configGRP, &config.configReconstruction, &config.configProcessing, nullptr); diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h index d2c3ee495c9ea..aaa6bff20163d 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h @@ -47,9 +47,9 @@ class GPUO2InterfaceUtils static std::unique_ptr getPadGainCalib(const o2::tpc::CalDet& in); static std::unique_ptr getCalibdEdxContainerDefault(); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding = false, std::function&)> digitsFilter = nullptr); template static float getNominalGPUBz(T& src) { diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx index 379be50b09caf..a2d9a9ec400ee 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx @@ -176,7 +176,7 @@ inline const auto* resolveMCLabels(const o2::dataformat } template -long int GPUTPCGMMerger::GetTrackLabelA(const S& trk) const +long GPUTPCGMMerger::GetTrackLabelA(const S& trk) const { GPUTPCGMSliceTrack* sliceTrack = nullptr; int nClusters = 0; @@ -206,7 +206,7 @@ long int GPUTPCGMMerger::GetTrackLabelA(const S& trk) const } template -long int GPUTPCGMMerger::GetTrackLabel(const S& trk) const +long GPUTPCGMMerger::GetTrackLabel(const S& trk) const { #ifdef GPUCA_TPC_GEOMETRY_O2 if (GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth) { @@ -902,8 +902,8 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int GPUTPCGMBorderTrack& b2 = B2[r2.fId]; #if defined(GPUCA_MERGER_BY_MC_LABEL) && !defined(GPUCA_GPUCODE) - long int label1 = GetTrackLabel(b1); - long int label2 = GetTrackLabel(b2); + long label1 = GetTrackLabel(b1); + long label2 = GetTrackLabel(b2); if (label1 != label2 && label1 != -1) // DEBUG CODE, match by MC label #endif { @@ -2201,7 +2201,7 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo const MergeLooperParam* params = mLooperCandidates; #if GPUCA_MERGE_LOOPER_MC && !defined(GPUCA_GPUCODE) - std::vector paramLabels(mMemory->nLooperMatchCandidates); + std::vector paramLabels(mMemory->nLooperMatchCandidates); for (unsigned int i = 0; i < mMemory->nLooperMatchCandidates; i++) { paramLabels[i] = GetTrackLabel(mOutputTracks[params[i].id]); } @@ -2261,8 +2261,8 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo float d = CAMath::Sum2(dtgl * (1.f / 0.03f), dqpt * (1.f / 0.04f)) + d2xy * (1.f / 4.f) + dznorm * (1.f / 0.3f); bool EQ = d < 6.f; #if GPUCA_MERGE_LOOPER_MC && !defined(GPUCA_GPUCODE) - const long int label1 = paramLabels[i]; - const long int label2 = paramLabels[j]; + const long label1 = paramLabels[i]; + const long label2 = paramLabels[j]; bool labelEQ = label1 != -1 && label1 == label2; if (1 || EQ || labelEQ) { //printf("Matching track %d/%d %u-%u (%ld/%ld): dist %f side %d %d, tgl %f %f, qpt %f %f, x %f %f, y %f %f\n", (int)EQ, (int)labelEQ, i, j, label1, label2, d, (int)mOutputTracks[params[i].id].CSide(), (int)mOutputTracks[params[j].id].CSide(), params[i].tgl, params[j].tgl, params[i].qpt, params[j].qpt, params[i].x, params[j].x, params[i].y, params[j].y); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h index 23a334a772313..05b128ad522e2 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h @@ -235,9 +235,9 @@ class GPUTPCGMMerger : public GPUProcessor #ifndef GPUCA_GPUCODE void PrintMergeGraph(const GPUTPCGMSliceTrack* trk, std::ostream& out) const; template - long int GetTrackLabelA(const S& trk) const; + long GetTrackLabelA(const S& trk) const; template - long int GetTrackLabel(const S& trk) const; + long GetTrackLabel(const S& trk) const; #endif GPUdi() void setBlockRange(int elems, int nBlocks, int iBlock, int& start, int& end); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx index 31a2c5828fe7d..7b5af5acede78 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx @@ -365,7 +365,7 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int } GPUbarrier(); - constexpr float maxVal = (((long int)1 << (sizeof(cahit) < 3 ? sizeof(cahit) * 8 : 24)) - 1); // Stay within float precision in any case! + constexpr float maxVal = (((long)1 << (sizeof(cahit) < 3 ? sizeof(cahit) * 8 : 24)) - 1); // Stay within float precision in any case! constexpr float packingConstant = 1.f / (maxVal - 2.f); const float y0 = row.mGrid.YMin(); const float z0 = row.mGrid.ZMin(); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx index be8280dc074a5..3c90adb9b03e6 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx @@ -35,7 +35,7 @@ GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int /*nBlocks*/, int nThreads, in GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() row = tracker.mData.mRows[s.mIRow]; GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() rowUp = tracker.mData.mRows[s.mIRow + 2]; for (int ih = iThread; ih < s.mNHits; ih += nThreads) { - long int lHitNumberOffset = row.mHitNumberOffset; + long lHitNumberOffset = row.mHitNumberOffset; unsigned int linkUpData = tracker.mData.mLinkUpData[lHitNumberOffset + ih]; if (tracker.mData.mLinkDownData[lHitNumberOffset + ih] == CALINK_INVAL && linkUpData != CALINK_INVAL && tracker.mData.mLinkUpData[rowUp.mHitNumberOffset + linkUpData] != CALINK_INVAL) { diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index c6813f9b33b50..52fc24b433d50 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -615,7 +615,7 @@ int LoadEvent(int iEvent, int x) return 0; } -void OutputStat(GPUChainTracking* t, long long int* nTracksTotal = nullptr, long long int* nClustersTotal = nullptr) +void OutputStat(GPUChainTracking* t, long* nTracksTotal = nullptr, long* nClustersTotal = nullptr) { int nTracks = 0; if (t->GetProcessingSettings().createO2Output) { @@ -633,7 +633,7 @@ void OutputStat(GPUChainTracking* t, long long int* nTracksTotal = nullptr, long } } -int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, int runs, int iEvent, long long int* nTracksTotal, long long int* nClustersTotal, int threadId = 0, HighResTimer* timerPipeline = nullptr) +int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, int runs, int iEvent, long* nTracksTotal, long* nClustersTotal, int threadId = 0, HighResTimer* timerPipeline = nullptr) { int iRun = 0, iteration = 0; while ((iteration = nIteration.fetch_add(1)) < runs) { @@ -871,8 +871,8 @@ int main(int argc, char** argv) if (configStandalone.runs2 > 1) { printf("RUN2: %d\n", iRunOuter); } - long long int nTracksTotal = 0; - long long int nClustersTotal = 0; + long nTracksTotal = 0; + long nClustersTotal = 0; int nEventsProcessed = 0; if (configStandalone.noEvents) { @@ -966,7 +966,7 @@ int main(int argc, char** argv) } } if (nEventsProcessed > 1) { - printf("Total: %lld clusters, %lld tracks\n", nClustersTotal, nTracksTotal); + printf("Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal); } } diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx index 101f07155f95f..dfba6baa96c0d 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx @@ -243,7 +243,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv fEventId = hltEventData.fEventID; - HLTInfo("### START DoEvent [event id: %llu, %d blocks, size: %d]", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize); + HLTInfo("### START DoEvent [event id: %lu, %d blocks, size: %d]", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize); // event processing function int iResult = 0; @@ -252,7 +252,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv fRawReaderMem->ClearBuffers(); if (!IsDataEvent()) { // process data events only - HLTInfo("### END DoEvent [event id: %llu, %d blocks, size: %d] (skipped: no data event)", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize); + HLTInfo("### END DoEvent [event id: %lu, %d blocks, size: %d] (skipped: no data event)", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize); return iResult; } @@ -390,7 +390,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv iResult = PushBack(&outputTrklsMC[0], outputTrklsMC.size() * sizeof(outputTrklsMC[0]), AliHLTTRDDefinitions::fgkTRDMCTrackletDataType, 0); } - HLTInfo("### END DoEvent [event id: %llu, %d blocks, size: %d, output tracklets: %d]", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize, outputTrkls.size()); + HLTInfo("### END DoEvent [event id: %lu, %d blocks, size: %d, output tracklets: %d]", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize, outputTrkls.size()); return iResult; } diff --git a/GPU/GPUTracking/display/3rdparty/KHR/khrplatform.h b/GPU/GPUTracking/display/3rdparty/KHR/khrplatform.h index b6648a9a3d2b9..9fb630df9b8ad 100644 --- a/GPU/GPUTracking/display/3rdparty/KHR/khrplatform.h +++ b/GPU/GPUTracking/display/3rdparty/KHR/khrplatform.h @@ -186,11 +186,11 @@ typedef unsigned __int64 khronos_uint64_t; typedef int khronos_int32_t; typedef unsigned int khronos_uint32_t; #if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; +typedef long khronos_int64_t; +typedef unsigned long khronos_uint64_t; #else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; +typedef long khronos_int64_t; +typedef unsigned long khronos_uint64_t; #endif /* __arch64__ */ #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 @@ -234,15 +234,15 @@ typedef unsigned short int khronos_uint16_t; * to be the only LLP64 architecture in current use. */ #ifdef _WIN64 -typedef signed long long int khronos_intptr_t; -typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; +typedef signed long khronos_intptr_t; +typedef unsigned long khronos_uintptr_t; +typedef signed long khronos_ssize_t; +typedef unsigned long khronos_usize_t; #else -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; +typedef signed long khronos_intptr_t; +typedef unsigned long khronos_uintptr_t; +typedef signed long khronos_ssize_t; +typedef unsigned long khronos_usize_t; #endif #if KHRONOS_SUPPORT_FLOAT diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 59d6d978c3eaf..49bfd813de3d6 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -636,7 +636,7 @@ void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) if (mUpdateVertexLists && mIOPtrs) { size_t totalVertizes = DrawGLScene_updateVertexList(); if (showTimer) { - printf("Event visualization time: %'d us (vertices %'lld / %'lld bytes)\n", (int)(mTimerDraw.GetCurrentElapsedTime() * 1000000.), (long long int)totalVertizes, (long long int)(totalVertizes * sizeof(mVertexBuffer[0][0]))); + printf("Event visualization time: %'d us (vertices %'ld / %'ld bytes)\n", (int)(mTimerDraw.GetCurrentElapsedTime() * 1000000.), (long)totalVertizes, (long)(totalVertizes * sizeof(mVertexBuffer[0][0]))); } } diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 85b0b49305fc9..dce1104303668 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -2489,7 +2489,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } } - unsigned long long int attachClusterCounts[N_CLS_HIST]; + unsigned long attachClusterCounts[N_CLS_HIST]; if (mQATasks & taskClusterAttach) { // Process Cluster Attachment Histograms if (mConfig.inputHistogramsOnly == 0) { @@ -2779,7 +2779,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) return (0); } -void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned long long int n, unsigned long long int normalization) +void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned long n, unsigned long normalization) { if (mode == 2) { // do nothing, just count num @@ -2796,17 +2796,17 @@ void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned lon createHist(mHistClusterCount[num], name2, name, 1000, 0, mConfig.histMaxNClusters, 1000, 0, 100); } else if (mode == 0) { if (normalization && mConfig.enableLocalOutput) { - printf("\t%35s: %'12llu (%6.2f%%)\n", name, n, 100.f * n / normalization); + printf("\t%35s: %'12lu (%6.2f%%)\n", name, n, 100.f * n / normalization); } if (mConfig.clusterRejectionHistograms) { - float ratio = 100.f * n / std::max(normalization, 1llu); + float ratio = 100.f * n / std::max(normalization, 1lu); mHistClusterCount[num]->Fill(normalization, ratio, 1); } } num++; } -int GPUQA::DoClusterCounts(unsigned long long int* attachClusterCounts, int mode) +int GPUQA::DoClusterCounts(unsigned long* attachClusterCounts, int mode) { int num = 0; if (mcPresent() && (mQATasks & taskClusterAttach) && attachClusterCounts) { diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index be8b00972439a..fbeedc8b1ff45 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -167,8 +167,8 @@ class GPUQA }; int InitQACreateHistograms(); - int DoClusterCounts(unsigned long long int* attachClusterCounts, int mode = 0); - void PrintClusterCount(int mode, int& num, const char* name, unsigned long long int n, unsigned long long int normalization); + int DoClusterCounts(unsigned long* attachClusterCounts, int mode = 0); + void PrintClusterCount(int mode, int& num, const char* name, unsigned long n, unsigned long normalization); void CopyO2MCtoIOPtr(GPUTrackingInOutPointers* ptr); template void SetAxisSize(T* e); @@ -190,7 +190,7 @@ class GPUQA int getTrackID() const { return AbsLabelID(track); } int getEventID() const { return 0; } int getSourceID() const { return 0; } - long int getTrackEventSourceID() const { return getTrackID(); } + long getTrackEventSourceID() const { return getTrackID(); } bool isFake() const { return track < 0; } bool isValid() const { return track != MC_LABEL_INVALID; } void invalidate() { track = MC_LABEL_INVALID; } @@ -290,7 +290,7 @@ class GPUQA TLegend* mLClust[N_CLS_TYPE]; struct counts_t { - long long int nRejected = 0, nTube = 0, nTube200 = 0, nLoopers = 0, nLowPt = 0, n200MeV = 0, nPhysics = 0, nProt = 0, nUnattached = 0, nTotal = 0, nHighIncl = 0, nAbove400 = 0, nFakeRemove400 = 0, nFullFakeRemove400 = 0, nBelow40 = 0, nFakeProtect40 = 0, nMergedLooper = 0; + long nRejected = 0, nTube = 0, nTube200 = 0, nLoopers = 0, nLowPt = 0, n200MeV = 0, nPhysics = 0, nProt = 0, nUnattached = 0, nTotal = 0, nHighIncl = 0, nAbove400 = 0, nFakeRemove400 = 0, nFullFakeRemove400 = 0, nBelow40 = 0, nFakeProtect40 = 0, nMergedLooper = 0; double nUnaccessible = 0; } mClusterCounts; @@ -338,7 +338,7 @@ class GPUQA std::vector> mGoodTracks; std::vector> mGoodHits; - std::vector mTrackingScratchBuffer; + std::vector mTrackingScratchBuffer; static std::vector mColors; static int initColors(); diff --git a/GPU/GPUTracking/qa/GPUQAHelper.h b/GPU/GPUTracking/qa/GPUQAHelper.h index ee2f8890ecc90..e33b298a437b6 100644 --- a/GPU/GPUTracking/qa/GPUQAHelper.h +++ b/GPU/GPUTracking/qa/GPUQAHelper.h @@ -128,7 +128,7 @@ class GPUTPCTrkLbl } // namespace internal struct GPUTPCTrkLbl_ret { - long int id = -1; + long id = -1; GPUTPCTrkLbl_ret() = default; template GPUTPCTrkLbl_ret(T){}; diff --git a/GPU/GPUTracking/utils/opencl_obtain_program.h b/GPU/GPUTracking/utils/opencl_obtain_program.h index 3678bb3fe04f2..b1e8e8dea7308 100644 --- a/GPU/GPUTracking/utils/opencl_obtain_program.h +++ b/GPU/GPUTracking/utils/opencl_obtain_program.h @@ -55,7 +55,7 @@ static int _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint n return (1); } current_ptr += sizeof(_makefiles_opencl_device_info); - // printf("Device %d: %s %s (size %lld)\n", i, dinfo->device_vendor, dinfo->device_name, (long long int) dinfo->binary_size); + // printf("Device %d: %s %s (size %ld)\n", i, dinfo->device_vendor, dinfo->device_name, (long) dinfo->binary_size); program_sizes[i] = dinfo->binary_size; program_binaries[i] = current_ptr; current_ptr += dinfo->binary_size; diff --git a/GPU/GPUbenchmark/cuda/Kernels.cu b/GPU/GPUbenchmark/cuda/Kernels.cu index c455e8f6126f4..ba6abd84f662d 100644 --- a/GPU/GPUbenchmark/cuda/Kernels.cu +++ b/GPU/GPUbenchmark/cuda/Kernels.cu @@ -619,7 +619,7 @@ void GPUbenchmark::globalInit() mState.nMultiprocessors = props.multiProcessorCount; mState.nMaxThreadsPerBlock = props.maxThreadsPerMultiProcessor; mState.nMaxThreadsPerDimension = props.maxThreadsDim[0]; - mState.scratchSize = static_cast(mOptions.freeMemoryFractionToAllocate * free); + mState.scratchSize = static_cast(mOptions.freeMemoryFractionToAllocate * free); if (mState.testChunks.empty()) { for (auto j{0}; j < mState.getMaxChunks() * mState.chunkReservedGB; j += mState.chunkReservedGB) { diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h index 79930ca467382..dc6c737b3c430 100644 --- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h +++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h @@ -140,7 +140,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject GPUd() void setNoCorrection(); /// Sets the time stamp of the current calibaration - GPUd() void setTimeStamp(long int v) { mTimeStamp = v; } + GPUd() void setTimeStamp(long v) { mTimeStamp = v; } /// Set safety marging for the interpolation around the TPC row. /// Outside of this area the interpolation returns the boundary values. @@ -201,7 +201,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject } /// Gives the time stamp of the current calibaration parameters - long int getTimeStamp() const { return mTimeStamp; } + long getTimeStamp() const { return mTimeStamp; } /// Gives the interpolation safety marging around the TPC row. GPUd() float getInterpolationSafetyMargin() const { return fInterpolationSafetyMargin; } @@ -269,7 +269,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject /// _______________ Calibration data _______________________________________________ - long int mTimeStamp; ///< time stamp of the current calibration + long mTimeStamp; ///< time stamp of the current calibration char* mSplineData[3]; //! (transient!!) pointer to the spline data in the flat buffer diff --git a/GPU/TPCFastTransformation/TPCFastTransform.cxx b/GPU/TPCFastTransformation/TPCFastTransform.cxx index 6424292a6035a..2e6e9a64c457d 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransform.cxx @@ -117,7 +117,7 @@ void TPCFastTransform::startConstruction(const TPCFastSpaceChargeCorrection& cor mCorrection.cloneFromObject(correction, nullptr); } -void TPCFastTransform::setCalibration(long int timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ) +void TPCFastTransform::setCalibration(long timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ) { /// Sets all drift calibration parameters and the time stamp /// diff --git a/GPU/TPCFastTransformation/TPCFastTransform.h b/GPU/TPCFastTransformation/TPCFastTransform.h index be3e4db7800c3..5bd30a557f295 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.h +++ b/GPU/TPCFastTransformation/TPCFastTransform.h @@ -158,7 +158,7 @@ class TPCFastTransform : public FlatObject /// /// It must be called once during construction, /// but also may be called afterwards to reset these parameters. - void setCalibration(long int timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ); + void setCalibration(long timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ); /// Set Lumi info void setLumi(float l) { mLumi = l; } @@ -166,7 +166,7 @@ class TPCFastTransform : public FlatObject void setLumiScaleFactor(float s) { mLumiScaleFactor = s; } /// Sets the time stamp of the current calibaration - void setTimeStamp(long int v) { mTimeStamp = v; } + void setTimeStamp(long v) { mTimeStamp = v; } /// Gives a reference for external initialization of TPC corrections GPUd() const TPCFastSpaceChargeCorrection& getCorrection() const { return mCorrection; } @@ -233,7 +233,7 @@ class TPCFastTransform : public FlatObject GPUd() const TPCFastTransformGeo& getGeometry() const { return mCorrection.getGeometry(); } /// Gives the time stamp of the current calibaration parameters - GPUd() long int getTimeStamp() const { return mTimeStamp; } + GPUd() long getTimeStamp() const { return mTimeStamp; } /// Return mVDrift in cm / time bin GPUd() float getVDrift() const { return mVdrift; } @@ -299,7 +299,7 @@ class TPCFastTransform : public FlatObject /// _______________ Calibration data. See Transform() method ________________________________ - long int mTimeStamp; ///< time stamp of the current calibration + long mTimeStamp; ///< time stamp of the current calibration /// Correction of (x,u,v) with irregular splines. /// diff --git a/GPU/TPCFastTransformation/TPCFastTransformManager.cxx b/GPU/TPCFastTransformation/TPCFastTransformManager.cxx index ec32c75c0211e..3c573b3288c50 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformManager.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransformManager.cxx @@ -142,7 +142,7 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, const float ldCorr = 0.; const float tofCorr = 0.; const float primVtxZ = 0.; - const long int initTimeStamp = -1; + const long initTimeStamp = -1; fastTransform.setCalibration(initTimeStamp, t0, vDrift, vdCorrY, ldCorr, tofCorr, primVtxZ); @@ -219,7 +219,7 @@ int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, // set the current time stamp - mOrigTransform->SetCurrentTimeStamp(static_cast(TimeStamp)); + mOrigTransform->SetCurrentTimeStamp(static_cast(TimeStamp)); fastTransform.setTimeStamp(TimeStamp); // find last calibrated time bin diff --git a/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C b/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C index d023f426195d2..7d5915b7a6237 100644 --- a/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C +++ b/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C @@ -41,7 +41,7 @@ int createTPCFastTransform(TPCFastTransform& fastTransform) return -1; } AliTPCTransform* origTransform = tpcCalib->GetTransform(); - UInt_t timeStamp = origTransform->GetCurrentTimeStamp(); + unsigned int timeStamp = origTransform->GetCurrentTimeStamp(); TPCFastTransformManager manager; diff --git a/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C b/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C index 91bb546e7d57e..5f64dac5bef63 100644 --- a/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C +++ b/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C @@ -64,7 +64,7 @@ int generateTPCDistortionNTupleAliRoot() return -1; } - UInt_t timeStamp = origTransform->GetCurrentTimeStamp(); + unsigned int timeStamp = origTransform->GetCurrentTimeStamp(); TPCFastTransformManager manager; TPCFastTransform fastTransform; diff --git a/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C b/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C index c3a3e3d057792..c4fdd733b610f 100644 --- a/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C +++ b/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C @@ -188,7 +188,7 @@ int initTPCcalibration(const Char_t* cdbUri, int runNumber, bool isMC) tpcCalib->GetTransform()->SetCurrentRecoParam(recParam); AliTPCTransform* origTransform = tpcCalib->GetTransform(); - origTransform->SetCurrentTimeStamp(static_cast(timeStamp)); + origTransform->SetCurrentTimeStamp(static_cast(timeStamp)); Double_t bz = AliTracker::GetBz(); cout << "\n\nBz field is set to " << bz << ", time stamp is set to " << timeStamp << endl diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C b/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C index a8467d6ebe397..35da74bd7e5a5 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C @@ -60,7 +60,7 @@ int IrregularSpline1DTest() std::cout << "Test interpolation.." << std::endl; gRandom->SetSeed(0); - UInt_t seed = gRandom->Integer(100000); // 605 + unsigned int seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C index 04906797c1b7f..92a1d6d18e814 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C @@ -70,7 +70,7 @@ int IrregularSpline2D3DTest() using namespace o2::gpu; gRandom->SetSeed(0); - UInt_t seed = gRandom->Integer(100000); // 605 + unsigned int seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index f38256e795bbf..c5e3ea7924115 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -618,7 +618,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) if (mSpecConfig.decompressTPC) { ptrs.tpcCompressedClusters = pCompClustersFlat; } else if (mSpecConfig.zsOnTheFly) { - const unsigned long long int* buffer = reinterpret_cast(&inputZS[0]); + const unsigned long* buffer = reinterpret_cast(&inputZS[0]); o2::gpu::GPUReconstructionConvert::RunZSEncoderCreateMeta(buffer, tpcZSonTheFlySizes.data(), *&ptrEp, &tpcZS); ptrs.tpcZS = &tpcZS; doInputDigits = doInputDigitsMC = mSpecConfig.processMC; From 6730e7490c2b660bdade4c30b71ee94c9ddfa3a9 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 13:07:42 +0200 Subject: [PATCH 0314/2205] GPU: Switch integer types to types --- .../DataFormatsTRD/RecoInputContainer.h | 2 +- Detectors/TPC/workflow/src/ZSSpec.cxx | 4 +- GPU/Common/GPUCommonAlgorithm.h | 26 +- GPU/Common/GPUCommonDefAPI.h | 34 +- GPU/Common/GPUCommonMath.h | 58 +- GPU/Common/GPUCommonRtypes.h | 4 +- GPU/Common/GPUCommonTransform3D.h | 2 +- GPU/Common/GPUROOTCartesianFwd.h | 10 +- GPU/Common/GPUROOTSMatrixFwd.h | 32 +- GPU/Common/test/testSMatrixImp.cu | 50 +- GPU/GPUTracking/Base/GPUConstantMem.h | 10 +- GPU/GPUTracking/Base/GPUGeneralKernels.cxx | 14 +- GPU/GPUTracking/Base/GPUGeneralKernels.h | 24 +- GPU/GPUTracking/Base/GPUKernelDebugOutput.h | 16 +- GPU/GPUTracking/Base/GPUMemoryResource.h | 12 +- GPU/GPUTracking/Base/GPUParam.cxx | 48 +- GPU/GPUTracking/Base/GPUParam.h | 26 +- GPU/GPUTracking/Base/GPUParam.inc | 30 +- GPU/GPUTracking/Base/GPUProcessor.h | 2 +- GPU/GPUTracking/Base/GPUReconstruction.cxx | 136 ++-- GPU/GPUTracking/Base/GPUReconstruction.h | 192 +++--- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 117 ++-- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 188 +++--- .../Base/GPUReconstructionConvert.cxx | 580 +++++++++--------- .../Base/GPUReconstructionConvert.h | 18 +- .../Base/GPUReconstructionDeviceBase.cxx | 40 +- .../Base/GPUReconstructionDeviceBase.h | 44 +- .../Base/GPUReconstructionHelpers.h | 16 +- .../Base/GPUReconstructionIncludesITS.h | 4 +- .../Base/GPUReconstructionKernelMacros.h | 14 +- .../Base/GPUReconstructionKernels.h | 44 +- .../Base/GPUReconstructionLibrary.cxx | 8 +- .../Base/GPUReconstructionTimeframe.cxx | 102 +-- .../Base/GPUReconstructionTimeframe.h | 40 +- .../Base/cuda/GPUReconstructionCUDA.cu | 112 ++-- .../Base/cuda/GPUReconstructionCUDA.h | 50 +- .../Base/cuda/GPUReconstructionCUDAGenRTC.cxx | 12 +- .../Base/cuda/GPUReconstructionCUDAIncludes.h | 6 +- .../Base/cuda/GPUReconstructionCUDAKernels.cu | 30 +- .../opencl-common/GPUReconstructionOCL.cxx | 80 +-- .../Base/opencl-common/GPUReconstructionOCL.h | 44 +- .../GPUReconstructionOCLInternals.h | 24 +- .../Base/opencl/GPUReconstructionOCL1.cxx | 12 +- .../Base/opencl/GPUReconstructionOCL1.h | 10 +- .../Base/opencl2/GPUReconstructionOCL2.cxx | 12 +- .../Base/opencl2/GPUReconstructionOCL2.h | 10 +- .../AliHLTTPCClusterStatComponent.cxx | 150 ++--- .../AliHLTTPCClusterStatComponent.h | 42 +- .../DataCompression/GPUTPCClusterRejection.h | 4 +- .../GPUTPCClusterStatistics.cxx | 54 +- .../DataCompression/GPUTPCClusterStatistics.h | 82 +-- .../DataCompression/GPUTPCCompression.cxx | 6 +- .../DataCompression/GPUTPCCompression.h | 60 +- .../GPUTPCCompressionKernels.cxx | 352 +++++------ .../GPUTPCCompressionKernels.h | 54 +- .../GPUTPCCompressionKernels.inc | 4 +- .../GPUTPCCompressionTrackModel.cxx | 42 +- .../GPUTPCCompressionTrackModel.h | 18 +- .../DataCompression/GPUTPCDecompression.cxx | 4 +- .../DataCompression/GPUTPCDecompression.h | 18 +- .../GPUTPCDecompressionKernels.cxx | 68 +- .../GPUTPCDecompressionKernels.h | 22 +- .../TPCClusterDecompressor.cxx | 28 +- .../DataCompression/TPCClusterDecompressor.h | 10 +- .../TPCClusterDecompressor.inc | 36 +- ...andalone-cluster-dump-entropy-analysed.cxx | 184 +++--- .../DataTypes/CalibdEdxContainer.cxx | 46 +- .../DataTypes/CalibdEdxContainer.h | 22 +- .../DataTypes/CalibdEdxTrackTopologyPol.cxx | 44 +- .../DataTypes/CalibdEdxTrackTopologyPol.h | 34 +- .../CalibdEdxTrackTopologySpline.cxx | 54 +- .../DataTypes/CalibdEdxTrackTopologySpline.h | 52 +- GPU/GPUTracking/DataTypes/GPUConfigDump.cxx | 4 +- GPU/GPUTracking/DataTypes/GPUDataTypes.cxx | 2 +- GPU/GPUTracking/DataTypes/GPUDataTypes.h | 100 +-- .../DataTypes/GPUMemorySizeScalers.h | 4 +- GPU/GPUTracking/DataTypes/GPUNewCalibValues.h | 2 +- GPU/GPUTracking/DataTypes/GPUO2FakeClasses.h | 18 +- GPU/GPUTracking/DataTypes/GPUOutputControl.h | 2 +- GPU/GPUTracking/DataTypes/GPUSettings.h | 34 +- .../DataTypes/GPUTPCClusterOccupancyMap.cxx | 6 +- .../DataTypes/GPUTPCClusterOccupancyMap.h | 6 +- .../DataTypes/GPUTPCGMMergedTrackHit.h | 8 +- .../DataTypes/GPUTPCGMPolynomialField.cxx | 18 +- .../DataTypes/GPUTPCGMPolynomialField.h | 32 +- GPU/GPUTracking/DataTypes/GPUTPCGeometry.h | 82 +-- .../DataTypes/GPUTRDInterfaceO2Track.h | 12 +- GPU/GPUTracking/DataTypes/GPUTRDTrack.h | 48 +- GPU/GPUTracking/DataTypes/GPUTRDTrack.inc | 22 +- GPU/GPUTracking/DataTypes/GPUTriggerOutputs.h | 6 +- GPU/GPUTracking/DataTypes/TPCPadBitMap.cxx | 8 +- GPU/GPUTracking/DataTypes/TPCPadBitMap.h | 22 +- GPU/GPUTracking/DataTypes/TPCPadGainCalib.cxx | 8 +- GPU/GPUTracking/DataTypes/TPCPadGainCalib.h | 38 +- GPU/GPUTracking/Debug/GPUROOTDumpCore.cxx | 2 +- GPU/GPUTracking/Definitions/GPUDef.h | 10 +- .../Definitions/GPUDefGPUParameters.h | 8 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 382 ++++++------ .../Definitions/clusterFinderDefs.h | 18 +- .../GPUTrackingLinkDef_Standalone.h | 2 +- .../Global/AliHLTGPUDumpComponent.cxx | 100 +-- .../Global/AliHLTGPUDumpComponent.h | 16 +- GPU/GPUTracking/Global/GPUChain.cxx | 24 +- GPU/GPUTracking/Global/GPUChain.h | 120 ++-- GPU/GPUTracking/Global/GPUChainITS.cxx | 10 +- GPU/GPUTracking/Global/GPUChainITS.h | 14 +- GPU/GPUTracking/Global/GPUChainTracking.cxx | 94 +-- GPU/GPUTracking/Global/GPUChainTracking.h | 104 ++-- .../Global/GPUChainTrackingClusterizer.cxx | 282 ++++----- .../Global/GPUChainTrackingCompression.cxx | 74 +-- .../GPUChainTrackingDebugAndProfiling.cxx | 58 +- GPU/GPUTracking/Global/GPUChainTrackingIO.cxx | 52 +- .../Global/GPUChainTrackingMerger.cxx | 48 +- .../Global/GPUChainTrackingRefit.cxx | 2 +- .../Global/GPUChainTrackingSliceTracker.cxx | 92 +-- .../Global/GPUChainTrackingTRD.cxx | 26 +- .../Global/GPUChainTrackingTransformation.cxx | 30 +- GPU/GPUTracking/Global/GPUErrors.cxx | 16 +- GPU/GPUTracking/Global/GPUErrors.h | 12 +- .../Global/GPUTrackingInputProvider.h | 30 +- .../HLTHeaders/AliHLTTPCClusterMCData.h | 4 +- .../HLTHeaders/AliHLTTPCRawCluster.h | 36 +- GPU/GPUTracking/ITS/GPUITSFitter.cxx | 2 +- GPU/GPUTracking/ITS/GPUITSFitter.h | 30 +- GPU/GPUTracking/ITS/GPUITSFitterKernels.cxx | 34 +- GPU/GPUTracking/ITS/GPUITSFitterKernels.h | 6 +- GPU/GPUTracking/ITS/GPUITSTrack.h | 2 +- GPU/GPUTracking/Interface/GPUO2Interface.cxx | 38 +- GPU/GPUTracking/Interface/GPUO2Interface.h | 20 +- .../GPUO2InterfaceConfigurableParam.cxx | 2 +- .../Interface/GPUO2InterfaceConfiguration.h | 8 +- .../Interface/GPUO2InterfaceDisplay.cxx | 8 +- .../Interface/GPUO2InterfaceDisplay.h | 6 +- .../Interface/GPUO2InterfaceQA.cxx | 6 +- GPU/GPUTracking/Interface/GPUO2InterfaceQA.h | 6 +- .../Interface/GPUO2InterfaceRefit.cxx | 40 +- .../Interface/GPUO2InterfaceRefit.h | 18 +- .../Interface/GPUO2InterfaceUtils.cxx | 12 +- .../Interface/GPUO2InterfaceUtils.h | 14 +- GPU/GPUTracking/Merger/GPUTPCGMBorderTrack.h | 30 +- GPU/GPUTracking/Merger/GPUTPCGMMergedTrack.h | 28 +- GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx | 518 ++++++++-------- GPU/GPUTracking/Merger/GPUTPCGMMerger.h | 278 ++++----- GPU/GPUTracking/Merger/GPUTPCGMMergerDump.cxx | 118 ++-- GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx | 78 +-- GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.h | 80 +-- GPU/GPUTracking/Merger/GPUTPCGMMergerTypes.h | 8 +- GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx | 74 +-- GPU/GPUTracking/Merger/GPUTPCGMO2Output.h | 4 +- .../Merger/GPUTPCGMPhysicalTrackModel.cxx | 10 +- .../Merger/GPUTPCGMPhysicalTrackModel.h | 8 +- .../Merger/GPUTPCGMPolynomialFieldManager.cxx | 80 +-- .../Merger/GPUTPCGMPolynomialFieldManager.h | 12 +- GPU/GPUTracking/Merger/GPUTPCGMPropagator.cxx | 24 +- GPU/GPUTracking/Merger/GPUTPCGMPropagator.h | 26 +- GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx | 12 +- GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.h | 66 +- GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx | 202 +++--- GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h | 70 +-- .../Merger/GPUTPCGMTracksToTPCSeeds.cxx | 24 +- .../Merger/GPUTPCGlobalDebugSortKernels.cxx | 72 +-- .../Merger/GPUTPCGlobalDebugSortKernels.h | 4 +- .../Merger/GPUTPCGlobalMergerComponent.cxx | 64 +- .../Merger/GPUTPCGlobalMergerComponent.h | 22 +- .../Merger/macros/checkPropagation.C | 38 +- .../Merger/macros/fitPolynomialFieldIts.C | 2 +- .../Merger/macros/fitPolynomialFieldTpc.C | 2 +- .../Merger/macros/fitPolynomialFieldTrd.C | 2 +- GPU/GPUTracking/Refit/GPUTrackParamConvert.h | 8 +- GPU/GPUTracking/Refit/GPUTrackingRefit.cxx | 48 +- GPU/GPUTracking/Refit/GPUTrackingRefit.h | 27 +- .../Refit/GPUTrackingRefitKernel.cxx | 12 +- .../Refit/GPUTrackingRefitKernel.h | 6 +- .../SliceTracker/GPUTPCBaseTrackParam.h | 8 +- .../SliceTracker/GPUTPCClusterData.h | 6 +- .../SliceTracker/GPUTPCCreateOccupancyMap.cxx | 26 +- .../SliceTracker/GPUTPCCreateOccupancyMap.h | 4 +- .../SliceTracker/GPUTPCCreateSliceData.cxx | 2 +- .../SliceTracker/GPUTPCCreateSliceData.h | 4 +- GPU/GPUTracking/SliceTracker/GPUTPCDef.h | 8 +- .../SliceTracker/GPUTPCGlobalTracking.cxx | 48 +- .../SliceTracker/GPUTPCGlobalTracking.h | 16 +- GPU/GPUTracking/SliceTracker/GPUTPCGrid.cxx | 54 +- GPU/GPUTracking/SliceTracker/GPUTPCGrid.h | 22 +- GPU/GPUTracking/SliceTracker/GPUTPCHitId.h | 8 +- GPU/GPUTracking/SliceTracker/GPUTPCMCInfo.h | 12 +- .../SliceTracker/GPUTPCNeighboursCleaner.cxx | 8 +- .../SliceTracker/GPUTPCNeighboursCleaner.h | 12 +- .../SliceTracker/GPUTPCNeighboursFinder.cxx | 68 +- .../SliceTracker/GPUTPCNeighboursFinder.h | 12 +- GPU/GPUTracking/SliceTracker/GPUTPCRow.h | 12 +- .../GPUTPCSectorDebugSortKernels.cxx | 32 +- .../GPUTPCSectorDebugSortKernels.h | 4 +- .../SliceTracker/GPUTPCSliceData.cxx | 104 ++-- .../SliceTracker/GPUTPCSliceData.h | 60 +- .../SliceTracker/GPUTPCSliceOutCluster.h | 18 +- .../SliceTracker/GPUTPCSliceOutput.cxx | 4 +- .../SliceTracker/GPUTPCSliceOutput.h | 22 +- .../SliceTracker/GPUTPCStartHitsFinder.cxx | 14 +- .../SliceTracker/GPUTPCStartHitsFinder.h | 10 +- .../SliceTracker/GPUTPCStartHitsSorter.cxx | 22 +- .../SliceTracker/GPUTPCStartHitsSorter.h | 10 +- GPU/GPUTracking/SliceTracker/GPUTPCTrack.h | 24 +- .../SliceTracker/GPUTPCTrackParam.cxx | 10 +- .../SliceTracker/GPUTPCTrackParam.h | 20 +- .../SliceTracker/GPUTPCTracker.cxx | 46 +- GPU/GPUTracking/SliceTracker/GPUTPCTracker.h | 140 ++--- .../SliceTracker/GPUTPCTrackerComponent.cxx | 78 +-- .../SliceTracker/GPUTPCTrackerComponent.h | 38 +- .../SliceTracker/GPUTPCTrackerDump.cxx | 40 +- GPU/GPUTracking/SliceTracker/GPUTPCTracklet.h | 24 +- .../GPUTPCTrackletConstructor.cxx | 94 +-- .../SliceTracker/GPUTPCTrackletConstructor.h | 42 +- .../SliceTracker/GPUTPCTrackletSelector.cxx | 28 +- .../SliceTracker/GPUTPCTrackletSelector.h | 12 +- .../Standalone/Benchmark/standalone.cxx | 62 +- .../tools/GPUExtractPbPbCollision.h | 64 +- .../Standalone/tools/dumpTRDClusterMatrices.C | 10 +- GPU/GPUTracking/Standalone/tools/rtc/test.cu | 4 +- GPU/GPUTracking/TPCClusterFinder/CfFragment.h | 4 +- GPU/GPUTracking/TPCClusterFinder/CfUtils.h | 62 +- .../TPCClusterFinder/GPUTPCCFChainContext.h | 32 +- .../GPUTPCCFChargeMapFiller.cxx | 12 +- .../GPUTPCCFChargeMapFiller.h | 12 +- .../GPUTPCCFCheckPadBaseline.cxx | 50 +- .../GPUTPCCFCheckPadBaseline.h | 8 +- .../TPCClusterFinder/GPUTPCCFClusterizer.cxx | 4 +- .../TPCClusterFinder/GPUTPCCFClusterizer.h | 6 +- .../TPCClusterFinder/GPUTPCCFDecodeZS.cxx | 418 ++++++------- .../TPCClusterFinder/GPUTPCCFDecodeZS.h | 94 +-- .../GPUTPCCFDeconvolution.cxx | 16 +- .../TPCClusterFinder/GPUTPCCFDeconvolution.h | 12 +- .../TPCClusterFinder/GPUTPCCFGather.cxx | 6 +- .../TPCClusterFinder/GPUTPCCFGather.h | 4 +- .../GPUTPCCFMCLabelFlattener.cxx | 4 +- .../GPUTPCCFMCLabelFlattener.h | 6 +- .../GPUTPCCFNoiseSuppression.cxx | 24 +- .../GPUTPCCFNoiseSuppression.h | 16 +- .../TPCClusterFinder/GPUTPCCFPeakFinder.cxx | 8 +- .../TPCClusterFinder/GPUTPCCFPeakFinder.h | 8 +- .../GPUTPCCFStreamCompaction.cxx | 52 +- .../GPUTPCCFStreamCompaction.h | 10 +- .../TPCClusterFinder/GPUTPCClusterFinder.cxx | 26 +- .../TPCClusterFinder/GPUTPCClusterFinder.h | 68 +- .../GPUTPCClusterFinderDump.cxx | 22 +- .../TPCClusterFinder/MCLabelAccumulator.cxx | 2 +- .../TPCClusterFinder/PackedCharge.h | 2 +- GPU/GPUTracking/TPCConvert/GPUTPCConvert.h | 8 +- .../TPCConvert/GPUTPCConvertImpl.h | 4 +- .../TPCConvert/GPUTPCConvertKernel.cxx | 12 +- .../TPCConvert/GPUTPCConvertKernel.h | 4 +- GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h | 98 +-- .../TRDTracking/GPUTRDInterfaces.h | 22 +- GPU/GPUTracking/TRDTracking/GPUTRDTrackData.h | 16 +- .../TRDTracking/GPUTRDTrackPoint.h | 4 +- GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx | 167 +++-- GPU/GPUTracking/TRDTracking/GPUTRDTracker.h | 65 +- .../TRDTracking/GPUTRDTrackerComponent.cxx | 84 +-- .../TRDTracking/GPUTRDTrackerComponent.h | 14 +- .../TRDTracking/GPUTRDTrackerDebug.h | 52 +- .../TRDTracking/GPUTRDTrackerKernels.cxx | 10 +- .../TRDTracking/GPUTRDTrackerKernels.h | 4 +- .../TRDTracking/GPUTRDTrackletLabels.h | 2 +- .../GPUTRDTrackletReaderComponent.cxx | 44 +- .../GPUTRDTrackletReaderComponent.h | 16 +- .../TRDTracking/GPUTRDTrackletWord.cxx | 8 +- .../TRDTracking/GPUTRDTrackletWord.h | 38 +- .../TRDTracking/macros/checkDbgOutput.C | 8 +- .../TRDTracking/macros/run_trd_tracker.C | 16 +- GPU/GPUTracking/dEdx/GPUdEdx.cxx | 16 +- GPU/GPUTracking/dEdx/GPUdEdx.h | 42 +- GPU/GPUTracking/display/GPUDisplay.cxx | 44 +- GPU/GPUTracking/display/GPUDisplay.h | 148 ++--- GPU/GPUTracking/display/GPUDisplayInterface.h | 16 +- .../display/backend/GPUDisplayBackend.cxx | 16 +- .../display/backend/GPUDisplayBackend.h | 48 +- .../backend/GPUDisplayBackendOpenGL.cxx | 90 +-- .../display/backend/GPUDisplayBackendOpenGL.h | 100 +-- .../backend/GPUDisplayBackendVulkan.cxx | 134 ++-- .../display/backend/GPUDisplayBackendVulkan.h | 38 +- .../display/filterMacros/TRDCandidate.C | 2 +- .../display/filterMacros/filterGPUTrack.C | 2 +- .../display/filterMacros/filterTPCTrack.C | 2 +- GPU/GPUTracking/display/filterMacros/hasTRD.C | 2 +- .../display/frontend/GPUDisplayFrontend.cxx | 16 +- .../display/frontend/GPUDisplayFrontend.h | 114 ++-- .../frontend/GPUDisplayFrontendGlfw.cxx | 58 +- .../display/frontend/GPUDisplayFrontendGlfw.h | 36 +- .../frontend/GPUDisplayFrontendGlut.cxx | 40 +- .../display/frontend/GPUDisplayFrontendGlut.h | 28 +- .../display/frontend/GPUDisplayFrontendNone.h | 2 +- .../frontend/GPUDisplayFrontendWayland.cxx | 30 +- .../frontend/GPUDisplayFrontendWayland.h | 22 +- .../frontend/GPUDisplayFrontendWindows.cxx | 20 +- .../frontend/GPUDisplayFrontendWindows.h | 4 +- .../frontend/GPUDisplayFrontendX11.cxx | 58 +- .../display/frontend/GPUDisplayFrontendX11.h | 14 +- .../display/frontend/GPUDisplayGUIWrapper.cxx | 8 +- .../display/frontend/GPUDisplayGUIWrapper.h | 6 +- .../display/frontend/GPUDisplayKeys.cxx | 48 +- .../display/helpers/GPUDisplayAnimation.cxx | 26 +- .../GPUDisplayBackendOpenGLMagneticField.cxx | 26 +- .../display/helpers/GPUDisplayColors.inc | 8 +- .../display/helpers/GPUDisplayHelpers.cxx | 2 +- .../helpers/GPUDisplayInterpolation.cxx | 20 +- .../helpers/GPUDisplayMagneticField.cxx | 20 +- .../display/helpers/GPUDisplayMagneticField.h | 32 +- .../display/helpers/GPUDisplayROOT.cxx | 4 +- GPU/GPUTracking/display/helpers/bitmapfile.h | 30 +- .../helpers/field-uniform-exporter.cxx | 18 +- .../display/render/GPUDisplayDraw.cxx | 236 +++---- .../display/render/GPUDisplayImportEvent.cxx | 48 +- .../display/shaders/GPUDisplayShaders.h | 152 ++--- GPU/GPUTracking/kernels.cmake | 66 +- .../oldFiles/AliHLT3DTrackParam.cxx | 54 +- GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.h | 26 +- .../oldFiles/GPUTPCGMOfflineFitter.cxx | 28 +- .../oldFiles/GPUTPCGMOfflineFitter.h | 6 +- GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h | 14 +- GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx | 8 +- GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h | 46 +- GPU/GPUTracking/qa/GPUQA.cxx | 558 ++++++++--------- GPU/GPUTracking/qa/GPUQA.h | 152 ++--- GPU/GPUTracking/qa/GPUQAHelper.h | 20 +- GPU/GPUTracking/qa/genEvents.cxx | 66 +- GPU/GPUTracking/qa/genEvents.h | 20 +- GPU/GPUTracking/utils/linux_helpers.h | 10 +- .../utils/makefile_opencl_compiler.cxx | 26 +- GPU/GPUTracking/utils/opencl_obtain_program.h | 10 +- .../utils/pthread_mutex_win32_wrapper.h | 32 +- GPU/GPUTracking/utils/qconfig.cxx | 125 ++-- GPU/GPUTracking/utils/qconfig.h | 102 +-- GPU/GPUTracking/utils/qconfig_helpers.h | 4 +- GPU/GPUTracking/utils/qsem.cxx | 18 +- GPU/GPUTracking/utils/qsem.h | 12 +- GPU/GPUTracking/utils/strtag.h | 7 +- GPU/GPUTracking/utils/threadserver.h | 26 +- GPU/GPUTracking/utils/timer.h | 6 +- GPU/GPUbenchmark/Shared/Kernels.h | 18 +- GPU/GPUbenchmark/Shared/Utils.h | 44 +- GPU/GPUbenchmark/cuda/Kernels.cu | 70 +-- GPU/GPUbenchmark/cuda/benchmark.cu | 52 +- GPU/GPUbenchmark/macro/showBenchmarks.C | 16 +- .../BandMatrixSolver.cxx | 70 +-- GPU/TPCFastTransformation/BandMatrixSolver.h | 74 +-- GPU/TPCFastTransformation/ChebyshevFit1D.cxx | 26 +- GPU/TPCFastTransformation/ChebyshevFit1D.h | 18 +- .../CorrectionMapsHelper.h | 24 +- .../MultivariatePolynomial.h | 34 +- .../MultivariatePolynomialHelper.cxx | 30 +- .../MultivariatePolynomialHelper.h | 108 ++-- .../NDPiecewisePolynomials.h | 202 +++--- GPU/TPCFastTransformation/Spline.h | 12 +- GPU/TPCFastTransformation/Spline1D.h | 6 +- GPU/TPCFastTransformation/Spline1DHelper.cxx | 148 ++--- GPU/TPCFastTransformation/Spline1DHelper.h | 14 +- .../Spline1DHelperOld.cxx | 214 +++---- GPU/TPCFastTransformation/Spline1DHelperOld.h | 28 +- GPU/TPCFastTransformation/Spline1DSpec.cxx | 54 +- GPU/TPCFastTransformation/Spline1DSpec.h | 80 +-- GPU/TPCFastTransformation/Spline2D.h | 10 +- GPU/TPCFastTransformation/Spline2DHelper.cxx | 214 +++---- GPU/TPCFastTransformation/Spline2DHelper.h | 34 +- GPU/TPCFastTransformation/Spline2DSpec.cxx | 32 +- GPU/TPCFastTransformation/Spline2DSpec.h | 96 +-- GPU/TPCFastTransformation/SplineHelper.cxx | 284 ++++----- GPU/TPCFastTransformation/SplineHelper.h | 42 +- GPU/TPCFastTransformation/SplineSpec.cxx | 30 +- GPU/TPCFastTransformation/SplineSpec.h | 126 ++-- GPU/TPCFastTransformation/SplineUtil.h | 36 +- GPU/TPCFastTransformation/SymMatrixSolver.cxx | 66 +- GPU/TPCFastTransformation/SymMatrixSolver.h | 14 +- .../TPCFastSpaceChargeCorrection.cxx | 86 +-- .../TPCFastSpaceChargeCorrection.h | 92 +-- .../TPCFastSpaceChargeCorrectionMap.h | 24 +- .../TPCFastTransform.cxx | 6 +- GPU/TPCFastTransformation/TPCFastTransform.h | 126 ++-- .../TPCFastTransformGeo.cxx | 22 +- .../TPCFastTransformGeo.h | 80 +-- .../TPCFastTransformManager.cxx | 40 +- .../TPCFastTransformManager.h | 10 +- .../TPCFastTransformQA.cxx | 24 +- .../TPCFastTransformQA.h | 8 +- .../alirootMacro/createTPCFastTransform.C | 6 +- .../generateTPCDistortionNTupleAliRoot.C | 24 +- .../alirootMacro/initTPCcalibration.C | 6 +- .../alirootMacro/moveTPCFastTransform.C | 2 +- .../devtools/ChebFitTest.C | 16 +- .../devtools/IrregularSpline1D.cxx | 42 +- .../devtools/IrregularSpline1D.h | 34 +- .../devtools/IrregularSpline1DTest.C | 40 +- .../devtools/IrregularSpline2D3D.cxx | 4 +- .../devtools/IrregularSpline2D3D.h | 68 +- .../IrregularSpline2D3DCalibrator.cxx | 68 +- .../devtools/IrregularSpline2D3DCalibrator.h | 20 +- .../IrregularSpline2D3DCalibratorTest.C | 44 +- .../devtools/IrregularSpline2D3DTest.C | 46 +- .../devtools/RegularSpline1D.h | 26 +- .../devtools/RegularSpline1DTest.C | 40 +- .../devtools/SemiregularSpline2D3D.cxx | 48 +- .../devtools/SemiregularSpline2D3D.h | 98 +-- .../devtools/SemiregularSpline2D3DTest.C | 46 +- GPU/TPCFastTransformation/macro/SplineDemo.C | 30 +- .../macro/SplineRecoveryDemo.C | 36 +- .../macro/TPCFastTransformInit.C | 34 +- .../macro/fastTransformQA.C | 8 +- .../macro/generateTPCCorrectionNTuple.C | 8 +- .../test/testMultivarPolynomials.cxx | 38 +- .../test/testSplines.cxx | 4 +- GPU/Utils/FlatObject.h | 36 +- GPU/Utils/GPUCommonBitSet.h | 26 +- GPU/Workflow/helper/src/GPUWorkflowHelper.cxx | 6 +- .../include/GPUWorkflow/GPUWorkflowSpec.h | 42 +- GPU/Workflow/src/GPUWorkflowITS.cxx | 2 +- GPU/Workflow/src/GPUWorkflowInternal.h | 12 +- GPU/Workflow/src/GPUWorkflowPipeline.cxx | 38 +- GPU/Workflow/src/GPUWorkflowSpec.cxx | 76 +-- GPU/Workflow/src/GPUWorkflowTPC.cxx | 6 +- GPU/Workflow/src/gpu-reco-workflow.cxx | 6 +- 419 files changed, 9278 insertions(+), 9266 deletions(-) diff --git a/DataFormats/Detectors/TRD/include/DataFormatsTRD/RecoInputContainer.h b/DataFormats/Detectors/TRD/include/DataFormatsTRD/RecoInputContainer.h index 21a079ec0df77..353f635306e68 100644 --- a/DataFormats/Detectors/TRD/include/DataFormatsTRD/RecoInputContainer.h +++ b/DataFormats/Detectors/TRD/include/DataFormatsTRD/RecoInputContainer.h @@ -88,7 +88,7 @@ inline void RecoInputContainer::fillGPUIOPtr(o2::gpu::GPUTrackingInOutPointers* ptrs->nTRDTriggerRecords = mNTriggerRecords; ptrs->trdTriggerTimes = &(trdTriggerTimes[0]); ptrs->trdTrackletIdxFirst = &(trdTriggerIndices[0]); - ptrs->trdTrigRecMask = reinterpret_cast(mTrigRecMask.data()); + ptrs->trdTrigRecMask = reinterpret_cast(mTrigRecMask.data()); ptrs->nTRDTracklets = mNTracklets; ptrs->trdTracklets = reinterpret_cast(mTracklets.data()); ptrs->trdSpacePoints = reinterpret_cast(mSpacePoints.data()); diff --git a/Detectors/TPC/workflow/src/ZSSpec.cxx b/Detectors/TPC/workflow/src/ZSSpec.cxx index 9ae422ae099d9..7cabef062c307 100644 --- a/Detectors/TPC/workflow/src/ZSSpec.cxx +++ b/Detectors/TPC/workflow/src/ZSSpec.cxx @@ -66,7 +66,7 @@ DataProcessorSpec getZSEncoderSpec(std::vector const& tpcSectors, bool outR using DigitArray = std::array, NSectors>; struct ProcessAttributes { - std::unique_ptr zsoutput; + std::unique_ptr zsoutput; std::unique_ptr itcorr; std::vector sizes; std::vector tpcSectors; @@ -216,7 +216,7 @@ DataProcessorSpec getZStoDigitsSpec(std::vector const& tpcSectors) struct ProcessAttributes { std::array, NSectors> outDigits; - std::unique_ptr zsinput; + std::unique_ptr zsinput; std::vector sizes; std::unique_ptr decoder; std::vector tpcSectors; diff --git a/GPU/Common/GPUCommonAlgorithm.h b/GPU/Common/GPUCommonAlgorithm.h index 9169886a047e8..f86bd42fe82f6 100644 --- a/GPU/Common/GPUCommonAlgorithm.h +++ b/GPU/Common/GPUCommonAlgorithm.h @@ -157,7 +157,7 @@ GPUdi() void GPUCommonAlgorithm::QuickSort(I f, I l, Cmp cmp) noexcept if (f == l) { return; } - using IndexType = unsigned short; + using IndexType = uint16_t; struct pair { IndexType first; @@ -166,7 +166,7 @@ GPUdi() void GPUCommonAlgorithm::QuickSort(I f, I l, Cmp cmp) noexcept struct Stack { pair data[11]; - unsigned char n{0}; + uint8_t n{0}; GPUd() void emplace(IndexType x, IndexType y) { @@ -295,12 +295,12 @@ GPUdi() void GPUCommonAlgorithm::sortInBlock(T* begin, T* end, const S& comp) #ifndef GPUCA_GPUCODE GPUCommonAlgorithm::sort(begin, end, comp); #else - int n = end - begin; - for (int i = 0; i < n; i++) { - for (int tIdx = get_local_id(0); tIdx < n; tIdx += get_local_size(0)) { - int offset = i % 2; - int curPos = 2 * tIdx + offset; - int nextPos = curPos + 1; + int32_t n = end - begin; + for (int32_t i = 0; i < n; i++) { + for (int32_t tIdx = get_local_id(0); tIdx < n; tIdx += get_local_size(0)) { + int32_t offset = i % 2; + int32_t curPos = 2 * tIdx + offset; + int32_t nextPos = curPos + 1; if (nextPos < n) { if (!comp(begin[curPos], begin[nextPos])) { @@ -363,9 +363,9 @@ GPUdi() T work_group_scan_inclusive_add_FUNC(T v, S& smem) #define work_group_broadcast(v, i) work_group_broadcast_FUNC(v, i, smem) template -GPUdi() T work_group_broadcast_FUNC(T v, int i, S& smem) +GPUdi() T work_group_broadcast_FUNC(T v, int32_t i, S& smem) { - if ((int)threadIdx.x == i) { + if ((int32_t)threadIdx.x == i) { smem.tmpBroadcast = v; } __syncthreads(); @@ -394,7 +394,7 @@ GPUdi() T warp_scan_inclusive_add_FUNC(T v, S& smem) #define warp_broadcast(v, i) warp_broadcast_FUNC(v, i) template -GPUdi() T warp_broadcast_FUNC(T v, int i) +GPUdi() T warp_broadcast_FUNC(T v, int32_t i) { #ifdef __CUDACC__ return __shfl_sync(0xFFFFFFFF, v, i); @@ -419,7 +419,7 @@ GPUdi() T work_group_reduce_add(T v) } template -GPUdi() T work_group_broadcast(T v, int i) +GPUdi() T work_group_broadcast(T v, int32_t i) { return v; } @@ -431,7 +431,7 @@ GPUdi() T warp_scan_inclusive_add(T v) } template -GPUdi() T warp_broadcast(T v, int i) +GPUdi() T warp_broadcast(T v, int32_t i) { return v; } diff --git a/GPU/Common/GPUCommonDefAPI.h b/GPU/Common/GPUCommonDefAPI.h index 5a152de8a2216..124a29ecc7a37 100644 --- a/GPU/Common/GPUCommonDefAPI.h +++ b/GPU/Common/GPUCommonDefAPI.h @@ -20,6 +20,10 @@ #error Please include GPUCommonDef.h! #endif +#ifndef GPUCA_GPUCODE_DEVICE +#include +#endif + //Define macros for GPU keywords. i-version defines inline functions. //All host-functions in GPU code are automatically inlined, to avoid duplicate symbols. //For non-inline host only functions, use no keyword at all! @@ -54,21 +58,21 @@ #define GPUconstantref() // reference / ptr to constant memory #define GPUconstexprref() // reference / ptr to variable declared as GPUconstexpr() - #ifndef __VECTOR_TYPES_H__ // ROOT will pull in these CUDA definitions if built against CUDA, so we have to add an ugly protection here + #ifndef __VECTOR_TYPES_H__ // FIXME: ROOT will pull in these CUDA definitions if built against CUDA, so we have to add an ugly protection here struct float4 { float x, y, z, w; }; struct float3 { float x, y, z; }; struct float2 { float x; float y; }; - struct uchar2 { unsigned char x, y; }; - struct short2 { short x, y; }; - struct ushort2 { unsigned short x, y; }; - struct int2 { int x, y; }; - struct int3 { int x, y, z; }; - struct int4 { int x, y, z, w; }; - struct uint1 { unsigned int x; }; - struct uint2 { unsigned int x, y; }; - struct uint3 { unsigned int x, y, z; }; - struct uint4 { unsigned int x, y, z, w; }; - struct dim3 { unsigned int x, y, z; }; + struct uchar2 { uint8_t x, y; }; + struct short2 { int16_t x, y; }; + struct ushort2 { uint16_t x, y; }; + struct int2 { int32_t x, y; }; + struct int3 { int32_t x, y, z; }; + struct int4 { int32_t x, y, z, w; }; + struct uint1 { uint32_t x; }; + struct uint2 { uint32_t x, y; }; + struct uint3 { uint32_t x, y, z; }; + struct uint4 { uint32_t x, y, z, w; }; + struct dim3 { uint32_t x, y, z; }; #endif #elif defined(__OPENCL__) // Defines for OpenCL #define GPUd() @@ -95,15 +99,15 @@ #define GPUbarrier() work_group_barrier(mem_fence::global | mem_fence::local); #define GPUbarrierWarp() #define GPUAtomic(type) atomic - static_assert(sizeof(atomic) == sizeof(unsigned int), "Invalid size of atomic type"); + static_assert(sizeof(atomic) == sizeof(uint32_t), "Invalid size of atomic type"); #else #define GPUbarrier() barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE) #define GPUbarrierWarp() #if defined(__OPENCLCPP__) && defined(GPUCA_OPENCL_CPP_CLANG_C11_ATOMICS) namespace GPUCA_NAMESPACE { namespace gpu { template struct oclAtomic; - template <> struct oclAtomic {typedef atomic_uint t;}; - static_assert(sizeof(oclAtomic::t) == sizeof(unsigned int), "Invalid size of atomic type"); + template <> struct oclAtomic {typedef atomic_uint t;}; + static_assert(sizeof(oclAtomic::t) == sizeof(uint32_t), "Invalid size of atomic type"); }} #define GPUAtomic(type) GPUCA_NAMESPACE::gpu::oclAtomic::t #else diff --git a/GPU/Common/GPUCommonMath.h b/GPU/Common/GPUCommonMath.h index b926188e5f39a..8b129ff29a987 100644 --- a/GPU/Common/GPUCommonMath.h +++ b/GPU/Common/GPUCommonMath.h @@ -27,6 +27,10 @@ #include #endif +#if !defined(GPUCA_GPUCODE_COMPILEKERNELS) && (!defined(GPUCA_GPUCODE_DEVICE) || defined(__CUDACC__) || defined(__HIPCC__)) +#include +#endif + #if !defined(__OPENCL__) || defined(__OPENCLCPP__) namespace GPUCA_NAMESPACE { @@ -75,13 +79,13 @@ class GPUCommonMath GPUd() static CONSTEXPR float Pi() { return 3.1415927f; } GPUd() static float Round(float x); GPUd() static float Floor(float x); - GPUd() static unsigned int Float2UIntReint(const float& x); - GPUd() static unsigned int Float2UIntRn(float x); - GPUd() static int Float2IntRn(float x); + GPUd() static uint32_t Float2UIntReint(const float& x); + GPUd() static uint32_t Float2UIntRn(float x); + GPUd() static int32_t Float2IntRn(float x); GPUd() static float Modf(float x, float y); GPUd() static bool Finite(float x); - GPUd() static unsigned int Clz(unsigned int val); - GPUd() static unsigned int Popcount(unsigned int val); + GPUd() static uint32_t Clz(uint32_t val); + GPUd() static uint32_t Popcount(uint32_t val); GPUhdni() static float Hypot(float x, float y); GPUhdni() static float Hypot(float x, float y, float z); @@ -137,10 +141,10 @@ class GPUCommonMath { GPUCommonMath::AtomicMinInternal(addr, val); } - GPUd() static int Mul24(int a, int b); + GPUd() static int32_t Mul24(int32_t a, int32_t b); GPUd() static float FMulRZ(float a, float b); - template + template GPUd() CONSTEXPR static T nextMultipleOf(T val); #ifdef GPUCA_NOCOMPAT @@ -163,11 +167,11 @@ class GPUCommonMath private: template - GPUd() static unsigned int AtomicExchInternal(S* addr, T val); + GPUd() static uint32_t AtomicExchInternal(S* addr, T val); template GPUd() static bool AtomicCASInternal(S* addr, T cmp, T val); template - GPUd() static unsigned int AtomicAddInternal(S* addr, T val); + GPUd() static uint32_t AtomicAddInternal(S* addr, T val); template GPUd() static void AtomicMaxInternal(S* addr, T val); template @@ -185,7 +189,7 @@ typedef GPUCommonMath CAMath; #define CHOICE(c1, c2, c3) (c1) // Select first option for Host #endif // clang-format on -template +template GPUdi() CONSTEXPR T GPUCommonMath::nextMultipleOf(T val) { if CONSTEXPR (I & (I - 1)) { @@ -212,23 +216,23 @@ GPUdi() float2 GPUCommonMath::MakeFloat2(float x, float y) GPUdi() float GPUCommonMath::Modf(float x, float y) { return CHOICE(fmodf(x, y), fmodf(x, y), fmod(x, y)); } -GPUdi() unsigned int GPUCommonMath::Float2UIntReint(const float& x) +GPUdi() uint32_t GPUCommonMath::Float2UIntReint(const float& x) { #if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__)) return __float_as_uint(x); #elif defined(GPUCA_GPUCODE_DEVICE) && (defined(__OPENCL__) || defined(__OPENCLCPP__)) return as_uint(x); #else - return reinterpret_cast(x); + return reinterpret_cast(x); #endif } -GPUdi() unsigned int GPUCommonMath::Float2UIntRn(float x) { return (unsigned int)(int)(x + 0.5f); } +GPUdi() uint32_t GPUCommonMath::Float2UIntRn(float x) { return (uint32_t)(int32_t)(x + 0.5f); } GPUdi() float GPUCommonMath::Floor(float x) { return CHOICE(floorf(x), floorf(x), floor(x)); } #ifdef GPUCA_NO_FAST_MATH GPUdi() float GPUCommonMath::Round(float x) { return CHOICE(roundf(x), roundf(x), round(x)); } -GPUdi() int GPUCommonMath::Float2IntRn(float x) { return (int)Round(x); } +GPUdi() int32_t GPUCommonMath::Float2IntRn(float x) { return (int32_t)Round(x); } GPUdi() bool GPUCommonMath::Finite(float x) { return CHOICE(std::isfinite(x), isfinite(x), true); } GPUhdi() float GPUCommonMath::Sqrt(float x) { return CHOICE(sqrtf(x), (float)sqrt((double)x), sqrt(x)); } GPUdi() float GPUCommonMath::ATan(float x) { return CHOICE((float)atan((double)x), (float)atan((double)x), atan(x)); } @@ -243,7 +247,7 @@ GPUdi() float GPUCommonMath::Log(float x) { return CHOICE((float)log((double)x), GPUdi() float GPUCommonMath::Exp(float x) { return CHOICE((float)exp((double)x), (float)exp((double)x), exp(x)); } #else GPUdi() float GPUCommonMath::Round(float x) { return CHOICE(roundf(x), rintf(x), rint(x)); } -GPUdi() int GPUCommonMath::Float2IntRn(float x) { return CHOICE((int)Round(x), __float2int_rn(x), (int)Round(x)); } +GPUdi() int32_t GPUCommonMath::Float2IntRn(float x) { return CHOICE((int32_t)Round(x), __float2int_rn(x), (int32_t)Round(x)); } GPUdi() bool GPUCommonMath::Finite(float x) { return CHOICE(std::isfinite(x), true, true); } GPUhdi() float GPUCommonMath::Sqrt(float x) { return CHOICE(sqrtf(x), sqrtf(x), sqrt(x)); } GPUdi() float GPUCommonMath::ATan(float x) { return CHOICE(atanf(x), atanf(x), atan(x)); } @@ -283,12 +287,12 @@ GPUhdi() void GPUCommonMath::SinCosd(double x, double& s, double& c) #endif } -GPUdi() unsigned int GPUCommonMath::Clz(unsigned int x) +GPUdi() uint32_t GPUCommonMath::Clz(uint32_t x) { #if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && (!defined(__OPENCL__) || defined(__OPENCLCPP__)) return x == 0 ? 32 : CHOICE(__builtin_clz(x), __clz(x), __builtin_clz(x)); // use builtin if available #else - for (int i = 31; i >= 0; i--) { + for (int32_t i = 31; i >= 0; i--) { if (x & (1u << i)) { return (31 - i); } @@ -297,7 +301,7 @@ GPUdi() unsigned int GPUCommonMath::Clz(unsigned int x) #endif } -GPUdi() unsigned int GPUCommonMath::Popcount(unsigned int x) +GPUdi() uint32_t GPUCommonMath::Popcount(uint32_t x) { #if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && (!defined(__OPENCL__) /*|| defined(__OPENCLCPP__)*/) // TODO: remove OPENCLCPP workaround when reported SPIR-V bug is fixed // use builtin if available @@ -404,7 +408,7 @@ GPUdi() float GPUCommonMath::InvSqrt(float _x) #else union { float f; - int i; + int32_t i; } x = {_x}; const float xhalf = 0.5f * x.f; x.i = 0x5f3759df - (x.i >> 1); @@ -428,7 +432,7 @@ GPUhdi() double GPUCommonMath::Abs(double x) #endif template <> -GPUhdi() int GPUCommonMath::Abs(int x) +GPUhdi() int32_t GPUCommonMath::Abs(int32_t x) { return CHOICE(abs(x), abs(x), abs(x)); } @@ -448,7 +452,7 @@ GPUhdi() float GPUCommonMath::Copysign(float x, float y) } template -GPUdi() unsigned int GPUCommonMath::AtomicExchInternal(S* addr, T val) +GPUdi() uint32_t GPUCommonMath::AtomicExchInternal(S* addr, T val) { #if defined(GPUCA_GPUCODE) && defined(__OPENCLCPP__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CPP_CLANG_C11_ATOMICS)) return ::atomic_exchange(addr, val); @@ -457,7 +461,7 @@ GPUdi() unsigned int GPUCommonMath::AtomicExchInternal(S* addr, T val) #elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__)) return ::atomicExch(addr, val); #elif defined(WITH_OPENMP) - unsigned int old; + uint32_t old; __atomic_exchange(addr, &val, &old, __ATOMIC_SEQ_CST); return old; #else @@ -482,7 +486,7 @@ GPUdi() bool GPUCommonMath::AtomicCASInternal(S* addr, T cmp, T val) } template -GPUdi() unsigned int GPUCommonMath::AtomicAddInternal(S* addr, T val) +GPUdi() uint32_t GPUCommonMath::AtomicAddInternal(S* addr, T val) { #if defined(GPUCA_GPUCODE) && defined(__OPENCLCPP__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CPP_CLANG_C11_ATOMICS)) return ::atomic_fetch_add(addr, val); @@ -538,9 +542,9 @@ GPUdii() void GPUCommonMath::AtomicMaxInternal(GPUglobalref() GPUgeneric() GPUAt val = 0.f; } if (val >= 0) { - AtomicMaxInternal((GPUAtomic(int)*)addr, __float_as_int(val)); + AtomicMaxInternal((GPUAtomic(int32_t)*)addr, __float_as_int(val)); } else { - AtomicMinInternal((GPUAtomic(unsigned int)*)addr, __float_as_uint(val)); + AtomicMinInternal((GPUAtomic(uint32_t)*)addr, __float_as_uint(val)); } } template <> @@ -550,9 +554,9 @@ GPUdii() void GPUCommonMath::AtomicMinInternal(GPUglobalref() GPUgeneric() GPUAt val = 0.f; } if (val >= 0) { - AtomicMinInternal((GPUAtomic(int)*)addr, __float_as_int(val)); + AtomicMinInternal((GPUAtomic(int32_t)*)addr, __float_as_int(val)); } else { - AtomicMaxInternal((GPUAtomic(unsigned int)*)addr, __float_as_uint(val)); + AtomicMaxInternal((GPUAtomic(uint32_t)*)addr, __float_as_uint(val)); } } #endif diff --git a/GPU/Common/GPUCommonRtypes.h b/GPU/Common/GPUCommonRtypes.h index 31b655986673a..5ae2ddbb83b26 100644 --- a/GPU/Common/GPUCommonRtypes.h +++ b/GPU/Common/GPUCommonRtypes.h @@ -26,8 +26,8 @@ #define ClassImp(name) #define templateClassImp(name) #ifndef GPUCA_GPUCODE_DEVICE -// typedef unsigned long long ULong64_t; -// typedef unsigned int UInt_t; +// typedef uint64_t ULong64_t; +// typedef uint32_t UInt_t; #include #endif #endif diff --git a/GPU/Common/GPUCommonTransform3D.h b/GPU/Common/GPUCommonTransform3D.h index 0d64e89041dfb..5cd09254d30d2 100644 --- a/GPU/Common/GPUCommonTransform3D.h +++ b/GPU/Common/GPUCommonTransform3D.h @@ -27,7 +27,7 @@ class Transform3D Transform3D() = default; Transform3D(float* v) { - for (int i = 0; i < 12; i++) { + for (int32_t i = 0; i < 12; i++) { m[i] = v[i]; } } diff --git a/GPU/Common/GPUROOTCartesianFwd.h b/GPU/Common/GPUROOTCartesianFwd.h index 7810bc6a33abe..89b0aa44eb78c 100644 --- a/GPU/Common/GPUROOTCartesianFwd.h +++ b/GPU/Common/GPUROOTCartesianFwd.h @@ -24,11 +24,11 @@ namespace ROOT { namespace Math { -template +template class SMatrix; -template +template class MatRepSym; -template +template class MatRepStd; template class PositionVector2D; @@ -53,9 +53,9 @@ namespace math_utils namespace detail { -template +template struct GPUPoint2D; -template +template struct GPUPoint3D; } // namespace detail diff --git a/GPU/Common/GPUROOTSMatrixFwd.h b/GPU/Common/GPUROOTSMatrixFwd.h index 2c19f034dc216..a3b5abc55d3bc 100644 --- a/GPU/Common/GPUROOTSMatrixFwd.h +++ b/GPU/Common/GPUROOTSMatrixFwd.h @@ -24,13 +24,13 @@ namespace ROOT { namespace Math { -template +template class SVector; -template +template class SMatrix; -template +template class MatRepSym; -template +template class MatRepStd; } // namespace Math } // namespace ROOT @@ -42,33 +42,33 @@ namespace math_utils namespace detail { -template +template class SVectorGPU; -template +template class SMatrixGPU; -template +template class MatRepSymGPU; -template +template class MatRepStdGPU; } // namespace detail #if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE) -template +template using SVector = ROOT::Math::SVector; -template +template using SMatrix = ROOT::Math::SMatrix; -template +template using MatRepSym = ROOT::Math::MatRepSym; -template +template using MatRepStd = ROOT::Math::MatRepStd; #else -template +template using SVector = detail::SVectorGPU; -template > +template > using SMatrix = detail::SMatrixGPU; -template +template using MatRepSym = detail::MatRepSymGPU; -template +template using MatRepStd = detail::MatRepStdGPU; #endif diff --git a/GPU/Common/test/testSMatrixImp.cu b/GPU/Common/test/testSMatrixImp.cu index 7ed1a23c68a5d..81f84e365b4f5 100644 --- a/GPU/Common/test/testSMatrixImp.cu +++ b/GPU/Common/test/testSMatrixImp.cu @@ -53,10 +53,10 @@ enum PrintMode { __device__ void floatToBinaryString(float number, char* buffer) { - unsigned char* bytePointer = reinterpret_cast(&number); - for (int byteIndex = 3; byteIndex >= 0; --byteIndex) { - unsigned char byte = bytePointer[byteIndex]; - for (int bitIndex = 7; bitIndex >= 0; --bitIndex) { + uint8_t* bytePointer = reinterpret_cast(&number); + for (int32_t byteIndex = 3; byteIndex >= 0; --byteIndex) { + uint8_t byte = bytePointer[byteIndex]; + for (int32_t bitIndex = 7; bitIndex >= 0; --bitIndex) { buffer[(3 - byteIndex) * 8 + (7 - bitIndex)] = (byte & (1 << bitIndex)) ? '1' : '0'; } } @@ -68,23 +68,23 @@ GPUd() void printMatrix(const MatrixType& matrix, const char* name, const PrintM { if (mode == PrintMode::Binary) { char buffer[33]; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = 0; j < 3; ++j) { floatToBinaryString(matrix(i, j), buffer); printf("%s(%d,%d) = %s\n", name, i, j, buffer); } } } if (mode == PrintMode::Decimal) { - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = 0; j < 3; ++j) { printf("%s(%i,%i) = %f\n", name, i, j, matrix(i, j)); } } } if (mode == PrintMode::Hexadecimal) { - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = 0; j < 3; ++j) { printf("%s(%d,%d) = %x\n", name, i, j, o2::gpu::CAMath::Float2UIntReint(matrix(i, j))); } } @@ -110,7 +110,7 @@ GPUg() void copyMatrixKernelSingle( // Invert test for an array of square matrices template GPUg() void invertMatrixKernelArray(T* matrices, - const int numMatrices) + const int32_t numMatrices) { for (auto iMatrix = blockIdx.x * blockDim.x + threadIdx.x; iMatrix < numMatrices; iMatrix += blockDim.x * gridDim.x) { matrices[iMatrix].Invert(); @@ -122,7 +122,7 @@ template GPUg() void copyMatrixKernelArray( T* srcMatrices, T* dstMatrices, - const int numMatrices) + const int32_t numMatrices) { for (auto iMatrix = blockIdx.x * blockDim.x + threadIdx.x; iMatrix < numMatrices; iMatrix += blockDim.x * gridDim.x) { srcMatrices[iMatrix] = dstMatrices[iMatrix]; @@ -136,8 +136,8 @@ void compareMatricesElementWise(const MatrixType& mat1, const MatrixType& mat2, { auto tol = boost::test_tools::tolerance(tolerance); - for (unsigned int i = 0; i < mat1.kRows; ++i) { - for (unsigned int j = 0; j < mat1.kCols; ++j) { + for (uint32_t i = 0; i < mat1.kRows; ++i) { + for (uint32_t j = 0; j < mat1.kCols; ++j) { BOOST_TEST(mat1(i, j) == mat2(i, j), tol); } } @@ -204,14 +204,14 @@ void discardResult(const T&) void prologue() { - int deviceCount; + int32_t deviceCount; cudaError_t error = cudaGetDeviceCount(&deviceCount); if (error != cudaSuccess || !deviceCount) { std::cerr << "No " << GPUPLATFORM << " devices found" << std::endl; return; } - for (int iDevice = 0; iDevice < deviceCount; ++iDevice) { + for (int32_t iDevice = 0; iDevice < deviceCount; ++iDevice) { cudaDeviceProp deviceProp; discardResult(cudaGetDeviceProperties(&deviceProp, iDevice)); printf("Testing on: %s, Device %d: %s\n", GPUPLATFORM, iDevice, deviceProp.name); @@ -233,8 +233,8 @@ struct GPUSMatrixImplFixtureSolo { std::uniform_real_distribution dis(1.0, 10.0); // Initialize host matrices with random values - for (int i = 0; i < 3; ++i) { - for (int j = i; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = i; j < 3; ++j) { SMatrixSym_h(i, j) = dis(gen); SMatrix_h(i, j) = dis(gen); } @@ -257,7 +257,7 @@ struct GPUSMatrixImplFixtureSolo { BOOST_FIXTURE_TEST_CASE(MatrixInversion, GPUSMatrixImplFixtureSolo) { - const int nBlocks{1}, nThreads{1}; + const int32_t nBlocks{1}, nThreads{1}; GPUBenchmark benchmark("Single symmetric matrix inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); benchmark.start(); gpu::invertMatrixKernelSingle<<>>(static_cast(SMatrixSym_d.get())); @@ -311,8 +311,8 @@ struct GPUSMatrixImplFixtureDuo { std::uniform_real_distribution dis(1.0, 10.0); // Initialize host matrices with random values - for (int i = 0; i < 3; ++i) { - for (int j = i; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = i; j < 3; ++j) { SMatrixSym_h_A(i, j) = dis(gen); SMatrix_h_A(i, j) = dis(gen); @@ -344,7 +344,7 @@ struct GPUSMatrixImplFixtureDuo { BOOST_FIXTURE_TEST_CASE(TestMatrixCopyingAndComparison, GPUSMatrixImplFixtureDuo) { - const int nBlocks{1}, nThreads{1}; + const int32_t nBlocks{1}, nThreads{1}; GPUBenchmark benchmark("Single symmetric matrix copy (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); benchmark.start(); gpu::copyMatrixKernelSingle<<>>(static_cast(SMatrixSym_d_A.get()), static_cast(SMatrixSym_d_B.get())); @@ -389,8 +389,8 @@ struct GPUSmatrixImplFixtureSoloArray { // Initialize host matrices with random values for (size_t iMatrix{0}; iMatrix < D; ++iMatrix) { - for (int i = 0; i < 3; ++i) { - for (int j = i; j < 3; ++j) { + for (int32_t i = 0; i < 3; ++i) { + for (int32_t j = i; j < 3; ++j) { SMatrixSymVector_h[iMatrix](i, j) = dis(gen); SMatrixVector_h[iMatrix](i, j) = dis(gen); } @@ -415,7 +415,7 @@ struct GPUSmatrixImplFixtureSoloArray { BOOST_FIXTURE_TEST_CASE(MatrixInversionArray, GPUSmatrixImplFixtureSoloArray<1'000'000>) { - const int nBlocks{20}, nThreads{512}; + const int32_t nBlocks{20}, nThreads{512}; GPUBenchmark benchmark("Array of 1'000'000 symmetric matrices inversion (" + std::to_string(nBlocks) + " blocks, " + std::to_string(nThreads) + " threads)"); benchmark.start(); gpu::invertMatrixKernelArray<<>>(static_cast(SMatrixSymArray_d.get()), 1'000'000); diff --git a/GPU/GPUTracking/Base/GPUConstantMem.h b/GPU/GPUTracking/Base/GPUConstantMem.h index 7445233f02e8c..df797f4c79419 100644 --- a/GPU/GPUTracking/Base/GPUConstantMem.h +++ b/GPU/GPUTracking/Base/GPUConstantMem.h @@ -96,10 +96,10 @@ struct GPUConstantMem { #endif #if defined(GPUCA_HAVE_O2HEADERS) && defined(GPUCA_NOCOMPAT) - template + template GPUd() auto& getTRDTracker(); #else // GPUCA_HAVE_O2HEADERS - template + template GPUdi() GPUTRDTrackerGPU& getTRDTracker() { return trdTrackerGPU; @@ -127,8 +127,8 @@ union GPUConstantMemCopyable { GPUh() ~GPUConstantMemCopyable() {} // NOLINT: We want an empty destructor, not a default one GPUh() GPUConstantMemCopyable(const GPUConstantMemCopyable& o) { - for (unsigned int k = 0; k < sizeof(GPUConstantMem) / sizeof(int); k++) { - ((int*)&v)[k] = ((int*)&o.v)[k]; + for (uint32_t k = 0; k < sizeof(GPUConstantMem) / sizeof(int32_t); k++) { + ((int32_t*)&v)[k] = ((int32_t*)&o.v)[k]; } } #endif @@ -164,7 +164,7 @@ GPUdi() GPUconstantref() const MEM_CONSTANT(GPUParam) & GPUProcessor::Param() co return GetConstantMem()->param; } -GPUdi() void GPUProcessor::raiseError(unsigned int code, unsigned int param1, unsigned int param2, unsigned int param3) const +GPUdi() void GPUProcessor::raiseError(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3) const { GetConstantMem()->errorCodes.raiseError(code, param1, param2, param3); } diff --git a/GPU/GPUTracking/Base/GPUGeneralKernels.cxx b/GPU/GPUTracking/Base/GPUGeneralKernels.cxx index 9d087fffdc227..8fc60bae6dbe9 100644 --- a/GPU/GPUTracking/Base/GPUGeneralKernels.cxx +++ b/GPU/GPUTracking/Base/GPUGeneralKernels.cxx @@ -17,23 +17,23 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUMemClean16::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() processors, GPUglobalref() void* ptr, unsigned long size) +GPUdii() void GPUMemClean16::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() processors, GPUglobalref() void* ptr, uint64_t size) { - const unsigned long stride = get_global_size(0); + const uint64_t stride = get_global_size(0); int4 i0; i0.x = i0.y = i0.z = i0.w = 0; int4* ptra = (int4*)ptr; - unsigned long len = (size + sizeof(int4) - 1) / sizeof(int4); - for (unsigned long i = get_global_id(0); i < len; i += stride) { + uint64_t len = (size + sizeof(int4) - 1) / sizeof(int4); + for (uint64_t i = get_global_id(0); i < len; i += stride) { ptra[i] = i0; } } template <> -GPUdii() void GPUitoa::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() processors, GPUglobalref() int* ptr, unsigned long size) +GPUdii() void GPUitoa::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() processors, GPUglobalref() int32_t* ptr, uint64_t size) { - const unsigned long stride = get_global_size(0); - for (unsigned long i = get_global_id(0); i < size; i += stride) { + const uint64_t stride = get_global_size(0); + for (uint64_t i = get_global_id(0); i < size; i += stride) { ptr[i] = i; } } diff --git a/GPU/GPUTracking/Base/GPUGeneralKernels.h b/GPU/GPUTracking/Base/GPUGeneralKernels.h index 1a9d6a58bb50f..44314e3393589 100644 --- a/GPU/GPUTracking/Base/GPUGeneralKernels.h +++ b/GPU/GPUTracking/Base/GPUGeneralKernels.h @@ -54,7 +54,7 @@ class GPUKernelTemplate struct GPUSharedMemory { }; - template + template struct GPUSharedMemoryWarpScan64 { // Provides the shared memory resources for warp wide CUB collectives #if (defined(__CUDACC__) || defined(__HIPCC__)) && defined(GPUCA_GPUCODE) && !defined(GPUCA_GPUCODE_HOSTONLY) @@ -65,7 +65,7 @@ class GPUKernelTemplate #endif }; - template + template struct GPUSharedMemoryScan64 { // Provides the shared memory resources for CUB collectives #if (defined(__CUDACC__) || defined(__HIPCC__)) && defined(GPUCA_GPUCODE) && !defined(GPUCA_GPUCODE_HOSTONLY) @@ -76,8 +76,8 @@ class GPUKernelTemplate typename BlockScan::TempStorage cubTmpMem; typename BlockReduce::TempStorage cubReduceTmpMem; typename WarpScan::TempStorage cubWarpTmpMem; - int tmpBroadcast; - int warpPredicateSum[I / GPUCA_WARP_SIZE]; + int32_t tmpBroadcast; + int32_t warpPredicateSum[I / GPUCA_WARP_SIZE]; }; #endif }; @@ -90,13 +90,13 @@ class GPUKernelTemplate return &processors; } #ifdef GPUCA_NOCOMPAT - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, Args... args) + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, Args... args) { } #else - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors) + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors) { } #endif @@ -107,8 +107,8 @@ class GPUMemClean16 : public GPUKernelTemplate { public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUCA_RECO_STEP::NoRecoStep; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, GPUglobalref() void* ptr, unsigned long size); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, GPUglobalref() void* ptr, uint64_t size); }; // Fill with incrementing sequnce of integers @@ -116,8 +116,8 @@ class GPUitoa : public GPUKernelTemplate { public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUCA_RECO_STEP::NoRecoStep; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, GPUglobalref() int* ptr, unsigned long size); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& processors, GPUglobalref() int32_t* ptr, uint64_t size); }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/GPUKernelDebugOutput.h b/GPU/GPUTracking/Base/GPUKernelDebugOutput.h index 86c66fa488fc5..2a032125ced79 100644 --- a/GPU/GPUTracking/Base/GPUKernelDebugOutput.h +++ b/GPU/GPUTracking/Base/GPUKernelDebugOutput.h @@ -37,12 +37,12 @@ class GPUKernelDebugOutput : public GPUProcessor void Print() { printf("------ Kernel Debug Output\n"); - for (int i = 0; i < 100 * 1024; i++) { - int* pos = mDebugOutMemory + i * 1024; - int count = *(pos++); + for (int32_t i = 0; i < 100 * 1024; i++) { + int32_t* pos = mDebugOutMemory + i * 1024; + int32_t count = *(pos++); if (count) { printf("Thread %d: ", i); - for (int j = 0; j < count; j++) { + for (int32_t j = 0; j < count; j++) { printf("%d, ", pos[j]); } printf("\n"); @@ -51,19 +51,19 @@ class GPUKernelDebugOutput : public GPUProcessor printf("------ End of Kernel Debug Output\n"); } #endif - GPUdi() int* memory() + GPUdi() int32_t* memory() { return mDebugOutMemory; } GPUdi() static size_t memorySize() { return 100 * 1024 * 1024; } - GPUd() void Add(unsigned int id, int val) const + GPUd() void Add(uint32_t id, int32_t val) const { printf("Filling debug: id %d, val %d, current count %d\n", id, val, *(mDebugOutMemory + id * 1024)); if (id > 100 * 1024) { return; } - int* pos = mDebugOutMemory + id * 1024; + int32_t* pos = mDebugOutMemory + id * 1024; if (*pos >= 1023) { return; } @@ -72,7 +72,7 @@ class GPUKernelDebugOutput : public GPUProcessor } private: - mutable int* mDebugOutMemory; + mutable int32_t* mDebugOutMemory; }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/GPUMemoryResource.h b/GPU/GPUTracking/Base/GPUMemoryResource.h index b8967787d7399..6d8125251800f 100644 --- a/GPU/GPUTracking/Base/GPUMemoryResource.h +++ b/GPU/GPUTracking/Base/GPUMemoryResource.h @@ -25,21 +25,21 @@ namespace gpu #ifdef GPUCA_NOCOMPAT_ALLOPENCL struct GPUMemoryReuse { - enum Type : int { + enum Type : int32_t { NONE = 0, REUSE_1TO1 = 1 }; - enum Group : unsigned short { + enum Group : uint16_t { ClustererScratch, ClustererZS, TrackerScratch, TrackerDataLinks, TrackerDataWeights }; - using ID = unsigned int; + using ID = uint32_t; - GPUMemoryReuse(Type t, Group g, unsigned short i) : type(t), id(((unsigned int)g << 16) | ((unsigned int)i & 0xFFFF)) {} - GPUMemoryReuse(bool condition, Type t, Group g, unsigned short i) : GPUMemoryReuse() + GPUMemoryReuse(Type t, Group g, uint16_t i) : type(t), id(((uint32_t)g << 16) | ((uint32_t)i & 0xFFFF)) {} + GPUMemoryReuse(bool condition, Type t, Group g, uint16_t i) : GPUMemoryReuse() { if (condition) { *this = GPUMemoryReuse{t, g, i}; @@ -102,7 +102,7 @@ class GPUMemoryResource const char* mName; size_t mSize; size_t mOverrideSize; - int mReuse; + int32_t mReuse; MemoryType mType; }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index a0d2f9c297f7c..765f55d19b19c 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -73,17 +73,17 @@ void GPUParam::SetDefaults(float solenoidBz) }; // clang-format on - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 6; k++) { + for (int32_t i = 0; i < 2; i++) { + for (int32_t j = 0; j < 3; j++) { + for (int32_t k = 0; k < 6; k++) { ParamS0Par[i][j][k] = kParamS0Par[i][j][k]; } } } - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 4; k++) { + for (int32_t i = 0; i < 2; i++) { + for (int32_t j = 0; j < 3; j++) { + for (int32_t k = 0; k < 4; k++) { ParamErrorsSeeding0[i][j][k] = kParamErrorsSeeding0[i][j][k]; } } @@ -98,11 +98,11 @@ void GPUParam::SetDefaults(float solenoidBz) constexpr float plusZmax = 249.778; constexpr float minusZmin = -249.645; constexpr float minusZmax = -0.0799937; - for (int i = 0; i < GPUCA_NSLICES; i++) { + for (int32_t i = 0; i < GPUCA_NSLICES; i++) { const bool zPlus = (i < GPUCA_NSLICES / 2); SliceParam[i].ZMin = zPlus ? plusZmin : minusZmin; SliceParam[i].ZMax = zPlus ? plusZmax : minusZmax; - int tmp = i; + int32_t tmp = i; if (tmp >= GPUCA_NSLICES / 2) { tmp -= GPUCA_NSLICES / 2; } @@ -175,10 +175,10 @@ void GPUParam::SetDefaults(const GPUSettingsGRP* g, const GPUSettingsRec* r, con void GPUParam::UpdateRun3ClusterErrors(const float* yErrorParam, const float* zErrorParam) { #ifdef GPUCA_TPC_GEOMETRY_O2 - for (int yz = 0; yz < 2; yz++) { + for (int32_t yz = 0; yz < 2; yz++) { const float* param = yz ? zErrorParam : yErrorParam; - for (int rowType = 0; rowType < 4; rowType++) { - constexpr int regionMap[4] = {0, 4, 6, 8}; + for (int32_t rowType = 0; rowType < 4; rowType++) { + constexpr int32_t regionMap[4] = {0, 4, 6, 8}; ParamErrors[yz][rowType][0] = param[0] * param[0]; ParamErrors[yz][rowType][1] = param[1] * param[1] * tpcGeometry.PadHeightByRegion(regionMap[rowType]); ParamErrors[yz][rowType][2] = param[2] * param[2] / tpcGeometry.TPCLength() / tpcGeometry.PadHeightByRegion(regionMap[rowType]); @@ -205,17 +205,17 @@ void GPUParam::LoadClusterErrors(bool Print) return; } - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 6; k++) { + for (int32_t i = 0; i < 2; i++) { + for (int32_t j = 0; j < 3; j++) { + for (int32_t k = 0; k < 6; k++) { ParamS0Par[i][j][k] = clparam->GetParamS0Par(i, j, k); } } } - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 4; k++) { + for (int32_t i = 0; i < 2; i++) { + for (int32_t j = 0; j < 3; j++) { + for (int32_t k = 0; k < 4; k++) { ParamErrorsSeeding0[i][j][k] = clparam->GetParamRMS0(i, j, k); } } @@ -229,11 +229,11 @@ void GPUParam::LoadClusterErrors(bool Print) #endif std::cout << "ParamS0Par[2][3][7]=" << std::endl; std::cout << " { " << std::endl; - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { std::cout << " { " << std::endl; - for (int j = 0; j < 3; j++) { + for (int32_t j = 0; j < 3; j++) { std::cout << " { "; - for (int k = 0; k < 6; k++) { + for (int32_t k = 0; k < 6; k++) { std::cout << ParamS0Par[i][j][k] << ", "; } std::cout << " }, " << std::endl; @@ -244,11 +244,11 @@ void GPUParam::LoadClusterErrors(bool Print) std::cout << "ParamErrorsSeeding0[2][3][4]=" << std::endl; std::cout << " { " << std::endl; - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { std::cout << " { " << std::endl; - for (int j = 0; j < 3; j++) { + for (int32_t j = 0; j < 3; j++) { std::cout << " { "; - for (int k = 0; k < 4; k++) { + for (int32_t k = 0; k < 4; k++) { std::cout << ParamErrorsSeeding0[i][j][k] << ", "; } std::cout << " }, " << std::endl; @@ -275,6 +275,8 @@ std::string GPUParamRTC::generateRTCCode(const GPUParam& param, bool useConstexp return "#ifndef GPUCA_GPUCODE_DEVICE\n" "#include \n" "#include \n" + "#include \n" + "#include \n" "#endif\n" "namespace o2::gpu { class GPUDisplayFrontendInterface; }\n" + qConfigPrintRtc(std::make_tuple(¶m.rec.tpc, ¶m.rec.trd, ¶m.rec, ¶m.par), useConstexpr); diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h index ef1cccf58cdbf..66f312f8f7dc8 100644 --- a/GPU/GPUTracking/Base/GPUParam.h +++ b/GPU/GPUTracking/Base/GPUParam.h @@ -57,13 +57,13 @@ struct GPUParam_t { float bzCLight; float qptB5Scaler; - signed char dodEdxDownscaled; - int continuousMaxTimeBin; + int8_t dodEdxDownscaled; + int32_t continuousMaxTimeBin; GPUTPCGeometry tpcGeometry; // TPC Geometry GPUTPCGMPolynomialField polynomialField; // Polynomial approx. of magnetic field for TPC GM - const unsigned int* occupancyMap; // Ptr to TPC occupancy map - unsigned int occupancyTotal; // Total occupancy in the TPC (nCl / nHbf) + const uint32_t* occupancyMap; // Ptr to TPC occupancy map + uint32_t occupancyTotal; // Total occupancy in the TPC (nCl / nHbf) GPUParamSlice SliceParam[GPUCA_NSLICES]; @@ -90,7 +90,7 @@ struct GPUParam : public internal::GPUParam_t void UpdateRun3ClusterErrors(const float* yErrorParam, const float* zErrorParam); #endif - GPUd() float Alpha(int iSlice) const + GPUd() float Alpha(int32_t iSlice) const { if (iSlice >= GPUCA_NSLICES / 2) { iSlice -= GPUCA_NSLICES / 2; @@ -100,20 +100,20 @@ struct GPUParam : public internal::GPUParam_t } return 0.174533f + par.dAlpha * iSlice; } - GPUd() float GetClusterErrorSeeding(int yz, int type, float zDiff, float angle2, float unscaledMult) const; - GPUd() void GetClusterErrorsSeeding2(char sector, int row, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const; + GPUd() float GetClusterErrorSeeding(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult) const; + GPUd() void GetClusterErrorsSeeding2(char sector, int32_t row, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const; GPUd() float GetSystematicClusterErrorIFC2(float trackX, float trackY, float z, bool sideC) const; GPUd() float GetSystematicClusterErrorC122(float trackX, float trackY, char sector) const; - GPUd() float GetClusterError2(int yz, int type, float zDiff, float angle2, float unscaledMult, float scaledAvgInvCharge, float scaledInvCharge) const; - GPUd() void GetClusterErrors2(char sector, int row, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const; - GPUd() void UpdateClusterError2ByState(short clusterState, float& ErrY2, float& ErrZ2) const; + GPUd() float GetClusterError2(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult, float scaledAvgInvCharge, float scaledInvCharge) const; + GPUd() void GetClusterErrors2(char sector, int32_t row, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const; + GPUd() void UpdateClusterError2ByState(int16_t clusterState, float& ErrY2, float& ErrZ2) const; GPUd() float GetUnscaledMult(float time) const; - GPUd() void Slice2Global(int iSlice, float x, float y, float z, float* X, float* Y, float* Z) const; - GPUd() void Global2Slice(int iSlice, float x, float y, float z, float* X, float* Y, float* Z) const; + GPUd() void Slice2Global(int32_t iSlice, float x, float y, float z, float* X, float* Y, float* Z) const; + GPUd() void Global2Slice(int32_t iSlice, float x, float y, float z, float* X, float* Y, float* Z) const; - GPUd() bool rejectEdgeClusterByY(float uncorrectedY, int iRow, float trackSigmaY) const; + GPUd() bool rejectEdgeClusterByY(float uncorrectedY, int32_t iRow, float trackSigmaY) const; }; #endif diff --git a/GPU/GPUTracking/Base/GPUParam.inc b/GPU/GPUTracking/Base/GPUParam.inc index f9e3059a1afce..c3d1aa837e368 100644 --- a/GPU/GPUTracking/Base/GPUParam.inc +++ b/GPU/GPUTracking/Base/GPUParam.inc @@ -27,7 +27,7 @@ namespace gpu { MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::Slice2Global(int iSlice, float x, float y, float z, float* X, float* Y, float* Z) const +GPUdi() void MEM_LG(GPUParam)::Slice2Global(int32_t iSlice, float x, float y, float z, float* X, float* Y, float* Z) const { // conversion of coordinates sector->global *X = x * SliceParam[iSlice].CosAlpha - y * SliceParam[iSlice].SinAlpha; @@ -36,7 +36,7 @@ GPUdi() void MEM_LG(GPUParam)::Slice2Global(int iSlice, float x, float y, float } MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::Global2Slice(int iSlice, float X, float Y, float Z, float* x, float* y, float* z) const +GPUdi() void MEM_LG(GPUParam)::Global2Slice(int32_t iSlice, float X, float Y, float Z, float* x, float* y, float* z) const { // conversion of coordinates global->sector *x = X * SliceParam[iSlice].CosAlpha + Y * SliceParam[iSlice].SinAlpha; @@ -47,9 +47,9 @@ GPUdi() void MEM_LG(GPUParam)::Global2Slice(int iSlice, float X, float Y, float #ifdef GPUCA_TPC_GEOMETRY_O2 MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const { - const int rowType = tpcGeometry.GetROC(iRow); + const int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); const float s2 = CAMath::Min(sinPhi * sinPhi, 0.95f * 0.95f); const float sec2 = 1.f / (1.f - s2); @@ -63,7 +63,7 @@ GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int iRow, f } MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int yz, int type, float zDiff, float angle2, float unscaledMult) const // Note, returns Err2 despite the name not containing 2 +GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult) const // Note, returns Err2 despite the name not containing 2 { MakeType(const float*) c = ParamErrors[yz][type]; // Note: c[0] = p[0]^2, c[1] = p[1]^2 * padHeight, c[2] = p[2]^2 / tpcLength / padHeight, c[3] = p[3]^2 * clusterErrorOccupancyScaler^2 float v = c[0] + c[1] * angle2 + c[2] * zDiff + c[3] * (unscaledMult * unscaledMult); @@ -74,7 +74,7 @@ GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int yz, int type, float z } MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetClusterError2(int yz, int type, float zDiff, float angle2, float unscaledMult, float scaledInvAvgCharge, float scaledInvCharge) const +GPUdi() float MEM_LG(GPUParam)::GetClusterError2(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult, float scaledInvAvgCharge, float scaledInvCharge) const { MakeType(const float*) c = ParamErrors[yz][type]; // Note: c[0] = p[0]^2, c[1] = p[1]^2 * padHeight, c[2] = p[2]^2 / tpcLength / padHeight, c[3] = p[3]^2 * clusterErrorOccupancyScaler^2 float v = c[0] + c[1] * angle2 * scaledInvAvgCharge + c[2] * zDiff * scaledInvCharge + c[3] * (unscaledMult * unscaledMult) * (scaledInvAvgCharge * scaledInvAvgCharge); @@ -134,7 +134,7 @@ GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float x, float y, #else // GPUCA_TPC_GEOMETRY_O2 MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int yz, int type, float zDiff, float angle2, float scaledMult) const +GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int32_t yz, int32_t type, float zDiff, float angle2, float scaledMult) const { MakeType(const float*) c = ParamErrorsSeeding0[yz][type]; float v = c[0] + c[1] * zDiff + c[2] * angle2; @@ -143,9 +143,9 @@ GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int yz, int type, float z } MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const { - int rowType = tpcGeometry.GetROC(iRow); + int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); const float s2 = CAMath::Min(sinPhi * sinPhi, 0.95f * 0.95f); float sec2 = 1.f / (1.f - s2); @@ -159,7 +159,7 @@ GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int iRow, f } MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetClusterError2(int yz, int type, float zDiff, float angle2, float unscaledMult, float avgInvCharge, float invCharge) const +GPUdi() float MEM_LG(GPUParam)::GetClusterError2(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult, float avgInvCharge, float invCharge) const { MakeType(const float*) c = ParamS0Par[yz][type]; float v = c[0] + c[1] * zDiff + c[2] * angle2 + c[3] * zDiff * zDiff + c[4] * angle2 * angle2 + c[5] * zDiff * angle2; @@ -187,9 +187,9 @@ GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float trackX, floa #endif // !GPUCA_TPC_GEOMETRY_O2 MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrors2(char sector, int iRow, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrors2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const { - const int rowType = tpcGeometry.GetROC(iRow); + const int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); const float s2 = CAMath::Min(sinPhi * sinPhi, 0.95f * 0.95f); const float sec2 = 1.f / (1.f - s2); @@ -205,7 +205,7 @@ GPUdi() void MEM_LG(GPUParam)::GetClusterErrors2(char sector, int iRow, float z, } MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::UpdateClusterError2ByState(short clusterState, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::UpdateClusterError2ByState(int16_t clusterState, float& ErrY2, float& ErrZ2) const { if (clusterState & GPUTPCGMMergedTrackHit::flagEdge) { ErrY2 += rec.tpc.extraClusterErrorEdgeY2; @@ -232,7 +232,7 @@ GPUdi() float MEM_LG(GPUParam)::GetUnscaledMult(float time) const if (!occupancyMap) { return 0.f; } - const unsigned int bin = CAMath::Max(0.f, time / rec.tpc.occupancyMapTimeBins); + const uint32_t bin = CAMath::Max(0.f, time / rec.tpc.occupancyMapTimeBins); return occupancyMap[bin]; #else return 0.f; @@ -240,7 +240,7 @@ GPUdi() float MEM_LG(GPUParam)::GetUnscaledMult(float time) const } MEM_CLASS_PRE() -GPUdi() bool MEM_LG(GPUParam)::rejectEdgeClusterByY(float uncorrectedY, int iRow, float trackSigmaY) const +GPUdi() bool MEM_LG(GPUParam)::rejectEdgeClusterByY(float uncorrectedY, int32_t iRow, float trackSigmaY) const { return CAMath::Abs(uncorrectedY) > (tpcGeometry.NPads(iRow) - 1) * 0.5f * tpcGeometry.PadWidth(iRow) + rec.tpc.rejectEdgeClustersMargin + trackSigmaY * rec.tpc.rejectEdgeClustersSigmaMargin; } diff --git a/GPU/GPUTracking/Base/GPUProcessor.h b/GPU/GPUTracking/Base/GPUProcessor.h index c3a709e5837f7..95b56a5c4cd28 100644 --- a/GPU/GPUTracking/Base/GPUProcessor.h +++ b/GPU/GPUTracking/Base/GPUProcessor.h @@ -54,7 +54,7 @@ class GPUProcessor GPUd() GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * GetConstantMem() const; // Body in GPUConstantMem.h to avoid circular headers GPUd() GPUconstantref() const MEM_CONSTANT(GPUParam) & Param() const; // ... - GPUd() void raiseError(unsigned int code, unsigned int param1 = 0, unsigned int param2 = 0, unsigned int param3 = 0) const; + GPUd() void raiseError(uint32_t code, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0) const; const GPUReconstruction& GetRec() const { return *mRec; } #ifndef __OPENCL__ diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index 2dd92862c0500..a526f11f103da 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -51,12 +51,12 @@ namespace GPUCA_NAMESPACE namespace gpu { struct GPUReconstructionPipelineQueue { - unsigned int op = 0; // For now, 0 = process, 1 = terminate + uint32_t op = 0; // For now, 0 = process, 1 = terminate GPUChain* chain = nullptr; std::mutex m; std::condition_variable c; bool done = false; - int retVal = 0; + int32_t retVal = 0; }; struct GPUReconstructionPipelineContext { @@ -74,7 +74,7 @@ constexpr const char* const GPUReconstruction::GEOMETRY_TYPE_NAMES[]; constexpr const char* const GPUReconstruction::IOTYPENAMES[]; constexpr GPUReconstruction::GeometryType GPUReconstruction::geometryType; -static long ptrDiff(void* a, void* b) { return (long)((char*)a - (char*)b); } +static int64_t ptrDiff(void* a, void* b) { return (int64_t)((char*)a - (char*)b); } GPUReconstruction::GPUReconstruction(const GPUSettingsDeviceBackend& cfg) : mHostConstantMem(new GPUConstantMem), mDeviceBackendSettings(cfg) { @@ -92,7 +92,7 @@ GPUReconstruction::GPUReconstruction(const GPUSettingsDeviceBackend& cfg) : mHos new (&mGRPSettings) GPUSettingsGRP; param().SetDefaults(&mGRPSettings); mMemoryScalers.reset(new GPUMemorySizeScalers); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { processors()->tpcTrackers[i].SetSlice(i); // TODO: Move to a better place #ifdef GPUCA_HAVE_O2HEADERS processors()->tpcClusterer[i].mISlice = i; @@ -123,7 +123,7 @@ void GPUReconstruction::GetITSTraits(std::unique_ptr* tr } } -int GPUReconstruction::SetNOMPThreads(int n) +int32_t GPUReconstruction::SetNOMPThreads(int32_t n) { #ifdef WITH_OPENMP omp_set_num_threads(mProcessingSettings.ompThreads = std::max(1, n < 0 ? mMaxOMPThreads : std::min(n, mMaxOMPThreads))); @@ -136,16 +136,16 @@ int GPUReconstruction::SetNOMPThreads(int n) #endif } -int GPUReconstruction::Init() +int32_t GPUReconstruction::Init() { if (mMaster) { throw std::runtime_error("Must not call init on slave!"); } - int retVal = InitPhaseBeforeDevice(); + int32_t retVal = InitPhaseBeforeDevice(); if (retVal) { return retVal; } - for (unsigned int i = 0; i < mSlaves.size(); i++) { + for (uint32_t i = 0; i < mSlaves.size(); i++) { retVal = mSlaves[i]->InitPhaseBeforeDevice(); if (retVal) { GPUError("Error initialization slave (before deviceinit)"); @@ -163,7 +163,7 @@ int GPUReconstruction::Init() if (InitPhasePermanentMemory()) { return 1; } - for (unsigned int i = 0; i < mSlaves.size(); i++) { + for (uint32_t i = 0; i < mSlaves.size(); i++) { mSlaves[i]->mDeviceMemoryBase = mDeviceMemoryPermanent; mSlaves[i]->mHostMemoryBase = mHostMemoryPermanent; mSlaves[i]->mDeviceMemorySize = mDeviceMemorySize - ((char*)mSlaves[i]->mDeviceMemoryBase - (char*)mDeviceMemoryBase); @@ -186,7 +186,7 @@ int GPUReconstruction::Init() return retVal; } ClearAllocatedMemory(); - for (unsigned int i = 0; i < mSlaves.size(); i++) { + for (uint32_t i = 0; i < mSlaves.size(); i++) { mSlaves[i]->mDeviceMemoryPermanent = mDeviceMemoryPermanent; mSlaves[i]->mHostMemoryPermanent = mHostMemoryPermanent; retVal = mSlaves[i]->InitPhaseAfterDevice(); @@ -199,14 +199,14 @@ int GPUReconstruction::Init() return 0; } -int GPUReconstruction::InitPhaseBeforeDevice() +int32_t GPUReconstruction::InitPhaseBeforeDevice() { if (mProcessingSettings.printSettings) { if (mSlaves.size() || mMaster) { printf("\nConfig Dump %s\n", mMaster ? "Slave" : "Master"); } const GPUChainTracking* chTrk; - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { if ((chTrk = dynamic_cast(mChains[i].get()))) { break; } @@ -224,7 +224,7 @@ int GPUReconstruction::InitPhaseBeforeDevice() mRecoSteps.stepsGPUMask &= mRecoSteps.steps; mRecoSteps.stepsGPUMask &= AvailableGPURecoSteps(); if (!IsGPU()) { - mRecoSteps.stepsGPUMask.set((unsigned char)0); + mRecoSteps.stepsGPUMask.set((uint8_t)0); } if (mProcessingSettings.forceMemoryPoolSize >= 1024 || mProcessingSettings.forceHostMemoryPoolSize >= 1024) { @@ -344,12 +344,12 @@ int GPUReconstruction::InitPhaseBeforeDevice() mMaxOMPThreads = mProcessingSettings.ompThreads; mMaxThreads = std::max(mMaxThreads, mProcessingSettings.ompThreads); if (IsGPU()) { - mNStreams = std::max(mProcessingSettings.nStreams, 3); + mNStreams = std::max(mProcessingSettings.nStreams, 3); } #ifdef GPUCA_HAVE_O2HEADERS if (mProcessingSettings.nTPCClustererLanes == -1) { - mProcessingSettings.nTPCClustererLanes = (GetRecoStepsGPU() & RecoStep::TPCClusterFinding) ? 3 : std::max(1, std::min(GPUCA_NSLICES, mProcessingSettings.ompKernels ? (mProcessingSettings.ompThreads >= 4 ? std::min(mProcessingSettings.ompThreads / 2, mProcessingSettings.ompThreads >= 32 ? GPUCA_NSLICES : 4) : 1) : mProcessingSettings.ompThreads)); + mProcessingSettings.nTPCClustererLanes = (GetRecoStepsGPU() & RecoStep::TPCClusterFinding) ? 3 : std::max(1, std::min(GPUCA_NSLICES, mProcessingSettings.ompKernels ? (mProcessingSettings.ompThreads >= 4 ? std::min(mProcessingSettings.ompThreads / 2, mProcessingSettings.ompThreads >= 32 ? GPUCA_NSLICES : 4) : 1) : mProcessingSettings.ompThreads)); } if (mProcessingSettings.overrideClusterizerFragmentLen == -1) { mProcessingSettings.overrideClusterizerFragmentLen = ((GetRecoStepsGPU() & RecoStep::TPCClusterFinding) || (mProcessingSettings.ompThreads / mProcessingSettings.nTPCClustererLanes >= 3)) ? TPC_MAX_FRAGMENT_LEN_GPU : TPC_MAX_FRAGMENT_LEN_HOST; @@ -370,7 +370,7 @@ int GPUReconstruction::InitPhaseBeforeDevice() } mDeviceMemorySize = mHostMemorySize = 0; - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { if (mChains[i]->EarlyConfigure()) { return 1; } @@ -395,17 +395,17 @@ int GPUReconstruction::InitPhaseBeforeDevice() mHostMemorySize = mProcessingSettings.forceHostMemoryPoolSize; } - for (unsigned int i = 0; i < mProcessors.size(); i++) { + for (uint32_t i = 0; i < mProcessors.size(); i++) { (mProcessors[i].proc->*(mProcessors[i].RegisterMemoryAllocation))(); } return 0; } -int GPUReconstruction::InitPhasePermanentMemory() +int32_t GPUReconstruction::InitPhasePermanentMemory() { if (IsGPU()) { - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->RegisterGPUProcessors(); } } @@ -413,17 +413,17 @@ int GPUReconstruction::InitPhasePermanentMemory() return 0; } -int GPUReconstruction::InitPhaseAfterDevice() +int32_t GPUReconstruction::InitPhaseAfterDevice() { if (mProcessingSettings.forceMaxMemScalers <= 1 && mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { mMemoryScalers->rescaleMaxMem(IsGPU() ? mDeviceMemorySize : mHostMemorySize); } - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { if (mChains[i]->Init()) { return 1; } } - for (unsigned int i = 0; i < mProcessors.size(); i++) { + for (uint32_t i = 0; i < mProcessors.size(); i++) { (mProcessors[i].proc->*(mProcessors[i].InitializeProcessor))(); } @@ -441,20 +441,20 @@ void GPUReconstruction::WriteConstantParams() } } -int GPUReconstruction::Finalize() +int32_t GPUReconstruction::Finalize() { - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->Finalize(); } return 0; } -int GPUReconstruction::Exit() +int32_t GPUReconstruction::Exit() { if (!mInitialized) { return 1; } - for (unsigned int i = 0; i < mSlaves.size(); i++) { + for (uint32_t i = 0; i < mSlaves.size(); i++) { if (mSlaves[i]->Exit()) { GPUError("Error exiting slave"); } @@ -463,7 +463,7 @@ int GPUReconstruction::Exit() mChains.clear(); // Make sure we destroy a possible ITS GPU tracker before we call the destructors mHostConstantMem.reset(); // Reset these explicitly before the destruction of other members unloads the library if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_INDIVIDUAL) { - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if (mMemoryResources[i].mReuse >= 0) { continue; } @@ -489,7 +489,7 @@ void GPUReconstruction::ComputeReuseMax(GPUProcessor* proc) if (proc == nullptr || re.proc == proc) { GPUMemoryResource& resMain = mMemoryResources[re.res[0]]; resMain.mOverrideSize = 0; - for (unsigned int i = 0; i < re.res.size(); i++) { + for (uint32_t i = 0; i < re.res.size(); i++) { GPUMemoryResource& res = mMemoryResources[re.res[i]]; resMain.mOverrideSize = std::max(resMain.mOverrideSize, (char*)res.SetPointers((void*)1) - (char*)1); } @@ -503,7 +503,7 @@ size_t GPUReconstruction::AllocateRegisteredMemory(GPUProcessor* proc, bool rese GPUInfo("Allocating memory %p", (void*)proc); } size_t total = 0; - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if (proc == nullptr ? !mMemoryResources[i].mProcessor->mAllocateAndInitializeLate : mMemoryResources[i].mProcessor == proc) { if (!(mMemoryResources[i].mType & GPUMemoryResource::MEMORY_CUSTOM)) { total += AllocateRegisteredMemory(i); @@ -523,8 +523,8 @@ size_t GPUReconstruction::AllocateRegisteredPermanentMemory() if (mProcessingSettings.debugLevel >= 5) { GPUInfo("Allocating Permanent Memory"); } - int total = 0; - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + int32_t total = 0; + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if ((mMemoryResources[i].mType & GPUMemoryResource::MEMORY_PERMANENT) && mMemoryResources[i].mPtr == nullptr) { total += AllocateRegisteredMemory(i); } @@ -600,7 +600,7 @@ void GPUReconstruction::AllocateRegisteredMemoryInternal(GPUMemoryResource* res, res->mSize = std::max((size_t)res->SetPointers((void*)1) - 1, res->mOverrideSize); if (res->mReuse >= 0) { if (res->mSize > mMemoryResources[res->mReuse].mSize) { - GPUError("Invalid reuse, insufficient size: %ld < %ld", (long)mMemoryResources[res->mReuse].mSize, (long)res->mSize); + GPUError("Invalid reuse, insufficient size: %ld < %ld", (int64_t)mMemoryResources[res->mReuse].mSize, (int64_t)res->mSize); throw std::bad_alloc(); } res->mPtrDevice = mMemoryResources[res->mReuse].mPtrDevice; @@ -671,12 +671,12 @@ void GPUReconstruction::AllocateRegisteredMemoryInternal(GPUMemoryResource* res, } } -void GPUReconstruction::AllocateRegisteredForeignMemory(short ires, GPUReconstruction* rec, GPUOutputControl* control) +void GPUReconstruction::AllocateRegisteredForeignMemory(int16_t ires, GPUReconstruction* rec, GPUOutputControl* control) { rec->AllocateRegisteredMemoryInternal(&rec->mMemoryResources[ires], control, this); } -size_t GPUReconstruction::AllocateRegisteredMemory(short ires, GPUOutputControl* control) +size_t GPUReconstruction::AllocateRegisteredMemory(int16_t ires, GPUOutputControl* control) { GPUMemoryResource* res = &mMemoryResources[ires]; if ((res->mType & GPUMemoryResource::MEMORY_PERMANENT) && res->mPtr != nullptr) { @@ -687,7 +687,7 @@ size_t GPUReconstruction::AllocateRegisteredMemory(short ires, GPUOutputControl* return res->mReuse >= 0 ? 0 : res->mSize; } -void* GPUReconstruction::AllocateUnmanagedMemory(size_t size, int type) +void* GPUReconstruction::AllocateUnmanagedMemory(size_t size, int32_t type) { if (type != GPUMemoryResource::MEMORY_HOST && (!IsGPU() || type != GPUMemoryResource::MEMORY_GPU)) { throw std::runtime_error("Requested invalid memory typo for unmanaged allocation"); @@ -745,14 +745,14 @@ void* GPUReconstruction::AllocateVolatileMemory(size_t size, bool device) void GPUReconstruction::ResetRegisteredMemoryPointers(GPUProcessor* proc) { - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if (proc == nullptr || mMemoryResources[i].mProcessor == proc) { ResetRegisteredMemoryPointers(i); } } } -void GPUReconstruction::ResetRegisteredMemoryPointers(short ires) +void GPUReconstruction::ResetRegisteredMemoryPointers(int16_t ires) { GPUMemoryResource* res = &mMemoryResources[ires]; if (!(res->mType & GPUMemoryResource::MEMORY_EXTERNAL) && (res->mType & GPUMemoryResource::MEMORY_HOST)) { @@ -775,14 +775,14 @@ void GPUReconstruction::ResetRegisteredMemoryPointers(short ires) void GPUReconstruction::FreeRegisteredMemory(GPUProcessor* proc, bool freeCustom, bool freePermanent) { - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if ((proc == nullptr || mMemoryResources[i].mProcessor == proc) && (freeCustom || !(mMemoryResources[i].mType & GPUMemoryResource::MEMORY_CUSTOM)) && (freePermanent || !(mMemoryResources[i].mType & GPUMemoryResource::MEMORY_PERMANENT))) { FreeRegisteredMemory(i); } } } -void GPUReconstruction::FreeRegisteredMemory(short ires) +void GPUReconstruction::FreeRegisteredMemory(int16_t ires) { FreeRegisteredMemory(&mMemoryResources[ires]); } @@ -816,12 +816,12 @@ void GPUReconstruction::ReturnVolatileMemory() mVolatileChunks.clear(); } -void GPUReconstruction::PushNonPersistentMemory(unsigned long tag) +void GPUReconstruction::PushNonPersistentMemory(uint64_t tag) { mNonPersistentMemoryStack.emplace_back(mHostMemoryPoolEnd, mDeviceMemoryPoolEnd, mNonPersistentIndividualAllocations.size(), tag); } -void GPUReconstruction::PopNonPersistentMemory(RecoStep step, unsigned long tag) +void GPUReconstruction::PopNonPersistentMemory(RecoStep step, uint64_t tag) { if (mProcessingSettings.keepDisplayMemory || mProcessingSettings.disableMemoryReuse) { return; @@ -842,7 +842,7 @@ void GPUReconstruction::PopNonPersistentMemory(RecoStep step, unsigned long tag) } mHostMemoryPoolEnd = std::get<0>(mNonPersistentMemoryStack.back()); mDeviceMemoryPoolEnd = std::get<1>(mNonPersistentMemoryStack.back()); - for (unsigned int i = std::get<2>(mNonPersistentMemoryStack.back()); i < mNonPersistentIndividualAllocations.size(); i++) { + for (uint32_t i = std::get<2>(mNonPersistentMemoryStack.back()); i < mNonPersistentIndividualAllocations.size(); i++) { GPUMemoryResource* res = mNonPersistentIndividualAllocations[i]; if (res->mReuse < 0) { operator delete(res->mPtrDevice GPUCA_OPERATOR_NEW_ALIGNMENT); @@ -874,14 +874,14 @@ void GPUReconstruction::UnblockStackedMemory() mDeviceMemoryPoolBlocked = nullptr; } -void GPUReconstruction::SetMemoryExternalInput(short res, void* ptr) +void GPUReconstruction::SetMemoryExternalInput(int16_t res, void* ptr) { mMemoryResources[res].mPtr = ptr; } void GPUReconstruction::ClearAllocatedMemory(bool clearOutputs) { - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { if (!(mMemoryResources[i].mType & GPUMemoryResource::MEMORY_PERMANENT) && (clearOutputs || !(mMemoryResources[i].mType & GPUMemoryResource::MEMORY_OUTPUT))) { FreeRegisteredMemory(i); } @@ -904,22 +904,22 @@ void GPUReconstruction::UpdateMaxMemoryUsed() void GPUReconstruction::PrintMemoryMax() { - printf("Maximum Memory Allocation: Host %'ld / Device %'ld\n", (long)mHostMemoryUsedMax, (long)mDeviceMemoryUsedMax); + printf("Maximum Memory Allocation: Host %'ld / Device %'ld\n", (int64_t)mHostMemoryUsedMax, (int64_t)mDeviceMemoryUsedMax); } void GPUReconstruction::PrintMemoryOverview() { if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { printf("Memory Allocation: Host %'ld / %'ld (Permanent %'ld), Device %'ld / %'ld, (Permanent %'ld) %d chunks\n", - ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), (long)mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), - ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), (long)mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), (int)mMemoryResources.size()); + ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), (int64_t)mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), + ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), (int64_t)mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), (int32_t)mMemoryResources.size()); } } void GPUReconstruction::PrintMemoryStatistics() { std::map> sizes; - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { auto& res = mMemoryResources[i]; if (res.mReuse >= 0) { continue; @@ -937,27 +937,27 @@ void GPUReconstruction::PrintMemoryStatistics() } printf("%59s CPU / %9s GPU\n", "", ""); for (auto it = sizes.begin(); it != sizes.end(); it++) { - printf("Allocation %30s %s: Size %'14ld / %'14ld\n", it->first.c_str(), it->second[2] ? "P" : " ", (long)it->second[0], (long)it->second[1]); + printf("Allocation %30s %s: Size %'14ld / %'14ld\n", it->first.c_str(), it->second[2] ? "P" : " ", (int64_t)it->second[0], (int64_t)it->second[1]); } PrintMemoryOverview(); - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->PrintMemoryStatistics(); } } -int GPUReconstruction::registerMemoryForGPU(const void* ptr, size_t size) +int32_t GPUReconstruction::registerMemoryForGPU(const void* ptr, size_t size) { if (mProcessingSettings.noGPUMemoryRegistration) { return 0; } - int retVal = registerMemoryForGPU_internal(ptr, size); + int32_t retVal = registerMemoryForGPU_internal(ptr, size); if (retVal == 0) { mRegisteredMemoryPtrs.emplace(ptr); } return retVal; } -int GPUReconstruction::unregisterMemoryForGPU(const void* ptr) +int32_t GPUReconstruction::unregisterMemoryForGPU(const void* ptr) { if (mProcessingSettings.noGPUMemoryRegistration) { return 0; @@ -971,11 +971,11 @@ int GPUReconstruction::unregisterMemoryForGPU(const void* ptr) } template -static inline int getStepNum(T step, bool validCheck, int N, const char* err = "Invalid step num") +static inline int32_t getStepNum(T step, bool validCheck, int32_t N, const char* err = "Invalid step num") { - static_assert(sizeof(step) == sizeof(unsigned int), "Invalid step enum size"); - int retVal = 8 * sizeof(unsigned int) - 1 - CAMath::Clz((unsigned int)step); - if ((unsigned int)step == 0 || retVal >= N) { + static_assert(sizeof(step) == sizeof(uint32_t), "Invalid step enum size"); + int32_t retVal = 8 * sizeof(uint32_t) - 1 - CAMath::Clz((uint32_t)step); + if ((uint32_t)step == 0 || retVal >= N) { if (!validCheck) { return -1; } @@ -984,8 +984,8 @@ static inline int getStepNum(T step, bool validCheck, int N, const char* err = " return retVal; } -int GPUReconstruction::getRecoStepNum(RecoStep step, bool validCheck) { return getStepNum(step, validCheck, GPUDataTypes::N_RECO_STEPS, "Invalid Reco Step"); } -int GPUReconstruction::getGeneralStepNum(GeneralStep step, bool validCheck) { return getStepNum(step, validCheck, GPUDataTypes::N_GENERAL_STEPS, "Invalid General Step"); } +int32_t GPUReconstruction::getRecoStepNum(RecoStep step, bool validCheck) { return getStepNum(step, validCheck, GPUDataTypes::N_RECO_STEPS, "Invalid Reco Step"); } +int32_t GPUReconstruction::getGeneralStepNum(GeneralStep step, bool validCheck) { return getStepNum(step, validCheck, GPUDataTypes::N_GENERAL_STEPS, "Invalid General Step"); } void GPUReconstruction::RunPipelineWorker() { @@ -1028,7 +1028,7 @@ void GPUReconstruction::TerminatePipelineWorker() EnqueuePipeline(true); } -int GPUReconstruction::EnqueuePipeline(bool terminate) +int32_t GPUReconstruction::EnqueuePipeline(bool terminate) { ClearAllocatedMemory(true); GPUReconstruction* rec = mMaster ? mMaster : this; @@ -1067,10 +1067,10 @@ GPUChain* GPUReconstruction::GetNextChainInQueue() void GPUReconstruction::PrepareEvent() // TODO: Clean this up, this should not be called from chainTracking but before { ClearAllocatedMemory(true); - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->PrepareEvent(); } - for (unsigned int i = 0; i < mProcessors.size(); i++) { + for (uint32_t i = 0; i < mProcessors.size(); i++) { if (mProcessors[i].proc->mAllocateAndInitializeLate) { continue; } @@ -1083,10 +1083,10 @@ void GPUReconstruction::PrepareEvent() // TODO: Clean this up, this should not b AllocateRegisteredMemory(nullptr); } -int GPUReconstruction::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::vector>* fillErrors) +int32_t GPUReconstruction::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::vector>* fillErrors) { - int retVal = 0; - for (unsigned int i = 0; i < mChains.size(); i++) { + int32_t retVal = 0; + for (uint32_t i = 0; i < mChains.size(); i++) { if (mChains[i]->CheckErrorCodes(cpuOnly, forceShowErrors, fillErrors)) { retVal++; } @@ -1100,7 +1100,7 @@ void GPUReconstruction::DumpSettings(const char* dir) f = dir; f += "settings.dump"; DumpStructToFile(&mGRPSettings, f.c_str()); - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->DumpSettings(dir); } } @@ -1121,7 +1121,7 @@ void GPUReconstruction::UpdateSettings(const GPUSettingsGRP* g, const GPUSetting } } -int GPUReconstruction::ReadSettings(const char* dir) +int32_t GPUReconstruction::ReadSettings(const char* dir) { std::string f; f = dir; @@ -1131,7 +1131,7 @@ int GPUReconstruction::ReadSettings(const char* dir) return 1; } param().UpdateSettings(&mGRPSettings); - for (unsigned int i = 0; i < mChains.size(); i++) { + for (uint32_t i = 0; i < mChains.size(); i++) { mChains[i]->ReadSettings(dir); } return 0; diff --git a/GPU/GPUTracking/Base/GPUReconstruction.h b/GPU/GPUTracking/Base/GPUReconstruction.h index 3484fb65d0faa..70a066532d938 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.h +++ b/GPU/GPUTracking/Base/GPUReconstruction.h @@ -76,7 +76,7 @@ class GPUReconstruction GPUReconstruction& operator=(const GPUReconstruction&) = delete; // General definitions - constexpr static unsigned int NSLICES = GPUCA_NSLICES; + constexpr static uint32_t NSLICES = GPUCA_NSLICES; using GeometryType = GPUDataTypes::GeometryType; using DeviceType = GPUDataTypes::DeviceType; @@ -93,94 +93,94 @@ class GPUReconstruction #endif static DeviceType GetDeviceType(const char* type); - enum InOutPointerType : unsigned int { CLUSTER_DATA = 0, - SLICE_OUT_TRACK = 1, - SLICE_OUT_CLUSTER = 2, - MC_LABEL_TPC = 3, - MC_INFO_TPC = 4, - MERGED_TRACK = 5, - MERGED_TRACK_HIT = 6, - TRD_TRACK = 7, - TRD_TRACKLET = 8, - RAW_CLUSTERS = 9, - CLUSTERS_NATIVE = 10, - TRD_TRACKLET_MC = 11, - TPC_COMPRESSED_CL = 12, - TPC_DIGIT = 13, - TPC_ZS = 14, - CLUSTER_NATIVE_MC = 15, - TPC_DIGIT_MC = 16, - TRD_SPACEPOINT = 17, - TRD_TRIGGERRECORDS = 18, - TF_SETTINGS = 19 }; + enum InOutPointerType : uint32_t { CLUSTER_DATA = 0, + SLICE_OUT_TRACK = 1, + SLICE_OUT_CLUSTER = 2, + MC_LABEL_TPC = 3, + MC_INFO_TPC = 4, + MERGED_TRACK = 5, + MERGED_TRACK_HIT = 6, + TRD_TRACK = 7, + TRD_TRACKLET = 8, + RAW_CLUSTERS = 9, + CLUSTERS_NATIVE = 10, + TRD_TRACKLET_MC = 11, + TPC_COMPRESSED_CL = 12, + TPC_DIGIT = 13, + TPC_ZS = 14, + CLUSTER_NATIVE_MC = 15, + TPC_DIGIT_MC = 16, + TRD_SPACEPOINT = 17, + TRD_TRIGGERRECORDS = 18, + TF_SETTINGS = 19 }; static constexpr const char* const IOTYPENAMES[] = {"TPC HLT Clusters", "TPC Slice Tracks", "TPC Slice Track Clusters", "TPC Cluster MC Labels", "TPC Track MC Informations", "TPC Tracks", "TPC Track Clusters", "TRD Tracks", "TRD Tracklets", "TPC Raw Clusters", "TPC Native Clusters", "TRD Tracklet MC Labels", "TPC Compressed Clusters", "TPC Digit", "TPC ZS Page", "TPC Native Clusters MC Labels", "TPC Digit MC Labeels", "TRD Spacepoints", "TRD Triggerrecords", "TF Settings"}; - static unsigned int getNIOTypeMultiplicity(InOutPointerType type) { return (type == CLUSTER_DATA || type == SLICE_OUT_TRACK || type == SLICE_OUT_CLUSTER || type == RAW_CLUSTERS || type == TPC_DIGIT || type == TPC_DIGIT_MC) ? NSLICES : 1; } + static uint32_t getNIOTypeMultiplicity(InOutPointerType type) { return (type == CLUSTER_DATA || type == SLICE_OUT_TRACK || type == SLICE_OUT_CLUSTER || type == RAW_CLUSTERS || type == TPC_DIGIT || type == TPC_DIGIT_MC) ? NSLICES : 1; } // Functionality to create an instance of GPUReconstruction for the desired device static GPUReconstruction* CreateInstance(const GPUSettingsDeviceBackend& cfg); static GPUReconstruction* CreateInstance(DeviceType type = DeviceType::CPU, bool forceType = true, GPUReconstruction* master = nullptr); - static GPUReconstruction* CreateInstance(int type, bool forceType, GPUReconstruction* master = nullptr) { return CreateInstance((DeviceType)type, forceType, master); } + static GPUReconstruction* CreateInstance(int32_t type, bool forceType, GPUReconstruction* master = nullptr) { return CreateInstance((DeviceType)type, forceType, master); } static GPUReconstruction* CreateInstance(const char* type, bool forceType, GPUReconstruction* master = nullptr); static bool CheckInstanceAvailable(DeviceType type, bool verbose); - enum class krnlDeviceType : int { CPU = 0, - Device = 1, - Auto = -1 }; + enum class krnlDeviceType : int32_t { CPU = 0, + Device = 1, + Auto = -1 }; // Global steering functions template T* AddChain(Args... args); - int Init(); - int Finalize(); - int Exit(); + int32_t Init(); + int32_t Finalize(); + int32_t Exit(); void DumpSettings(const char* dir = ""); - int ReadSettings(const char* dir = ""); + int32_t ReadSettings(const char* dir = ""); void PrepareEvent(); - virtual int RunChains() = 0; - unsigned int getNEventsProcessed() { return mNEventsProcessed; } - unsigned int getNEventsProcessedInStat() { return mStatNEvents; } - int registerMemoryForGPU(const void* ptr, size_t size); - int unregisterMemoryForGPU(const void* ptr); + virtual int32_t RunChains() = 0; + uint32_t getNEventsProcessed() { return mNEventsProcessed; } + uint32_t getNEventsProcessedInStat() { return mStatNEvents; } + int32_t registerMemoryForGPU(const void* ptr, size_t size); + int32_t unregisterMemoryForGPU(const void* ptr); virtual void* getGPUPointer(void* ptr) { return ptr; } virtual void startGPUProfiling() {} virtual void endGPUProfiling() {} - int CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr); + int32_t CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr); void RunPipelineWorker(); void TerminatePipelineWorker(); // Helpers for memory allocation - GPUMemoryResource& Res(short num) { return mMemoryResources[num]; } + GPUMemoryResource& Res(int16_t num) { return mMemoryResources[num]; } template - short RegisterMemoryAllocation(T* proc, void* (T::*setPtr)(void*), int type, const char* name = "", const GPUMemoryReuse& re = GPUMemoryReuse()); + int16_t RegisterMemoryAllocation(T* proc, void* (T::*setPtr)(void*), int32_t type, const char* name = "", const GPUMemoryReuse& re = GPUMemoryReuse()); size_t AllocateMemoryResources(); size_t AllocateRegisteredMemory(GPUProcessor* proc, bool resetCustom = false); - size_t AllocateRegisteredMemory(short res, GPUOutputControl* control = nullptr); - void AllocateRegisteredForeignMemory(short res, GPUReconstruction* rec, GPUOutputControl* control = nullptr); - void* AllocateUnmanagedMemory(size_t size, int type); + size_t AllocateRegisteredMemory(int16_t res, GPUOutputControl* control = nullptr); + void AllocateRegisteredForeignMemory(int16_t res, GPUReconstruction* rec, GPUOutputControl* control = nullptr); + void* AllocateUnmanagedMemory(size_t size, int32_t type); void* AllocateVolatileDeviceMemory(size_t size); void* AllocateVolatileMemory(size_t size, bool device); void FreeRegisteredMemory(GPUProcessor* proc, bool freeCustom = false, bool freePermanent = false); - void FreeRegisteredMemory(short res); + void FreeRegisteredMemory(int16_t res); void ClearAllocatedMemory(bool clearOutputs = true); void ReturnVolatileDeviceMemory(); void ReturnVolatileMemory(); - void PushNonPersistentMemory(unsigned long tag); - void PopNonPersistentMemory(RecoStep step, unsigned long tag); + void PushNonPersistentMemory(uint64_t tag); + void PopNonPersistentMemory(RecoStep step, uint64_t tag); void BlockStackedMemory(GPUReconstruction* rec); void UnblockStackedMemory(); void ResetRegisteredMemoryPointers(GPUProcessor* proc); - void ResetRegisteredMemoryPointers(short res); + void ResetRegisteredMemoryPointers(int16_t res); void ComputeReuseMax(GPUProcessor* proc); void PrintMemoryStatistics(); void PrintMemoryOverview(); void PrintMemoryMax(); - void SetMemoryExternalInput(short res, void* ptr); + void SetMemoryExternalInput(int16_t res, void* ptr); GPUMemorySizeScalers* MemoryScalers() { return mMemoryScalers.get(); } // Helpers to fetch processors from other shared libraries @@ -199,26 +199,26 @@ class GPUReconstruction void SetSettings(float solenoidBzNominalGPU, const GPURecoStepConfiguration* workflow = nullptr); void SetSettings(const GPUSettingsGRP* grp, const GPUSettingsRec* rec = nullptr, const GPUSettingsProcessing* proc = nullptr, const GPURecoStepConfiguration* workflow = nullptr); void SetResetTimers(bool reset) { mProcessingSettings.resetTimers = reset; } // May update also after Init() - void SetDebugLevelTmp(int level) { mProcessingSettings.debugLevel = level; } // Temporarily, before calling SetSettings() + void SetDebugLevelTmp(int32_t level) { mProcessingSettings.debugLevel = level; } // Temporarily, before calling SetSettings() void UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p = nullptr); void SetOutputControl(const GPUOutputControl& v) { mOutputControl = v; } void SetOutputControl(void* ptr, size_t size); void SetInputControl(void* ptr, size_t size); GPUOutputControl& OutputControl() { return mOutputControl; } - int GetMaxThreads() const { return mMaxThreads; } - int SetNOMPThreads(int n); - int NStreams() const { return mNStreams; } + int32_t GetMaxThreads() const { return mMaxThreads; } + int32_t SetNOMPThreads(int32_t n); + int32_t NStreams() const { return mNStreams; } const void* DeviceMemoryBase() const { return mDeviceMemoryBase; } RecoStepField GetRecoSteps() const { return mRecoSteps.steps; } RecoStepField GetRecoStepsGPU() const { return mRecoSteps.stepsGPUMask; } InOutTypeField GetRecoStepsInputs() const { return mRecoSteps.inputs; } InOutTypeField GetRecoStepsOutputs() const { return mRecoSteps.outputs; } - int getRecoStepNum(RecoStep step, bool validCheck = true); - int getGeneralStepNum(GeneralStep step, bool validCheck = true); + int32_t getRecoStepNum(RecoStep step, bool validCheck = true); + int32_t getGeneralStepNum(GeneralStep step, bool validCheck = true); - void setErrorCodeOutput(std::vector>* v) { mOutputErrorCodes = v; } - std::vector>* getErrorCodeOutput() { return mOutputErrorCodes; } + void setErrorCodeOutput(std::vector>* v) { mOutputErrorCodes = v; } + std::vector>* getErrorCodeOutput() { return mOutputErrorCodes; } // Registration of GPU Processors template @@ -237,20 +237,20 @@ class GPUReconstruction void AllocateRegisteredMemoryInternal(GPUMemoryResource* res, GPUOutputControl* control, GPUReconstruction* recPool); void FreeRegisteredMemory(GPUMemoryResource* res); GPUReconstruction(const GPUSettingsDeviceBackend& cfg); // Constructor - int InitPhaseBeforeDevice(); + int32_t InitPhaseBeforeDevice(); virtual void UpdateAutomaticProcessingSettings() {} - virtual int InitDevice() = 0; - int InitPhasePermanentMemory(); - int InitPhaseAfterDevice(); + virtual int32_t InitDevice() = 0; + int32_t InitPhasePermanentMemory(); + int32_t InitPhaseAfterDevice(); void WriteConstantParams(); - virtual int ExitDevice() = 0; - virtual size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream = -1, gpu_reconstruction_kernels::deviceEvent* ev = nullptr) = 0; + virtual int32_t ExitDevice() = 0; + virtual size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, gpu_reconstruction_kernels::deviceEvent* ev = nullptr) = 0; void UpdateMaxMemoryUsed(); - int EnqueuePipeline(bool terminate = false); + int32_t EnqueuePipeline(bool terminate = false); GPUChain* GetNextChainInQueue(); - virtual int registerMemoryForGPU_internal(const void* ptr, size_t size) = 0; - virtual int unregisterMemoryForGPU_internal(const void* ptr) = 0; + virtual int32_t registerMemoryForGPU_internal(const void* ptr, size_t size) = 0; + virtual int32_t unregisterMemoryForGPU_internal(const void* ptr) = 0; // Management for GPU thread contexts class GPUThreadContext @@ -270,7 +270,7 @@ class GPUReconstruction // Private helper functions for reading / writing / allocating IO buffer from/to file template - unsigned int DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type); + uint32_t DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type); template size_t ReadData(FILE* fp, const T** entries, S* num, std::unique_ptr* mem, InOutPointerType type, T** nonConstPtrs = nullptr); template @@ -286,7 +286,7 @@ class GPUReconstruction template std::unique_ptr ReadStructFromFile(const char* file); template - int ReadStructFromFile(const char* file, T* obj); + int32_t ReadStructFromFile(const char* file, T* obj); // Others virtual RecoStepField AvailableGPURecoSteps() { return RecoStep::AllRecoSteps; } @@ -335,18 +335,18 @@ class GPUReconstruction // Others bool mInitialized = false; - unsigned int mStatNEvents = 0; - unsigned int mNEventsProcessed = 0; + uint32_t mStatNEvents = 0; + uint32_t mNEventsProcessed = 0; double mStatKernelTime = 0.; double mStatWallTime = 0.; std::shared_ptr mROOTDump; - std::vector>* mOutputErrorCodes = nullptr; + std::vector>* mOutputErrorCodes = nullptr; - int mMaxThreads = 0; // Maximum number of threads that may be running, on CPU or GPU - int mThreadId = -1; // Thread ID that is valid for the local CUDA context - int mGPUStuck = 0; // Marks that the GPU is stuck, skip future events - int mNStreams = 1; // Number of parallel GPU streams - int mMaxOMPThreads = 0; // Maximum number of OMP threads + int32_t mMaxThreads = 0; // Maximum number of threads that may be running, on CPU or GPU + int32_t mThreadId = -1; // Thread ID that is valid for the local CUDA context + int32_t mGPUStuck = 0; // Marks that the GPU is stuck, skip future events + int32_t mNStreams = 1; // Number of parallel GPU streams + int32_t mMaxOMPThreads = 0; // Maximum number of OMP threads // Management for GPUProcessors struct ProcessorData { @@ -359,12 +359,12 @@ class GPUReconstruction std::vector mProcessors; struct MemoryReuseMeta { MemoryReuseMeta() = default; - MemoryReuseMeta(GPUProcessor* p, unsigned short r) : proc(p), res{r} {} + MemoryReuseMeta(GPUProcessor* p, uint16_t r) : proc(p), res{r} {} GPUProcessor* proc = nullptr; - std::vector res; + std::vector res; }; std::unordered_map mMemoryReuse1to1; - std::vector> mNonPersistentMemoryStack; + std::vector> mNonPersistentMemoryStack; std::vector mNonPersistentIndividualAllocations; std::unique_ptr mPipelineContext; @@ -380,8 +380,8 @@ class GPUReconstruction private: friend class GPUReconstruction; LibraryLoader(const char* lib, const char* func); - int LoadLibrary(); - int CloseLibrary(); + int32_t LoadLibrary(); + int32_t CloseLibrary(); GPUReconstruction* GetPtr(const GPUSettingsDeviceBackend& cfg); const char* mLibName; @@ -414,7 +414,7 @@ inline T* GPUReconstruction::AllocateIOMemoryHelper(size_t n, const T*& ptr, std retVal = u.get(); if (mProcessingSettings.registerStandaloneInputMemory) { if (registerMemoryForGPU(u.get(), n * sizeof(T))) { - GPUError("Error registering memory for GPU: %p - %ld bytes\n", (void*)u.get(), (long)(n * sizeof(T))); + GPUError("Error registering memory for GPU: %p - %ld bytes\n", (void*)u.get(), (int64_t)(n * sizeof(T))); throw std::bad_alloc(); } } @@ -431,7 +431,7 @@ inline T* GPUReconstruction::AddChain(Args... args) } template -inline short GPUReconstruction::RegisterMemoryAllocation(T* proc, void* (T::*setPtr)(void*), int type, const char* name, const GPUMemoryReuse& re) +inline int16_t GPUReconstruction::RegisterMemoryAllocation(T* proc, void* (T::*setPtr)(void*), int32_t type, const char* name, const GPUMemoryReuse& re) { if (!(type & (GPUMemoryResource::MEMORY_HOST | GPUMemoryResource::MEMORY_GPU))) { if ((type & GPUMemoryResource::MEMORY_SCRATCH) && !mProcessingSettings.keepDisplayMemory) { // keepAllMemory --> keepDisplayMemory @@ -447,7 +447,7 @@ inline short GPUReconstruction::RegisterMemoryAllocation(T* proc, void* (T::*set if (mMemoryResources.size() >= 32768) { throw std::bad_alloc(); } - unsigned short retVal = mMemoryResources.size() - 1; + uint16_t retVal = mMemoryResources.size() - 1; if (re.type != GPUMemoryReuse::NONE && !mProcessingSettings.disableMemoryReuse) { const auto& it = mMemoryReuse1to1.find(re.id); if (it == mMemoryReuse1to1.end()) { @@ -487,25 +487,25 @@ inline void GPUReconstruction::SetupGPUProcessor(T* proc, bool allocate) } template -inline unsigned int GPUReconstruction::DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type) +inline uint32_t GPUReconstruction::DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type) { - int count = getNIOTypeMultiplicity(type); - unsigned int numTotal = 0; - for (int i = 0; i < count; i++) { + int32_t count = getNIOTypeMultiplicity(type); + uint32_t numTotal = 0; + for (int32_t i = 0; i < count; i++) { numTotal += num[i]; } if (numTotal == 0) { return 0; } fwrite(&type, sizeof(type), 1, fp); - for (int i = 0; i < count; i++) { + for (int32_t i = 0; i < count; i++) { fwrite(&num[i], sizeof(num[i]), 1, fp); if (num[i]) { fwrite(entries[i], sizeof(*entries[i]), num[i], fp); } } if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Dumped %ld %s", (long)numTotal, IOTYPENAMES[type]); + GPUInfo("Dumped %ld %s", (int64_t)numTotal, IOTYPENAMES[type]); } return numTotal; } @@ -524,9 +524,9 @@ inline size_t GPUReconstruction::ReadData(FILE* fp, const T** entries, S* num, s return 0; } - int count = getNIOTypeMultiplicity(type); + int32_t count = getNIOTypeMultiplicity(type); size_t numTotal = 0; - for (int i = 0; i < count; i++) { + for (int32_t i = 0; i < count; i++) { r = fread(&num[i], sizeof(num[i]), 1, fp); T* m = AllocateIOMemoryHelper(num[i], entries[i], mem[i]); if (nonConstPtrs) { @@ -539,7 +539,7 @@ inline size_t GPUReconstruction::ReadData(FILE* fp, const T** entries, S* num, s } (void)r; if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %ld %s", (long)numTotal, IOTYPENAMES[type]); + GPUInfo("Read %ld %s", (int64_t)numTotal, IOTYPENAMES[type]); } return numTotal; } @@ -569,7 +569,7 @@ inline std::unique_ptr GPUReconstruction::ReadFlatObjectFromFile(const char* r = fread(size, sizeof(size[0]), 2, fp); if (r == 0 || size[0] != sizeof(T)) { fclose(fp); - GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (long)size[0], (long)sizeof(T)); + GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (int64_t)size[0], (int64_t)sizeof(T)); throw std::runtime_error("invalid size"); } std::unique_ptr retVal(new T); @@ -579,7 +579,7 @@ inline std::unique_ptr GPUReconstruction::ReadFlatObjectFromFile(const char* r = fread(buf, 1, size[1], fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %ld bytes from %s", (long)r, file); + GPUInfo("Read %ld bytes from %s", (int64_t)r, file); } retVal->clearInternalBufferPtr(); retVal->setActualBufferAddress(buf); @@ -611,20 +611,20 @@ inline std::unique_ptr GPUReconstruction::ReadStructFromFile(const char* file r = fread(&size, sizeof(size), 1, fp); if (r == 0 || size != sizeof(T)) { fclose(fp); - GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (long)size, (long)sizeof(T)); + GPUError("ERROR reading %s, invalid size: %ld (%ld expected)", file, (int64_t)size, (int64_t)sizeof(T)); throw std::runtime_error("invalid size"); } std::unique_ptr newObj(new T); r = fread(newObj.get(), 1, size, fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %ld bytes from %s", (long)r, file); + GPUInfo("Read %ld bytes from %s", (int64_t)r, file); } return newObj; } template -inline int GPUReconstruction::ReadStructFromFile(const char* file, T* obj) +inline int32_t GPUReconstruction::ReadStructFromFile(const char* file, T* obj) { FILE* fp = fopen(file, "rb"); if (fp == nullptr) { @@ -639,7 +639,7 @@ inline int GPUReconstruction::ReadStructFromFile(const char* file, T* obj) r = fread(obj, 1, size, fp); fclose(fp); if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Read %ld bytes from %s", (long)r, file); + GPUInfo("Read %ld bytes from %s", (int64_t)r, file); } return 0; } diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index abdaab020179a..6fcceded9826d 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -43,8 +43,8 @@ #if defined(WITH_OPENMP) || defined(_OPENMP) #include #else -static inline int omp_get_thread_num() { return 0; } -static inline int omp_get_max_threads() { return 1; } +static inline int32_t omp_get_thread_num() { return 0; } +static inline int32_t omp_get_max_threads() { return 1; } #endif using namespace GPUCA_NAMESPACE::gpu; @@ -60,8 +60,8 @@ GPUReconstructionCPU::~GPUReconstructionCPU() Exit(); // Needs to be identical to GPU backend bahavior in order to avoid calling abstract methods later in the destructor } -template -inline int GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetupTime& _xyz, const Args&... args) +template +inline int32_t GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetupTime& _xyz, const Args&... args) { auto& x = _xyz.x; auto& y = _xyz.y; @@ -71,12 +71,12 @@ inline int GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetup if (x.nThreads != 1) { throw std::runtime_error("Cannot run device kernel on host with nThreads != 1"); } - unsigned int num = y.num == 0 || y.num == -1 ? 1 : y.num; - for (unsigned int k = 0; k < num; k++) { - int ompThreads = 0; + uint32_t num = y.num == 0 || y.num == -1 ? 1 : y.num; + for (uint32_t k = 0; k < num; k++) { + int32_t ompThreads = 0; if (mProcessingSettings.ompKernels == 2) { ompThreads = mProcessingSettings.ompThreads / mNestedLoopOmpFactor; - if ((unsigned int)getOMPThreadNum() < mProcessingSettings.ompThreads % mNestedLoopOmpFactor) { + if ((uint32_t)getOMPThreadNum() < mProcessingSettings.ompThreads % mNestedLoopOmpFactor) { ompThreads++; } ompThreads = std::max(1, ompThreads); @@ -88,12 +88,12 @@ inline int GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetup printf("Running %d ompThreads\n", ompThreads); } GPUCA_OPENMP(parallel for num_threads(ompThreads)) - for (unsigned int iB = 0; iB < x.nBlocks; iB++) { + for (uint32_t iB = 0; iB < x.nBlocks; iB++) { typename T::GPUSharedMemory smem; T::template Thread
(x.nBlocks, 1, iB, 0, smem, T::Processor(*mHostConstantMem)[y.start + k], args...); } } else { - for (unsigned int iB = 0; iB < x.nBlocks; iB++) { + for (uint32_t iB = 0; iB < x.nBlocks; iB++) { typename T::GPUSharedMemory smem; T::template Thread(x.nBlocks, 1, iB, 0, smem, T::Processor(*mHostConstantMem)[y.start + k], args...); } @@ -103,45 +103,45 @@ inline int GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetup } template <> -inline int GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetupTime& _xyz, void* const& ptr, unsigned long const& size) +inline int32_t GPUReconstructionCPUBackend::runKernelBackendInternal(const krnlSetupTime& _xyz, void* const& ptr, uint64_t const& size) { memset(ptr, 0, size); return 0; } -template -int GPUReconstructionCPUBackend::runKernelBackend(const krnlSetupArgs& args) +template +int32_t GPUReconstructionCPUBackend::runKernelBackend(const krnlSetupArgs& args) { return std::apply([this, &args](auto&... vals) { return runKernelBackendInternal(args.s, vals...); }, args.v); } -template +template krnlProperties GPUReconstructionCPUBackend::getKernelPropertiesBackend() { return krnlProperties{1, 1}; } -#define GPUCA_KRNL(x_class, x_attributes, x_arguments, x_forward, x_types) \ - template int GPUReconstructionCPUBackend::runKernelBackend(const krnlSetupArgs& args); \ +#define GPUCA_KRNL(x_class, x_attributes, x_arguments, x_forward, x_types) \ + template int32_t GPUReconstructionCPUBackend::runKernelBackend(const krnlSetupArgs& args); \ template krnlProperties GPUReconstructionCPUBackend::getKernelPropertiesBackend(); #include "GPUReconstructionKernelList.h" #undef GPUCA_KRNL -size_t GPUReconstructionCPU::TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) { return 0; } -size_t GPUReconstructionCPU::GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev, deviceEvent* evList, int nEvents) { return 0; } -size_t GPUReconstructionCPU::GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev, deviceEvent* evList, int nEvents) +size_t GPUReconstructionCPU::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) { return 0; } +size_t GPUReconstructionCPU::GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev, deviceEvent* evList, int32_t nEvents) { return 0; } +size_t GPUReconstructionCPU::GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev, deviceEvent* evList, int32_t nEvents) { memcpy(dst, src, size); return 0; } -size_t GPUReconstructionCPU::WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream, deviceEvent* ev) { return 0; } -int GPUReconstructionCPU::GPUDebug(const char* state, int stream, bool force) { return 0; } -size_t GPUReconstructionCPU::TransferMemoryResourcesHelper(GPUProcessor* proc, int stream, bool all, bool toGPU) +size_t GPUReconstructionCPU::WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream, deviceEvent* ev) { return 0; } +int32_t GPUReconstructionCPU::GPUDebug(const char* state, int32_t stream, bool force) { return 0; } +size_t GPUReconstructionCPU::TransferMemoryResourcesHelper(GPUProcessor* proc, int32_t stream, bool all, bool toGPU) { - int inc = toGPU ? GPUMemoryResource::MEMORY_INPUT_FLAG : GPUMemoryResource::MEMORY_OUTPUT_FLAG; - int exc = toGPU ? GPUMemoryResource::MEMORY_OUTPUT_FLAG : GPUMemoryResource::MEMORY_INPUT_FLAG; + int32_t inc = toGPU ? GPUMemoryResource::MEMORY_INPUT_FLAG : GPUMemoryResource::MEMORY_OUTPUT_FLAG; + int32_t exc = toGPU ? GPUMemoryResource::MEMORY_OUTPUT_FLAG : GPUMemoryResource::MEMORY_INPUT_FLAG; size_t n = 0; - for (unsigned int i = 0; i < mMemoryResources.size(); i++) { + for (uint32_t i = 0; i < mMemoryResources.size(); i++) { GPUMemoryResource& res = mMemoryResources[i]; if (res.mPtr == nullptr) { continue; @@ -164,19 +164,19 @@ size_t GPUReconstructionCPU::TransferMemoryResourcesHelper(GPUProcessor* proc, i return n; } -int GPUReconstructionCPU::GetThread() +int32_t GPUReconstructionCPU::GetThread() { // Get Thread ID #if defined(__APPLE__) return (0); // syscall is deprecated on MacOS..., only needed for GPU support which we don't do on Mac anyway #elif defined(_WIN32) - return ((int)(size_t)GetCurrentThread()); + return ((int32_t)(size_t)GetCurrentThread()); #else - return ((int)syscall(SYS_gettid)); + return ((int32_t)syscall(SYS_gettid)); #endif } -int GPUReconstructionCPU::InitDevice() +int32_t GPUReconstructionCPU::InitDevice() { if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { if (mMaster == nullptr) { @@ -196,7 +196,7 @@ int GPUReconstructionCPU::InitDevice() return 0; } -int GPUReconstructionCPU::ExitDevice() +int32_t GPUReconstructionCPU::ExitDevice() { if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { if (mMaster == nullptr) { @@ -208,7 +208,7 @@ int GPUReconstructionCPU::ExitDevice() return 0; } -int GPUReconstructionCPU::RunChains() +int32_t GPUReconstructionCPU::RunChains() { mMemoryScalers->temporaryFactor = 1.; mStatNEvents++; @@ -229,8 +229,8 @@ int GPUReconstructionCPU::RunChains() if (mSlaves.size() || mMaster) { WriteConstantParams(); // Reinitialize } - for (unsigned int i = 0; i < mChains.size(); i++) { - int retVal = mChains[i]->RunChain(); + for (uint32_t i = 0; i < mChains.size(); i++) { + int32_t retVal = mChains[i]->RunChain(); if (retVal) { return retVal; } @@ -247,12 +247,12 @@ int GPUReconstructionCPU::RunChains() double kernelTotal = 0; std::vector kernelStepTimes(GPUDataTypes::N_RECO_STEPS); - for (unsigned int i = 0; i < mTimers.size(); i++) { + for (uint32_t i = 0; i < mTimers.size(); i++) { double time = 0; if (mTimers[i] == nullptr) { continue; } - for (int j = 0; j < mTimers[i]->num; j++) { + for (int32_t j = 0; j < mTimers[i]->num; j++) { HighResTimer& timer = mTimers[i]->timer[j]; time += timer.GetElapsedTime(); if (mProcessingSettings.resetTimers) { @@ -260,33 +260,32 @@ int GPUReconstructionCPU::RunChains() } } - char type = mTimers[i]->type; + uint32_t type = mTimers[i]->type; if (type == 0) { kernelTotal += time; - int stepNum = getRecoStepNum(mTimers[i]->step); + int32_t stepNum = getRecoStepNum(mTimers[i]->step); kernelStepTimes[stepNum] += time; } - type = type == 0 ? 'K' : 'C'; char bandwidth[256] = ""; if (mTimers[i]->memSize && mStatNEvents && time != 0.) { - snprintf(bandwidth, 256, " (%6.3f GB/s - %'14lu bytes)", mTimers[i]->memSize / time * 1e-9, (unsigned long)(mTimers[i]->memSize / mStatNEvents)); + snprintf(bandwidth, 256, " (%6.3f GB/s - %'14lu bytes)", mTimers[i]->memSize / time * 1e-9, (uint64_t)(mTimers[i]->memSize / mStatNEvents)); } - printf("Execution Time: Task (%c %8ux): %50s Time: %'10lu us%s\n", type, mTimers[i]->count, mTimers[i]->name.c_str(), (unsigned long)(time * 1000000 / mStatNEvents), bandwidth); + printf("Execution Time: Task (%c %8ux): %50s Time: %'10lu us%s\n", type == 0 ? 'K' : 'C', mTimers[i]->count, mTimers[i]->name.c_str(), (uint64_t)(time * 1000000 / mStatNEvents), bandwidth); if (mProcessingSettings.resetTimers) { mTimers[i]->count = 0; mTimers[i]->memSize = 0; } } - for (int i = 0; i < GPUDataTypes::N_RECO_STEPS; i++) { + for (int32_t i = 0; i < GPUDataTypes::N_RECO_STEPS; i++) { if (kernelStepTimes[i] != 0. || mTimersRecoSteps[i].timerTotal.GetElapsedTime() != 0.) { - printf("Execution Time: Step : %11s %38s Time: %'10lu us ( Total Time : %'14lu us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(kernelStepTimes[i] * 1000000 / mStatNEvents), (unsigned long)(mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: Step : %11s %38s Time: %'10lu us ( Total Time : %'14lu us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(kernelStepTimes[i] * 1000000 / mStatNEvents), (uint64_t)(mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents)); } if (mTimersRecoSteps[i].bytesToGPU) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents), mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToGPU / mStatNEvents, mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].countToGPU); } if (mTimersRecoSteps[i].bytesToHost) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], (unsigned long)(mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents), mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToHost / mStatNEvents, mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].countToHost); } if (mProcessingSettings.resetTimers) { @@ -298,16 +297,16 @@ int GPUReconstructionCPU::RunChains() mTimersRecoSteps[i].countToHost = 0; } } - for (int i = 0; i < GPUDataTypes::N_GENERAL_STEPS; i++) { + for (int32_t i = 0; i < GPUDataTypes::N_GENERAL_STEPS; i++) { if (mTimersGeneralSteps[i].GetElapsedTime() != 0.) { - printf("Execution Time: General Step : %50s Time: %'10lu us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], (unsigned long)(mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: General Step : %50s Time: %'10lu us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], (uint64_t)(mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents)); } } mStatKernelTime = kernelTotal * 1000000 / mStatNEvents; - printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Kernel", (unsigned long)mStatKernelTime, nEventReport.c_str()); - printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Wall", (unsigned long)mStatWallTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Kernel", (uint64_t)mStatKernelTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Wall", (uint64_t)mStatWallTime, nEventReport.c_str()); } else if (GetProcessingSettings().debugLevel >= 0) { - GPUInfo("Total Wall Time: %lu us%s", (unsigned long)mStatWallTime, nEventReport.c_str()); + GPUInfo("Total Wall Time: %lu us%s", (uint64_t)mStatWallTime, nEventReport.c_str()); } if (mProcessingSettings.resetTimers) { mStatNEvents = 0; @@ -319,26 +318,26 @@ int GPUReconstructionCPU::RunChains() void GPUReconstructionCPU::ResetDeviceProcessorTypes() { - for (unsigned int i = 0; i < mProcessors.size(); i++) { + for (uint32_t i = 0; i < mProcessors.size(); i++) { if (mProcessors[i].proc->mGPUProcessorType != GPUProcessor::PROCESSOR_TYPE_DEVICE && mProcessors[i].proc->mLinkedProcessor) { mProcessors[i].proc->mLinkedProcessor->InitGPUProcessor(this, GPUProcessor::PROCESSOR_TYPE_DEVICE); } } } -int GPUReconstructionCPUBackend::getOMPThreadNum() +int32_t GPUReconstructionCPUBackend::getOMPThreadNum() { return omp_get_thread_num(); } -int GPUReconstructionCPUBackend::getOMPMaxThreads() +int32_t GPUReconstructionCPUBackend::getOMPMaxThreads() { return omp_get_max_threads(); } static std::atomic_flag timerFlag = ATOMIC_FLAG_INIT; // TODO: Should be a class member not global, but cannot be moved to header due to ROOT limitation -GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::insertTimer(unsigned int id, std::string&& name, int J, int num, int type, RecoStep step) +GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::insertTimer(uint32_t id, std::string&& name, int32_t J, int32_t num, int32_t type, RecoStep step) { while (timerFlag.test_and_set()) { } @@ -358,7 +357,7 @@ GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::insertTimer(unsigned int return retVal; } -GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::getTimerById(unsigned int id) +GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::getTimerById(uint32_t id) { timerMeta* retVal = nullptr; while (timerFlag.test_and_set()) { @@ -372,16 +371,16 @@ GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::getTimerById(unsigned int return retVal; } -unsigned int GPUReconstructionCPU::getNextTimerId() +uint32_t GPUReconstructionCPU::getNextTimerId() { - static std::atomic id{0}; + static std::atomic id{0}; return id.fetch_add(1); } -unsigned int GPUReconstructionCPU::SetAndGetNestedLoopOmpFactor(bool condition, unsigned int max) +uint32_t GPUReconstructionCPU::SetAndGetNestedLoopOmpFactor(bool condition, uint32_t max) { if (condition && mProcessingSettings.ompKernels != 1) { - mNestedLoopOmpFactor = mProcessingSettings.ompKernels == 2 ? std::min(max, mProcessingSettings.ompThreads) : mProcessingSettings.ompThreads; + mNestedLoopOmpFactor = mProcessingSettings.ompKernels == 2 ? std::min(max, mProcessingSettings.ompThreads) : mProcessingSettings.ompThreads; } else { mNestedLoopOmpFactor = 1; } @@ -391,7 +390,7 @@ unsigned int GPUReconstructionCPU::SetAndGetNestedLoopOmpFactor(bool condition, return mNestedLoopOmpFactor; } -void GPUReconstructionCPU::UpdateParamOccupancyMap(const unsigned int* mapHost, const unsigned int* mapGPU, unsigned int occupancyTotal, int stream) +void GPUReconstructionCPU::UpdateParamOccupancyMap(const uint32_t* mapHost, const uint32_t* mapGPU, uint32_t occupancyTotal, int32_t stream) { param().occupancyMap = mapHost; param().occupancyTotal = occupancyTotal; diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index 378743dc8ef0c..6ac393b1e2aac 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -38,15 +38,15 @@ class GPUReconstructionCPUBackend : public GPUReconstruction protected: GPUReconstructionCPUBackend(const GPUSettingsDeviceBackend& cfg) : GPUReconstruction(cfg) {} - template - int runKernelBackend(const gpu_reconstruction_kernels::krnlSetupArgs& args); - template - int runKernelBackendInternal(const gpu_reconstruction_kernels::krnlSetupTime& _xyz, const Args&... args); - template + template + int32_t runKernelBackend(const gpu_reconstruction_kernels::krnlSetupArgs& args); + template + int32_t runKernelBackendInternal(const gpu_reconstruction_kernels::krnlSetupTime& _xyz, const Args&... args); + template gpu_reconstruction_kernels::krnlProperties getKernelPropertiesBackend(); - unsigned int mNestedLoopOmpFactor = 1; - static int getOMPThreadNum(); - static int getOMPMaxThreads(); + uint32_t mNestedLoopOmpFactor = 1; + static int32_t getOMPThreadNum(); + static int32_t getOMPMaxThreads(); }; class GPUReconstructionCPU : public GPUReconstructionKernels @@ -59,104 +59,104 @@ class GPUReconstructionCPU : public GPUReconstructionKernels - int runKernel(krnlSetup&& setup, Args&&... args); - template + template + int32_t runKernel(krnlSetup&& setup, Args&&... args); + template const gpu_reconstruction_kernels::krnlProperties getKernelProperties() { return getKernelPropertiesImpl(gpu_reconstruction_kernels::classArgument()); } - template + template constexpr static const char* GetKernelName(); - virtual int GPUDebug(const char* state = "UNKNOWN", int stream = -1, bool force = false); - int GPUStuck() { return mGPUStuck; } + virtual int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1, bool force = false); + int32_t GPUStuck() { return mGPUStuck; } void ResetDeviceProcessorTypes(); template void AddGPUEvents(T*& events); - int RunChains() override; + int32_t RunChains() override; HighResTimer& getRecoStepTimer(RecoStep step) { return mTimersRecoSteps[getRecoStepNum(step)].timerTotal; } HighResTimer& getGeneralStepTimer(GeneralStep step) { return mTimersGeneralSteps[getGeneralStepNum(step)]; } - void SetNestedLoopOmpFactor(unsigned int f) { mNestedLoopOmpFactor = f; } - unsigned int SetAndGetNestedLoopOmpFactor(bool condition, unsigned int max); + void SetNestedLoopOmpFactor(uint32_t f) { mNestedLoopOmpFactor = f; } + uint32_t SetAndGetNestedLoopOmpFactor(bool condition, uint32_t max); - void UpdateParamOccupancyMap(const unsigned int* mapHost, const unsigned int* mapGPU, unsigned int occupancyTotal, int stream = -1); + void UpdateParamOccupancyMap(const uint32_t* mapHost, const uint32_t* mapGPU, uint32_t occupancyTotal, int32_t stream = -1); protected: struct GPUProcessorProcessors : public GPUProcessor { GPUConstantMem* mProcessorsProc = nullptr; void* SetPointersDeviceProcessor(void* mem); - short mMemoryResProcessors = -1; + int16_t mMemoryResProcessors = -1; }; GPUReconstructionCPU(const GPUSettingsDeviceBackend& cfg) : GPUReconstructionKernels(cfg) {} -#define GPUCA_KRNL(x_class, attributes, x_arguments, x_forward, x_types) \ - inline int runKernelImplWrapper(gpu_reconstruction_kernels::classArgument, bool cpuFallback, double& timer, krnlSetup&& setup GPUCA_M_STRIP(x_arguments)) \ - { \ - if (cpuFallback) { \ - return GPUReconstructionCPU::runKernelImpl(krnlSetupArgs(setup.x, setup.y, setup.z, timer GPUCA_M_STRIP(x_forward))); \ - } else { \ - return runKernelImpl(krnlSetupArgs(setup.x, setup.y, setup.z, timer GPUCA_M_STRIP(x_forward))); \ - } \ +#define GPUCA_KRNL(x_class, attributes, x_arguments, x_forward, x_types) \ + inline int32_t runKernelImplWrapper(gpu_reconstruction_kernels::classArgument, bool cpuFallback, double& timer, krnlSetup&& setup GPUCA_M_STRIP(x_arguments)) \ + { \ + if (cpuFallback) { \ + return GPUReconstructionCPU::runKernelImpl(krnlSetupArgs(setup.x, setup.y, setup.z, timer GPUCA_M_STRIP(x_forward))); \ + } else { \ + return runKernelImpl(krnlSetupArgs(setup.x, setup.y, setup.z, timer GPUCA_M_STRIP(x_forward))); \ + } \ } #include "GPUReconstructionKernelList.h" #undef GPUCA_KRNL - int registerMemoryForGPU_internal(const void* ptr, size_t size) override { return 0; } - int unregisterMemoryForGPU_internal(const void* ptr) override { return 0; } + int32_t registerMemoryForGPU_internal(const void* ptr, size_t size) override { return 0; } + int32_t unregisterMemoryForGPU_internal(const void* ptr) override { return 0; } - virtual void SynchronizeStream(int stream) {} - virtual void SynchronizeEvents(deviceEvent* evList, int nEvents = 1) {} - virtual void StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents = 1) {} - virtual bool IsEventDone(deviceEvent* evList, int nEvents = 1) { return true; } - virtual void RecordMarker(deviceEvent ev, int stream) {} + virtual void SynchronizeStream(int32_t stream) {} + virtual void SynchronizeEvents(deviceEvent* evList, int32_t nEvents = 1) {} + virtual void StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents = 1) {} + virtual bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) { return true; } + virtual void RecordMarker(deviceEvent ev, int32_t stream) {} virtual void SynchronizeGPU() {} virtual void ReleaseEvent(deviceEvent ev) {} - virtual int StartHelperThreads() { return 0; } - virtual int StopHelperThreads() { return 0; } - virtual void RunHelperThreads(int (GPUReconstructionHelpers::helperDelegateBase::*function)(int, int, GPUReconstructionHelpers::helperParam*), GPUReconstructionHelpers::helperDelegateBase* functionCls, int count) {} + virtual int32_t StartHelperThreads() { return 0; } + virtual int32_t StopHelperThreads() { return 0; } + virtual void RunHelperThreads(int32_t (GPUReconstructionHelpers::helperDelegateBase::*function)(int32_t, int32_t, GPUReconstructionHelpers::helperParam*), GPUReconstructionHelpers::helperDelegateBase* functionCls, int32_t count) {} virtual void WaitForHelperThreads() {} - virtual int HelperError(int iThread) const { return 0; } - virtual int HelperDone(int iThread) const { return 0; } - virtual void ResetHelperThreads(int helpers) {} - - size_t TransferMemoryResourceToGPU(GPUMemoryResource* res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { return TransferMemoryInternal(res, stream, ev, evList, nEvents, true, res->Ptr(), res->PtrDevice()); } - size_t TransferMemoryResourceToHost(GPUMemoryResource* res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { return TransferMemoryInternal(res, stream, ev, evList, nEvents, false, res->PtrDevice(), res->Ptr()); } - size_t TransferMemoryResourcesToGPU(GPUProcessor* proc, int stream = -1, bool all = false) { return TransferMemoryResourcesHelper(proc, stream, all, true); } - size_t TransferMemoryResourcesToHost(GPUProcessor* proc, int stream = -1, bool all = false) { return TransferMemoryResourcesHelper(proc, stream, all, false); } - size_t TransferMemoryResourceLinkToGPU(short res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { return TransferMemoryResourceToGPU(&mMemoryResources[res], stream, ev, evList, nEvents); } - size_t TransferMemoryResourceLinkToHost(short res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { return TransferMemoryResourceToHost(&mMemoryResources[res], stream, ev, evList, nEvents); } - virtual size_t GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1); - virtual size_t GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1); - size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream = -1, deviceEvent* ev = nullptr) override; - virtual size_t TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst); - - int InitDevice() override; - int ExitDevice() override; - int GetThread(); - - virtual int PrepareTextures() { return 0; } - virtual int DoStuckProtection(int stream, deviceEvent event) { return 0; } + virtual int32_t HelperError(int32_t iThread) const { return 0; } + virtual int32_t HelperDone(int32_t iThread) const { return 0; } + virtual void ResetHelperThreads(int32_t helpers) {} + + size_t TransferMemoryResourceToGPU(GPUMemoryResource* res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { return TransferMemoryInternal(res, stream, ev, evList, nEvents, true, res->Ptr(), res->PtrDevice()); } + size_t TransferMemoryResourceToHost(GPUMemoryResource* res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { return TransferMemoryInternal(res, stream, ev, evList, nEvents, false, res->PtrDevice(), res->Ptr()); } + size_t TransferMemoryResourcesToGPU(GPUProcessor* proc, int32_t stream = -1, bool all = false) { return TransferMemoryResourcesHelper(proc, stream, all, true); } + size_t TransferMemoryResourcesToHost(GPUProcessor* proc, int32_t stream = -1, bool all = false) { return TransferMemoryResourcesHelper(proc, stream, all, false); } + size_t TransferMemoryResourceLinkToGPU(int16_t res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { return TransferMemoryResourceToGPU(&mMemoryResources[res], stream, ev, evList, nEvents); } + size_t TransferMemoryResourceLinkToHost(int16_t res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { return TransferMemoryResourceToHost(&mMemoryResources[res], stream, ev, evList, nEvents); } + virtual size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1); + virtual size_t GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1); + size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override; + virtual size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst); + + int32_t InitDevice() override; + int32_t ExitDevice() override; + int32_t GetThread(); + + virtual int32_t PrepareTextures() { return 0; } + virtual int32_t DoStuckProtection(int32_t stream, deviceEvent event) { return 0; } // Pointers to tracker classes GPUProcessorProcessors mProcShadow; // Host copy of tracker objects that will be used on the GPU GPUConstantMem*& mProcessorsShadow = mProcShadow.mProcessorsProc; - unsigned int mBlockCount = 1; - unsigned int mThreadCount = 1; - unsigned int mWarpSize = 1; + uint32_t mBlockCount = 1; + uint32_t mThreadCount = 1; + uint32_t mWarpSize = 1; struct timerMeta { std::unique_ptr timer; std::string name; - int num; // How many parallel instances to sum up (CPU threads / GPU streams) - int type; // 0 = kernel, 1 = CPU step, 2 = DMA transfer - unsigned int count; // How often was the timer queried + int32_t num; // How many parallel instances to sum up (CPU threads / GPU streams) + int32_t type; // 0 = kernel, 1 = CPU step, 2 = DMA transfer + uint32_t count; // How often was the timer queried RecoStep step; // Which RecoStep is this size_t memSize; // Memory size for memory bandwidth computation }; @@ -167,8 +167,8 @@ class GPUReconstructionCPU : public GPUReconstructionKernels> mTimers; RecoStepTimerMeta mTimersRecoSteps[GPUDataTypes::N_RECO_STEPS]; HighResTimer timerTotal; - template - HighResTimer& getKernelTimer(RecoStep step, int num = 0, size_t addMemorySize = 0); - template - HighResTimer& getTimer(const char* name, int num = -1); + template + HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0); + template + HighResTimer& getTimer(const char* name, int32_t num = -1); std::vector> mEvents; private: - size_t TransferMemoryResourcesHelper(GPUProcessor* proc, int stream, bool all, bool toGPU); - unsigned int getNextTimerId(); - timerMeta* getTimerById(unsigned int id); - timerMeta* insertTimer(unsigned int id, std::string&& name, int J, int num, int type, RecoStep step); + size_t TransferMemoryResourcesHelper(GPUProcessor* proc, int32_t stream, bool all, bool toGPU); + uint32_t getNextTimerId(); + timerMeta* getTimerById(uint32_t id); + timerMeta* insertTimer(uint32_t id, std::string&& name, int32_t J, int32_t num, int32_t type, RecoStep step); }; -template -inline int GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args) +template +inline int32_t GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args) { HighResTimer* t = nullptr; GPUCA_RECO_STEP myStep = S::GetRecoStep() == GPUCA_RECO_STEP::NoRecoStep ? setup.x.step : S::GetRecoStep(); if (myStep == GPUCA_RECO_STEP::NoRecoStep) { throw std::runtime_error("Failure running general kernel without defining RecoStep"); } - int cpuFallback = IsGPU() ? (setup.x.device == krnlDeviceType::CPU ? 2 : (mRecoSteps.stepsGPUMask & myStep) != myStep) : 0; - unsigned int& nThreads = setup.x.nThreads; - unsigned int& nBlocks = setup.x.nBlocks; - const unsigned int stream = setup.x.stream; + int32_t cpuFallback = IsGPU() ? (setup.x.device == krnlDeviceType::CPU ? 2 : (mRecoSteps.stepsGPUMask & myStep) != myStep) : 0; + uint32_t& nThreads = setup.x.nThreads; + uint32_t& nBlocks = setup.x.nBlocks; + const uint32_t stream = setup.x.stream; auto prop = getKernelProperties(); - const int autoThreads = cpuFallback ? 1 : prop.nThreads; - const int autoBlocks = cpuFallback ? 1 : (prop.forceBlocks ? prop.forceBlocks : (prop.minBlocks * mBlockCount)); - if (nBlocks == (unsigned int)-1) { + const int32_t autoThreads = cpuFallback ? 1 : prop.nThreads; + const int32_t autoBlocks = cpuFallback ? 1 : (prop.forceBlocks ? prop.forceBlocks : (prop.minBlocks * mBlockCount)); + if (nBlocks == (uint32_t)-1) { nBlocks = (nThreads + autoThreads - 1) / autoThreads; nThreads = autoThreads; - } else if (nBlocks == (unsigned int)-2) { + } else if (nBlocks == (uint32_t)-2) { nBlocks = nThreads; nThreads = autoThreads; - } else if (nBlocks == (unsigned int)-3) { + } else if (nBlocks == (uint32_t)-3) { nBlocks = autoBlocks; nThreads = autoThreads; - } else if ((int)nThreads < 0) { + } else if ((int32_t)nThreads < 0) { nThreads = cpuFallback ? 1 : -nThreads; } if (nThreads > GPUCA_MAX_THREADS) { @@ -233,7 +233,7 @@ inline int GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args) } } double deviceTimerTime = 0.; - int retVal = runKernelImplWrapper(gpu_reconstruction_kernels::classArgument(), cpuFallback, deviceTimerTime, std::forward(setup), std::forward(args)...); + int32_t retVal = runKernelImplWrapper(gpu_reconstruction_kernels::classArgument(), cpuFallback, deviceTimerTime, std::forward(setup), std::forward(args)...); if (GPUDebug(GetKernelName(), stream)) { throw std::runtime_error("kernel failure"); } @@ -271,10 +271,10 @@ inline void GPUReconstructionCPU::AddGPUEvents(T*& events) events = (T*)mEvents.back().data(); } -template -HighResTimer& GPUReconstructionCPU::getKernelTimer(RecoStep step, int num, size_t addMemorySize) +template +HighResTimer& GPUReconstructionCPU::getKernelTimer(RecoStep step, int32_t num, size_t addMemorySize) { - static int id = getNextTimerId(); + static int32_t id = getNextTimerId(); timerMeta* timer = getTimerById(id); if (timer == nullptr) { timer = insertTimer(id, GetKernelName(), -1, NSLICES, 0, step); @@ -288,13 +288,13 @@ HighResTimer& GPUReconstructionCPU::getKernelTimer(RecoStep step, int num, size_ return timer->timer[num]; } -template -HighResTimer& GPUReconstructionCPU::getTimer(const char* name, int num) +template +HighResTimer& GPUReconstructionCPU::getTimer(const char* name, int32_t num) { - static int id = getNextTimerId(); + static int32_t id = getNextTimerId(); timerMeta* timer = getTimerById(id); if (timer == nullptr) { - int max = std::max({getOMPMaxThreads(), mProcessingSettings.nDeviceHelperThreads + 1, mProcessingSettings.nStreams}); + int32_t max = std::max({getOMPMaxThreads(), mProcessingSettings.nDeviceHelperThreads + 1, mProcessingSettings.nStreams}); timer = insertTimer(id, name, J, max, 1, RecoStep::NoRecoStep); } if (num == -1) { diff --git a/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx b/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx index 7c8f3dc1cf1b3..03898d16d5105 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionConvert.cxx @@ -47,21 +47,21 @@ using namespace o2::tpc; using namespace o2::tpc::constants; using namespace std::string_literals; -void GPUReconstructionConvert::ConvertNativeToClusterData(o2::tpc::ClusterNativeAccess* native, std::unique_ptr* clusters, unsigned int* nClusters, const TPCFastTransform* transform, int continuousMaxTimeBin) +void GPUReconstructionConvert::ConvertNativeToClusterData(o2::tpc::ClusterNativeAccess* native, std::unique_ptr* clusters, uint32_t* nClusters, const TPCFastTransform* transform, int32_t continuousMaxTimeBin) { #ifdef GPUCA_HAVE_O2HEADERS memset(nClusters, 0, NSLICES * sizeof(nClusters[0])); - unsigned int offset = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - unsigned int nClSlice = 0; - for (int j = 0; j < GPUCA_ROW_COUNT; j++) { + uint32_t offset = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + uint32_t nClSlice = 0; + for (int32_t j = 0; j < GPUCA_ROW_COUNT; j++) { nClSlice += native->nClusters[i][j]; } nClusters[i] = nClSlice; clusters[i].reset(new GPUTPCClusterData[nClSlice]); nClSlice = 0; - for (int j = 0; j < GPUCA_ROW_COUNT; j++) { - for (unsigned int k = 0; k < native->nClusters[i][j]; k++) { + for (int32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t k = 0; k < native->nClusters[i][j]; k++) { const auto& clin = native->clusters[i][j][k]; float x = 0, y = 0, z = 0; if (continuousMaxTimeBin == 0) { @@ -86,12 +86,12 @@ void GPUReconstructionConvert::ConvertNativeToClusterData(o2::tpc::ClusterNative #endif } -void GPUReconstructionConvert::ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess& native, std::unique_ptr& nativeBuffer, const AliHLTTPCRawCluster** rawClusters, unsigned int* nRawClusters) +void GPUReconstructionConvert::ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess& native, std::unique_ptr& nativeBuffer, const AliHLTTPCRawCluster** rawClusters, uint32_t* nRawClusters) { #ifdef GPUCA_HAVE_O2HEADERS memset((void*)&native, 0, sizeof(native)); - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < nRawClusters[i]; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < nRawClusters[i]; j++) { native.nClusters[i][rawClusters[i][j].GetPadRow()]++; } native.nClustersTotal += nRawClusters[i]; @@ -99,13 +99,13 @@ void GPUReconstructionConvert::ConvertRun2RawToNative(o2::tpc::ClusterNativeAcce nativeBuffer.reset(new ClusterNative[native.nClustersTotal]); native.clustersLinear = nativeBuffer.get(); native.setOffsetPtrs(); - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { native.nClusters[i][j] = 0; } - for (unsigned int j = 0; j < nRawClusters[i]; j++) { + for (uint32_t j = 0; j < nRawClusters[i]; j++) { const AliHLTTPCRawCluster& org = rawClusters[i][j]; - int row = org.GetPadRow(); + int32_t row = org.GetPadRow(); ClusterNative& c = nativeBuffer[native.clusterOffset[i][row] + native.nClusters[i][row]++]; c.setTimeFlags(org.GetTime(), org.GetFlags()); c.setPad(org.GetPad()); @@ -118,13 +118,13 @@ void GPUReconstructionConvert::ConvertRun2RawToNative(o2::tpc::ClusterNativeAcce #endif } -int GPUReconstructionConvert::GetMaxTimeBin(const ClusterNativeAccess& native) +int32_t GPUReconstructionConvert::GetMaxTimeBin(const ClusterNativeAccess& native) { #ifdef GPUCA_HAVE_O2HEADERS float retVal = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - for (unsigned int k = 0; k < native.nClusters[i][j]; k++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t k = 0; k < native.nClusters[i][j]; k++) { if (native.clusters[i][j][k].getTime() > retVal) { retVal = native.clusters[i][j][k].getTime(); } @@ -137,12 +137,12 @@ int GPUReconstructionConvert::GetMaxTimeBin(const ClusterNativeAccess& native) #endif } -int GPUReconstructionConvert::GetMaxTimeBin(const GPUTrackingInOutDigits& digits) +int32_t GPUReconstructionConvert::GetMaxTimeBin(const GPUTrackingInOutDigits& digits) { #ifdef GPUCA_HAVE_O2HEADERS float retVal = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int k = 0; k < digits.nTPCDigits[i]; k++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t k = 0; k < digits.nTPCDigits[i]; k++) { if (digits.tpcDigits[i][k].getTimeStamp() > retVal) { retVal = digits.tpcDigits[i][k].getTimeStamp(); } @@ -154,26 +154,26 @@ int GPUReconstructionConvert::GetMaxTimeBin(const GPUTrackingInOutDigits& digits #endif } -int GPUReconstructionConvert::GetMaxTimeBin(const GPUTrackingInOutZS& zspages) +int32_t GPUReconstructionConvert::GetMaxTimeBin(const GPUTrackingInOutZS& zspages) { #ifdef GPUCA_HAVE_O2HEADERS float retVal = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - int firstHBF = zspages.slice[i].count[0] ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)zspages.slice[i].zsPtr[0][0]) : 0; - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - for (unsigned int k = 0; k < zspages.slice[i].count[j]; k++) { + for (uint32_t i = 0; i < NSLICES; i++) { + int32_t firstHBF = zspages.slice[i].count[0] ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)zspages.slice[i].zsPtr[0][0]) : 0; + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t k = 0; k < zspages.slice[i].count[j]; k++) { const char* page = (const char*)zspages.slice[i].zsPtr[j][k]; - for (unsigned int l = 0; l < zspages.slice[i].nZSPtr[j][k]; l++) { + for (uint32_t l = 0; l < zspages.slice[i].nZSPtr[j][k]; l++) { o2::header::RAWDataHeader* rdh = (o2::header::RAWDataHeader*)(page + l * TPCZSHDR::TPC_ZS_PAGE_SIZE); TPCZSHDR* hdr = (TPCZSHDR*)(page + l * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); - int nTimeBinSpan = hdr->nTimeBinSpan; + int32_t nTimeBinSpan = hdr->nTimeBinSpan; if (hdr->version >= o2::tpc::ZSVersion::ZSVersionDenseLinkBased) { TPCZSHDRV2* hdr2 = (TPCZSHDRV2*)hdr; if (hdr2->flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) { nTimeBinSpan += 256; } } - unsigned int timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN + nTimeBinSpan; + uint32_t timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN + nTimeBinSpan; if (timeBin > retVal) { retVal = timeBin; } @@ -195,34 +195,34 @@ namespace // anonymous // ------------------------------------------------- TPC ZS General ------------------------------------------------- -typedef std::array zsPage; +typedef std::array zsPage; struct zsEncoder { - int curRegion = 0, outputRegion = 0; - unsigned int encodeBits = 0; - unsigned int zsVersion = 0; - unsigned int iSector = 0; + int32_t curRegion = 0, outputRegion = 0; + uint32_t encodeBits = 0; + uint32_t zsVersion = 0; + uint32_t iSector = 0; o2::raw::RawFileWriter* raw = nullptr; const o2::InteractionRecord* ir = nullptr; const GPUParam* param = nullptr; bool padding = false; - int lastEndpoint = -2, lastTime = -1, lastRow = GPUCA_ROW_COUNT; - int endpoint = 0, outputEndpoint = 0; - long hbf = -1, nexthbf = 0; + int32_t lastEndpoint = -2, lastTime = -1, lastRow = GPUCA_ROW_COUNT; + int32_t endpoint = 0, outputEndpoint = 0; + int64_t hbf = -1, nexthbf = 0; zsPage* page = nullptr; - unsigned char* pagePtr = nullptr; - int bcShiftInFirstHBF = 0; - int firstTimebinInPage = -1; + uint8_t* pagePtr = nullptr; + int32_t bcShiftInFirstHBF = 0; + int32_t firstTimebinInPage = -1; float encodeBitsFactor = 0; bool needAnotherPage = false; - unsigned int packetCounter = 0; - unsigned int pageCounter = 0; - void ZSfillEmpty(void* ptr, int shift, unsigned int feeId, int orbit, int linkid); - static void ZSstreamOut(unsigned short* bufIn, unsigned int& lenIn, unsigned char* bufOut, unsigned int& lenOut, unsigned int nBits); - long getHbf(long timestamp) { return (timestamp * LHCBCPERTIMEBIN + bcShiftInFirstHBF) / o2::constants::lhc::LHCMaxBunches; } + uint32_t packetCounter = 0; + uint32_t pageCounter = 0; + void ZSfillEmpty(void* ptr, int32_t shift, uint32_t feeId, int32_t orbit, int32_t linkid); + static void ZSstreamOut(uint16_t* bufIn, uint32_t& lenIn, uint8_t* bufOut, uint32_t& lenOut, uint32_t nBits); + int64_t getHbf(int64_t timestamp) { return (timestamp * LHCBCPERTIMEBIN + bcShiftInFirstHBF) / o2::constants::lhc::LHCMaxBunches; } }; -inline void zsEncoder::ZSfillEmpty(void* ptr, int shift, unsigned int feeId, int orbit, int linkid) +inline void zsEncoder::ZSfillEmpty(void* ptr, int32_t shift, uint32_t feeId, int32_t orbit, int32_t linkid) { o2::header::RAWDataHeader* rdh = (o2::header::RAWDataHeader*)ptr; o2::raw::RDHUtils::setHeartBeatOrbit(*rdh, orbit); @@ -236,15 +236,15 @@ inline void zsEncoder::ZSfillEmpty(void* ptr, int shift, unsigned int feeId, int o2::raw::RDHUtils::setPageCounter(*rdh, pageCounter++); } -inline void zsEncoder::ZSstreamOut(unsigned short* bufIn, unsigned int& lenIn, unsigned char* bufOut, unsigned int& lenOut, unsigned int nBits) +inline void zsEncoder::ZSstreamOut(uint16_t* bufIn, uint32_t& lenIn, uint8_t* bufOut, uint32_t& lenOut, uint32_t nBits) { - unsigned int byte = 0, bits = 0; - unsigned int mask = (1 << nBits) - 1; - for (unsigned int i = 0; i < lenIn; i++) { + uint32_t byte = 0, bits = 0; + uint32_t mask = (1 << nBits) - 1; + for (uint32_t i = 0; i < lenIn; i++) { byte |= (bufIn[i] & mask) << bits; bits += nBits; while (bits >= 8) { - bufOut[lenOut++] = (unsigned char)(byte & 0xFF); + bufOut[lenOut++] = (uint8_t)(byte & 0xFF); byte = byte >> 8; bits -= 8; } @@ -255,42 +255,42 @@ inline void zsEncoder::ZSstreamOut(unsigned short* bufIn, unsigned int& lenIn, u lenIn = 0; } -static inline auto ZSEncoderGetDigits(const GPUTrackingInOutDigits& in, int i) { return in.tpcDigits[i]; } -static inline auto ZSEncoderGetNDigits(const GPUTrackingInOutDigits& in, int i) { return in.nTPCDigits[i]; } +static inline auto ZSEncoderGetDigits(const GPUTrackingInOutDigits& in, int32_t i) { return in.tpcDigits[i]; } +static inline auto ZSEncoderGetNDigits(const GPUTrackingInOutDigits& in, int32_t i) { return in.nTPCDigits[i]; } #ifdef GPUCA_O2_LIB using DigitArray = std::array, o2::tpc::Sector::MAXSECTOR>; -static inline auto ZSEncoderGetDigits(const DigitArray& in, int i) { return in[i].data(); } -static inline auto ZSEncoderGetNDigits(const DigitArray& in, int i) { return in[i].size(); } +static inline auto ZSEncoderGetDigits(const DigitArray& in, int32_t i) { return in[i].data(); } +static inline auto ZSEncoderGetNDigits(const DigitArray& in, int32_t i) { return in[i].size(); } #endif // GPUCA_O2_LIB // ------------------------------------------------- TPC ZS Original Row-based ZS ------------------------------------------------- struct zsEncoderRow : public zsEncoder { - std::array streamBuffer = {}; - std::array streamBuffer8 = {}; + std::array streamBuffer = {}; + std::array streamBuffer8 = {}; TPCZSHDR* hdr = nullptr; TPCZSTBHDR* curTBHdr = nullptr; - unsigned char* nSeq = nullptr; - int seqLen = 0; - int endpointStart = 0; - int nRowsInTB = 0; - unsigned int streamSize = 0, streamSize8 = 0; - constexpr static int RAWLNK = rdh_utils::UserLogicLinkID; - - bool checkInput(std::vector& tmpBuffer, unsigned int k); + uint8_t* nSeq = nullptr; + int32_t seqLen = 0; + int32_t endpointStart = 0; + int32_t nRowsInTB = 0; + uint32_t streamSize = 0, streamSize8 = 0; + constexpr static int32_t RAWLNK = rdh_utils::UserLogicLinkID; + + bool checkInput(std::vector& tmpBuffer, uint32_t k); bool writeSubPage(); void init() { encodeBits = zsVersion == 2 ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; } void initPage() {} - unsigned int encodeSequence(std::vector& tmpBuffer, unsigned int k); + uint32_t encodeSequence(std::vector& tmpBuffer, uint32_t k); bool sort(const o2::tpc::Digit a, const o2::tpc::Digit b); - void decodePage(std::vector& outputBuffer, const zsPage* page, unsigned int endpoint, unsigned int firstOrbit, unsigned int triggerBC = 0); + void decodePage(std::vector& outputBuffer, const zsPage* page, uint32_t endpoint, uint32_t firstOrbit, uint32_t triggerBC = 0); }; inline bool zsEncoderRow::sort(const o2::tpc::Digit a, const o2::tpc::Digit b) { - int endpointa = param->tpcGeometry.GetRegion(a.getRow()); - int endpointb = param->tpcGeometry.GetRegion(b.getRow()); + int32_t endpointa = param->tpcGeometry.GetRegion(a.getRow()); + int32_t endpointb = param->tpcGeometry.GetRegion(b.getRow()); endpointa = 2 * endpointa + (a.getRow() >= param->tpcGeometry.GetRegionStart(endpointa) + param->tpcGeometry.GetRegionRows(endpointa) / 2); endpointb = 2 * endpointb + (b.getRow() >= param->tpcGeometry.GetRegionStart(endpointb) + param->tpcGeometry.GetRegionRows(endpointb) / 2); if (endpointa != endpointb) { @@ -305,7 +305,7 @@ inline bool zsEncoderRow::sort(const o2::tpc::Digit a, const o2::tpc::Digit b) return a.getPad() < b.getPad(); } -bool zsEncoderRow::checkInput(std::vector& tmpBuffer, unsigned int k) +bool zsEncoderRow::checkInput(std::vector& tmpBuffer, uint32_t k) { seqLen = 1; if (lastRow != tmpBuffer[k].getRow()) { @@ -316,54 +316,54 @@ bool zsEncoderRow::checkInput(std::vector& tmpBuffer, unsigned i endpointStart += param->tpcGeometry.GetRegionRows(curRegion) / 2; } } - for (unsigned int l = k + 1; l < tmpBuffer.size(); l++) { + for (uint32_t l = k + 1; l < tmpBuffer.size(); l++) { if (tmpBuffer[l].getRow() == tmpBuffer[k].getRow() && tmpBuffer[l].getTimeStamp() == tmpBuffer[k].getTimeStamp() && tmpBuffer[l].getPad() == tmpBuffer[l - 1].getPad() + 1) { seqLen++; } else { break; } } - if (lastEndpoint >= 0 && lastTime != -1 && (int)hdr->nTimeBinSpan + tmpBuffer[k].getTimeStamp() - lastTime >= 256) { + if (lastEndpoint >= 0 && lastTime != -1 && (int32_t)hdr->nTimeBinSpan + tmpBuffer[k].getTimeStamp() - lastTime >= 256) { lastEndpoint = -1; } if (endpoint == lastEndpoint) { - unsigned int sizeChk = (unsigned int)(pagePtr - reinterpret_cast(page)); // already written + uint32_t sizeChk = (uint32_t)(pagePtr - reinterpret_cast(page)); // already written sizeChk += 2 * (nRowsInTB + (tmpBuffer[k].getRow() != lastRow && tmpBuffer[k].getTimeStamp() == lastTime)); // TB HDR sizeChk += streamSize8; // in stream buffer sizeChk += (lastTime != tmpBuffer[k].getTimeStamp()) && ((sizeChk + (streamSize * encodeBits + 7) / 8) & 1); // time bin alignment sizeChk += (tmpBuffer[k].getTimeStamp() != lastTime || tmpBuffer[k].getRow() != lastRow) ? 3 : 0; // new row overhead sizeChk += (lastTime != -1 && tmpBuffer[k].getTimeStamp() > lastTime) ? ((tmpBuffer[k].getTimeStamp() - lastTime - 1) * 2) : 0; // empty time bins sizeChk += 2; // sequence metadata - const unsigned int streamSizeChkBits = streamSize * encodeBits + ((lastTime != tmpBuffer[k].getTimeStamp() && (streamSize * encodeBits) % 8) ? (8 - (streamSize * encodeBits) % 8) : 0); + const uint32_t streamSizeChkBits = streamSize * encodeBits + ((lastTime != tmpBuffer[k].getTimeStamp() && (streamSize * encodeBits) % 8) ? (8 - (streamSize * encodeBits) % 8) : 0); if (sizeChk + (encodeBits + streamSizeChkBits + 7) / 8 > TPCZSHDR::TPC_ZS_PAGE_SIZE) { lastEndpoint = -1; } else if (sizeChk + (seqLen * encodeBits + streamSizeChkBits + 7) / 8 > TPCZSHDR::TPC_ZS_PAGE_SIZE) { seqLen = ((TPCZSHDR::TPC_ZS_PAGE_SIZE - sizeChk) * 8 - streamSizeChkBits) / encodeBits; } // sizeChk += (seqLen * encodeBits + streamSizeChkBits + 7) / 8; - // printf("Endpoint %d (%d), Pos %d, Chk %d, Len %d, rows %d, StreamSize %d %d, time %d (%d), row %d (%d), pad %d\n", endpoint, lastEndpoint, (int) (pagePtr - reinterpret_cast(page)), sizeChk, seqLen, nRowsInTB, streamSize8, streamSize, (int)tmpBuffer[k].getTimeStamp(), lastTime, (int)tmpBuffer[k].getRow(), lastRow, tmpBuffer[k].getPad()); + // printf("Endpoint %d (%d), Pos %d, Chk %d, Len %d, rows %d, StreamSize %d %d, time %d (%d), row %d (%d), pad %d\n", endpoint, lastEndpoint, (int32_t) (pagePtr - reinterpret_cast(page)), sizeChk, seqLen, nRowsInTB, streamSize8, streamSize, (int32_t)tmpBuffer[k].getTimeStamp(), lastTime, (int32_t)tmpBuffer[k].getRow(), lastRow, tmpBuffer[k].getPad()); } return endpoint != lastEndpoint || tmpBuffer[k].getTimeStamp() != lastTime; } bool zsEncoderRow::writeSubPage() { - if (pagePtr != reinterpret_cast(page)) { + if (pagePtr != reinterpret_cast(page)) { pagePtr += 2 * nRowsInTB; ZSstreamOut(streamBuffer.data(), streamSize, streamBuffer8.data(), streamSize8, encodeBits); pagePtr = std::copy(streamBuffer8.data(), streamBuffer8.data() + streamSize8, pagePtr); - if (pagePtr - reinterpret_cast(page) > 8192) { + if (pagePtr - reinterpret_cast(page) > 8192) { throw std::runtime_error("internal error during ZS encoding"); } streamSize8 = 0; - for (int l = 1; l < nRowsInTB; l++) { + for (int32_t l = 1; l < nRowsInTB; l++) { curTBHdr->rowAddr1()[l - 1] += 2 * nRowsInTB; } } return endpoint != lastEndpoint; } -unsigned int zsEncoderRow::encodeSequence(std::vector& tmpBuffer, unsigned int k) +uint32_t zsEncoderRow::encodeSequence(std::vector& tmpBuffer, uint32_t k) { if (tmpBuffer[k].getTimeStamp() != lastTime) { if (lastTime != -1) { @@ -371,7 +371,7 @@ unsigned int zsEncoderRow::encodeSequence(std::vector& tmpBuffer pagePtr += (tmpBuffer[k].getTimeStamp() - lastTime - 1) * 2; } hdr->nTimeBinSpan++; - if ((pagePtr - reinterpret_cast(page)) & 1) { + if ((pagePtr - reinterpret_cast(page)) & 1) { pagePtr++; } curTBHdr = reinterpret_cast(pagePtr); @@ -383,7 +383,7 @@ unsigned int zsEncoderRow::encodeSequence(std::vector& tmpBuffer curTBHdr->rowMask |= 1 << (tmpBuffer[k].getRow() - endpointStart); ZSstreamOut(streamBuffer.data(), streamSize, streamBuffer8.data(), streamSize8, encodeBits); if (nRowsInTB) { - curTBHdr->rowAddr1()[nRowsInTB - 1] = (pagePtr - reinterpret_cast(page)) + streamSize8; + curTBHdr->rowAddr1()[nRowsInTB - 1] = (pagePtr - reinterpret_cast(page)) + streamSize8; } nRowsInTB++; nSeq = streamBuffer8.data() + streamSize8++; @@ -392,15 +392,15 @@ unsigned int zsEncoderRow::encodeSequence(std::vector& tmpBuffer (*nSeq)++; streamBuffer8[streamSize8++] = tmpBuffer[k].getPad(); streamBuffer8[streamSize8++] = streamSize + seqLen; - for (int l = 0; l < seqLen; l++) { - streamBuffer[streamSize++] = (unsigned short)(tmpBuffer[k + l].getChargeFloat() * encodeBitsFactor + 0.5f); + for (int32_t l = 0; l < seqLen; l++) { + streamBuffer[streamSize++] = (uint16_t)(tmpBuffer[k + l].getChargeFloat() * encodeBitsFactor + 0.5f); } return seqLen; } -void zsEncoderRow::decodePage(std::vector& outputBuffer, const zsPage* decPage, unsigned int decEndpoint, unsigned int firstOrbit, unsigned int triggerBC) +void zsEncoderRow::decodePage(std::vector& outputBuffer, const zsPage* decPage, uint32_t decEndpoint, uint32_t firstOrbit, uint32_t triggerBC) { - const unsigned char* decPagePtr = reinterpret_cast(decPage); + const uint8_t* decPagePtr = reinterpret_cast(decPage); const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)decPagePtr; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { return; @@ -412,21 +412,21 @@ void zsEncoderRow::decodePage(std::vector& outputBuffer, const z throw std::runtime_error("invalid ZS version "s + std::to_string(decHDR->version) + " (1 or 2 expected)"s); } const float decodeBitsFactor = 1.f / (1 << (encodeBits - 10)); - unsigned int mask = (1 << encodeBits) - 1; - int cruid = decHDR->cruID; - unsigned int sector = cruid / 10; + uint32_t mask = (1 << encodeBits) - 1; + int32_t cruid = decHDR->cruID; + uint32_t sector = cruid / 10; if (sector != iSector) { throw std::runtime_error("invalid TPC sector"); } - int region = cruid % 10; - if ((unsigned int)region != decEndpoint / 2) { + int32_t region = cruid % 10; + if ((uint32_t)region != decEndpoint / 2) { throw std::runtime_error("CRU ID / endpoint mismatch"); } - int nRowsRegion = param->tpcGeometry.GetRegionRows(region); + int32_t nRowsRegion = param->tpcGeometry.GetRegionRows(region); - int timeBin = (decHDR->timeOffset + (unsigned long)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; - for (int l = 0; l < decHDR->nTimeBinSpan; l++) { - if ((decPagePtr - reinterpret_cast(decPage)) & 1) { + int32_t timeBin = (decHDR->timeOffset + (uint64_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + for (int32_t l = 0; l < decHDR->nTimeBinSpan; l++) { + if ((decPagePtr - reinterpret_cast(decPage)) & 1) { decPagePtr++; } const TPCZSTBHDR* tbHdr = reinterpret_cast(decPagePtr); @@ -434,23 +434,23 @@ void zsEncoderRow::decodePage(std::vector& outputBuffer, const z if (tbHdr->rowMask != 0 && ((upperRows) ^ ((decEndpoint & 1) != 0))) { throw std::runtime_error("invalid endpoint"); } - const int rowOffset = param->tpcGeometry.GetRegionStart(region) + (upperRows ? (nRowsRegion / 2) : 0); - const int nRows = upperRows ? (nRowsRegion - nRowsRegion / 2) : (nRowsRegion / 2); - const int nRowsUsed = __builtin_popcount((unsigned int)(tbHdr->rowMask & 0x7FFF)); + const int32_t rowOffset = param->tpcGeometry.GetRegionStart(region) + (upperRows ? (nRowsRegion / 2) : 0); + const int32_t nRows = upperRows ? (nRowsRegion - nRowsRegion / 2) : (nRowsRegion / 2); + const int32_t nRowsUsed = __builtin_popcount((uint32_t)(tbHdr->rowMask & 0x7FFF)); decPagePtr += nRowsUsed ? (2 * nRowsUsed) : 2; - int rowPos = 0; - for (int m = 0; m < nRows; m++) { + int32_t rowPos = 0; + for (int32_t m = 0; m < nRows; m++) { if ((tbHdr->rowMask & (1 << m)) == 0) { continue; } - const unsigned char* rowData = rowPos == 0 ? decPagePtr : (reinterpret_cast(decPage) + tbHdr->rowAddr1()[rowPos - 1]); - const int nSeqRead = *rowData; - const unsigned char* adcData = rowData + 2 * nSeqRead + 1; - int nADC = (rowData[2 * nSeqRead] * encodeBits + 7) / 8; + const uint8_t* rowData = rowPos == 0 ? decPagePtr : (reinterpret_cast(decPage) + tbHdr->rowAddr1()[rowPos - 1]); + const int32_t nSeqRead = *rowData; + const uint8_t* adcData = rowData + 2 * nSeqRead + 1; + int32_t nADC = (rowData[2 * nSeqRead] * encodeBits + 7) / 8; decPagePtr += 1 + 2 * nSeqRead + nADC; - unsigned int byte = 0, bits = 0, posXbits = 0; - std::array decBuffer; - for (int n = 0; n < nADC; n++) { + uint32_t byte = 0, bits = 0, posXbits = 0; + std::array decBuffer; + for (int32_t n = 0; n < nADC; n++) { byte |= *(adcData++) << bits; bits += 8; while (bits >= encodeBits) { @@ -460,9 +460,9 @@ void zsEncoderRow::decodePage(std::vector& outputBuffer, const z } } posXbits = 0; - for (int n = 0; n < nSeqRead; n++) { - const int decSeqLen = rowData[(n + 1) * 2] - (n ? rowData[n * 2] : 0); - for (int o = 0; o < decSeqLen; o++) { + for (int32_t n = 0; n < nSeqRead; n++) { + const int32_t decSeqLen = rowData[(n + 1) * 2] - (n ? rowData[n * 2] : 0); + for (int32_t o = 0; o < decSeqLen; o++) { outputBuffer.emplace_back(o2::tpc::Digit{cruid, decBuffer[posXbits++] * decodeBitsFactor, (tpccf::Row)(rowOffset + m), (tpccf::Pad)(rowData[n * 2 + 1] + o), timeBin + l}); } } @@ -477,14 +477,14 @@ void zsEncoderRow::decodePage(std::vector& outputBuffer, const z struct zsEncoderLinkBased : public zsEncoder { TPCZSHDRV2* hdr = nullptr; TPCZSHDRV2 hdrBuffer; - int inverseChannelMapping[5][32]; - int nSamples = 0; - int link = 0; + int32_t inverseChannelMapping[5][32]; + int32_t nSamples = 0; + int32_t link = 0; bool finishPage = false; - std::vector adcValues = {}; + std::vector adcValues = {}; std::bitset<80> bitmask = {}; - void createBitmask(std::vector& tmpBuffer, unsigned int k); + void createBitmask(std::vector& tmpBuffer, uint32_t k); void init(); bool sort(const o2::tpc::Digit a, const o2::tpc::Digit b); }; @@ -492,14 +492,14 @@ struct zsEncoderLinkBased : public zsEncoder { void zsEncoderLinkBased::init() { encodeBits = TPCZSHDRV2::TPC_ZS_NBITS_V34; - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 32; j++) { + for (int32_t i = 0; i < 5; i++) { + for (int32_t j = 0; j < 32; j++) { inverseChannelMapping[i][j] = -1; } } - for (int iCRU = 0; iCRU < 2; iCRU++) { - for (int iChannel = 0; iChannel < 80; iChannel++) { - int sampaOnFEC = 0, channelOnSAMPA = 0; + for (int32_t iCRU = 0; iCRU < 2; iCRU++) { + for (int32_t iChannel = 0; iChannel < 80; iChannel++) { + int32_t sampaOnFEC = 0, channelOnSAMPA = 0; Mapper::getSampaAndChannelOnFEC(iCRU, iChannel, sampaOnFEC, channelOnSAMPA); if (inverseChannelMapping[sampaOnFEC][channelOnSAMPA] != -1 && inverseChannelMapping[sampaOnFEC][channelOnSAMPA] != iChannel) { GPUError("ERROR: Channel conflict: %d %d: %d vs %d", sampaOnFEC, channelOnSAMPA, inverseChannelMapping[sampaOnFEC][channelOnSAMPA], iChannel); @@ -508,8 +508,8 @@ void zsEncoderLinkBased::init() inverseChannelMapping[sampaOnFEC][channelOnSAMPA] = iChannel; } } - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 32; j++) { + for (int32_t i = 0; i < 5; i++) { + for (int32_t j = 0; j < 32; j++) { if (inverseChannelMapping[i][j] == -1) { GPUError("ERROR: Map missing for sampa %d channel %d", i, j); throw std::runtime_error("ZS error"); @@ -518,30 +518,30 @@ void zsEncoderLinkBased::init() } } -void zsEncoderLinkBased::createBitmask(std::vector& tmpBuffer, unsigned int k) +void zsEncoderLinkBased::createBitmask(std::vector& tmpBuffer, uint32_t k) { const auto& mapper = Mapper::instance(); nSamples = 0; adcValues.clear(); bitmask.reset(); - unsigned int l; + uint32_t l; for (l = k; l < tmpBuffer.size(); l++) { const auto& a = tmpBuffer[l]; - int cruinsector = param->tpcGeometry.GetRegion(a.getRow()); + int32_t cruinsector = param->tpcGeometry.GetRegion(a.getRow()); o2::tpc::GlobalPadNumber pad = mapper.globalPadNumber(o2::tpc::PadPos(a.getRow(), a.getPad())); o2::tpc::FECInfo fec = mapper.fecInfo(pad); o2::tpc::CRU cru = cruinsector; - int fecInPartition = fec.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); - int tmpEndpoint = 2 * cruinsector + (fecInPartition >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); + int32_t fecInPartition = fec.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); + int32_t tmpEndpoint = 2 * cruinsector + (fecInPartition >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); if (l == k) { link = fecInPartition; endpoint = tmpEndpoint; } else if (endpoint != tmpEndpoint || link != fecInPartition || tmpBuffer[l].getTimeStamp() != tmpBuffer[k].getTimeStamp()) { break; } - int channel = inverseChannelMapping[fec.getSampaChip()][fec.getSampaChannel()]; + int32_t channel = inverseChannelMapping[fec.getSampaChip()][fec.getSampaChannel()]; bitmask[channel] = 1; - adcValues.emplace_back((unsigned short)(a.getChargeFloat() * encodeBitsFactor + 0.5f)); + adcValues.emplace_back((uint16_t)(a.getChargeFloat() * encodeBitsFactor + 0.5f)); } nSamples = l - k; } @@ -549,8 +549,8 @@ void zsEncoderLinkBased::createBitmask(std::vector& tmpBuffer, u bool zsEncoderLinkBased::sort(const o2::tpc::Digit a, const o2::tpc::Digit b) { // Fixme: this is blasphemy... one shoult precompute all values and sort an index array - int cruinsectora = param->tpcGeometry.GetRegion(a.getRow()); - int cruinsectorb = param->tpcGeometry.GetRegion(b.getRow()); + int32_t cruinsectora = param->tpcGeometry.GetRegion(a.getRow()); + int32_t cruinsectorb = param->tpcGeometry.GetRegion(b.getRow()); if (cruinsectora != cruinsectorb) { return cruinsectora < cruinsectorb; } @@ -560,11 +560,11 @@ bool zsEncoderLinkBased::sort(const o2::tpc::Digit a, const o2::tpc::Digit b) o2::tpc::FECInfo feca = mapper.fecInfo(pada); o2::tpc::FECInfo fecb = mapper.fecInfo(padb); o2::tpc::CRU cru = cruinsectora; - int fecInPartitiona = feca.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); - int fecInPartitionb = fecb.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); + int32_t fecInPartitiona = feca.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); + int32_t fecInPartitionb = fecb.getIndex() - mapper.getPartitionInfo(cru.partition()).getSectorFECOffset(); - int endpointa = 2 * cruinsectora + (fecInPartitiona >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); - int endpointb = 2 * cruinsectorb + (fecInPartitionb >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); + int32_t endpointa = 2 * cruinsectora + (fecInPartitiona >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); + int32_t endpointb = 2 * cruinsectorb + (fecInPartitionb >= (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); if (endpointa != endpointb) { return endpointa < endpointb; } @@ -580,16 +580,16 @@ bool zsEncoderLinkBased::sort(const o2::tpc::Digit a, const o2::tpc::Digit b) // ------------------------------------------------- TPC Improved Link Based ZS ------------------------------------------------- struct zsEncoderImprovedLinkBased : public zsEncoderLinkBased { - bool checkInput(std::vector& tmpBuffer, unsigned int k); - unsigned int encodeSequence(std::vector& tmpBuffer, unsigned int k); - void decodePage(std::vector& outputBuffer, const zsPage* page, unsigned int endpoint, unsigned int firstOrbit, unsigned int triggerBC = 0); + bool checkInput(std::vector& tmpBuffer, uint32_t k); + uint32_t encodeSequence(std::vector& tmpBuffer, uint32_t k); + void decodePage(std::vector& outputBuffer, const zsPage* page, uint32_t endpoint, uint32_t firstOrbit, uint32_t triggerBC = 0); bool writeSubPage(); void initPage(); - constexpr static int RAWLNK = rdh_utils::ILBZSLinkID; + constexpr static int32_t RAWLNK = rdh_utils::ILBZSLinkID; }; -bool zsEncoderImprovedLinkBased::checkInput(std::vector& tmpBuffer, unsigned int k) +bool zsEncoderImprovedLinkBased::checkInput(std::vector& tmpBuffer, uint32_t k) { createBitmask(tmpBuffer, k); finishPage = endpoint != lastEndpoint; @@ -597,7 +597,7 @@ bool zsEncoderImprovedLinkBased::checkInput(std::vector& tmpBuff finishPage = true; } if (!finishPage) { - unsigned int sizeChk = (unsigned int)(pagePtr - reinterpret_cast(page)); + uint32_t sizeChk = (uint32_t)(pagePtr - reinterpret_cast(page)); sizeChk += sizeof(o2::tpc::zerosupp_link_based::CommonHeader); if (TPCZSHDRV2::TIGHTLY_PACKED_V3) { sizeChk += (nSamples * TPCZSHDRV2::TPC_ZS_NBITS_V34 + 127) / 128 * 16; @@ -611,7 +611,7 @@ bool zsEncoderImprovedLinkBased::checkInput(std::vector& tmpBuff return finishPage; } -unsigned int zsEncoderImprovedLinkBased::encodeSequence(std::vector& tmpBuffer, unsigned int k) +uint32_t zsEncoderImprovedLinkBased::encodeSequence(std::vector& tmpBuffer, uint32_t k) { o2::tpc::zerosupp_link_based::CommonHeader* tbHdr = (o2::tpc::zerosupp_link_based::CommonHeader*)pagePtr; pagePtr += sizeof(*tbHdr); @@ -625,17 +625,17 @@ unsigned int zsEncoderImprovedLinkBased::encodeSequence(std::vectornTimebinHeaders++; if (TPCZSHDRV2::TIGHTLY_PACKED_V3) { tbHdr->numWordsPayload = (nSamples * TPCZSHDRV2::TPC_ZS_NBITS_V34 + 127) / 128; // tightly packed ADC samples - unsigned int tmp = 0; - unsigned int tmpIn = nSamples; + uint32_t tmp = 0; + uint32_t tmpIn = nSamples; ZSstreamOut(adcValues.data(), tmpIn, pagePtr, tmp, encodeBits); } else { tbHdr->numWordsPayload = (nSamples + 2 * TPCZSHDRV2::SAMPLESPER64BIT - 1) / (2 * TPCZSHDRV2::SAMPLESPER64BIT); - unsigned long* payloadPtr = (unsigned long*)pagePtr; - for (unsigned int i = 0; i < 2 * tbHdr->numWordsPayload; i++) { + uint64_t* payloadPtr = (uint64_t*)pagePtr; + for (uint32_t i = 0; i < 2 * tbHdr->numWordsPayload; i++) { payloadPtr[i] = 0; } - for (unsigned int i = 0; i < nSamples; i++) { - payloadPtr[i / TPCZSHDRV2::SAMPLESPER64BIT] |= ((unsigned long)adcValues[i]) << ((i % TPCZSHDRV2::SAMPLESPER64BIT) * TPCZSHDRV2::TPC_ZS_NBITS_V34); + for (uint32_t i = 0; i < nSamples; i++) { + payloadPtr[i / TPCZSHDRV2::SAMPLESPER64BIT] |= ((uint64_t)adcValues[i]) << ((i % TPCZSHDRV2::SAMPLESPER64BIT) * TPCZSHDRV2::TPC_ZS_NBITS_V34); } } pagePtr += tbHdr->numWordsPayload * 16; @@ -654,10 +654,10 @@ void zsEncoderImprovedLinkBased::initPage() hdr->firstZSDataOffset = 0; } -void zsEncoderImprovedLinkBased::decodePage(std::vector& outputBuffer, const zsPage* decPage, unsigned int decEndpoint, unsigned int firstOrbit, unsigned int triggerBC) +void zsEncoderImprovedLinkBased::decodePage(std::vector& outputBuffer, const zsPage* decPage, uint32_t decEndpoint, uint32_t firstOrbit, uint32_t triggerBC) { const auto& mapper = Mapper::instance(); - const unsigned char* decPagePtr = reinterpret_cast(decPage); + const uint8_t* decPagePtr = reinterpret_cast(decPage); const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)decPagePtr; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { return; @@ -672,20 +672,20 @@ void zsEncoderImprovedLinkBased::decodePage(std::vector& outputB throw std::runtime_error("Magic word missing"); } const float decodeBitsFactor = 1.f / (1 << (encodeBits - 10)); - unsigned int mask = (1 << encodeBits) - 1; - int cruid = decHDR->cruID; - unsigned int sector = cruid / 10; + uint32_t mask = (1 << encodeBits) - 1; + int32_t cruid = decHDR->cruID; + uint32_t sector = cruid / 10; if (sector != iSector) { throw std::runtime_error("invalid TPC sector"); } - int region = cruid % 10; + int32_t region = cruid % 10; decPagePtr += decHDR->firstZSDataOffset * 16; - for (unsigned int i = 0; i < decHDR->nTimebinHeaders; i++) { + for (uint32_t i = 0; i < decHDR->nTimebinHeaders; i++) { const o2::tpc::zerosupp_link_based::Header* tbHdr = (const o2::tpc::zerosupp_link_based::Header*)decPagePtr; #if 0 // Decoding using the function for the original linkZS o2::tpc::CRU cru = cruid % 10; - const int feeLink = tbHdr->fecInPartition - (decEndpoint & 1) * ((mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); - auto fillADC = [&outputBuffer](int cru, int rowInSector, int padInRow, int timeBin, float adcValue) { + const int32_t feeLink = tbHdr->fecInPartition - (decEndpoint & 1) * ((mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2); + auto fillADC = [&outputBuffer](int32_t cru, int32_t rowInSector, int32_t padInRow, int32_t timeBin, float adcValue) { outputBuffer.emplace_back(o2::tpc::Digit{cruid, adcValue, rowInSector, padInRow, timeBin}); return true; }; @@ -695,17 +695,17 @@ void zsEncoderImprovedLinkBased::decodePage(std::vector& outputB if (!tbHdr->isLinkZS()) { throw std::runtime_error("ZS TB Hdr does not have linkZS magic word"); } - int timeBin = (int(decHDR->timeOffset) + int(tbHdr->bunchCrossing) + (int)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - triggerBC) / LHCBCPERTIMEBIN; + int32_t timeBin = (int32_t(decHDR->timeOffset) + int32_t(tbHdr->bunchCrossing) + (int32_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - triggerBC) / LHCBCPERTIMEBIN; if (timeBin < 0) { LOGP(debug, "zsEncoderImprovedLinkBased::decodePage skipping digits hdr->tOff {} + hdr->bc {} + (orbit {} - firstOrbit {}) * maxBunch {} - triggerBC {} = {} < 0", decHDR->timeOffset, tbHdr->bunchCrossing, o2::raw::RDHUtils::getHeartBeatOrbit(*rdh), firstOrbit, o2::constants::lhc::LHCMaxBunches, triggerBC, timeBin); continue; } - const unsigned char* adcData = (const unsigned char*)(decPagePtr + sizeof(*tbHdr)); + const uint8_t* adcData = (const uint8_t*)(decPagePtr + sizeof(*tbHdr)); const auto& bitmask = tbHdr->getChannelBits(); - int nADC = bitmask.count(); - std::vector decBuffer(nADC); + int32_t nADC = bitmask.count(); + std::vector decBuffer(nADC); if (TPCZSHDRV2::TIGHTLY_PACKED_V3) { - unsigned int byte = 0, bits = 0, posXbits = 0; + uint32_t byte = 0, bits = 0, posXbits = 0; while (posXbits < nADC) { byte |= *(adcData++) << bits; bits += 8; @@ -716,14 +716,14 @@ void zsEncoderImprovedLinkBased::decodePage(std::vector& outputB } } } else { - const unsigned long* adcData64 = (const unsigned long*)adcData; - for (int j = 0; j < nADC; j++) { + const uint64_t* adcData64 = (const uint64_t*)adcData; + for (int32_t j = 0; j < nADC; j++) { decBuffer[j] = (adcData64[j / TPCZSHDRV2::SAMPLESPER64BIT] >> ((j % TPCZSHDRV2::SAMPLESPER64BIT) * TPCZSHDRV2::TPC_ZS_NBITS_V34)) & mask; } } - for (int j = 0, k = 0; j < bitmask.size(); j++) { + for (int32_t j = 0, k = 0; j < bitmask.size(); j++) { if (bitmask[j]) { - int sampaOnFEC = 0, channelOnSAMPA = 0; + int32_t sampaOnFEC = 0, channelOnSAMPA = 0; mapper.getSampaAndChannelOnFEC(cruid, j, sampaOnFEC, channelOnSAMPA); const auto padSecPos = mapper.padSecPos(cruid, tbHdr->fecInPartition, sampaOnFEC, channelOnSAMPA); const auto& padPos = padSecPos.getPadPos(); @@ -738,34 +738,34 @@ void zsEncoderImprovedLinkBased::decodePage(std::vector& outputB // ------------------------------------------------- TPC ZS Dense Link Based ZS ------------------------------------------------- struct zsEncoderDenseLinkBased : public zsEncoderLinkBased { - bool checkInput(std::vector& tmpBuffer, unsigned int k); - unsigned int encodeSequence(std::vector& tmpBuffer, unsigned int k); - void decodePage(std::vector& outputBuffer, const zsPage* page, unsigned int endpoint, unsigned int firstOrbit, unsigned int triggerBC = 0); + bool checkInput(std::vector& tmpBuffer, uint32_t k); + uint32_t encodeSequence(std::vector& tmpBuffer, uint32_t k); + void decodePage(std::vector& outputBuffer, const zsPage* page, uint32_t endpoint, uint32_t firstOrbit, uint32_t triggerBC = 0); bool writeSubPage(); void initPage(); - void amendPageErrorMessage(std::ostringstream& oss, const o2::header::RAWDataHeader* rdh, const TPCZSHDRV2* decHDR, const unsigned char* payloadEnd, const unsigned char* decPagePtr, unsigned int nOutput); + void amendPageErrorMessage(std::ostringstream& oss, const o2::header::RAWDataHeader* rdh, const TPCZSHDRV2* decHDR, const uint8_t* payloadEnd, const uint8_t* decPagePtr, uint32_t nOutput); - unsigned short curTimeBin = 0; - std::vector sequenceBuffer; - std::vector sequenceBufferADC; + uint16_t curTimeBin = 0; + std::vector sequenceBuffer; + std::vector sequenceBufferADC; - constexpr static int RAWLNK = rdh_utils::DLBZSLinkID; - constexpr static int v2nbits = 10; + constexpr static int32_t RAWLNK = rdh_utils::DLBZSLinkID; + constexpr static int32_t v2nbits = 10; }; -bool zsEncoderDenseLinkBased::checkInput(std::vector& tmpBuffer, unsigned int k) +bool zsEncoderDenseLinkBased::checkInput(std::vector& tmpBuffer, uint32_t k) { createBitmask(tmpBuffer, k); finishPage = endpoint != lastEndpoint; - unsigned short newTimeBin = tmpBuffer[k].getTimeStamp() - firstTimebinInPage; + uint16_t newTimeBin = tmpBuffer[k].getTimeStamp() - firstTimebinInPage; bool retVall = finishPage || newTimeBin != curTimeBin; return retVall; } -unsigned int zsEncoderDenseLinkBased::encodeSequence(std::vector& tmpBuffer, unsigned int k) +uint32_t zsEncoderDenseLinkBased::encodeSequence(std::vector& tmpBuffer, uint32_t k) { if (sequenceBuffer.size() == 0) { - unsigned short bc = (long)tmpBuffer[k].getTimeStamp() * LHCBCPERTIMEBIN - (long)hbf * o2::constants::lhc::LHCMaxBunches; + uint16_t bc = (int64_t)tmpBuffer[k].getTimeStamp() * LHCBCPERTIMEBIN - (int64_t)hbf * o2::constants::lhc::LHCMaxBunches; if (zsVersion == ZSVersion::ZSVersionDenseLinkBasedV2) { bc &= 0xFFC; } @@ -781,10 +781,10 @@ unsigned int zsEncoderDenseLinkBased::encodeSequence(std::vector sequenceBuffer[0]++; sequenceBuffer.emplace_back(link); - unsigned char* plink = &sequenceBuffer.back(); + uint8_t* plink = &sequenceBuffer.back(); std::bitset<10> bitmaskL2; - for (int i = 9; i >= 0; i--) { + for (int32_t i = 9; i >= 0; i--) { bitmaskL2.set(i, ((bitmask >> (i * 8)) & std::bitset<80>(0xFF)).any()); } if (bitmaskL2.all()) { @@ -794,7 +794,7 @@ unsigned int zsEncoderDenseLinkBased::encodeSequence(std::vector sequenceBuffer.emplace_back(bitmaskL2.to_ulong() & 0xFF); } - for (int i = 0; i < 10; i++) { + for (int32_t i = 0; i < 10; i++) { if (bitmaskL2.test(i)) { sequenceBuffer.emplace_back(((bitmask >> (i * 8)) & std::bitset<80>(0xFF)).to_ulong()); } @@ -810,34 +810,34 @@ unsigned int zsEncoderDenseLinkBased::encodeSequence(std::vector bool zsEncoderDenseLinkBased::writeSubPage() { - unsigned int offset = sequenceBuffer.size(); + uint32_t offset = sequenceBuffer.size(); if (sequenceBufferADC.size()) { bool need12bit = zsVersion != ZSVersion::ZSVersionDenseLinkBasedV2; - unsigned int needNow = 0; + uint32_t needNow = 0; if (zsVersion == ZSVersion::ZSVersionDenseLinkBasedV2) { - for (unsigned int i = 0; i < sequenceBufferADC.size(); i++) { + for (uint32_t i = 0; i < sequenceBufferADC.size(); i++) { if (sequenceBufferADC[i] >= (1 << v2nbits)) { need12bit = true; break; } } } - unsigned int encodeBitsBlock = encodeBits; + uint32_t encodeBitsBlock = encodeBits; if (!need12bit) { encodeBitsBlock = v2nbits; sequenceBuffer[0] |= 0x10; } sequenceBuffer.resize(offset + (sequenceBufferADC.size() * encodeBitsBlock + 7) / 8); - unsigned int tmp = 0; - unsigned int tmpIn = sequenceBufferADC.size(); + uint32_t tmp = 0; + uint32_t tmpIn = sequenceBufferADC.size(); ZSstreamOut(sequenceBufferADC.data(), tmpIn, sequenceBuffer.data() + offset, tmp, encodeBitsBlock); sequenceBufferADC.clear(); } if (sequenceBuffer.size()) { - unsigned int sizeLeft = TPCZSHDR::TPC_ZS_PAGE_SIZE - (pagePtr - (unsigned char*)page) - sizeof(TPCZSHDRV2) - (hdr->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0); - unsigned int size = sequenceBuffer.size(); - unsigned int fill = std::min(sizeLeft, size); + uint32_t sizeLeft = TPCZSHDR::TPC_ZS_PAGE_SIZE - (pagePtr - (uint8_t*)page) - sizeof(TPCZSHDRV2) - (hdr->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0); + uint32_t size = sequenceBuffer.size(); + uint32_t fill = std::min(sizeLeft, size); memcpy(pagePtr, sequenceBuffer.data(), fill); pagePtr += fill; if (size != fill) { @@ -863,10 +863,10 @@ void zsEncoderDenseLinkBased::initPage() hdr->flags = 0; } -void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuffer, const zsPage* decPage, unsigned int decEndpoint, unsigned int firstOrbit, unsigned int triggerBC) +void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuffer, const zsPage* decPage, uint32_t decEndpoint, uint32_t firstOrbit, uint32_t triggerBC) { const auto& mapper = Mapper::instance(); - const unsigned char* decPagePtr = reinterpret_cast(decPage); + const uint8_t* decPagePtr = reinterpret_cast(decPage); const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)decPagePtr; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { return; @@ -879,21 +879,21 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff if (decHDR->magicWord != o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader) { throw std::runtime_error("Magic word missing"); } - const unsigned char* payloadEnd = ((const unsigned char*)decPage) + o2::raw::RDHUtils::getMemorySize(*rdh) - sizeof(TPCZSHDRV2) - ((decHDR->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0); + const uint8_t* payloadEnd = ((const uint8_t*)decPage) + o2::raw::RDHUtils::getMemorySize(*rdh) - sizeof(TPCZSHDRV2) - ((decHDR->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0); const float decodeBitsFactor = 1.f / (1 << (encodeBits - 10)); - int cruid = decHDR->cruID; - unsigned int sector = cruid / 10; + int32_t cruid = decHDR->cruID; + uint32_t sector = cruid / 10; if (sector != iSector) { throw std::runtime_error("invalid TPC sector"); } - int region = cruid % 10; + int32_t region = cruid % 10; decPagePtr += decHDR->firstZSDataOffset - sizeof(o2::header::RAWDataHeader); - std::vector tmpBuffer; + std::vector tmpBuffer; bool extendFailure = false; - unsigned int nOutput = 0; - unsigned int minTimeBin = -1, maxTimeBin = 0; - for (unsigned int i = 0; i < decHDR->nTimebinHeaders; i++) { - int sizeLeftInPage = payloadEnd - decPagePtr; + uint32_t nOutput = 0; + uint32_t minTimeBin = -1, maxTimeBin = 0; + for (uint32_t i = 0; i < decHDR->nTimebinHeaders; i++) { + int32_t sizeLeftInPage = payloadEnd - decPagePtr; if (sizeLeftInPage <= 0) { throw std::runtime_error("Decoding ran beyond end of page before processing extended timebin"); } @@ -902,11 +902,11 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff throw std::runtime_error("pageExtends signaled, but current page is not full"); } - const unsigned char* pageNext = ((const unsigned char*)decPage) + TPCZSHDR::TPC_ZS_PAGE_SIZE; + const uint8_t* pageNext = ((const uint8_t*)decPage) + TPCZSHDR::TPC_ZS_PAGE_SIZE; const o2::header::RAWDataHeader* rdhNext = (const o2::header::RAWDataHeader*)pageNext; - if ((unsigned short)(o2::raw::RDHUtils::getPageCounter(*rdh) + 1) != o2::raw::RDHUtils::getPageCounter(*rdhNext)) { - GPUError("Incomplete HBF: Payload extended to next page, but next page missing in stream (packet counters %d %d)", (int)o2::raw::RDHUtils::getPageCounter(*rdh), (int)o2::raw::RDHUtils::getPageCounter(*rdhNext)); + if ((uint16_t)(o2::raw::RDHUtils::getPageCounter(*rdh) + 1) != o2::raw::RDHUtils::getPageCounter(*rdhNext)) { + GPUError("Incomplete HBF: Payload extended to next page, but next page missing in stream (packet counters %d %d)", (int32_t)o2::raw::RDHUtils::getPageCounter(*rdh), (int32_t)o2::raw::RDHUtils::getPageCounter(*rdhNext)); extendFailure = true; decPagePtr = payloadEnd; // Next 8kb page is missing in stream, cannot decode remaining data, skip it break; @@ -919,33 +919,33 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff decPagePtr = tmpBuffer.data(); payloadEnd = decPagePtr + tmpBuffer.size(); } - unsigned char linkCount = *((const unsigned char*)decPagePtr) & 0x0F; - unsigned short linkBC = (*((const unsigned short*)decPagePtr) & 0xFFF0) >> 4; - bool v2Flag = decHDR->version == ZSVersion::ZSVersionDenseLinkBasedV2 && *((const unsigned char*)decPagePtr) & 0x10; + uint8_t linkCount = *((const uint8_t*)decPagePtr) & 0x0F; + uint16_t linkBC = (*((const uint16_t*)decPagePtr) & 0xFFF0) >> 4; + bool v2Flag = decHDR->version == ZSVersion::ZSVersionDenseLinkBasedV2 && *((const uint8_t*)decPagePtr) & 0x10; if (decHDR->version == ZSVersion::ZSVersionDenseLinkBasedV2) { linkBC &= 0xFFC; } - decPagePtr += sizeof(unsigned short); - std::vector links; + decPagePtr += sizeof(uint16_t); + std::vector links; std::vector> bitmasks; - unsigned int nTotalSamples = 0; - for (unsigned int l = 0; l < linkCount; l++) { - unsigned char decLinkX = *((const unsigned char*)decPagePtr); - decPagePtr += sizeof(unsigned char); - unsigned char decLink = decLinkX & 0b00011111; + uint32_t nTotalSamples = 0; + for (uint32_t l = 0; l < linkCount; l++) { + uint8_t decLinkX = *((const uint8_t*)decPagePtr); + decPagePtr += sizeof(uint8_t); + uint8_t decLink = decLinkX & 0b00011111; std::bitset<10> bitmaskL2; if (decLinkX & 0b00100000) { bitmaskL2.set(); } else { - bitmaskL2 = std::bitset<10>(((((unsigned short)decLinkX) & 0b11000000) << 2) | (unsigned short)*((const unsigned char*)decPagePtr)); - decPagePtr += sizeof(unsigned char); + bitmaskL2 = std::bitset<10>(((((uint16_t)decLinkX) & 0b11000000) << 2) | (uint16_t) * ((const uint8_t*)decPagePtr)); + decPagePtr += sizeof(uint8_t); } std::bitset<80> bitmask(0); - for (int i = 0; i < 10; i++) { + for (int32_t i = 0; i < 10; i++) { if (bitmaskL2.test(i)) { - bitmask |= std::bitset<80>(*((const unsigned char*)decPagePtr)) << i * 8; - decPagePtr += sizeof(unsigned char); + bitmask |= std::bitset<80>(*((const uint8_t*)decPagePtr)) << i * 8; + decPagePtr += sizeof(uint8_t); } } links.emplace_back(decLink); @@ -953,12 +953,12 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff nTotalSamples += bitmask.count(); } - const unsigned char* adcData = (const unsigned char*)decPagePtr; - int encodeBitsBlock = v2Flag ? v2nbits : encodeBits; + const uint8_t* adcData = (const uint8_t*)decPagePtr; + int32_t encodeBitsBlock = v2Flag ? v2nbits : encodeBits; decPagePtr += (nTotalSamples * encodeBitsBlock + 7) / 8; // time bin might be smaller 0 due to triggerBC - int timeBin = (int(linkBC) + (int)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - int(triggerBC)) / LHCBCPERTIMEBIN; + int32_t timeBin = (int32_t(linkBC) + (int32_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - int32_t(triggerBC)) / LHCBCPERTIMEBIN; if (timeBin < 0 || nTotalSamples == 0) { if (timeBin < 0 && nTotalSamples > 0) { LOGP(debug, "zsEncoderDenseLinkBased::decodePage skipping digits (linkBC {} + orbit {} - firstOrbit {}) * maxBunch {} - triggerBC {} = {} < 0, nTotalSamples {}", linkBC, o2::raw::RDHUtils::getHeartBeatOrbit(*rdh), firstOrbit, o2::constants::lhc::LHCMaxBunches, triggerBC, timeBin, nTotalSamples); @@ -972,9 +972,9 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff minTimeBin = timeBin; } - std::vector samples(nTotalSamples); - unsigned int mask = (1 << encodeBitsBlock) - 1; - unsigned int byte = 0, bits = 0, posXbits = 0; + std::vector samples(nTotalSamples); + uint32_t mask = (1 << encodeBitsBlock) - 1; + uint32_t byte = 0, bits = 0, posXbits = 0; while (posXbits < nTotalSamples) { byte |= *(adcData++) << bits; bits += 8; @@ -984,16 +984,16 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff bits -= encodeBitsBlock; } } - unsigned int samplePos = 0; + uint32_t samplePos = 0; - for (unsigned int l = 0; l < linkCount; l++) { - unsigned char decLink = links[l]; + for (uint32_t l = 0; l < linkCount; l++) { + uint8_t decLink = links[l]; const auto& bitmask = bitmasks[l]; - int nADC = bitmask.count(); + int32_t nADC = bitmask.count(); - for (int j = 0; j < bitmask.size(); j++) { + for (int32_t j = 0; j < bitmask.size(); j++) { if (bitmask[j]) { - int sampaOnFEC = 0, channelOnSAMPA = 0; + int32_t sampaOnFEC = 0, channelOnSAMPA = 0; mapper.getSampaAndChannelOnFEC(cruid, j, sampaOnFEC, channelOnSAMPA); const auto padSecPos = mapper.padSecPos(cruid, decLink, sampaOnFEC, channelOnSAMPA); const auto& padPos = padSecPos.getPadPos(); @@ -1004,12 +1004,12 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff } } - int hdrMinTimeBin = (int(decHDR->timeOffset) + int(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - triggerBC); + int32_t hdrMinTimeBin = (int32_t(decHDR->timeOffset) + int32_t(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - triggerBC); if (triggerBC > 0 && hdrMinTimeBin < 0) { hdrMinTimeBin = 0; } hdrMinTimeBin /= LHCBCPERTIMEBIN; - int hdrMaxTimeBin = hdrMinTimeBin + decHDR->nTimeBinSpan + ((decHDR->flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) ? 256 : 0); + int32_t hdrMaxTimeBin = hdrMinTimeBin + decHDR->nTimeBinSpan + ((decHDR->flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) ? 256 : 0); if (!extendFailure && nOutput != decHDR->nADCsamples) { std::ostringstream oss; @@ -1039,7 +1039,7 @@ void zsEncoderDenseLinkBased::decodePage(std::vector& outputBuff } } -void zsEncoderDenseLinkBased::amendPageErrorMessage(std::ostringstream& oss, const o2::header::RAWDataHeader* rdh, const TPCZSHDRV2* decHDR, const unsigned char* payloadEnd, const unsigned char* decPagePtr, unsigned int nOutput) +void zsEncoderDenseLinkBased::amendPageErrorMessage(std::ostringstream& oss, const o2::header::RAWDataHeader* rdh, const TPCZSHDRV2* decHDR, const uint8_t* payloadEnd, const uint8_t* decPagePtr, uint32_t nOutput) { if (payloadEnd && decPagePtr) { oss << " (payloadEnd " << (void*)payloadEnd << " - decPagePtr " << (void*)decPagePtr << " - " << (payloadEnd - decPagePtr) << " bytes left, " << nOutput << " of " << decHDR->nADCsamples << " digits decoded)\n"; @@ -1049,11 +1049,11 @@ void zsEncoderDenseLinkBased::amendPageErrorMessage(std::ostringstream& oss, con constexpr size_t bufferSize = 3 * std::max(sizeof(*rdh), sizeof(*decHDR)) + 1; char dumpBuffer[bufferSize]; for (size_t i = 0; i < sizeof(*rdh); i++) { - snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int)((unsigned char*)rdh)[i]); + snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int32_t)((uint8_t*)rdh)[i]); } oss << "RDH of page: " << dumpBuffer << "\n"; for (size_t i = 0; i < sizeof(*decHDR); i++) { - snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int)((unsigned char*)decHDR)[i]); + snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int32_t)((uint8_t*)decHDR)[i]); } oss << "Meta header of page: " << dumpBuffer << "\n"; } @@ -1064,7 +1064,7 @@ void zsEncoderDenseLinkBased::amendPageErrorMessage(std::ostringstream& oss, con template struct zsEncoderRun : public T { - unsigned int run(std::vector* buffer, std::vector& tmpBuffer, size_t* totalSize = nullptr); + uint32_t run(std::vector* buffer, std::vector& tmpBuffer, size_t* totalSize = nullptr); size_t compare(std::vector* buffer, std::vector& tmpBuffer); using T::bcShiftInFirstHBF; @@ -1104,23 +1104,23 @@ struct zsEncoderRun : public T { }; template -inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vector& tmpBuffer, size_t* totalSize) +inline uint32_t zsEncoderRun::run(std::vector* buffer, std::vector& tmpBuffer, size_t* totalSize) { - unsigned int totalPages = 0; + uint32_t totalPages = 0; zsPage singleBuffer; #ifdef GPUCA_O2_LIB - int maxhbf = 0; - int minhbf = o2::constants::lhc::LHCMaxBunches; + int32_t maxhbf = 0; + int32_t minhbf = o2::constants::lhc::LHCMaxBunches; #endif bcShiftInFirstHBF = ir ? ir->bc : 0; - int orbitShift = ir ? ir->orbit : 0; - int rawcru = 0; - int rawendpoint = 0; + int32_t orbitShift = ir ? ir->orbit : 0; + int32_t rawcru = 0; + int32_t rawendpoint = 0; (void)(rawcru + rawendpoint); // avoid compiler warning encodeBitsFactor = (1 << (encodeBits - 10)); std::sort(tmpBuffer.begin(), tmpBuffer.end(), [this](const o2::tpc::Digit a, const o2::tpc::Digit b) { return sort(a, b); }); - for (unsigned int k = 0; k <= tmpBuffer.size();) { + for (uint32_t k = 0; k <= tmpBuffer.size();) { bool mustWritePage = false, mustWriteSubPage = false; if (needAnotherPage) { needAnotherPage = false; @@ -1151,13 +1151,13 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto if (page && mustWritePage) { if constexpr (std::is_same_v) { - if ((pagePtr - (unsigned char*)page) % o2::raw::RDHUtils::GBTWord128) { - pagePtr += o2::raw::RDHUtils::GBTWord128 - (pagePtr - (unsigned char*)page) % o2::raw::RDHUtils::GBTWord128; + if ((pagePtr - (uint8_t*)page) % o2::raw::RDHUtils::GBTWord128) { + pagePtr += o2::raw::RDHUtils::GBTWord128 - (pagePtr - (uint8_t*)page) % o2::raw::RDHUtils::GBTWord128; } - unsigned char* triggerWord = nullptr; + uint8_t* triggerWord = nullptr; if (hbf != nexthbf || endpoint != lastEndpoint) { - if ((pagePtr - (unsigned char*)page) + sizeof(TPCZSHDRV2) + o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE <= TPCZSHDR::TPC_ZS_PAGE_SIZE) { - if ((pagePtr - (unsigned char*)page) % (2 * o2::raw::RDHUtils::GBTWord128)) { + if ((pagePtr - (uint8_t*)page) + sizeof(TPCZSHDRV2) + o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE <= TPCZSHDR::TPC_ZS_PAGE_SIZE) { + if ((pagePtr - (uint8_t*)page) % (2 * o2::raw::RDHUtils::GBTWord128)) { pagePtr += o2::raw::RDHUtils::GBTWord128; // align to 256 bit, size constrained cannot be affected by this } hdr->flags |= o2::tpc::TPCZSHDRV2::ZSFlags::TriggerWordPresent; @@ -1172,12 +1172,12 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto triggerWord = pagePtr; pagePtr += o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE; } - if ((pagePtr - (unsigned char*)page) % (2 * o2::raw::RDHUtils::GBTWord128) == 0) { + if ((pagePtr - (uint8_t*)page) % (2 * o2::raw::RDHUtils::GBTWord128) == 0) { pagePtr += o2::raw::RDHUtils::GBTWord128; // align to 128bit mod 256 } TPCZSHDRV2* pagehdr = (TPCZSHDRV2*)pagePtr; pagePtr += sizeof(TPCZSHDRV2); - if (pagePtr - (unsigned char*)page > TPCZSHDR::TPC_ZS_PAGE_SIZE) { + if (pagePtr - (uint8_t*)page > TPCZSHDR::TPC_ZS_PAGE_SIZE) { throw std::runtime_error("TPC ZS page overflow"); } memcpy(pagehdr, hdr, sizeof(*hdr)); @@ -1187,15 +1187,15 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto } const rdh_utils::FEEIDType rawfeeid = rdh_utils::getFEEID(rawcru, rawendpoint, this->RAWLNK); if (totalSize) { - *totalSize += !std::is_same_v && (lastEndpoint == -1 || hbf == nexthbf) ? TPCZSHDR::TPC_ZS_PAGE_SIZE : (pagePtr - (unsigned char*)page); + *totalSize += !std::is_same_v && (lastEndpoint == -1 || hbf == nexthbf) ? TPCZSHDR::TPC_ZS_PAGE_SIZE : (pagePtr - (uint8_t*)page); } - size_t size = !std::is_same_v && (padding || lastEndpoint == -1 || hbf == nexthbf) ? TPCZSHDR::TPC_ZS_PAGE_SIZE : (pagePtr - (unsigned char*)page); + size_t size = !std::is_same_v && (padding || lastEndpoint == -1 || hbf == nexthbf) ? TPCZSHDR::TPC_ZS_PAGE_SIZE : (pagePtr - (uint8_t*)page); size = CAMath::nextMultipleOf(size); #ifdef GPUCA_O2_LIB if (raw) { raw->addData(rawfeeid, rawcru, 0, rawendpoint, *ir + hbf * o2::constants::lhc::LHCMaxBunches, gsl::span((char*)page + sizeof(o2::header::RAWDataHeader), (char*)page + size), true, 0, 2); - maxhbf = std::max(maxhbf, hbf); - minhbf = std::min(minhbf, hbf); + maxhbf = std::max(maxhbf, hbf); + minhbf = std::min(minhbf, hbf); } else #endif { @@ -1240,7 +1240,7 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto buffer[outputEndpoint].emplace_back(); page = &buffer[outputEndpoint].back(); } - pagePtr = reinterpret_cast(page); + pagePtr = reinterpret_cast(page); std::fill(page->begin(), page->end(), 0); pagePtr += sizeof(o2::header::RAWDataHeader); if constexpr (std::is_same_v) { @@ -1255,7 +1255,7 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto hdr->nADCsamples = 0; rawcru = iSector * 10 + outputRegion; rawendpoint = outputEndpoint & 1; - hdr->timeOffset = (long)(needAnotherPage ? firstTimebinInPage : tmpBuffer[k].getTimeStamp()) * LHCBCPERTIMEBIN - (long)hbf * o2::constants::lhc::LHCMaxBunches; + hdr->timeOffset = (int64_t)(needAnotherPage ? firstTimebinInPage : tmpBuffer[k].getTimeStamp()) * LHCBCPERTIMEBIN - (int64_t)hbf * o2::constants::lhc::LHCMaxBunches; firstTimebinInPage = tmpBuffer[k].getTimeStamp(); initPage(); totalPages++; @@ -1263,7 +1263,7 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto if (needAnotherPage) { continue; } - unsigned int nEncoded = encodeSequence(tmpBuffer, k); + uint32_t nEncoded = encodeSequence(tmpBuffer, k); lastTime = tmpBuffer[k].getTimeStamp(); lastRow = tmpBuffer[k].getRow(); hdr->nADCsamples += nEncoded; @@ -1272,13 +1272,13 @@ inline unsigned int zsEncoderRun::run(std::vector* buffer, std::vecto if (raw) { #ifdef GPUCA_O2_LIB if (iSector == 0) { - for (int i = minhbf; i <= maxhbf; i++) { + for (int32_t i = minhbf; i <= maxhbf; i++) { raw->addData(46208, 360, rdh_utils::SACLinkID, 0, *ir + i * o2::constants::lhc::LHCMaxBunches, gsl::span((char*)&singleBuffer, (char*)&singleBuffer), true, 0, 4); } } #endif } else { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { if (buffer[j].size() == 0) { buffer[j].emplace_back(); ZSfillEmpty(&buffer[j].back(), bcShiftInFirstHBF, rdh_utils::getFEEID(iSector * 10 + j / 2, j & 1, this->RAWLNK), orbitShift, this->RAWLNK); @@ -1295,27 +1295,27 @@ size_t zsEncoderRun::compare(std::vector* buffer, std::vector compareBuffer; compareBuffer.reserve(tmpBuffer.size()); - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - unsigned int firstOrbit = ir ? ir->orbit : 0; - for (unsigned int k = 0; k < buffer[j].size(); k++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + uint32_t firstOrbit = ir ? ir->orbit : 0; + for (uint32_t k = 0; k < buffer[j].size(); k++) { zsPage* decPage = &buffer[j][k]; decodePage(compareBuffer, decPage, j, firstOrbit); } } if (tmpBuffer.size() != compareBuffer.size()) { nErrors += tmpBuffer.size(); - printf("Number of clusters mismatch %d %d\n", (int)tmpBuffer.size(), (int)compareBuffer.size()); + printf("Number of clusters mismatch %d %d\n", (int32_t)tmpBuffer.size(), (int32_t)compareBuffer.size()); } else { - for (unsigned int j = 0; j < tmpBuffer.size(); j++) { + for (uint32_t j = 0; j < tmpBuffer.size(); j++) { const float decodeBitsFactor = (1 << (encodeBits - 10)); const float c = CAMath::Round(tmpBuffer[j].getChargeFloat() * decodeBitsFactor) / decodeBitsFactor; - int ok = c == compareBuffer[j].getChargeFloat() && (int)tmpBuffer[j].getTimeStamp() == (int)compareBuffer[j].getTimeStamp() && (int)tmpBuffer[j].getPad() == (int)compareBuffer[j].getPad() && (int)tmpBuffer[j].getRow() == (int)compareBuffer[j].getRow(); + int32_t ok = c == compareBuffer[j].getChargeFloat() && (int32_t)tmpBuffer[j].getTimeStamp() == (int32_t)compareBuffer[j].getTimeStamp() && (int32_t)tmpBuffer[j].getPad() == (int32_t)compareBuffer[j].getPad() && (int32_t)tmpBuffer[j].getRow() == (int32_t)compareBuffer[j].getRow(); if (ok) { continue; } nErrors++; printf("%4u: OK %d: Charge %3d %3d Time %4d %4d Pad %3d %3d Row %3d %3d\n", j, ok, - (int)c, (int)compareBuffer[j].getChargeFloat(), (int)tmpBuffer[j].getTimeStamp(), (int)compareBuffer[j].getTimeStamp(), (int)tmpBuffer[j].getPad(), (int)compareBuffer[j].getPad(), (int)tmpBuffer[j].getRow(), (int)compareBuffer[j].getRow()); + (int32_t)c, (int32_t)compareBuffer[j].getChargeFloat(), (int32_t)tmpBuffer[j].getTimeStamp(), (int32_t)compareBuffer[j].getTimeStamp(), (int32_t)tmpBuffer[j].getPad(), (int32_t)compareBuffer[j].getPad(), (int32_t)tmpBuffer[j].getRow(), (int32_t)compareBuffer[j].getRow()); } } return nErrors; @@ -1325,7 +1325,7 @@ size_t zsEncoderRun::compare(std::vector* buffer, std::vector -void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) +void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int32_t version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) { // Pass in either outBuffer / outSizes, to fill standalone output buffers, or raw to use RawFileWriter // ir is the interaction record for time bin 0 @@ -1334,7 +1334,7 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr buffer[NSLICES][GPUTrackingInOutZS::NENDPOINTS]; - unsigned int totalPages = 0; + uint32_t totalPages = 0; size_t totalSize = 0; size_t nErrors = 0; size_t digitsInput = 0; @@ -1342,7 +1342,7 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr tmpBuffer; digitsInput += ZSEncoderGetNDigits(in, i); tmpBuffer.resize(ZSEncoderGetNDigits(in, i)); @@ -1394,10 +1394,10 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptrreset(new unsigned long[totalPages * TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned long)]); - unsigned long offset = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + outBuffer->reset(new uint64_t[totalPages * TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint64_t)]); + uint64_t offset = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { memcpy((char*)outBuffer->get() + offset, buffer[i][j].data(), buffer[i][j].size() * TPCZSHDR::TPC_ZS_PAGE_SIZE); offset += buffer[i][j].size() * TPCZSHDR::TPC_ZS_PAGE_SIZE; outSizes[i * GPUTrackingInOutZS::NENDPOINTS + j] = buffer[i][j].size(); @@ -1405,7 +1405,7 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr(const GPUTrackingInOutDigits&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); +template void GPUReconstructionConvert::RunZSEncoder(const GPUTrackingInOutDigits&, std::unique_ptr*, uint32_t*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int32_t, bool, float, bool, std::function&)> digitsFilter); #ifdef GPUCA_O2_LIB -template void GPUReconstructionConvert::RunZSEncoder(const DigitArray&, std::unique_ptr*, unsigned int*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int, bool, float, bool, std::function&)> digitsFilter); +template void GPUReconstructionConvert::RunZSEncoder(const DigitArray&, std::unique_ptr*, uint32_t*, o2::raw::RawFileWriter*, const o2::InteractionRecord*, const GPUParam&, int32_t, bool, float, bool, std::function&)> digitsFilter); #endif #endif -void GPUReconstructionConvert::RunZSEncoderCreateMeta(const unsigned long* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out) +void GPUReconstructionConvert::RunZSEncoderCreateMeta(const uint64_t* buffer, const uint32_t* sizes, void** ptrs, GPUTrackingInOutZS* out) { - unsigned long offset = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + uint64_t offset = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { ptrs[i * GPUTrackingInOutZS::NENDPOINTS + j] = (char*)buffer + offset; offset += sizes[i * GPUTrackingInOutZS::NENDPOINTS + j] * TPCZSHDR::TPC_ZS_PAGE_SIZE; out->slice[i].zsPtr[j] = &ptrs[i * GPUTrackingInOutZS::NENDPOINTS + j]; @@ -1437,14 +1437,14 @@ void GPUReconstructionConvert::RunZSEncoderCreateMeta(const unsigned long* buffe void GPUReconstructionConvert::RunZSFilter(std::unique_ptr* buffers, const o2::tpc::Digit* const* ptrs, size_t* nsb, const size_t* ns, const GPUParam& param, bool zs12bit, float threshold) { #ifdef GPUCA_HAVE_O2HEADERS - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { if (buffers[i].get() != ptrs[i] || nsb != ns) { throw std::runtime_error("Not owning digits"); } - unsigned int j = 0; - const unsigned int decodeBits = zs12bit ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; + uint32_t j = 0; + const uint32_t decodeBits = zs12bit ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; const float decodeBitsFactor = (1 << (decodeBits - 10)); - for (unsigned int k = 0; k < ns[i]; k++) { + for (uint32_t k = 0; k < ns[i]; k++) { if (buffers[i][k].getChargeFloat() >= threshold) { if (k > j) { buffers[i][j] = buffers[i][k]; @@ -1464,7 +1464,7 @@ void GPUReconstructionConvert::RunZSFilter(std::unique_ptr* bu #ifdef GPUCA_O2_LIB template -static inline auto GetDecoder_internal(const GPUParam* param, int version) +static inline auto GetDecoder_internal(const GPUParam* param, int32_t version) { std::shared_ptr enc = std::make_shared(); if (param == nullptr) { @@ -1474,7 +1474,7 @@ static inline auto GetDecoder_internal(const GPUParam* param, int version) enc->param = param; enc->zsVersion = version; enc->init(); - return [enc](std::vector& outBuffer, const void* page, unsigned int firstTfOrbit, unsigned int triggerBC = 0) { + return [enc](std::vector& outBuffer, const void* page, uint32_t firstTfOrbit, uint32_t triggerBC = 0) { const o2::header::RAWDataHeader& rdh = *(const o2::header::RAWDataHeader*)page; if (o2::raw::RDHUtils::getMemorySize(rdh) == sizeof(o2::header::RAWDataHeader)) { return; @@ -1484,12 +1484,12 @@ static inline auto GetDecoder_internal(const GPUParam* param, int version) } o2::tpc::CRU cru(o2::tpc::rdh_utils::getCRU(rdh)); enc->iSector = cru.sector(); - int endpoint = cru.region() * 2 + o2::tpc::rdh_utils::getEndPoint(rdh); + int32_t endpoint = cru.region() * 2 + o2::tpc::rdh_utils::getEndPoint(rdh); enc->decodePage(outBuffer, (const zsPage*)page, endpoint, firstTfOrbit, triggerBC); }; } -std::function&, const void*, unsigned int, unsigned int)> GPUReconstructionConvert::GetDecoder(int version, const GPUParam* param) +std::function&, const void*, uint32_t, uint32_t)> GPUReconstructionConvert::GetDecoder(int32_t version, const GPUParam* param) { if (version >= o2::tpc::ZSVersion::ZSVersionRowBased10BitADC && version <= o2::tpc::ZSVersion::ZSVersionRowBased12BitADC) { return GetDecoder_internal(param, version); diff --git a/GPU/GPUTracking/Base/GPUReconstructionConvert.h b/GPU/GPUTracking/Base/GPUReconstructionConvert.h index 8ff66491c947e..6e0f80d6678b9 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionConvert.h +++ b/GPU/GPUTracking/Base/GPUReconstructionConvert.h @@ -50,17 +50,17 @@ struct GPUTrackingInOutZS; class GPUReconstructionConvert { public: - constexpr static unsigned int NSLICES = GPUCA_NSLICES; - static void ConvertNativeToClusterData(o2::tpc::ClusterNativeAccess* native, std::unique_ptr* clusters, unsigned int* nClusters, const TPCFastTransform* transform, int continuousMaxTimeBin = 0); - static void ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess& native, std::unique_ptr& nativeBuffer, const AliHLTTPCRawCluster** rawClusters, unsigned int* nRawClusters); + constexpr static uint32_t NSLICES = GPUCA_NSLICES; + static void ConvertNativeToClusterData(o2::tpc::ClusterNativeAccess* native, std::unique_ptr* clusters, uint32_t* nClusters, const TPCFastTransform* transform, int32_t continuousMaxTimeBin = 0); + static void ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess& native, std::unique_ptr& nativeBuffer, const AliHLTTPCRawCluster** rawClusters, uint32_t* nRawClusters); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); - static void RunZSEncoderCreateMeta(const unsigned long* buffer, const unsigned int* sizes, void** ptrs, GPUTrackingInOutZS* out); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, const GPUParam& param, int32_t version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoderCreateMeta(const uint64_t* buffer, const uint32_t* sizes, void** ptrs, GPUTrackingInOutZS* out); static void RunZSFilter(std::unique_ptr* buffers, const o2::tpc::Digit* const* ptrs, size_t* nsb, const size_t* ns, const GPUParam& param, bool zs12bit, float threshold); - static int GetMaxTimeBin(const o2::tpc::ClusterNativeAccess& native); - static int GetMaxTimeBin(const GPUTrackingInOutDigits& digits); - static int GetMaxTimeBin(const GPUTrackingInOutZS& zspages); - static std::function&, const void*, unsigned int, unsigned int)> GetDecoder(int version, const GPUParam* param); + static int32_t GetMaxTimeBin(const o2::tpc::ClusterNativeAccess& native); + static int32_t GetMaxTimeBin(const GPUTrackingInOutDigits& digits); + static int32_t GetMaxTimeBin(const GPUTrackingInOutZS& zspages); + static std::function&, const void*, uint32_t, uint32_t)> GetDecoder(int32_t version, const GPUParam* param); }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx index 95f4ea50ae046..452a32988dbbb 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx @@ -67,7 +67,7 @@ void* GPUReconstructionDeviceBase::helperWrapper(GPUReconstructionHelpers::helpe par->mutex[0].lock(); while (par->terminate == false) { - for (int i = par->num + 1; i < par->count; i += mProcessingSettings.nDeviceHelperThreads + 1) { + for (int32_t i = par->num + 1; i < par->count; i += mProcessingSettings.nDeviceHelperThreads + 1) { // if (mProcessingSettings.debugLevel >= 3) GPUInfo("\tHelper Thread %d Running, Slice %d+%d, Phase %d", par->num, i, par->phase); if ((par->functionCls->*par->function)(i, par->num + 1, par)) { par->error = 1; @@ -98,7 +98,7 @@ void GPUReconstructionDeviceBase::ResetThisHelperThread(GPUReconstructionHelpers par->mutex[1].unlock(); } -int GPUReconstructionDeviceBase::GetGlobalLock(void*& pLock) +int32_t GPUReconstructionDeviceBase::GetGlobalLock(void*& pLock) { #ifdef _WIN32 HANDLE* semLock = new HANDLE; @@ -144,11 +144,11 @@ void GPUReconstructionDeviceBase::ReleaseGlobalLock(void* sem) #endif } -void GPUReconstructionDeviceBase::ResetHelperThreads(int helpers) +void GPUReconstructionDeviceBase::ResetHelperThreads(int32_t helpers) { GPUImportant("Error occurred, GPU tracker helper threads will be reset (Number of threads %d (%d))", mProcessingSettings.nDeviceHelperThreads, mNSlaveThreads); SynchronizeGPU(); - for (int i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { + for (int32_t i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { mHelperParams[i].reset = true; if (helpers || i >= mProcessingSettings.nDeviceHelperThreads) { pthread_mutex_lock(&((pthread_mutex_t*)mHelperParams[i].mutex)[1]); @@ -157,9 +157,9 @@ void GPUReconstructionDeviceBase::ResetHelperThreads(int helpers) GPUImportant("GPU Tracker helper threads have ben reset"); } -int GPUReconstructionDeviceBase::StartHelperThreads() +int32_t GPUReconstructionDeviceBase::StartHelperThreads() { - int nThreads = mProcessingSettings.nDeviceHelperThreads; + int32_t nThreads = mProcessingSettings.nDeviceHelperThreads; if (nThreads) { mHelperParams = new GPUReconstructionHelpers::helperParam[nThreads]; if (mHelperParams == nullptr) { @@ -167,12 +167,12 @@ int GPUReconstructionDeviceBase::StartHelperThreads() ExitDevice(); return (1); } - for (int i = 0; i < nThreads; i++) { + for (int32_t i = 0; i < nThreads; i++) { mHelperParams[i].cls = this; mHelperParams[i].terminate = false; mHelperParams[i].reset = false; mHelperParams[i].num = i; - for (int j = 0; j < 2; j++) { + for (int32_t j = 0; j < 2; j++) { mHelperParams[i].mutex[j].lock(); } @@ -187,10 +187,10 @@ int GPUReconstructionDeviceBase::StartHelperThreads() return (0); } -int GPUReconstructionDeviceBase::StopHelperThreads() +int32_t GPUReconstructionDeviceBase::StopHelperThreads() { if (mNSlaveThreads) { - for (int i = 0; i < mNSlaveThreads; i++) { + for (int32_t i = 0; i < mNSlaveThreads; i++) { mHelperParams[i].terminate = true; mHelperParams[i].mutex[0].unlock(); mHelperParams[i].mutex[1].lock(); @@ -207,14 +207,14 @@ int GPUReconstructionDeviceBase::StopHelperThreads() void GPUReconstructionDeviceBase::WaitForHelperThreads() { - for (int i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { + for (int32_t i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { pthread_mutex_lock(&((pthread_mutex_t*)mHelperParams[i].mutex)[1]); } } -void GPUReconstructionDeviceBase::RunHelperThreads(int (GPUReconstructionHelpers::helperDelegateBase::*function)(int i, int t, GPUReconstructionHelpers::helperParam* p), GPUReconstructionHelpers::helperDelegateBase* functionCls, int count) +void GPUReconstructionDeviceBase::RunHelperThreads(int32_t (GPUReconstructionHelpers::helperDelegateBase::*function)(int32_t i, int32_t t, GPUReconstructionHelpers::helperParam* p), GPUReconstructionHelpers::helperDelegateBase* functionCls, int32_t count) { - for (int i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { + for (int32_t i = 0; i < mProcessingSettings.nDeviceHelperThreads; i++) { mHelperParams[i].done = 0; mHelperParams[i].error = 0; mHelperParams[i].function = function; @@ -224,7 +224,7 @@ void GPUReconstructionDeviceBase::RunHelperThreads(int (GPUReconstructionHelpers } } -int GPUReconstructionDeviceBase::InitDevice() +int32_t GPUReconstructionDeviceBase::InitDevice() { // cpu_set_t mask; // CPU_ZERO(&mask); @@ -250,7 +250,7 @@ int GPUReconstructionDeviceBase::InitDevice() AddGPUEvents(mDebugEvents); } - int retVal = InitDevice_Runtime(); + int32_t retVal = InitDevice_Runtime(); if (retVal) { GPUImportant("GPU Tracker initialization failed"); return (1); @@ -286,13 +286,13 @@ void* GPUReconstructionDeviceBase::GPUProcessorProcessors::SetPointersDeviceProc return mem; } -int GPUReconstructionDeviceBase::ExitDevice() +int32_t GPUReconstructionDeviceBase::ExitDevice() { if (StopHelperThreads()) { return (1); } - int retVal = ExitDevice_Runtime(); + int32_t retVal = ExitDevice_Runtime(); mProcessorsShadow = nullptr; mHostMemoryPool = mHostMemoryBase = mDeviceMemoryPool = mDeviceMemoryBase = mHostMemoryPoolEnd = mDeviceMemoryPoolEnd = mHostMemoryPermanent = mDeviceMemoryPermanent = nullptr; mHostMemorySize = mDeviceMemorySize = 0; @@ -300,12 +300,12 @@ int GPUReconstructionDeviceBase::ExitDevice() return retVal; } -int GPUReconstructionDeviceBase::registerMemoryForGPU_internal(const void* ptr, size_t size) +int32_t GPUReconstructionDeviceBase::registerMemoryForGPU_internal(const void* ptr, size_t size) { return IsGPU(); } -int GPUReconstructionDeviceBase::unregisterMemoryForGPU_internal(const void* ptr) +int32_t GPUReconstructionDeviceBase::unregisterMemoryForGPU_internal(const void* ptr) { return IsGPU(); } @@ -321,7 +321,7 @@ void GPUReconstructionDeviceBase::unregisterRemainingRegisteredMemory() void GPUReconstructionDeviceBase::runConstantRegistrators() { auto& list = getDeviceConstantMemRegistratorsVector(); - for (unsigned int i = 0; i < list.size(); i++) { + for (uint32_t i = 0; i < list.size(); i++) { mDeviceConstantMemList.emplace_back(list[i]()); } } diff --git a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h index 9e119629271ab..6b32301f44b9c 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h +++ b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h @@ -45,40 +45,40 @@ class GPUReconstructionDeviceBase : public GPUReconstructionCPU protected: GPUReconstructionDeviceBase(const GPUSettingsDeviceBackend& cfg, size_t sizeCheck); - int InitDevice() override; - virtual int InitDevice_Runtime() = 0; - int ExitDevice() override; - virtual int ExitDevice_Runtime() = 0; - int registerMemoryForGPU_internal(const void* ptr, size_t size) override; - int unregisterMemoryForGPU_internal(const void* ptr) override; + int32_t InitDevice() override; + virtual int32_t InitDevice_Runtime() = 0; + int32_t ExitDevice() override; + virtual int32_t ExitDevice_Runtime() = 0; + int32_t registerMemoryForGPU_internal(const void* ptr, size_t size) override; + int32_t unregisterMemoryForGPU_internal(const void* ptr) override; void unregisterRemainingRegisteredMemory(); - virtual const GPUTPCTracker* CPUTracker(int iSlice) { return &processors()->tpcTrackers[iSlice]; } + virtual const GPUTPCTracker* CPUTracker(int32_t iSlice) { return &processors()->tpcTrackers[iSlice]; } - int GPUDebug(const char* state = "UNKNOWN", int stream = -1, bool force = false) override = 0; - size_t TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) override = 0; - size_t GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) override = 0; - size_t GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) override; - size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream = -1, deviceEvent* ev = nullptr) override = 0; + int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1, bool force = false) override = 0; + size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override = 0; + size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override = 0; + size_t GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; + size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override = 0; - int StartHelperThreads() override; - int StopHelperThreads() override; - void RunHelperThreads(int (GPUReconstructionHelpers::helperDelegateBase::*function)(int, int, GPUReconstructionHelpers::helperParam*), GPUReconstructionHelpers::helperDelegateBase* functionCls, int count) override; - int HelperError(int iThread) const override { return mHelperParams[iThread].error; } - int HelperDone(int iThread) const override { return mHelperParams[iThread].done; } + int32_t StartHelperThreads() override; + int32_t StopHelperThreads() override; + void RunHelperThreads(int32_t (GPUReconstructionHelpers::helperDelegateBase::*function)(int32_t, int32_t, GPUReconstructionHelpers::helperParam*), GPUReconstructionHelpers::helperDelegateBase* functionCls, int32_t count) override; + int32_t HelperError(int32_t iThread) const override { return mHelperParams[iThread].error; } + int32_t HelperDone(int32_t iThread) const override { return mHelperParams[iThread].done; } void WaitForHelperThreads() override; - void ResetHelperThreads(int helpers) override; + void ResetHelperThreads(int32_t helpers) override; void ResetThisHelperThread(GPUReconstructionHelpers::helperParam* par); - int GetGlobalLock(void*& pLock); + int32_t GetGlobalLock(void*& pLock); void ReleaseGlobalLock(void* sem); static void* helperWrapper_static(void* arg); void* helperWrapper(GPUReconstructionHelpers::helperParam* par); - int mDeviceId = -1; // Device ID used by backend + int32_t mDeviceId = -1; // Device ID used by backend GPUReconstructionHelpers::helperParam* mHelperParams = nullptr; // Control Struct for helper threads - int mNSlaveThreads = 0; // Number of slave threads currently active + int32_t mNSlaveThreads = 0; // Number of slave threads currently active struct DebugEvents { deviceEvent DebugStart, DebugStop; // Debug timer events @@ -94,7 +94,7 @@ class GPUReconstructionDeviceBase : public GPUReconstructionCPU void runConstantRegistrators(); }; -inline size_t GPUReconstructionDeviceBase::GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev, deviceEvent* evList, int nEvents) +inline size_t GPUReconstructionDeviceBase::GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev, deviceEvent* evList, int32_t nEvents) { if (onGpu) { return GPUMemCpy(dst, src, size, stream, toGPU, ev, evList, nEvents); diff --git a/GPU/GPUTracking/Base/GPUReconstructionHelpers.h b/GPU/GPUTracking/Base/GPUReconstructionHelpers.h index a9be3d4c8d1c0..75bce35e02fa1 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionHelpers.h +++ b/GPU/GPUTracking/Base/GPUReconstructionHelpers.h @@ -32,16 +32,16 @@ class GPUReconstructionHelpers struct helperParam { pthread_t threadId; GPUReconstructionDeviceBase* cls; - int num; + int32_t num; std::mutex mutex[2]; - char terminate; + int8_t terminate; helperDelegateBase* functionCls; - int (helperDelegateBase::*function)(int, int, helperParam*); - int phase; - int count; - volatile int done; - volatile char error; - volatile char reset; + int32_t (helperDelegateBase::*function)(int32_t, int32_t, helperParam*); + int32_t phase; + int32_t count; + volatile int32_t done; + volatile int8_t error; + volatile int8_t reset; }; }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/GPUReconstructionIncludesITS.h b/GPU/GPUTracking/Base/GPUReconstructionIncludesITS.h index 665fd494d3147..faf9e0afdf18b 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionIncludesITS.h +++ b/GPU/GPUTracking/Base/GPUReconstructionIncludesITS.h @@ -39,13 +39,13 @@ class TimeFrame class VertexerTraitsGPU : public VertexerTraits { }; -template +template class TrackerTraitsGPU : public TrackerTraits { }; namespace gpu { -template +template class TimeFrameGPU : public TimeFrame { }; diff --git a/GPU/GPUTracking/Base/GPUReconstructionKernelMacros.h b/GPU/GPUTracking/Base/GPUReconstructionKernelMacros.h index 1a48333534f62..de6d5d079cd00 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionKernelMacros.h +++ b/GPU/GPUTracking/Base/GPUReconstructionKernelMacros.h @@ -53,7 +53,7 @@ #define GPUCA_ATTRRES(XX, ...) GPUCA_M_EXPAND(GPUCA_M_CAT(GPUCA_ATTRRES_, GPUCA_M_FIRST(__VA_ARGS__)))(XX, __VA_ARGS__) // GPU Kernel entry point for single sector #define GPUCA_KRNLGPU_SINGLE_DEF(x_class, x_attributes, x_arguments, ...) \ - GPUg() void GPUCA_ATTRRES(,GPUCA_M_SHIFT(GPUCA_M_STRIP(x_attributes))) GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))(GPUCA_CONSMEM_PTR int iSlice_internal GPUCA_M_STRIP(x_arguments)) + GPUg() void GPUCA_ATTRRES(,GPUCA_M_SHIFT(GPUCA_M_STRIP(x_attributes))) GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))(GPUCA_CONSMEM_PTR int32_t iSlice_internal GPUCA_M_STRIP(x_arguments)) #ifdef GPUCA_KRNL_DEFONLY #define GPUCA_KRNLGPU_SINGLE(...) GPUCA_KRNLGPU_SINGLE_DEF(__VA_ARGS__); #else @@ -66,16 +66,16 @@ // GPU Kernel entry point for multiple sector #define GPUCA_KRNLGPU_MULTI_DEF(x_class, x_attributes, x_arguments, ...) \ - GPUg() void GPUCA_ATTRRES(,GPUCA_M_SHIFT(GPUCA_M_STRIP(x_attributes))) GPUCA_M_CAT3(krnl_, GPUCA_M_KRNL_NAME(x_class), _multi)(GPUCA_CONSMEM_PTR int firstSlice, int nSliceCount GPUCA_M_STRIP(x_arguments)) + GPUg() void GPUCA_ATTRRES(,GPUCA_M_SHIFT(GPUCA_M_STRIP(x_attributes))) GPUCA_M_CAT3(krnl_, GPUCA_M_KRNL_NAME(x_class), _multi)(GPUCA_CONSMEM_PTR int32_t firstSlice, int32_t nSliceCount GPUCA_M_STRIP(x_arguments)) #ifdef GPUCA_KRNL_DEFONLY #define GPUCA_KRNLGPU_MULTI(...) GPUCA_KRNLGPU_MULTI_DEF(__VA_ARGS__); #else #define GPUCA_KRNLGPU_MULTI(x_class, x_attributes, x_arguments, x_forward, ...) GPUCA_KRNLGPU_MULTI_DEF(x_class, x_attributes, x_arguments, x_forward, __VA_ARGS__) \ { \ - const int iSlice_internal = nSliceCount * (get_group_id(0) + (get_num_groups(0) % nSliceCount != 0 && nSliceCount * (get_group_id(0) + 1) % get_num_groups(0) != 0)) / get_num_groups(0); \ - const int nSliceBlockOffset = get_num_groups(0) * iSlice_internal / nSliceCount; \ - const int sliceBlockId = get_group_id(0) - nSliceBlockOffset; \ - const int sliceGridDim = get_num_groups(0) * (iSlice_internal + 1) / nSliceCount - get_num_groups(0) * (iSlice_internal) / nSliceCount; \ + const int32_t iSlice_internal = nSliceCount * (get_group_id(0) + (get_num_groups(0) % nSliceCount != 0 && nSliceCount * (get_group_id(0) + 1) % get_num_groups(0) != 0)) / get_num_groups(0); \ + const int32_t nSliceBlockOffset = get_num_groups(0) * iSlice_internal / nSliceCount; \ + const int32_t sliceBlockId = get_group_id(0) - nSliceBlockOffset; \ + const int32_t sliceGridDim = get_num_groups(0) * (iSlice_internal + 1) / nSliceCount - get_num_groups(0) * (iSlice_internal) / nSliceCount; \ GPUshared() typename GPUCA_M_STRIP_FIRST(x_class)::MEM_LOCAL(GPUSharedMemory) smem; \ GPUCA_M_STRIP_FIRST(x_class)::template Thread(sliceGridDim, get_local_size(0), sliceBlockId, get_local_id(0), smem, GPUCA_M_STRIP_FIRST(x_class)::Processor(GPUCA_CONSMEM)[firstSlice + iSlice_internal] GPUCA_M_STRIP(x_forward)); \ } @@ -134,7 +134,7 @@ #define GPUCA_KRNL_PROP(x_class, x_attributes) \ template <> gpu_reconstruction_kernels::krnlProperties GPUCA_KRNL_BACKEND_CLASS::getKernelPropertiesBackend() { \ gpu_reconstruction_kernels::krnlProperties ret = gpu_reconstruction_kernels::krnlProperties{GPUCA_ATTRRES(_INTERNAL_PROP,GPUCA_M_SHIFT(GPUCA_M_STRIP(x_attributes)))}; \ - return ret.nThreads > 0 ? ret : gpu_reconstruction_kernels::krnlProperties{(int)mThreadCount}; \ + return ret.nThreads > 0 ? ret : gpu_reconstruction_kernels::krnlProperties{(int32_t)mThreadCount}; \ } // Generate GPU kernel and host wrapper diff --git a/GPU/GPUTracking/Base/GPUReconstructionKernels.h b/GPU/GPUTracking/Base/GPUReconstructionKernels.h index 840cf8b5944b6..e5c22dd7f3cd5 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionKernels.h +++ b/GPU/GPUTracking/Base/GPUReconstructionKernels.h @@ -39,43 +39,43 @@ struct deviceEvent { void* v = nullptr; // We use only pointers anyway, and since cl_event and cudaEvent_t and hipEvent_t are actually pointers, we can cast them to deviceEvent (void*) this way. }; -template +template struct classArgument { using t = T; - static constexpr int i = I; + static constexpr int32_t i = I; }; struct krnlExec { - constexpr krnlExec(unsigned int b, unsigned int t, int s, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto) : nBlocks(b), nThreads(t), stream(s), device(d), step(GPUCA_RECO_STEP::NoRecoStep) {} - constexpr krnlExec(unsigned int b, unsigned int t, int s, GPUCA_RECO_STEP st) : nBlocks(b), nThreads(t), stream(s), device(GPUReconstruction::krnlDeviceType::Auto), step(st) {} - constexpr krnlExec(unsigned int b, unsigned int t, int s, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) : nBlocks(b), nThreads(t), stream(s), device(d), step(st) {} - unsigned int nBlocks; - unsigned int nThreads; - int stream; + constexpr krnlExec(uint32_t b, uint32_t t, int32_t s, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto) : nBlocks(b), nThreads(t), stream(s), device(d), step(GPUCA_RECO_STEP::NoRecoStep) {} + constexpr krnlExec(uint32_t b, uint32_t t, int32_t s, GPUCA_RECO_STEP st) : nBlocks(b), nThreads(t), stream(s), device(GPUReconstruction::krnlDeviceType::Auto), step(st) {} + constexpr krnlExec(uint32_t b, uint32_t t, int32_t s, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) : nBlocks(b), nThreads(t), stream(s), device(d), step(st) {} + uint32_t nBlocks; + uint32_t nThreads; + int32_t stream; GPUReconstruction::krnlDeviceType device; GPUCA_RECO_STEP step; }; struct krnlRunRange { constexpr krnlRunRange() = default; - constexpr krnlRunRange(unsigned int a) : start(a), num(0) {} - constexpr krnlRunRange(unsigned int s, int n) : start(s), num(n) {} + constexpr krnlRunRange(uint32_t a) : start(a), num(0) {} + constexpr krnlRunRange(uint32_t s, int32_t n) : start(s), num(n) {} - unsigned int start = 0; - int num = 0; + uint32_t start = 0; + int32_t num = 0; }; struct krnlEvent { - constexpr krnlEvent(deviceEvent* e = nullptr, deviceEvent* el = nullptr, int n = 1) : ev(e), evList(el), nEvents(n) {} + constexpr krnlEvent(deviceEvent* e = nullptr, deviceEvent* el = nullptr, int32_t n = 1) : ev(e), evList(el), nEvents(n) {} deviceEvent* ev; deviceEvent* evList; - int nEvents; + int32_t nEvents; }; struct krnlProperties { - krnlProperties(int t = 0, int b = 1, int b2 = 0) : nThreads(t), minBlocks(b), forceBlocks(b2) {} - unsigned int nThreads; - unsigned int minBlocks; - unsigned int forceBlocks; - unsigned int total() { return forceBlocks ? forceBlocks : (nThreads * minBlocks); } + krnlProperties(int32_t t = 0, int32_t b = 1, int32_t b2 = 0) : nThreads(t), minBlocks(b), forceBlocks(b2) {} + uint32_t nThreads; + uint32_t minBlocks; + uint32_t forceBlocks; + uint32_t total() { return forceBlocks ? forceBlocks : (nThreads * minBlocks); } }; struct krnlSetup { @@ -89,7 +89,7 @@ struct krnlSetupTime : public krnlSetup { double& t; }; -template +template struct krnlSetupArgs : public gpu_reconstruction_kernels::classArgument { krnlSetupArgs(const krnlExec& xx, const krnlRunRange& yy, const krnlEvent& zz, double& tt, const Args&... args) : s{{xx, yy, zz}, tt}, v(args...) {} const krnlSetupTime s; @@ -110,11 +110,11 @@ class GPUReconstructionKernels : public T using krnlEvent = gpu_reconstruction_kernels::krnlEvent; using krnlSetup = gpu_reconstruction_kernels::krnlSetup; using krnlSetupTime = gpu_reconstruction_kernels::krnlSetupTime; - template + template using krnlSetupArgs = gpu_reconstruction_kernels::krnlSetupArgs; #define GPUCA_KRNL(x_class, attributes, x_arguments, x_forward, x_types) \ - virtual int runKernelImpl(const krnlSetupArgs& args) \ + virtual int32_t runKernelImpl(const krnlSetupArgs& args) \ { \ return T::template runKernelBackend(args); \ } \ diff --git a/GPU/GPUTracking/Base/GPUReconstructionLibrary.cxx b/GPU/GPUTracking/Base/GPUReconstructionLibrary.cxx index 7aab8ff26be29..d4d7b12dc8cc6 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionLibrary.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionLibrary.cxx @@ -111,11 +111,11 @@ std::shared_ptr* GPUReconstruction::GetLibrary return &sLibOCL2; #endif } else { - GPUError("Error: Invalid device type %u", (unsigned int)type); + GPUError("Error: Invalid device type %u", (uint32_t)type); return nullptr; } if (verbose) { - GPUInfo("%s Support not compiled in for device type %u (%s)", GPUDataTypes::DEVICE_TYPE_NAMES[type], (unsigned int)type, GPUDataTypes::DEVICE_TYPE_NAMES[type]); + GPUInfo("%s Support not compiled in for device type %u (%s)", GPUDataTypes::DEVICE_TYPE_NAMES[type], (uint32_t)type, GPUDataTypes::DEVICE_TYPE_NAMES[type]); } return nullptr; } @@ -139,7 +139,7 @@ GPUReconstruction::LibraryLoader::LibraryLoader(const char* lib, const char* fun GPUReconstruction::LibraryLoader::~LibraryLoader() { CloseLibrary(); } -int GPUReconstruction::LibraryLoader::LoadLibrary() +int32_t GPUReconstruction::LibraryLoader::LoadLibrary() { static std::mutex mut; std::lock_guard lock(mut); @@ -183,7 +183,7 @@ GPUReconstruction* GPUReconstruction::LibraryLoader::GetPtr(const GPUSettingsDev return tmp(cfg); } -int GPUReconstruction::LibraryLoader::CloseLibrary() +int32_t GPUReconstruction::LibraryLoader::CloseLibrary() { if (mGPUEntry == nullptr) { return 1; diff --git a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx index cf26311da0966..840a24a695706 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.cxx @@ -39,7 +39,7 @@ extern GPUSettingsStandalone configStandalone; } static auto& config = configStandalone.TF; -GPUReconstructionTimeframe::GPUReconstructionTimeframe(GPUChainTracking* chain, int (*read)(int), int nEvents) : mChain(chain), mReadEvent(read), mNEventsInDirectory(nEvents), mDisUniReal(0.f, 1.f), mRndGen1(configStandalone.seed), mRndGen2(mDisUniInt(mRndGen1)) +GPUReconstructionTimeframe::GPUReconstructionTimeframe(GPUChainTracking* chain, int32_t (*read)(int32_t), int32_t nEvents) : mChain(chain), mReadEvent(read), mNEventsInDirectory(nEvents), mDisUniReal(0.f, 1.f), mRndGen1(configStandalone.seed), mRndGen2(mDisUniInt(mRndGen1)) { mMaxBunchesFull = TIME_ORBIT / config.bunchSpacing; mMaxBunches = (TIME_ORBIT - config.abortGapTime) / config.bunchSpacing; @@ -67,40 +67,40 @@ GPUReconstructionTimeframe::GPUReconstructionTimeframe(GPUChainTracking* chain, } } -int GPUReconstructionTimeframe::ReadEventShifted(int iEvent, float shiftZ, float minZ, float maxZ, bool silent) +int32_t GPUReconstructionTimeframe::ReadEventShifted(int32_t iEvent, float shiftZ, float minZ, float maxZ, bool silent) { mReadEvent(iEvent); if (config.overlayRaw) { float shiftTTotal = (((double)config.timeFrameLen - DRIFT_TIME) * ((double)TPCZ / (double)DRIFT_TIME) - shiftZ) / mChain->GetTPCTransformHelper()->getCorrMap()->getVDrift(); - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (unsigned int j = 0; j < mChain->mIOPtrs.nRawClusters[iSlice]; j++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t j = 0; j < mChain->mIOPtrs.nRawClusters[iSlice]; j++) { auto& tmp = mChain->mIOMem.rawClusters[iSlice][j]; tmp.fTime += shiftTTotal; } } } if (shiftZ != 0.f) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (unsigned int j = 0; j < mChain->mIOPtrs.nClusterData[iSlice]; j++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t j = 0; j < mChain->mIOPtrs.nClusterData[iSlice]; j++) { auto& tmp = mChain->mIOMem.clusterData[iSlice][j]; tmp.z += iSlice < NSLICES / 2 ? shiftZ : -shiftZ; } } - for (unsigned int i = 0; i < mChain->mIOPtrs.nMCInfosTPC; i++) { + for (uint32_t i = 0; i < mChain->mIOPtrs.nMCInfosTPC; i++) { auto& tmp = mChain->mIOMem.mcInfosTPC[i]; tmp.z += i < NSLICES / 2 ? shiftZ : -shiftZ; } } // Remove clusters outside boundaries - unsigned int nClusters = 0; - unsigned int removed = 0; + uint32_t nClusters = 0; + uint32_t removed = 0; if (minZ > -1e6 || maxZ > -1e6) { - unsigned int currentClusterTotal = 0; - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - unsigned int currentClusterSlice = 0; + uint32_t currentClusterTotal = 0; + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t currentClusterSlice = 0; bool doRaw = config.overlayRaw && mChain->mIOPtrs.nClusterData[iSlice] == mChain->mIOPtrs.nRawClusters[iSlice]; - for (unsigned int i = 0; i < mChain->mIOPtrs.nClusterData[iSlice]; i++) { + for (uint32_t i = 0; i < mChain->mIOPtrs.nClusterData[iSlice]; i++) { float sign = iSlice < NSLICES / 2 ? 1 : -1; if (sign * mChain->mIOMem.clusterData[iSlice][i].z >= minZ && sign * mChain->mIOMem.clusterData[iSlice][i].z <= maxZ) { if (currentClusterSlice != i) { @@ -130,13 +130,13 @@ int GPUReconstructionTimeframe::ReadEventShifted(int iEvent, float shiftZ, float mChain->mIOPtrs.nMCLabelsTPC = nClusters; } } else { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { nClusters += mChain->mIOPtrs.nClusterData[i]; } } if (!silent) { - GPUInfo("Read %u Clusters with %d MC labels and %d MC tracks", nClusters, (int)mChain->mIOPtrs.nMCLabelsTPC, (int)mChain->mIOPtrs.nMCInfosTPC); + GPUInfo("Read %u Clusters with %d MC labels and %d MC tracks", nClusters, (int32_t)mChain->mIOPtrs.nMCLabelsTPC, (int32_t)mChain->mIOPtrs.nMCInfosTPC); if (minZ > -1e6 || maxZ > 1e6) { GPUInfo("\tRemoved %u / %u clusters", removed, nClusters + removed); } @@ -149,9 +149,9 @@ int GPUReconstructionTimeframe::ReadEventShifted(int iEvent, float shiftZ, float void GPUReconstructionTimeframe::MergeShiftedEvents() { mChain->ClearIOPointers(); - for (unsigned int i = 0; i < mShiftedEvents.size(); i++) { + for (uint32_t i = 0; i < mShiftedEvents.size(); i++) { auto& ptr = std::get<0>(mShiftedEvents[i]); - for (unsigned int j = 0; j < NSLICES; j++) { + for (uint32_t j = 0; j < NSLICES; j++) { mChain->mIOPtrs.nClusterData[j] += ptr.nClusterData[j]; if (config.overlayRaw) { mChain->mIOPtrs.nRawClusters[j] += ptr.nRawClusters[j]; @@ -162,10 +162,10 @@ void GPUReconstructionTimeframe::MergeShiftedEvents() mChain->mIOPtrs.nMCInfosTPCCol += ptr.nMCInfosTPCCol; SetDisplayInformation(i); } - unsigned int nClustersTotal = 0; - unsigned int nClustersTotalRaw = 0; - unsigned int nClustersSliceOffset[NSLICES] = {0}; - for (unsigned int i = 0; i < NSLICES; i++) { + uint32_t nClustersTotal = 0; + uint32_t nClustersTotalRaw = 0; + uint32_t nClustersSliceOffset[NSLICES] = {0}; + for (uint32_t i = 0; i < NSLICES; i++) { nClustersSliceOffset[i] = nClustersTotal; nClustersTotal += mChain->mIOPtrs.nClusterData[i]; nClustersTotalRaw += mChain->mIOPtrs.nRawClusters[i]; @@ -181,13 +181,13 @@ void GPUReconstructionTimeframe::MergeShiftedEvents() mChain->AllocateIOMemory(); mChain->mIOPtrs.clustersNative = nullptr; - unsigned int nTrackOffset = 0; - unsigned int nColOffset = 0; - unsigned int nClustersEventOffset[NSLICES] = {0}; - for (unsigned int i = 0; i < mShiftedEvents.size(); i++) { + uint32_t nTrackOffset = 0; + uint32_t nColOffset = 0; + uint32_t nClustersEventOffset[NSLICES] = {0}; + for (uint32_t i = 0; i < mShiftedEvents.size(); i++) { auto& ptr = std::get<0>(mShiftedEvents[i]); - unsigned int inEventOffset = 0; - for (unsigned int j = 0; j < NSLICES; j++) { + uint32_t inEventOffset = 0; + for (uint32_t j = 0; j < NSLICES; j++) { memcpy((void*)&mChain->mIOMem.clusterData[j][nClustersEventOffset[j]], (void*)ptr.clusterData[j], ptr.nClusterData[j] * sizeof(ptr.clusterData[j][0])); if (nClustersTotalRaw) { memcpy((void*)&mChain->mIOMem.rawClusters[j][nClustersEventOffset[j]], (void*)ptr.rawClusters[j], ptr.nRawClusters[j] * sizeof(ptr.rawClusters[j][0])); @@ -195,10 +195,10 @@ void GPUReconstructionTimeframe::MergeShiftedEvents() if (mChain->mIOPtrs.nMCLabelsTPC) { memcpy((void*)&mChain->mIOMem.mcLabelsTPC[nClustersSliceOffset[j] + nClustersEventOffset[j]], (void*)&ptr.mcLabelsTPC[inEventOffset], ptr.nClusterData[j] * sizeof(ptr.mcLabelsTPC[0])); } - for (unsigned int k = 0; k < ptr.nClusterData[j]; k++) { + for (uint32_t k = 0; k < ptr.nClusterData[j]; k++) { mChain->mIOMem.clusterData[j][nClustersEventOffset[j] + k].id = nClustersSliceOffset[j] + nClustersEventOffset[j] + k; if (mChain->mIOPtrs.nMCLabelsTPC) { - for (int l = 0; l < 3; l++) { + for (int32_t l = 0; l < 3; l++) { auto& label = mChain->mIOMem.mcLabelsTPC[nClustersSliceOffset[j] + nClustersEventOffset[j] + k].fClusterID[l]; if (label.fMCID >= 0) { label.fMCID += nTrackOffset; @@ -212,7 +212,7 @@ void GPUReconstructionTimeframe::MergeShiftedEvents() } memcpy((void*)&mChain->mIOMem.mcInfosTPC[nTrackOffset], (void*)ptr.mcInfosTPC, ptr.nMCInfosTPC * sizeof(ptr.mcInfosTPC[0])); - for (unsigned int j = 0; j < ptr.nMCInfosTPCCol; j++) { + for (uint32_t j = 0; j < ptr.nMCInfosTPCCol; j++) { mChain->mIOMem.mcInfosTPCCol[nColOffset + j] = ptr.mcInfosTPCCol[j]; mChain->mIOMem.mcInfosTPCCol[nColOffset + j].first += nTrackOffset; } @@ -220,28 +220,28 @@ void GPUReconstructionTimeframe::MergeShiftedEvents() nColOffset += ptr.nMCInfosTPCCol; } - GPUInfo("Merged %d events, %u clusters total", (int)mShiftedEvents.size(), nClustersTotal); + GPUInfo("Merged %d events, %u clusters total", (int32_t)mShiftedEvents.size(), nClustersTotal); mShiftedEvents.clear(); } -int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) +int32_t GPUReconstructionTimeframe::LoadCreateTimeFrame(int32_t iEvent) { if (config.nTotalEventsInTF && mNTotalCollisions >= config.nTotalEventsInTF) { return (2); } - long nBunch = -DRIFT_TIME / config.bunchSpacing; - long lastBunch = config.timeFrameLen / config.bunchSpacing; - long lastTFBunch = lastBunch - DRIFT_TIME / config.bunchSpacing; - int nCollisions = 0, nBorderCollisions = 0, nTrainCollissions = 0, nMultipleCollisions = 0, nTrainMultipleCollisions = 0; - int nTrain = 0; - int mcMin = -1, mcMax = -1; - unsigned int nTotalClusters = 0; + int64_t nBunch = -DRIFT_TIME / config.bunchSpacing; + int64_t lastBunch = config.timeFrameLen / config.bunchSpacing; + int64_t lastTFBunch = lastBunch - DRIFT_TIME / config.bunchSpacing; + int32_t nCollisions = 0, nBorderCollisions = 0, nTrainCollissions = 0, nMultipleCollisions = 0, nTrainMultipleCollisions = 0; + int32_t nTrain = 0; + int32_t mcMin = -1, mcMax = -1; + uint32_t nTotalClusters = 0; while (nBunch < lastBunch) { - for (int iTrain = 0; iTrain < config.bunchTrainCount && nBunch < lastBunch; iTrain++) { - int nCollisionsInTrain = 0; - for (int iBunch = 0; iBunch < config.bunchCount && nBunch < lastBunch; iBunch++) { + for (int32_t iTrain = 0; iTrain < config.bunchTrainCount && nBunch < lastBunch; iTrain++) { + int32_t nCollisionsInTrain = 0; + for (int32_t iBunch = 0; iBunch < config.bunchCount && nBunch < lastBunch; iBunch++) { const bool inTF = nBunch >= 0 && nBunch < lastTFBunch && (config.nTotalEventsInTF == 0 || nCollisions < mNTotalCollisions + config.nTotalEventsInTF); if (mcMin == -1 && inTF) { mcMin = mChain->mIOPtrs.nMCInfosTPC; @@ -249,7 +249,7 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) if (mcMax == -1 && nBunch >= 0 && !inTF) { mcMax = mChain->mIOPtrs.nMCInfosTPC; } - int nInBunchPileUp = 0; + int32_t nInBunchPileUp = 0; double randVal = mDisUniReal(inTF ? mRndGen2 : mRndGen1); double p = exp(-mCollisionProbability); double p2 = p; @@ -269,7 +269,7 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) } else { nBorderCollisions++; } - int useEvent; + int32_t useEvent; if (config.noEventRepeat == 1) { useEvent = mSimBunchNoRepeatEvent; } else { @@ -282,13 +282,13 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) } mEventUsed[useEvent] = 1; double shift = (double)nBunch * (double)config.bunchSpacing * (double)TPCZ / (double)DRIFT_TIME; - int nClusters = ReadEventShifted(useEvent, shift, 0, (double)config.timeFrameLen * (double)TPCZ / (double)DRIFT_TIME, true); + int32_t nClusters = ReadEventShifted(useEvent, shift, 0, (double)config.timeFrameLen * (double)TPCZ / (double)DRIFT_TIME, true); if (nClusters < 0) { GPUError("Unexpected error"); return (1); } nTotalClusters += nClusters; - printf("Placing event %4d+%d (ID %4d) at z %7.3f (time %'dns) %s(collisions %4d, bunch %6ld, train %3d) (%'10d clusters, %'10d MC labels, %'10d track MC info)\n", nCollisions, nBorderCollisions, useEvent, shift, (int)(nBunch * config.bunchSpacing), inTF ? " inside" : "outside", + printf("Placing event %4d+%d (ID %4d) at z %7.3f (time %'dns) %s(collisions %4d, bunch %6ld, train %3d) (%'10d clusters, %'10d MC labels, %'10d track MC info)\n", nCollisions, nBorderCollisions, useEvent, shift, (int32_t)(nBunch * config.bunchSpacing), inTF ? " inside" : "outside", nCollisions, nBunch, nTrain, nClusters, mChain->mIOPtrs.nMCLabelsTPC, mChain->mIOPtrs.nMCInfosTPC); nInBunchPileUp++; nCollisionsInTrain++; @@ -318,7 +318,7 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) GPUInfo("Timeframe statistics: collisions: %d+%d in %d trains (inside / outside), average rate %f (pile up: in bunch %d, in train %d)", nCollisions, nBorderCollisions, nTrainCollissions, (float)nCollisions / (float)(config.timeFrameLen - DRIFT_TIME) * 1e9, nMultipleCollisions, nTrainMultipleCollisions); MergeShiftedEvents(); - GPUInfo("\tTotal clusters: %u, MC Labels %d, MC Infos %d", nTotalClusters, (int)mChain->mIOPtrs.nMCLabelsTPC, (int)mChain->mIOPtrs.nMCInfosTPC); + GPUInfo("\tTotal clusters: %u, MC Labels %d, MC Infos %d", nTotalClusters, (int32_t)mChain->mIOPtrs.nMCLabelsTPC, (int32_t)mChain->mIOPtrs.nMCInfosTPC); if (!config.noBorder && mChain->GetQA()) { mChain->GetQA()->SetMCTrackRange(mcMin, mcMax); @@ -326,9 +326,9 @@ int GPUReconstructionTimeframe::LoadCreateTimeFrame(int iEvent) return (0); } -int GPUReconstructionTimeframe::LoadMergedEvents(int iEvent) +int32_t GPUReconstructionTimeframe::LoadMergedEvents(int32_t iEvent) { - for (int iEventInTimeframe = 0; iEventInTimeframe < config.nMerge; iEventInTimeframe++) { + for (int32_t iEventInTimeframe = 0; iEventInTimeframe < config.nMerge; iEventInTimeframe++) { float shift; if (config.shiftFirstEvent || iEventInTimeframe) { if (config.randomizeDistance) { @@ -361,10 +361,10 @@ int GPUReconstructionTimeframe::LoadMergedEvents(int iEvent) return (0); } -void GPUReconstructionTimeframe::SetDisplayInformation(int iCol) +void GPUReconstructionTimeframe::SetDisplayInformation(int32_t iCol) { if (mChain->GetEventDisplay()) { - for (unsigned int sl = 0; sl < NSLICES; sl++) { + for (uint32_t sl = 0; sl < NSLICES; sl++) { mChain->GetEventDisplay()->SetCollisionFirstCluster(iCol, sl, mChain->mIOPtrs.nClusterData[sl]); } mChain->GetEventDisplay()->SetCollisionFirstCluster(iCol, NSLICES, mChain->mIOPtrs.nMCInfosTPC); diff --git a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h index e93f7234e7cdc..1ffb730b54d55 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h +++ b/GPU/GPUTracking/Base/GPUReconstructionTimeframe.h @@ -36,41 +36,41 @@ struct ClusterNativeAccess; class GPUReconstructionTimeframe { public: - GPUReconstructionTimeframe(GPUChainTracking* rec, int (*read)(int), int nEvents); - int LoadCreateTimeFrame(int iEvent); - int LoadMergedEvents(int iEvent); - int ReadEventShifted(int i, float shiftZ, float minZ = -1e6, float maxZ = -1e6, bool silent = false); + GPUReconstructionTimeframe(GPUChainTracking* rec, int32_t (*read)(int32_t), int32_t nEvents); + int32_t LoadCreateTimeFrame(int32_t iEvent); + int32_t LoadMergedEvents(int32_t iEvent); + int32_t ReadEventShifted(int32_t i, float shiftZ, float minZ = -1e6, float maxZ = -1e6, bool silent = false); void MergeShiftedEvents(); - static constexpr int ORBIT_RATE = 11245; - static constexpr int DRIFT_TIME = 93000; - static constexpr int TPCZ = GPUTPCGeometry::TPCLength(); - static constexpr int TIME_ORBIT = 1000000000 / ORBIT_RATE; + static constexpr int32_t ORBIT_RATE = 11245; + static constexpr int32_t DRIFT_TIME = 93000; + static constexpr int32_t TPCZ = GPUTPCGeometry::TPCLength(); + static constexpr int32_t TIME_ORBIT = 1000000000 / ORBIT_RATE; private: - constexpr static unsigned int NSLICES = GPUReconstruction::NSLICES; + constexpr static uint32_t NSLICES = GPUReconstruction::NSLICES; - void SetDisplayInformation(int iCol); + void SetDisplayInformation(int32_t iCol); GPUChainTracking* mChain; - int (*mReadEvent)(int); - int mNEventsInDirectory; + int32_t (*mReadEvent)(int32_t); + int32_t mNEventsInDirectory; std::uniform_real_distribution mDisUniReal; - std::uniform_int_distribution mDisUniInt; + std::uniform_int_distribution mDisUniInt; std::mt19937_64 mRndGen1; std::mt19937_64 mRndGen2; - int mTrainDist = 0; + int32_t mTrainDist = 0; float mCollisionProbability = 0.f; - int mMaxBunchesFull; - int mMaxBunches; + int32_t mMaxBunchesFull; + int32_t mMaxBunches; - int mNTotalCollisions = 0; + int32_t mNTotalCollisions = 0; - long mEventStride; - int mSimBunchNoRepeatEvent; - std::vector mEventUsed; + int64_t mEventStride; + int32_t mSimBunchNoRepeatEvent; + std::vector mEventUsed; std::vector> mShiftedEvents; }; } // namespace gpu diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu index 52aad75f5c55d..4a7607d5daf5e 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu @@ -62,7 +62,7 @@ GPUReconstructionCUDABackend::~GPUReconstructionCUDABackend() } } -int GPUReconstructionCUDABackend::GPUFailedMsgAI(const long error, const char* file, int line) +int32_t GPUReconstructionCUDABackend::GPUFailedMsgAI(const int64_t error, const char* file, int32_t line) { // Check for CUDA Error and in the case of an error display the corresponding error string if (error == cudaSuccess) { @@ -72,7 +72,7 @@ int GPUReconstructionCUDABackend::GPUFailedMsgAI(const long error, const char* f return 1; } -void GPUReconstructionCUDABackend::GPUFailedMsgA(const long error, const char* file, int line) +void GPUReconstructionCUDABackend::GPUFailedMsgA(const int64_t error, const char* file, int32_t line) { if (GPUFailedMsgAI(error, file, line)) { static bool runningCallbacks = false; @@ -121,11 +121,11 @@ void GPUReconstructionCUDA::UpdateAutomaticProcessingSettings() GPUCA_GPUReconstructionUpdateDefaults(); } -int GPUReconstructionCUDA::InitDevice_Runtime() +int32_t GPUReconstructionCUDA::InitDevice_Runtime() { #ifndef __HIPCC__ // CUDA - constexpr int reqVerMaj = 2; - constexpr int reqVerMin = 0; + constexpr int32_t reqVerMaj = 2; + constexpr int32_t reqVerMin = 0; #endif if (mProcessingSettings.rtc.enable && mProcessingSettings.rtc.runTest == 2) { genAndLoadRTC(); @@ -134,7 +134,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mMaster == nullptr) { cudaDeviceProp deviceProp; - int count, bestDevice = -1; + int32_t count, bestDevice = -1; double bestDeviceSpeed = -1, deviceSpeed; if (GPUFailedMsgI(cudaGetDeviceCount(&count))) { GPUError("Error getting CUDA Device Count"); @@ -146,7 +146,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() std::vector devicesOK(count, false); std::vector devMemory(count, 0); bool contextCreated = false; - for (int i = 0; i < count; i++) { + for (int32_t i = 0; i < count; i++) { if (mProcessingSettings.debugLevel >= 4) { GPUInfo("Examining device %d", i); } @@ -182,7 +182,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mProcessingSettings.debugLevel >= 4) { GPUInfo("Obtained device properties for device %d", i); } - int deviceOK = true; + int32_t deviceOK = true; [[maybe_unused]] const char* deviceFailure = ""; #ifndef __HIPCC__ if (deviceProp.major < reqVerMaj || (deviceProp.major == reqVerMaj && deviceProp.minor < reqVerMin)) { @@ -203,7 +203,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() continue; } devicesOK[i] = true; - devMemory[i] = std::min(free, std::max(0, total - REQUIRE_MEMORY_RESERVED)); + devMemory[i] = std::min(free, std::max(0, total - REQUIRE_MEMORY_RESERVED)); if (deviceSpeed > bestDeviceSpeed) { bestDevice = i; bestDeviceSpeed = deviceSpeed; @@ -216,7 +216,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() bool noDevice = false; if (bestDevice == -1) { - GPUWarning("No %sCUDA Device available, aborting CUDA Initialisation (Required mem: %ld)", count ? "appropriate " : "", (long)mDeviceMemorySize); + GPUWarning("No %sCUDA Device available, aborting CUDA Initialisation (Required mem: %ld)", count ? "appropriate " : "", (int64_t)mDeviceMemorySize); #ifndef __HIPCC__ GPUImportant("Requiring Revision %d.%d, Mem: %lu", reqVerMaj, reqVerMin, std::max(mDeviceMemorySize, REQUIRE_MIN_MEMORY)); #endif @@ -244,28 +244,28 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mProcessingSettings.debugLevel >= 2) { GPUInfo("Using CUDA Device %s with Properties:", deviceProp.name); - GPUInfo("\ttotalGlobalMem = %ld", (unsigned long)deviceProp.totalGlobalMem); - GPUInfo("\tsharedMemPerBlock = %ld", (unsigned long)deviceProp.sharedMemPerBlock); + GPUInfo("\ttotalGlobalMem = %ld", (uint64_t)deviceProp.totalGlobalMem); + GPUInfo("\tsharedMemPerBlock = %ld", (uint64_t)deviceProp.sharedMemPerBlock); GPUInfo("\tregsPerBlock = %d", deviceProp.regsPerBlock); GPUInfo("\twarpSize = %d", deviceProp.warpSize); - GPUInfo("\tmemPitch = %ld", (unsigned long)deviceProp.memPitch); + GPUInfo("\tmemPitch = %ld", (uint64_t)deviceProp.memPitch); GPUInfo("\tmaxThreadsPerBlock = %d", deviceProp.maxThreadsPerBlock); GPUInfo("\tmaxThreadsDim = %d %d %d", deviceProp.maxThreadsDim[0], deviceProp.maxThreadsDim[1], deviceProp.maxThreadsDim[2]); GPUInfo("\tmaxGridSize = %d %d %d", deviceProp.maxGridSize[0], deviceProp.maxGridSize[1], deviceProp.maxGridSize[2]); - GPUInfo("\ttotalConstMem = %ld", (unsigned long)deviceProp.totalConstMem); + GPUInfo("\ttotalConstMem = %ld", (uint64_t)deviceProp.totalConstMem); GPUInfo("\tmajor = %d", deviceProp.major); GPUInfo("\tminor = %d", deviceProp.minor); GPUInfo("\tclockRate = %d", deviceProp.clockRate); GPUInfo("\tmemoryClockRate = %d", deviceProp.memoryClockRate); GPUInfo("\tmultiProcessorCount = %d", deviceProp.multiProcessorCount); - GPUInfo("\ttextureAlignment = %ld", (unsigned long)deviceProp.textureAlignment); + GPUInfo("\ttextureAlignment = %ld", (uint64_t)deviceProp.textureAlignment); GPUInfo(" "); } if (deviceProp.warpSize != GPUCA_WARP_SIZE) { throw std::runtime_error("Invalid warp size on GPU"); } mBlockCount = deviceProp.multiProcessorCount; - mMaxThreads = std::max(mMaxThreads, deviceProp.maxThreadsPerBlock * mBlockCount); + mMaxThreads = std::max(mMaxThreads, deviceProp.maxThreadsPerBlock * mBlockCount); #ifndef __HIPCC__ // CUDA mWarpSize = 32; #else // HIP @@ -281,13 +281,13 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #ifdef GPUCA_USE_TEXTURES if (GPUCA_SLICE_DATA_MEMORY * NSLICES > (size_t)deviceProp.maxTexture1DLinear) { - GPUError("Invalid maximum texture size of device: %ld < %ld\n", (long)deviceProp.maxTexture1DLinear, (long)(GPUCA_SLICE_DATA_MEMORY * NSLICES)); + GPUError("Invalid maximum texture size of device: %ld < %ld\n", (int64_t)deviceProp.maxTexture1DLinear, (int64_t)(GPUCA_SLICE_DATA_MEMORY * NSLICES)); return (1); } #endif #ifndef GPUCA_NO_CONSTANT_MEMORY if (gGPUConstantMemBufferSize > deviceProp.totalConstMem) { - GPUError("Insufficient constant memory available on GPU %d < %d!", (int)deviceProp.totalConstMem, (int)gGPUConstantMemBufferSize); + GPUError("Insufficient constant memory available on GPU %d < %d!", (int32_t)deviceProp.totalConstMem, (int32_t)gGPUConstantMemBufferSize); return (1); } #endif @@ -320,7 +320,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #endif if (mDeviceMemorySize == 1 || mDeviceMemorySize == 2) { - mDeviceMemorySize = std::max(0, devMemory[mDeviceId] - REQUIRE_FREE_MEMORY_RESERVED_PER_SM * deviceProp.multiProcessorCount); // Take all GPU memory but some reserve + mDeviceMemorySize = std::max(0, devMemory[mDeviceId] - REQUIRE_FREE_MEMORY_RESERVED_PER_SM * deviceProp.multiProcessorCount); // Take all GPU memory but some reserve if (mDeviceMemorySize >= RESERVE_EXTRA_MEM_THRESHOLD) { mDeviceMemorySize -= RESERVE_EXTRA_MEM_OFFSET; } @@ -335,7 +335,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() if (mDeviceMemorySize > deviceProp.totalGlobalMem || GPUFailedMsgI(cudaMalloc(&mDeviceMemoryBase, mDeviceMemorySize))) { size_t free, total; GPUFailedMsg(cudaMemGetInfo(&free, &total)); - GPUError("CUDA Memory Allocation Error (trying %ld bytes, %ld available on GPU, %ld free)", (long)mDeviceMemorySize, (long)deviceProp.totalGlobalMem, (long)free); + GPUError("CUDA Memory Allocation Error (trying %ld bytes, %ld available on GPU, %ld free)", (int64_t)mDeviceMemorySize, (int64_t)deviceProp.totalGlobalMem, (int64_t)free); GPUFailedMsgI(cudaDeviceReset()); return (1); } @@ -343,12 +343,12 @@ int GPUReconstructionCUDA::InitDevice_Runtime() GPUInfo("Allocating memory on Host"); } if (GPUFailedMsgI(cudaMallocHost(&mHostMemoryBase, mHostMemorySize))) { - GPUError("Error allocating Page Locked Host Memory (trying %ld bytes)", (long)mHostMemorySize); + GPUError("Error allocating Page Locked Host Memory (trying %ld bytes)", (int64_t)mHostMemorySize); GPUFailedMsgI(cudaDeviceReset()); return (1); } if (mProcessingSettings.debugLevel >= 1) { - GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (long)mDeviceMemorySize, mDeviceMemoryBase, (long)mHostMemorySize, mHostMemoryBase); + GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (int64_t)mDeviceMemorySize, mDeviceMemoryBase, (int64_t)mHostMemorySize, mHostMemoryBase); memset(mHostMemoryBase, 0xDD, mHostMemorySize); if (GPUFailedMsgI(cudaMemset(mDeviceMemoryBase, 0xDD, mDeviceMemorySize))) { GPUError("Error during CUDA memset"); @@ -357,7 +357,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() } } - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { if (GPUFailedMsgI(cudaStreamCreateWithFlags(&mInternals->Streams[i], cudaStreamNonBlocking))) { GPUError("Error creating CUDA Stream"); GPUFailedMsgI(cudaDeviceReset()); @@ -390,7 +390,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #ifndef GPUCA_NO_CONSTANT_MEMORY runConstantRegistrators(); devPtrConstantMem = mDeviceConstantMemList[0]; - for (unsigned int i = 0; i < mInternals->kernelModules.size(); i++) { + for (uint32_t i = 0; i < mInternals->kernelModules.size(); i++) { #ifndef __HIPCC__ CUdeviceptr tmp; // CUDA has a custom type, that initializes to zero and cannot be initialized with nullptr #else @@ -405,7 +405,7 @@ int GPUReconstructionCUDA::InitDevice_Runtime() #endif mDeviceConstantMem = (GPUConstantMem*)devPtrConstantMem; - GPUInfo("CUDA Initialisation successfull (Device %d: %s (Frequency %d, Cores %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", mDeviceId, deviceProp.name, deviceProp.clockRate, deviceProp.multiProcessorCount, (long)mHostMemorySize, (long)mDeviceMemorySize, (int)GPUCA_GPU_STACK_SIZE, (long)gGPUConstantMemBufferSize); + GPUInfo("CUDA Initialisation successfull (Device %d: %s (Frequency %d, Cores %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", mDeviceId, deviceProp.name, deviceProp.clockRate, deviceProp.multiProcessorCount, (int64_t)mHostMemorySize, (int64_t)mDeviceMemorySize, (int32_t)GPUCA_GPU_STACK_SIZE, (int64_t)gGPUConstantMemBufferSize); } else { GPUReconstructionCUDA* master = dynamic_cast(mMaster); mDeviceId = master->mDeviceId; @@ -422,9 +422,9 @@ int GPUReconstructionCUDA::InitDevice_Runtime() GPUInfo("CUDA Initialized from master"); } - for (unsigned int i = 0; i < mEvents.size(); i++) { + for (uint32_t i = 0; i < mEvents.size(); i++) { cudaEvent_t* events = (cudaEvent_t*)mEvents[i].data(); - for (unsigned int j = 0; j < mEvents[i].size(); j++) { + for (uint32_t j = 0; j < mEvents[i].size(); j++) { #ifndef __HIPCC__ // CUDA if (GPUFailedMsgI(cudaEventCreate(&events[j]))) { #else @@ -443,11 +443,11 @@ int GPUReconstructionCUDA::InitDevice_Runtime() void GPUReconstructionCUDA::genAndLoadRTC() { std::string filename = ""; - unsigned int nCompile = 0; + uint32_t nCompile = 0; if (genRTC(filename, nCompile)) { throw std::runtime_error("Runtime compilation failed"); } - for (unsigned int i = 0; i < nCompile; i++) { + for (uint32_t i = 0; i < nCompile; i++) { if (mProcessingSettings.rtc.runTest != 2) { mInternals->kernelModules.emplace_back(std::make_unique()); GPUFailedMsg(cuModuleLoad(mInternals->kernelModules.back().get(), (filename + "_" + std::to_string(i) + mRtcBinExtension).c_str())); @@ -461,16 +461,16 @@ void GPUReconstructionCUDA::genAndLoadRTC() loadKernelModules(mProcessingSettings.rtc.compilePerKernel); } -int GPUReconstructionCUDA::ExitDevice_Runtime() +int32_t GPUReconstructionCUDA::ExitDevice_Runtime() { // Uninitialize CUDA GPUFailedMsg(cudaSetDevice(mDeviceId)); SynchronizeGPU(); unregisterRemainingRegisteredMemory(); - for (unsigned int i = 0; i < mEvents.size(); i++) { + for (uint32_t i = 0; i < mEvents.size(); i++) { cudaEvent_t* events = (cudaEvent_t*)mEvents[i].data(); - for (unsigned int j = 0; j < mEvents[i].size(); j++) { + for (uint32_t j = 0; j < mEvents[i].size(); j++) { GPUFailedMsgI(cudaEventDestroy(events[j])); } } @@ -481,12 +481,12 @@ int GPUReconstructionCUDA::ExitDevice_Runtime() GPUFailedMsgI(cudaFree(mDeviceConstantMem)); #endif - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { GPUFailedMsgI(cudaStreamDestroy(mInternals->Streams[i])); } GPUFailedMsgI(cudaFreeHost(mHostMemoryBase)); - for (unsigned int i = 0; i < mInternals->kernelModules.size(); i++) { + for (uint32_t i = 0; i < mInternals->kernelModules.size(); i++) { GPUFailedMsg(cuModuleUnload(*mInternals->kernelModules[i])); } @@ -499,7 +499,7 @@ int GPUReconstructionCUDA::ExitDevice_Runtime() return (0); } -size_t GPUReconstructionCUDA::GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev, deviceEvent* evList, int nEvents) +size_t GPUReconstructionCUDA::GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev, deviceEvent* evList, int32_t nEvents) { if (mProcessingSettings.debugLevel >= 3) { stream = -1; @@ -511,7 +511,7 @@ size_t GPUReconstructionCUDA::GPUMemCpy(void* dst, const void* src, size_t size, if (evList == nullptr) { nEvents = 0; } - for (int k = 0; k < nEvents; k++) { + for (int32_t k = 0; k < nEvents; k++) { GPUFailedMsg(cudaStreamWaitEvent(mInternals->Streams[stream], evList[k].get(), 0)); } GPUFailedMsg(cudaMemcpyAsync(dst, src, size, toGPU == -2 ? cudaMemcpyDeviceToDevice : toGPU ? cudaMemcpyHostToDevice : cudaMemcpyDeviceToHost, mInternals->Streams[stream])); @@ -522,7 +522,7 @@ size_t GPUReconstructionCUDA::GPUMemCpy(void* dst, const void* src, size_t size, return size; } -size_t GPUReconstructionCUDA::TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) +size_t GPUReconstructionCUDA::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) { if (!(res->Type() & GPUMemoryResource::MEMORY_GPU)) { if (mProcessingSettings.debugLevel >= 4) { @@ -531,14 +531,14 @@ size_t GPUReconstructionCUDA::TransferMemoryInternal(GPUMemoryResource* res, int return 0; } if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (long)res->Size()); + GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (int64_t)res->Size()); } return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); } -size_t GPUReconstructionCUDA::WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream, deviceEvent* ev) +size_t GPUReconstructionCUDA::WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream, deviceEvent* ev) { - for (unsigned int i = 0; i < 1 + mDeviceConstantMemList.size(); i++) { + for (uint32_t i = 0; i < 1 + mDeviceConstantMemList.size(); i++) { void* basePtr = i ? mDeviceConstantMemList[i - 1] : mDeviceConstantMem; if (basePtr == nullptr || (i && basePtr == (void*)mDeviceConstantMem)) { continue; @@ -556,7 +556,7 @@ size_t GPUReconstructionCUDA::WriteToConstantMemory(size_t offset, const void* s } void GPUReconstructionCUDA::ReleaseEvent(deviceEvent ev) {} -void GPUReconstructionCUDA::RecordMarker(deviceEvent ev, int stream) { GPUFailedMsg(cudaEventRecord(ev.get(), mInternals->Streams[stream])); } +void GPUReconstructionCUDA::RecordMarker(deviceEvent ev, int32_t stream) { GPUFailedMsg(cudaEventRecord(ev.get(), mInternals->Streams[stream])); } std::unique_ptr GPUReconstructionCUDA::GetThreadContext() { @@ -565,25 +565,25 @@ std::unique_ptr GPUReconstructionCUDA::GetT } void GPUReconstructionCUDA::SynchronizeGPU() { GPUFailedMsg(cudaDeviceSynchronize()); } -void GPUReconstructionCUDA::SynchronizeStream(int stream) { GPUFailedMsg(cudaStreamSynchronize(mInternals->Streams[stream])); } +void GPUReconstructionCUDA::SynchronizeStream(int32_t stream) { GPUFailedMsg(cudaStreamSynchronize(mInternals->Streams[stream])); } -void GPUReconstructionCUDA::SynchronizeEvents(deviceEvent* evList, int nEvents) +void GPUReconstructionCUDA::SynchronizeEvents(deviceEvent* evList, int32_t nEvents) { - for (int i = 0; i < nEvents; i++) { + for (int32_t i = 0; i < nEvents; i++) { GPUFailedMsg(cudaEventSynchronize(evList[i].get())); } } -void GPUReconstructionCUDA::StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents) +void GPUReconstructionCUDA::StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents) { - for (int i = 0; i < nEvents; i++) { + for (int32_t i = 0; i < nEvents; i++) { GPUFailedMsg(cudaStreamWaitEvent(mInternals->Streams[stream], evList[i].get(), 0)); } } -bool GPUReconstructionCUDA::IsEventDone(deviceEvent* evList, int nEvents) +bool GPUReconstructionCUDA::IsEventDone(deviceEvent* evList, int32_t nEvents) { - for (int i = 0; i < nEvents; i++) { + for (int32_t i = 0; i < nEvents; i++) { cudaError_t retVal = cudaEventSynchronize(evList[i].get()); if (retVal == cudaErrorNotReady) { return false; @@ -593,7 +593,7 @@ bool GPUReconstructionCUDA::IsEventDone(deviceEvent* evList, int nEvents) return (true); } -int GPUReconstructionCUDA::GPUDebug(const char* state, int stream, bool force) +int32_t GPUReconstructionCUDA::GPUDebug(const char* state, int32_t stream, bool force) { // Wait for CUDA-Kernel to finish and check for CUDA errors afterwards, in case of debugmode cudaError cuErr; @@ -615,7 +615,7 @@ int GPUReconstructionCUDA::GPUDebug(const char* state, int stream, bool force) return (0); } -int GPUReconstructionCUDA::registerMemoryForGPU_internal(const void* ptr, size_t size) +int32_t GPUReconstructionCUDA::registerMemoryForGPU_internal(const void* ptr, size_t size) { if (mProcessingSettings.debugLevel >= 3) { GPUInfo("Registering %zu bytes of memory for GPU", size); @@ -623,16 +623,16 @@ int GPUReconstructionCUDA::registerMemoryForGPU_internal(const void* ptr, size_t return GPUFailedMsgI(cudaHostRegister((void*)ptr, size, cudaHostRegisterDefault)); } -int GPUReconstructionCUDA::unregisterMemoryForGPU_internal(const void* ptr) +int32_t GPUReconstructionCUDA::unregisterMemoryForGPU_internal(const void* ptr) { return GPUFailedMsgI(cudaHostUnregister((void*)ptr)); } void GPUReconstructionCUDABackend::PrintKernelOccupancies() { - int maxBlocks = 0, threads = 0, suggestedBlocks = 0, nRegs = 0, sMem = 0; + int32_t maxBlocks = 0, threads = 0, suggestedBlocks = 0, nRegs = 0, sMem = 0; GPUFailedMsg(cudaSetDevice(mDeviceId)); - for (unsigned int i = 0; i < mInternals->kernelFunctions.size(); i++) { + for (uint32_t i = 0; i < mInternals->kernelFunctions.size(); i++) { GPUFailedMsg(cuOccupancyMaxPotentialBlockSize(&suggestedBlocks, &threads, *mInternals->kernelFunctions[i], 0, 0, 0)); GPUFailedMsg(cuOccupancyMaxActiveBlocksPerMultiprocessor(&maxBlocks, *mInternals->kernelFunctions[i], threads, 0)); GPUFailedMsg(cuFuncGetAttribute(&nRegs, CU_FUNC_ATTRIBUTE_NUM_REGS, *mInternals->kernelFunctions[i])); @@ -643,7 +643,7 @@ void GPUReconstructionCUDABackend::PrintKernelOccupancies() void GPUReconstructionCUDA::loadKernelModules(bool perKernel, bool perSingleMulti) { - unsigned int j = 0; + uint32_t j = 0; #define GPUCA_KRNL(...) \ GPUCA_KRNL_WRAP(GPUCA_KRNL_LOAD_, __VA_ARGS__) \ j += !perSingleMulti; @@ -671,12 +671,12 @@ void GPUReconstructionCUDA::loadKernelModules(bool perKernel, bool perSingleMult #undef GPUCA_KRNL_LOAD_multi if (j != mInternals->kernelModules.size()) { - GPUFatal("Did not load all kernels (%u < %u)", j, (unsigned int)mInternals->kernelModules.size()); + GPUFatal("Did not load all kernels (%u < %u)", j, (uint32_t)mInternals->kernelModules.size()); } } #ifndef __HIPCC__ // CUDA -int GPUReconstructionCUDA::PrepareTextures() +int32_t GPUReconstructionCUDA::PrepareTextures() { #ifdef GPUCA_USE_TEXTURES cudaChannelFormatDesc channelDescu2 = cudaCreateChannelDesc(); diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h index acf4ffbcf2965..93e2d19071275 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h @@ -35,25 +35,25 @@ class GPUReconstructionCUDABackend : public GPUReconstructionDeviceBase { public: ~GPUReconstructionCUDABackend() override; - static int GPUFailedMsgAI(const long error, const char* file, int line); - void GPUFailedMsgA(const long error, const char* file, int line); + static int32_t GPUFailedMsgAI(const int64_t error, const char* file, int32_t line); + void GPUFailedMsgA(const int64_t error, const char* file, int32_t line); protected: GPUReconstructionCUDABackend(const GPUSettingsDeviceBackend& cfg); void PrintKernelOccupancies() override; - template - int runKernelBackend(const krnlSetupArgs& args); - template + template + int32_t runKernelBackend(const krnlSetupArgs& args); + template void runKernelBackendInternal(const krnlSetupTime& _xyz, const Args&... args); - template + template gpu_reconstruction_kernels::krnlProperties getKernelPropertiesBackend(); - template + template class backendInternal; - template - static int getRTCkernelNum(int k = -1); + template + static int32_t getRTCkernelNum(int32_t k = -1); void getRTCKernelCalls(std::vector& kernels); @@ -67,31 +67,31 @@ class GPUReconstructionCUDA : public GPUReconstructionKernels GetThreadContext() override; void SynchronizeGPU() override; - int GPUDebug(const char* state = "UNKNOWN", int stream = -1, bool force = false) override; - void SynchronizeStream(int stream) override; - void SynchronizeEvents(deviceEvent* evList, int nEvents = 1) override; - void StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents = 1) override; - bool IsEventDone(deviceEvent* evList, int nEvents = 1) override; - int registerMemoryForGPU_internal(const void* ptr, size_t size) override; - int unregisterMemoryForGPU_internal(const void* ptr) override; - - size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream = -1, deviceEvent* ev = nullptr) override; - size_t TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) override; - size_t GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) override; + int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1, bool force = false) override; + void SynchronizeStream(int32_t stream) override; + void SynchronizeEvents(deviceEvent* evList, int32_t nEvents = 1) override; + void StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents = 1) override; + bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) override; + int32_t registerMemoryForGPU_internal(const void* ptr, size_t size) override; + int32_t unregisterMemoryForGPU_internal(const void* ptr) override; + + size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override; + size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override; + size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; void ReleaseEvent(deviceEvent ev) override; - void RecordMarker(deviceEvent ev, int stream) override; + void RecordMarker(deviceEvent ev, int32_t stream) override; void GetITSTraits(std::unique_ptr* trackerTraits, std::unique_ptr* vertexerTraits, std::unique_ptr* timeFrame) override; #ifndef __HIPCC__ // CUDA bool CanQueryMaxMemory() override { return true; } - int PrepareTextures() override; + int32_t PrepareTextures() override; void startGPUProfiling() override; void endGPUProfiling() override; #else // HIP @@ -99,7 +99,7 @@ class GPUReconstructionCUDA : public GPUReconstructionKernels kernels; getRTCKernelCalls(kernels); std::string kernelsall; - for (unsigned int i = 0; i < kernels.size(); i++) { + for (uint32_t i = 0; i < kernels.size(); i++) { kernelsall += kernels[i] + "\n"; } @@ -70,7 +70,7 @@ int GPUReconstructionCUDA::genRTC(std::string& filename, unsigned int& nCompile) nCompile = mProcessingSettings.rtc.compilePerKernel ? kernels.size() : 1; bool cacheLoaded = false; - int fd = 0; + int32_t fd = 0; if (mProcessingSettings.rtc.cacheOutput) { if (mProcessingSettings.RTCcacheFolder != ".") { std::filesystem::create_directories(mProcessingSettings.RTCcacheFolder); @@ -133,7 +133,7 @@ int GPUReconstructionCUDA::genRTC(std::string& filename, unsigned int& nCompile) break; } std::vector buffer; - for (unsigned int i = 0; i < nCompile; i++) { + for (uint32_t i = 0; i < nCompile; i++) { if (fread(&len, sizeof(len), 1, fp) != 1) { throw std::runtime_error("Cache file corrupt"); } @@ -167,7 +167,7 @@ int GPUReconstructionCUDA::genRTC(std::string& filename, unsigned int& nCompile) #ifdef WITH_OPENMP #pragma omp parallel for schedule(dynamic, 1) #endif - for (unsigned int i = 0; i < nCompile; i++) { + for (uint32_t i = 0; i < nCompile; i++) { if (mProcessingSettings.debugLevel >= 3) { printf("Compiling %s\n", (filename + "_" + std::to_string(i) + mRtcSrcExtension).c_str()); } @@ -223,7 +223,7 @@ int GPUReconstructionCUDA::genRTC(std::string& filename, unsigned int& nCompile) } std::vector buffer; - for (unsigned int i = 0; i < nCompile; i++) { + for (uint32_t i = 0; i < nCompile; i++) { FILE* fp2 = fopen((filename + "_" + std::to_string(i) + mRtcBinExtension).c_str(), "rb"); if (fp2 == nullptr) { throw std::runtime_error("Cannot open cuda module file"); diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAIncludes.h b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAIncludes.h index 6b767019b5b39..ae79494ded496 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAIncludes.h +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAIncludes.h @@ -16,10 +16,12 @@ #define O2_GPU_GPURECONSTRUCTIONCUDAINCLUDES_H #include +#include +#include #include #include #include -#pragma GCC diagnostic push +#pragma GCC diagnostic push // FIXME: Is this still needed? #pragma GCC diagnostic ignored "-Wshadow" #include #include @@ -29,7 +31,5 @@ #pragma GCC diagnostic pop #include #include -#include -#include #endif diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu index ecf44b6407d3c..9fad6caf5e853 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu @@ -29,16 +29,16 @@ texture gAliTexRefu; #include "GPUReconstructionIncludesDeviceAll.h" #if defined(__HIPCC__) && defined(GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM) -__global__ void gGPUConstantMemBuffer_dummy(int* p) { *p = *(int*)&gGPUConstantMemBuffer; } +__global__ void gGPUConstantMemBuffer_dummy(int32_t* p) { *p = *(int32_t*)&gGPUConstantMemBuffer; } #endif template <> -inline void GPUReconstructionCUDABackend::runKernelBackendInternal(const krnlSetupTime& _xyz, void* const& ptr, unsigned long const& size) +inline void GPUReconstructionCUDABackend::runKernelBackendInternal(const krnlSetupTime& _xyz, void* const& ptr, uint64_t const& size) { GPUFailedMsg(cudaMemsetAsync(ptr, 0, size, mInternals->Streams[_xyz.x.stream])); } -template +template inline void GPUReconstructionCUDABackend::runKernelBackendInternal(const krnlSetupTime& _xyz, const Args&... args) { #if !defined(GPUCA_KERNEL_COMPILE_MODE) || GPUCA_KERNEL_COMPILE_MODE != 1 @@ -50,7 +50,7 @@ inline void GPUReconstructionCUDABackend::runKernelBackendInternal(const krnlSet auto& x = _xyz.x; auto& y = _xyz.y; const void* pArgs[sizeof...(Args) + 3]; // 3 is max: cons mem + y.start + y.num - int arg_offset = 0; + int32_t arg_offset = 0; #ifdef GPUCA_NO_CONSTANT_MEMORY arg_offset = 1; pArgs[0] = &mDeviceConstantMem; @@ -66,13 +66,13 @@ inline void GPUReconstructionCUDABackend::runKernelBackendInternal(const krnlSet } } -template -int GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs& args) +template +int32_t GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs& args) { auto& x = args.s.x; auto& z = args.s.z; if (z.evList) { - for (int k = 0; k < z.nEvents; k++) { + for (int32_t k = 0; k < z.nEvents; k++) { GPUFailedMsg(cudaStreamWaitEvent(mInternals->Streams[x.stream], ((cudaEvent_t*)z.evList)[k], 0)); } } @@ -98,7 +98,7 @@ int GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs(const krnlSetupArgs& args); + template int32_t GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs& args); #else #if defined(GPUCA_KERNEL_COMPILE_MODE) && GPUCA_KERNEL_COMPILE_MODE == 2 #define GPUCA_KRNL_DEFONLY @@ -107,7 +107,7 @@ int GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs(const krnlSetupArgs& args); + template int32_t GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs& args); #ifndef __HIPCC__ // CUDA version #define GPUCA_KRNL_CALL_single(x_class, ...) \ GPUCA_M_CAT(krnl_, GPUCA_M_KRNL_NAME(x_class))<<mInternals->Streams[x.stream]>>>(GPUCA_CONSMEM_CALL y.start, args...); @@ -126,19 +126,19 @@ int GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgs -int GPUReconstructionCUDABackend::getRTCkernelNum(int k) +template +int32_t GPUReconstructionCUDABackend::getRTCkernelNum(int32_t k) { - static int num = k; + static int32_t num = k; if (num < 0) { throw std::runtime_error("Invalid kernel"); } return num; } -#define GPUCA_KRNL(x_class, ...) \ - template int GPUReconstructionCUDABackend::getRTCkernelNum(int k); \ - template int GPUReconstructionCUDABackend::getRTCkernelNum(int k); +#define GPUCA_KRNL(x_class, ...) \ + template int32_t GPUReconstructionCUDABackend::getRTCkernelNum(int32_t k); \ + template int32_t GPUReconstructionCUDABackend::getRTCkernelNum(int32_t k); #include "GPUReconstructionKernelList.h" #undef GPUCA_KRNL diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx index abcde6766c00c..4c90d0068882f 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx @@ -53,7 +53,7 @@ GPUReconstructionOCL::~GPUReconstructionOCL() } } -int GPUReconstructionOCL::GPUFailedMsgAI(const long error, const char* file, int line) +int32_t GPUReconstructionOCL::GPUFailedMsgAI(const int64_t error, const char* file, int32_t line) { // Check for OPENCL Error and in the case of an error display the corresponding error string if (error == CL_SUCCESS) { @@ -63,7 +63,7 @@ int GPUReconstructionOCL::GPUFailedMsgAI(const long error, const char* file, int return 1; } -void GPUReconstructionOCL::GPUFailedMsgA(const long error, const char* file, int line) +void GPUReconstructionOCL::GPUFailedMsgA(const int64_t error, const char* file, int32_t line) { if (GPUFailedMsgAI(error, file, line)) { static bool runningCallbacks = false; @@ -80,7 +80,7 @@ void GPUReconstructionOCL::UpdateAutomaticProcessingSettings() GPUCA_GPUReconstructionUpdateDefaults(); } -int GPUReconstructionOCL::InitDevice_Runtime() +int32_t GPUReconstructionOCL::InitDevice_Runtime() { if (mMaster == nullptr) { cl_int ocl_error; @@ -103,13 +103,13 @@ int GPUReconstructionOCL::InitDevice_Runtime() bool found = false; if (mProcessingSettings.platformNum >= 0) { - if (mProcessingSettings.platformNum >= (int)num_platforms) { + if (mProcessingSettings.platformNum >= (int32_t)num_platforms) { quit("Invalid platform specified"); } mInternals->platform = mInternals->platforms[mProcessingSettings.platformNum]; found = true; } else { - for (unsigned int i_platform = 0; i_platform < num_platforms; i_platform++) { + for (uint32_t i_platform = 0; i_platform < num_platforms; i_platform++) { char platform_profile[256] = {}, platform_version[256] = {}, platform_name[256] = {}, platform_vendor[256] = {}; clGetPlatformInfo(mInternals->platforms[i_platform], CL_PLATFORM_PROFILE, sizeof(platform_profile), platform_profile, nullptr); clGetPlatformInfo(mInternals->platforms[i_platform], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, nullptr); @@ -151,7 +151,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() GPUInfo("Available OPENCL devices:"); } std::vector devicesOK(count, false); - for (unsigned int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { if (mProcessingSettings.debugLevel >= 3) { GPUInfo("Examining device %d", i); } @@ -165,7 +165,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() clGetDeviceInfo(mInternals->devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(shaders), &shaders, nullptr); clGetDeviceInfo(mInternals->devices[i], CL_DEVICE_ADDRESS_BITS, sizeof(nbits), &nbits, nullptr); clGetDeviceInfo(mInternals->devices[i], CL_DEVICE_ENDIAN_LITTLE, sizeof(endian), &endian, nullptr); - int deviceOK = true; + int32_t deviceOK = true; const char* deviceFailure = ""; if (mProcessingSettings.gpuDeviceOnly && ((device_type & CL_DEVICE_TYPE_CPU) || !(device_type & CL_DEVICE_TYPE_GPU))) { deviceOK = false; @@ -182,7 +182,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() double bestDeviceSpeed = -1, deviceSpeed = (double)freq * (double)shaders; if (mProcessingSettings.debugLevel >= 2) { - GPUImportant("Device %s%2d: %s %s (Frequency %d, Shaders %d, %d bit) (Speed Value: %ld)%s %s", deviceOK ? " " : "[", i, device_vendor, device_name, (int)freq, (int)shaders, (int)nbits, (long)deviceSpeed, deviceOK ? " " : " ]", deviceOK ? "" : deviceFailure); + GPUImportant("Device %s%2d: %s %s (Frequency %d, Shaders %d, %d bit) (Speed Value: %ld)%s %s", deviceOK ? " " : "[", i, device_vendor, device_name, (int32_t)freq, (int32_t)shaders, (int32_t)nbits, (int64_t)deviceSpeed, deviceOK ? " " : " ]", deviceOK ? "" : deviceFailure); } if (!deviceOK) { continue; @@ -229,18 +229,18 @@ int GPUReconstructionOCL::InitDevice_Runtime() if (mProcessingSettings.debugLevel >= 2) { GPUInfo("Using OpenCL device %d: %s %s with properties:", bestDevice, device_vendor, device_name); GPUInfo("\tVersion = %s", deviceVersion); - GPUInfo("\tFrequency = %d", (int)freq); - GPUInfo("\tShaders = %d", (int)shaders); - GPUInfo("\tGLobalMemory = %ld", (long)globalMem); - GPUInfo("\tContantMemoryBuffer = %ld", (long)constantBuffer); - GPUInfo("\tLocalMemory = %ld", (long)localMem); - GPUInfo("\tmaxThreadsPerBlock = %ld", (long)maxWorkGroup); - GPUInfo("\tmaxThreadsDim = %ld %ld %ld", (long)maxWorkItems[0], (long)maxWorkItems[1], (long)maxWorkItems[2]); + GPUInfo("\tFrequency = %d", (int32_t)freq); + GPUInfo("\tShaders = %d", (int32_t)shaders); + GPUInfo("\tGLobalMemory = %ld", (int64_t)globalMem); + GPUInfo("\tContantMemoryBuffer = %ld", (int64_t)constantBuffer); + GPUInfo("\tLocalMemory = %ld", (int64_t)localMem); + GPUInfo("\tmaxThreadsPerBlock = %ld", (int64_t)maxWorkGroup); + GPUInfo("\tmaxThreadsDim = %ld %ld %ld", (int64_t)maxWorkItems[0], (int64_t)maxWorkItems[1], (int64_t)maxWorkItems[2]); GPUInfo(" "); } #ifndef GPUCA_NO_CONSTANT_MEMORY if (gGPUConstantMemBufferSize > constantBuffer) { - quit("Insufficient constant memory available on GPU %d < %d!", (int)constantBuffer, (int)gGPUConstantMemBufferSize); + quit("Insufficient constant memory available on GPU %d < %d!", (int32_t)constantBuffer, (int32_t)gGPUConstantMemBufferSize); } #endif @@ -248,7 +248,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() mDeviceName += " (OpenCL)"; mBlockCount = shaders; mWarpSize = 32; - mMaxThreads = std::max(mMaxThreads, maxWorkGroup * mBlockCount); + mMaxThreads = std::max(mMaxThreads, maxWorkGroup * mBlockCount); mInternals->context = clCreateContext(nullptr, ContextForAllPlatforms() ? count : 1, ContextForAllPlatforms() ? mInternals->devices.get() : &mInternals->device, nullptr, nullptr, &ocl_error); if (GPUFailedMsgI(ocl_error)) { @@ -276,7 +276,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() quit("OPENCL Constant Memory Allocation Error"); } - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { #ifdef CL_VERSION_2_0 cl_queue_properties prop = mProcessingSettings.deviceTimers ? CL_QUEUE_PROFILING_ENABLE : 0; mInternals->command_queue[i] = clCreateCommandQueueWithProperties(mInternals->context, mInternals->device, &prop, &ocl_error); @@ -342,12 +342,12 @@ int GPUReconstructionOCL::InitDevice_Runtime() mDeviceConstantMem = (GPUConstantMem*)((void**)mHostMemoryBase)[1]; if (mProcessingSettings.debugLevel >= 1) { - GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (long)mDeviceMemorySize, mDeviceMemoryBase, (long)mHostMemorySize, mHostMemoryBase); + GPUInfo("Memory ptrs: GPU (%ld bytes): %p - Host (%ld bytes): %p", (int64_t)mDeviceMemorySize, mDeviceMemoryBase, (int64_t)mHostMemorySize, mHostMemoryBase); memset(mHostMemoryBase, 0xDD, mHostMemorySize); } - GPUInfo("OPENCL Initialisation successfull (%d: %s %s (Frequency %d, Shaders %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", bestDevice, device_vendor, device_name, (int)freq, (int)shaders, (long)mDeviceMemorySize, - (long)mHostMemorySize, -1, (long)gGPUConstantMemBufferSize); + GPUInfo("OPENCL Initialisation successfull (%d: %s %s (Frequency %d, Shaders %d), %ld / %ld bytes host / global memory, Stack frame %d, Constant memory %ld)", bestDevice, device_vendor, device_name, (int32_t)freq, (int32_t)shaders, (int64_t)mDeviceMemorySize, + (int64_t)mHostMemorySize, -1, (int64_t)gGPUConstantMemBufferSize); } else { GPUReconstructionOCL* master = dynamic_cast(mMaster); mBlockCount = master->mBlockCount; @@ -361,7 +361,7 @@ int GPUReconstructionOCL::InitDevice_Runtime() return (0); } -int GPUReconstructionOCL::ExitDevice_Runtime() +int32_t GPUReconstructionOCL::ExitDevice_Runtime() { // Uninitialize OPENCL SynchronizeGPU(); @@ -370,14 +370,14 @@ int GPUReconstructionOCL::ExitDevice_Runtime() if (mDeviceMemoryBase) { clReleaseMemObject(mInternals->mem_gpu); clReleaseMemObject(mInternals->mem_constant); - for (unsigned int i = 0; i < mInternals->kernels.size(); i++) { + for (uint32_t i = 0; i < mInternals->kernels.size(); i++) { clReleaseKernel(mInternals->kernels[i].first); } mInternals->kernels.clear(); } if (mHostMemoryBase) { clEnqueueUnmapMemObject(mInternals->command_queue[0], mInternals->mem_host, mHostMemoryBase, 0, nullptr, nullptr); - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { clReleaseCommandQueue(mInternals->command_queue[i]); } clReleaseMemObject(mInternals->mem_host); @@ -393,7 +393,7 @@ int GPUReconstructionOCL::ExitDevice_Runtime() return (0); } -size_t GPUReconstructionOCL::GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev, deviceEvent* evList, int nEvents) +size_t GPUReconstructionOCL::GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev, deviceEvent* evList, int32_t nEvents) { if (evList == nullptr) { nEvents = 0; @@ -414,7 +414,7 @@ size_t GPUReconstructionOCL::GPUMemCpy(void* dst, const void* src, size_t size, return size; } -size_t GPUReconstructionOCL::TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) +size_t GPUReconstructionOCL::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) { if (!(res->Type() & GPUMemoryResource::MEMORY_GPU)) { if (mProcessingSettings.debugLevel >= 4) { @@ -423,12 +423,12 @@ size_t GPUReconstructionOCL::TransferMemoryInternal(GPUMemoryResource* res, int return 0; } if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (long)res->Size()); + GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (int64_t)res->Size()); } return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); } -size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream, deviceEvent* ev) +size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream, deviceEvent* ev) { if (stream == -1) { SynchronizeGPU(); @@ -439,13 +439,13 @@ size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* sr void GPUReconstructionOCL::ReleaseEvent(deviceEvent ev) { GPUFailedMsg(clReleaseEvent(ev.get())); } -void GPUReconstructionOCL::RecordMarker(deviceEvent ev, int stream) { GPUFailedMsg(clEnqueueMarkerWithWaitList(mInternals->command_queue[stream], 0, nullptr, ev.getEventList())); } +void GPUReconstructionOCL::RecordMarker(deviceEvent ev, int32_t stream) { GPUFailedMsg(clEnqueueMarkerWithWaitList(mInternals->command_queue[stream], 0, nullptr, ev.getEventList())); } -int GPUReconstructionOCL::DoStuckProtection(int stream, deviceEvent event) +int32_t GPUReconstructionOCL::DoStuckProtection(int32_t stream, deviceEvent event) { if (mProcessingSettings.stuckProtection) { cl_int tmp = 0; - for (int i = 0; i <= mProcessingSettings.stuckProtection / 50; i++) { + for (int32_t i = 0; i <= mProcessingSettings.stuckProtection / 50; i++) { usleep(50); clGetEventInfo(event.get(), CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(tmp), &tmp, nullptr); if (tmp == CL_COMPLETE) { @@ -454,7 +454,7 @@ int GPUReconstructionOCL::DoStuckProtection(int stream, deviceEvent event) } if (tmp != CL_COMPLETE) { mGPUStuck = 1; - quit("GPU Stuck, future processing in this component is disabled, skipping event (GPU Event State %d)", (int)tmp); + quit("GPU Stuck, future processing in this component is disabled, skipping event (GPU Event State %d)", (int32_t)tmp); } } else { clFinish(mInternals->command_queue[stream]); @@ -464,26 +464,26 @@ int GPUReconstructionOCL::DoStuckProtection(int stream, deviceEvent event) void GPUReconstructionOCL::SynchronizeGPU() { - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { GPUFailedMsg(clFinish(mInternals->command_queue[i])); } } -void GPUReconstructionOCL::SynchronizeStream(int stream) { GPUFailedMsg(clFinish(mInternals->command_queue[stream])); } +void GPUReconstructionOCL::SynchronizeStream(int32_t stream) { GPUFailedMsg(clFinish(mInternals->command_queue[stream])); } -void GPUReconstructionOCL::SynchronizeEvents(deviceEvent* evList, int nEvents) { GPUFailedMsg(clWaitForEvents(nEvents, evList->getEventList())); } +void GPUReconstructionOCL::SynchronizeEvents(deviceEvent* evList, int32_t nEvents) { GPUFailedMsg(clWaitForEvents(nEvents, evList->getEventList())); } -void GPUReconstructionOCL::StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents) +void GPUReconstructionOCL::StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents) { if (nEvents) { GPUFailedMsg(clEnqueueMarkerWithWaitList(mInternals->command_queue[stream], nEvents, evList->getEventList(), nullptr)); } } -bool GPUReconstructionOCL::IsEventDone(deviceEvent* evList, int nEvents) +bool GPUReconstructionOCL::IsEventDone(deviceEvent* evList, int32_t nEvents) { cl_int eventdone; - for (int i = 0; i < nEvents; i++) { + for (int32_t i = 0; i < nEvents; i++) { GPUFailedMsg(clGetEventInfo(evList[i].get(), CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(eventdone), &eventdone, nullptr)); if (eventdone != CL_COMPLETE) { return false; @@ -492,13 +492,13 @@ bool GPUReconstructionOCL::IsEventDone(deviceEvent* evList, int nEvents) return true; } -int GPUReconstructionOCL::GPUDebug(const char* state, int stream, bool force) +int32_t GPUReconstructionOCL::GPUDebug(const char* state, int32_t stream, bool force) { // Wait for OPENCL-Kernel to finish and check for OPENCL errors afterwards, in case of debugmode if (!force && mProcessingSettings.debugLevel <= 0) { return (0); } - for (int i = 0; i < mNStreams; i++) { + for (int32_t i = 0; i < mNStreams; i++) { if (GPUFailedMsgI(clFinish(mInternals->command_queue[i]))) { GPUError("OpenCL Error while synchronizing (%s) (Stream %d/%d)", state, stream, i); } diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h index 98a0559c8f8a4..b74785da42c1d 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h @@ -34,38 +34,38 @@ class GPUReconstructionOCL : public GPUReconstructionDeviceBase GPUReconstructionOCL(const GPUSettingsDeviceBackend& cfg); protected: - int InitDevice_Runtime() override; - int ExitDevice_Runtime() override; + int32_t InitDevice_Runtime() override; + int32_t ExitDevice_Runtime() override; void UpdateAutomaticProcessingSettings() override; - int GPUFailedMsgAI(const long error, const char* file, int line); - void GPUFailedMsgA(const long error, const char* file, int line); + int32_t GPUFailedMsgAI(const int64_t error, const char* file, int32_t line); + void GPUFailedMsgA(const int64_t error, const char* file, int32_t line); void SynchronizeGPU() override; - int DoStuckProtection(int stream, deviceEvent event) override; - int GPUDebug(const char* state = "UNKNOWN", int stream = -1, bool force = false) override; - void SynchronizeStream(int stream) override; - void SynchronizeEvents(deviceEvent* evList, int nEvents = 1) override; - void StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents = 1) override; - bool IsEventDone(deviceEvent* evList, int nEvents = 1) override; + int32_t DoStuckProtection(int32_t stream, deviceEvent event) override; + int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1, bool force = false) override; + void SynchronizeStream(int32_t stream) override; + void SynchronizeEvents(deviceEvent* evList, int32_t nEvents = 1) override; + void StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents = 1) override; + bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) override; - size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int stream = -1, deviceEvent* ev = nullptr) override; - size_t TransferMemoryInternal(GPUMemoryResource* res, int stream, deviceEvent* ev, deviceEvent* evList, int nEvents, bool toGPU, const void* src, void* dst) override; - size_t GPUMemCpy(void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) override; + size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override; + size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override; + size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; void ReleaseEvent(deviceEvent ev) override; - void RecordMarker(deviceEvent ev, int stream) override; + void RecordMarker(deviceEvent ev, int32_t stream) override; - virtual int GetOCLPrograms() = 0; - virtual bool CheckPlatform(unsigned int i) = 0; + virtual int32_t GetOCLPrograms() = 0; + virtual bool CheckPlatform(uint32_t i) = 0; virtual bool ContextForAllPlatforms() { return false; } - template - int AddKernel(bool multi = false); - template - unsigned int FindKernel(int num); + template + int32_t AddKernel(bool multi = false); + template + uint32_t FindKernel(int32_t num); template - int runKernelBackendInternal(const krnlSetupTime& _xyz, K& k, const Args&... args); - template + int32_t runKernelBackendInternal(const krnlSetupTime& _xyz, K& k, const Args&... args); + template gpu_reconstruction_kernels::krnlProperties getKernelPropertiesBackend(); GPUReconstructionOCLInternals* mInternals; diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h index 53ce88c0324ef..182bef9f9d739 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCLInternals.h @@ -28,7 +28,7 @@ namespace GPUCA_NAMESPACE::gpu { -static const char* opencl_error_string(int errorcode) +static const char* opencl_error_string(int32_t errorcode) { switch (errorcode) { case CL_SUCCESS: @@ -131,15 +131,15 @@ static const char* opencl_error_string(int errorcode) #define GPUFailedMsg(x) GPUFailedMsgA(x, __FILE__, __LINE__) #define GPUFailedMsgI(x) GPUFailedMsgAI(x, __FILE__, __LINE__) -static inline long OCLsetKernelParameters_helper(cl_kernel& k, int i) +static inline int64_t OCLsetKernelParameters_helper(cl_kernel& k, int32_t i) { return 0; } template -static inline long OCLsetKernelParameters_helper(cl_kernel& kernel, int i, const T& firstParameter, const Args&... restOfParameters) +static inline int64_t OCLsetKernelParameters_helper(cl_kernel& kernel, int32_t i, const T& firstParameter, const Args&... restOfParameters) { - long retVal = clSetKernelArg(kernel, i, sizeof(T), &firstParameter); + int64_t retVal = clSetKernelArg(kernel, i, sizeof(T), &firstParameter); if (retVal) { return retVal; } @@ -147,12 +147,12 @@ static inline long OCLsetKernelParameters_helper(cl_kernel& kernel, int i, const } template -static inline long OCLsetKernelParameters(cl_kernel& kernel, const Args&... args) +static inline int64_t OCLsetKernelParameters(cl_kernel& kernel, const Args&... args) { return OCLsetKernelParameters_helper(kernel, 0, args...); } -static inline long clExecuteKernelA(cl_command_queue queue, cl_kernel krnl, size_t local_size, size_t global_size, cl_event* pEvent, cl_event* wait = nullptr, cl_int nWaitEvents = 1) +static inline int64_t clExecuteKernelA(cl_command_queue queue, cl_kernel krnl, size_t local_size, size_t global_size, cl_event* pEvent, cl_event* wait = nullptr, cl_int nWaitEvents = 1) { return clEnqueueNDRangeKernel(queue, krnl, 1, nullptr, &global_size, &local_size, wait == nullptr ? 0 : nWaitEvents, wait, pEvent); } @@ -173,7 +173,7 @@ struct GPUReconstructionOCLInternals { }; template -inline int GPUReconstructionOCL::runKernelBackendInternal(const krnlSetupTime& _xyz, K& k, const Args&... args) +inline int32_t GPUReconstructionOCL::runKernelBackendInternal(const krnlSetupTime& _xyz, K& k, const Args&... args) { auto& x = _xyz.x; auto& y = _xyz.y; @@ -207,8 +207,8 @@ inline int GPUReconstructionOCL::runKernelBackendInternal(const krnlSetupTime& _ return 0; } -template -int GPUReconstructionOCL::AddKernel(bool multi) +template +int32_t GPUReconstructionOCL::AddKernel(bool multi) { std::string name(GetKernelName()); if (multi) { @@ -226,15 +226,15 @@ int GPUReconstructionOCL::AddKernel(bool multi) return 0; } -template -inline unsigned int GPUReconstructionOCL::FindKernel(int num) +template +inline uint32_t GPUReconstructionOCL::FindKernel(int32_t num) { std::string name(GetKernelName()); if (num > 1) { name += "_multi"; } - for (unsigned int k = 0; k < mInternals->kernels.size(); k++) { + for (uint32_t k = 0; k < mInternals->kernels.size(); k++) { if (mInternals->kernels[k].second == name) { return (k); } diff --git a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.cxx b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.cxx index 02a230fd69d2a..3f84ab0f6ac15 100644 --- a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.cxx +++ b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.cxx @@ -36,21 +36,21 @@ GPUReconstructionOCL1Backend::GPUReconstructionOCL1Backend(const GPUSettingsDevi { } -template -int GPUReconstructionOCL1Backend::runKernelBackend(const krnlSetupArgs& args) +template +int32_t GPUReconstructionOCL1Backend::runKernelBackend(const krnlSetupArgs& args) { cl_kernel k = args.s.y.num > 1 ? getKernelObject() : getKernelObject(); return std::apply([this, &args, &k](auto&... vals) { return runKernelBackendInternal(args.s, k, vals...); }, args.v); } -template +template S& GPUReconstructionOCL1Backend::getKernelObject() { - static unsigned int krnl = FindKernel(MULTI ? 2 : 1); + static uint32_t krnl = FindKernel(MULTI ? 2 : 1); return mInternals->kernels[krnl].first; } -int GPUReconstructionOCL1Backend::GetOCLPrograms() +int32_t GPUReconstructionOCL1Backend::GetOCLPrograms() { cl_uint count; if (GPUFailedMsgI(clGetDeviceIDs(mInternals->platform, CL_DEVICE_TYPE_ALL, 0, nullptr, &count))) { @@ -84,7 +84,7 @@ int GPUReconstructionOCL1Backend::GetOCLPrograms() return 0; } -bool GPUReconstructionOCL1Backend::CheckPlatform(unsigned int i) +bool GPUReconstructionOCL1Backend::CheckPlatform(uint32_t i) { char platform_version[64] = {}, platform_vendor[64] = {}; clGetPlatformInfo(mInternals->platforms[i], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, nullptr); diff --git a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h index ab09dab50a084..c9a3b89a79cd1 100644 --- a/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h +++ b/GPU/GPUTracking/Base/opencl/GPUReconstructionOCL1.h @@ -35,15 +35,15 @@ class GPUReconstructionOCL1Backend : public GPUReconstructionOCL protected: GPUReconstructionOCL1Backend(const GPUSettingsDeviceBackend& cfg); - template - int runKernelBackend(const krnlSetupArgs& args); - template + template + int32_t runKernelBackend(const krnlSetupArgs& args); + template S& getKernelObject(); RecoStepField AvailableGPURecoSteps() override { return (RecoStep::TPCSliceTracking); } bool ContextForAllPlatforms() override { return true; } - bool CheckPlatform(unsigned int i) override; - int GetOCLPrograms() override; + bool CheckPlatform(uint32_t i) override; + int32_t GetOCLPrograms() override; }; using GPUReconstructionOCL1 = GPUReconstructionKernels; diff --git a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx index 2c27694b8b111..a118e6d589712 100644 --- a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx +++ b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx @@ -38,21 +38,21 @@ GPUReconstructionOCL2Backend::GPUReconstructionOCL2Backend(const GPUSettingsDevi { } -template -int GPUReconstructionOCL2Backend::runKernelBackend(const krnlSetupArgs& args) +template +int32_t GPUReconstructionOCL2Backend::runKernelBackend(const krnlSetupArgs& args) { cl_kernel k = args.s.y.num > 1 ? getKernelObject() : getKernelObject(); return std::apply([this, &args, &k](auto&... vals) { return runKernelBackendInternal(args.s, k, vals...); }, args.v); } -template +template S& GPUReconstructionOCL2Backend::getKernelObject() { - static unsigned int krnl = FindKernel(MULTI ? 2 : 1); + static uint32_t krnl = FindKernel(MULTI ? 2 : 1); return mInternals->kernels[krnl].first; } -int GPUReconstructionOCL2Backend::GetOCLPrograms() +int32_t GPUReconstructionOCL2Backend::GetOCLPrograms() { char platform_version[256] = {}; GPUFailedMsg(clGetPlatformInfo(mInternals->platform, CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, nullptr)); @@ -113,7 +113,7 @@ int GPUReconstructionOCL2Backend::GetOCLPrograms() return 0; } -bool GPUReconstructionOCL2Backend::CheckPlatform(unsigned int i) +bool GPUReconstructionOCL2Backend::CheckPlatform(uint32_t i) { char platform_version[64] = {}, platform_vendor[64] = {}; clGetPlatformInfo(mInternals->platforms[i], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, nullptr); diff --git a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.h b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.h index 237838a90ca33..8ce73df32b701 100644 --- a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.h +++ b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.h @@ -35,13 +35,13 @@ class GPUReconstructionOCL2Backend : public GPUReconstructionOCL protected: GPUReconstructionOCL2Backend(const GPUSettingsDeviceBackend& cfg); - template - int runKernelBackend(const krnlSetupArgs& args); - template + template + int32_t runKernelBackend(const krnlSetupArgs& args); + template S& getKernelObject(); - int GetOCLPrograms() override; - bool CheckPlatform(unsigned int i) override; + int32_t GetOCLPrograms() override; + bool CheckPlatform(uint32_t i) override; }; using GPUReconstructionOCL2 = GPUReconstructionKernels; diff --git a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx index bbe4934de590d..d6f9ff692c15f 100644 --- a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx +++ b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.cxx @@ -61,15 +61,15 @@ void AliHLTTPCClusterStatComponent::GetInputDataTypes(AliHLTComponentDataTypeLis AliHLTComponentDataType AliHLTTPCClusterStatComponent::GetOutputDataType() { return kAliHLTDataTypeHistogram | kAliHLTDataOriginOut; } -void AliHLTTPCClusterStatComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) +void AliHLTTPCClusterStatComponent::GetOutputDataSize(uint64_t& constBase, double& inputMultiplier) { constBase = 2000000; inputMultiplier = 0.0; } -int AliHLTTPCClusterStatComponent::ProcessOption(TString option, TString value) +int32_t AliHLTTPCClusterStatComponent::ProcessOption(TString option, TString value) { - int iResult = 0; + int32_t iResult = 0; if (option.EqualTo("print-clusters")) { fPrintClusters = 1; @@ -90,9 +90,9 @@ int AliHLTTPCClusterStatComponent::ProcessOption(TString option, TString value) return iResult; } -int AliHLTTPCClusterStatComponent::DoInit(int argc, const char** argv) +int32_t AliHLTTPCClusterStatComponent::DoInit(int argc, const char** argv) { - int iResult = 0; + int32_t iResult = 0; if (ProcessOptionString(GetComponentArgs()) < 0) { HLTFatal("wrong config string! %s", GetComponentArgs().c_str()); @@ -135,7 +135,7 @@ int AliHLTTPCClusterStatComponent::DoInit(int argc, const char** argv) return iResult; } -int AliHLTTPCClusterStatComponent::DoDeinit() +int32_t AliHLTTPCClusterStatComponent::DoDeinit() { if (fDumpClusters) { fclose(fp); @@ -145,7 +145,7 @@ int AliHLTTPCClusterStatComponent::DoDeinit() return 0; } -void AliHLTTPCClusterStatComponent::TransformReverse(int slice, int row, float y, float z, float padtime[]) +void AliHLTTPCClusterStatComponent::TransformReverse(int32_t slice, int32_t row, float y, float z, float padtime[]) { AliTPCcalibDB* calib = AliTPCcalibDB::Instance(); AliTPCParam* param = calib->GetParameters(); @@ -156,8 +156,8 @@ void AliHLTTPCClusterStatComponent::TransformReverse(int slice, int row, float y float sign = slice < NSLICES / 2 ? 1 : -1; float zwidth; - int sector; - int sectorrow; + int32_t sector; + int32_t sectorrow; if (row < AliHLTTPCGeometry::GetNRowLow()) { sector = slice; sectorrow = row; @@ -181,7 +181,7 @@ void AliHLTTPCClusterStatComponent::TransformReverse(int slice, int row, float y padtime[1] = (1024.f - time); } -void AliHLTTPCClusterStatComponent::TransformForward(int slice, int row, float pad, float time, float xyz[]) +void AliHLTTPCClusterStatComponent::TransformForward(int32_t slice, int32_t row, float pad, float time, float xyz[]) { AliTPCcalibDB* calib = AliTPCcalibDB::Instance(); AliTPCParam* param = calib->GetParameters(); @@ -192,8 +192,8 @@ void AliHLTTPCClusterStatComponent::TransformForward(int slice, int row, float p float sign = slice < NSLICES / 2 ? 1 : -1; float zwidth; - int sector; - int sectorrow; + int32_t sector; + int32_t sectorrow; if (row < AliHLTTPCGeometry::GetNRowLow()) { sector = slice; sectorrow = row; @@ -240,9 +240,9 @@ static bool AliHLTTPCClusterStat_sorthelper(const AliHLTTPCRawCluster& a, const return (false); } -int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* /*outputPtr*/, AliHLTUInt32_t& /*size*/, AliHLTComponentBlockDataList& /*outputBlocks*/) +int32_t AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* /*outputPtr*/, AliHLTUInt32_t& /*size*/, AliHLTComponentBlockDataList& /*outputBlocks*/) { - int iResult = 0; + int32_t iResult = 0; if (!IsDataEvent()) { return iResult; @@ -251,7 +251,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa if (!fAggregate) { fTotal = fEdge = fSplitPad = fSplitTime = fSplitPadTime = fSplitPadOrTime = 0; } - int nBlocks = evtData.fBlockCnt; + int32_t nBlocks = evtData.fBlockCnt; AliHLTTPCRawClusterData* clustersArray[NSLICES][NPATCHES]; AliHLTTPCClusterXYZData* clustersTransformedArray[NSLICES][NPATCHES]; @@ -272,25 +272,25 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa const AliTPCRecoParam* rec = transform->GetCurrentRecoParam(); transform->SetCurrentTimeStamp(GetTimeStamp()); - for (int ndx = 0; ndx < nBlocks; ndx++) { + for (int32_t ndx = 0; ndx < nBlocks; ndx++) { const AliHLTComponentBlockData* iter = blocks + ndx; if (iter->fDataType == (AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC)) { - int slice = AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification); - int patch = AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification); + int32_t slice = AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification); + int32_t patch = AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification); clustersArray[slice][patch] = (AliHLTTPCRawClusterData*)(iter->fPtr); } if (iter->fDataType == AliHLTTPCDefinitions::ClustersXYZDataType()) { - int slice = AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification); - int patch = AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification); + int32_t slice = AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification); + int32_t patch = AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification); clustersTransformedArray[slice][patch] = (AliHLTTPCClusterXYZData*)(iter->fPtr); if (clustersTransformedArray[slice][patch]->fCount) { clustersTrackIDArray[slice][patch] = new AliHLTTPCTrackHelperStruct[clustersTransformedArray[slice][patch]->fCount]; memset(clustersTrackIDArray[slice][patch], 0, clustersTransformedArray[slice][patch]->fCount * sizeof(AliHLTTPCTrackHelperStruct)); - for (int i = 0; i < clustersTransformedArray[slice][patch]->fCount; i++) { + for (int32_t i = 0; i < clustersTransformedArray[slice][patch]->fCount; i++) { clustersTrackIDArray[slice][patch][i].fID = -1; } } @@ -311,7 +311,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa double residualBarrelTrackY = 0, residualBarrelTrackZ = 0, residualExternalTrackY = 0, residualExternalTrackZ = 0, residualBacktransformPad = 0, residualBacktransformTime = 0; double residualBarrelTrackYabs = 0, residualBarrelTrackZabs = 0, residualExternalTrackYabs = 0, residualExternalTrackZabs = 0, residualBacktransformPadabs = 0, residualBacktransformTimeabs = 0; double residualFitTrackY = 0, residualFitTrackZ = 0, residualFitTrackYabs = 0, residualFitTrackZabs = 0, residualTrackRawPad = 0, residualTrackRawTime = 0, residualTrackRawPadabs = 0, residualTrackRawTimeabs = 0; - int nClusterTracks = 0, nClusters = 0, nClusterTracksRaw = 0; + int32_t nClusterTracks = 0, nClusters = 0, nClusterTracksRaw = 0; const AliHLTUInt8_t* pCurrent = reinterpret_cast(tracks->fTracklets); if (fCompressionStudy) { @@ -319,7 +319,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa prop.SetMaxSinPhi(.999); prop.SetMaterialTPC(); GPUTPCGMPolynomialField field; - int err = GPUTPCGMPolynomialFieldManager::GetPolynomialField(field); + int32_t err = GPUTPCGMPolynomialFieldManager::GetPolynomialField(field); if (err != 0) { HLTError("Can not initialize polynomial magnetic field"); return -1; @@ -339,15 +339,15 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa GPUTPCGMTrackParam ftrack; float falpha; - int hitsUsed = 0; + int32_t hitsUsed = 0; float averageCharge = 0; float averageQMax = 0; AliHLTTPCTrackHelperStruct* hitIndexCache[1024]; - for (int ip = 0; ip < track->fNPoints; ip++) { - int clusterID = track->fPointIDs[ip]; - int slice = AliHLTTPCGeometry::CluID2Slice(clusterID); - int patch = AliHLTTPCGeometry::CluID2Partition(clusterID); - int index = AliHLTTPCGeometry::CluID2Index(clusterID); + for (int32_t ip = 0; ip < track->fNPoints; ip++) { + int32_t clusterID = track->fPointIDs[ip]; + int32_t slice = AliHLTTPCGeometry::CluID2Slice(clusterID); + int32_t patch = AliHLTTPCGeometry::CluID2Partition(clusterID); + int32_t index = AliHLTTPCGeometry::CluID2Index(clusterID); if (clustersTrackIDArray[slice][patch][index].fID != -1) { HLTDebug("Already assigned hit %d of track %d, skipping", ip, i); @@ -362,7 +362,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa AliHLTTPCRawCluster& cluster = clustersArray[slice][patch]->fClusters[index]; AliHLTTPCClusterXYZ& clusterTransformed = clustersTransformedArray[slice][patch]->fClusters[index]; - int padrow = AliHLTTPCGeometry::GetFirstRow(patch) + cluster.GetPadRow(); + int32_t padrow = AliHLTTPCGeometry::GetFirstRow(patch) + cluster.GetPadRow(); float x = AliHLTTPCGeometry::Row2X(padrow); float y = 0.0f; float z = 0.0f; @@ -392,7 +392,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa if (ip == 0) { ftrack.Par()[0] = xyz[1]; ftrack.Par()[1] = xyz[2]; - for (int k = 2; k < 5; k++) { + for (int32_t k = 2; k < 5; k++) { ftrack.Par()[k] = etrack.GetParameter()[k]; } ftrack.SetX(xyz[0]); @@ -466,7 +466,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa averageQMax += cluster.GetQMax(); if (ip != 0) { - int rowType = padrow < 64 ? 0 : (padrow < 128 ? 2 : 1); + int32_t rowType = padrow < 64 ? 0 : (padrow < 128 ? 2 : 1); prop.Update(xyz[1], xyz[2], rowType, *mSliceParam, 0, 0, nullptr, false, slice > 18, -1.f, 0.f, 0.f); } } @@ -474,19 +474,19 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa averageCharge /= hitsUsed; averageQMax /= hitsUsed; } - for (int ip = 0; ip < hitsUsed; ip++) { + for (int32_t ip = 0; ip < hitsUsed; ip++) { hitIndexCache[ip]->fAverageQMax = averageQMax; hitIndexCache[ip]->fAverageQTot = averageCharge; } - pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(unsigned int); + pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(uint32_t); } } - for (unsigned int is = 0; is < NSLICES; is++) { - for (unsigned int ip = 0; ip < NPATCHES; ip++) { + for (uint32_t is = 0; is < NSLICES; is++) { + for (uint32_t ip = 0; ip < NPATCHES; ip++) { AliHLTTPCRawClusterData* clusters = clustersArray[is][ip]; AliHLTTPCClusterXYZData* clustersTransformed = clustersTransformedArray[is][ip]; - int firstRow = AliHLTTPCGeometry::GetFirstRow(ip); + int32_t firstRow = AliHLTTPCGeometry::GetFirstRow(ip); if (clusters == nullptr) { HLTDebug("Clusters missing for slice %d patch %d\n", is, ip); @@ -507,29 +507,29 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa std::sort(sortedClusters, sortedClusters + clusters->fCount, AliHLTTPCClusterStat_sorthelper); } - for (unsigned int iCluster = 0; iCluster < clusters->fCount; iCluster++) { + for (uint32_t iCluster = 0; iCluster < clusters->fCount; iCluster++) { AliHLTTPCRawCluster& cluster = clusters->fClusters[iCluster]; AliHLTTPCClusterXYZ& clusterTransformed = clustersTransformed->fClusters[iCluster]; static AliHLTTPCTrackHelperStruct tmp; AliHLTTPCTrackHelperStruct& clusterTrack = fCompressionStudy ? clustersTrackIDArray[is][ip][iCluster] : tmp; if (fCompressionStudy) { - int row = cluster.GetPadRow() + firstRow; + int32_t row = cluster.GetPadRow() + firstRow; float xyz[3]; TransformForward(is, row, cluster.GetPad(), cluster.GetTime(), xyz); /*float xyzOrig[3], xyzLocGlob[3]; { - int sector = AliHLTTPCGeometry::GetNRowLow() ? is : is + NSLICES; - int sectorrow = AliHLTTPCGeometry::GetNRowLow() ? row : row - AliHLTTPCGeometry::GetNRowLow(); + int32_t sector = AliHLTTPCGeometry::GetNRowLow() ? is : is + NSLICES; + int32_t sectorrow = AliHLTTPCGeometry::GetNRowLow() ? row : row - AliHLTTPCGeometry::GetNRowLow(); Double_t xx[] = {(double) sectorrow, cluster.GetPad(), cluster.GetTime()}; transform->Transform(xx, §or, 0, 1); Double_t yy[] = {(double) sectorrow, cluster.GetPad(), cluster.GetTime()}; transform->Local2RotatedGlobal(sector, yy); - for (int k = 0; k < 3; k++) + for (int32_t k = 0; k < 3; k++) { xyzOrig[k] = xx[k]; xyzLocGlob[k] = yy[k]; @@ -566,9 +566,9 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa AliHLTTPCRawCluster& cluster2 = fSort ? sortedClusters[iCluster] : cluster; if (fPrintClusters) { - HLTImportant("Event %d Slice %d, Patch %d, Row %d, Pad %.2f, Time %.2f, SPad %.2f, STime %.2f, QMax %d, QTot %d, SplitPad %d, SplitTime %d, Edge %d, TrackId %d, ResPad %.2f ResTime %.2f AvgQTot %d AvgQMax %d", fEvent, is, ip, (int)cluster2.GetPadRow(), cluster2.GetPad(), - cluster2.GetTime(), cluster2.GetSigmaPad2(), cluster2.GetSigmaTime2(), (int)cluster2.GetQMax(), (int)cluster2.GetCharge(), (int)cluster2.GetFlagSplitPad(), (int)cluster2.GetFlagSplitTime(), (int)cluster2.GetFlagEdge(), (int)clusterTrack.fID, - clusterTrack.fResidualPad, clusterTrack.fResidualTime, (int)clusterTrack.fAverageQTot, (int)clusterTrack.fAverageQMax); + HLTImportant("Event %d Slice %d, Patch %d, Row %d, Pad %.2f, Time %.2f, SPad %.2f, STime %.2f, QMax %d, QTot %d, SplitPad %d, SplitTime %d, Edge %d, TrackId %d, ResPad %.2f ResTime %.2f AvgQTot %d AvgQMax %d", fEvent, is, ip, (int32_t)cluster2.GetPadRow(), cluster2.GetPad(), + cluster2.GetTime(), cluster2.GetSigmaPad2(), cluster2.GetSigmaTime2(), (int32_t)cluster2.GetQMax(), (int32_t)cluster2.GetCharge(), (int32_t)cluster2.GetFlagSplitPad(), (int32_t)cluster2.GetFlagSplitTime(), (int32_t)cluster2.GetFlagEdge(), (int32_t)clusterTrack.fID, + clusterTrack.fResidualPad, clusterTrack.fResidualTime, (int32_t)clusterTrack.fAverageQTot, (int32_t)clusterTrack.fAverageQMax); } if (fCompressionStudy && clusterTrack.fID == -1) { @@ -585,11 +585,11 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa const AliHLTUInt8_t* pCurrent = reinterpret_cast(tracks->fTracklets); for (unsigned i = 0; i < tracks->fCount; i++) { const AliHLTExternalTrackParam* track = reinterpret_cast(pCurrent); - for (int ip = 0; ip < track->fNPoints; ip++) { - int clusterID = track->fPointIDs[ip]; - int slice = AliHLTTPCGeometry::CluID2Slice(clusterID); - int patch = AliHLTTPCGeometry::CluID2Partition(clusterID); - int index = AliHLTTPCGeometry::CluID2Index(clusterID); + for (int32_t ip = 0; ip < track->fNPoints; ip++) { + int32_t clusterID = track->fPointIDs[ip]; + int32_t slice = AliHLTTPCGeometry::CluID2Slice(clusterID); + int32_t patch = AliHLTTPCGeometry::CluID2Partition(clusterID); + int32_t index = AliHLTTPCGeometry::CluID2Index(clusterID); AliHLTTPCRawCluster& cluster = clustersArray[slice][patch]->fClusters[index]; AliHLTTPCClusterXYZ& clusterTransformed = clustersTransformedArray[slice][patch]->fClusters[index]; @@ -599,19 +599,19 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa PrintDumpClustersScaled(slice, patch, cluster, clusterTransformed, clusterTrack); } } - pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(unsigned int); + pCurrent += sizeof(AliHLTExternalTrackParam) + track->fNPoints * sizeof(uint32_t); } } - for (unsigned int is = 0; is < NSLICES; is++) { - for (unsigned int ip = 0; ip < NPATCHES; ip++) { + for (uint32_t is = 0; is < NSLICES; is++) { + for (uint32_t ip = 0; ip < NPATCHES; ip++) { if (clustersTrackIDArray[is][ip]) { delete[] clustersTrackIDArray[is][ip]; } } } - int total = fTotal == 0 ? 1 : fTotal; + int32_t total = fTotal == 0 ? 1 : fTotal; fAssigned += nClusterTracks; HLTImportant("Total %d Assigned %d (%2.0f\%) SplitPad %d (%2.0f\%) SplitTime %d (%2.0f\%) SplitPadTime %d (%2.0f\%) SplitPadOrTime %d (%2.0f\%) Edge %d (%2.0f\%)", fTotal, fAssigned, (float)fAssigned / (float)total * 100.f, fSplitPad, (float)fSplitPad / (float)total * 100.f, fSplitTime, (float)fSplitTime / (float)total * 100.f, fSplitPadTime, (float)fSplitPadTime / (float)total * 100.f, fSplitPadOrTime, (float)fSplitPadOrTime / (float)total * 100.f, fEdge, (float)fEdge / (float)total * 100.f); @@ -655,7 +655,7 @@ int AliHLTTPCClusterStatComponent::DoEvent(const AliHLTComponentEventData& evtDa return iResult; } -void AliHLTTPCClusterStatComponent::PrintDumpClustersScaled(int is, int ip, AliHLTTPCRawCluster& cluster, AliHLTTPCClusterXYZ& clusterTransformed, AliHLTTPCClusterStatComponent::AliHLTTPCTrackHelperStruct& clusterTrack) +void AliHLTTPCClusterStatComponent::PrintDumpClustersScaled(int32_t is, int32_t ip, AliHLTTPCRawCluster& cluster, AliHLTTPCClusterXYZ& clusterTransformed, AliHLTTPCClusterStatComponent::AliHLTTPCTrackHelperStruct& clusterTrack) { AliHLTUInt64_t pad64 = 0; if (!isnan(cluster.GetPad())) { @@ -691,28 +691,28 @@ void AliHLTTPCClusterStatComponent::PrintDumpClustersScaled(int is, int ip, AliH time64res = (AliHLTUInt64_t)round(clusterTrack.fResidualTime * AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale); if (fDumpClusters) { - int dumpVals[16] = {fEvent, - (int)is, - (int)ip, - (int)cluster.GetPadRow(), - (int)pad64, - (int)time64, - (int)sigmaPad64, - (int)sigmaTime64, - (int)cluster.GetQMax(), - (int)cluster.GetCharge(), - (int)(cluster.GetFlagEdge() * 4 + cluster.GetFlagSplitPad() * 2 + cluster.GetFlagSplitTime()), - (int)clusterTrack.fID, - (int)pad64res, - (int)time64res, - (int)clusterTrack.fAverageQTot, - (int)clusterTrack.fAverageQMax}; - fwrite(dumpVals, sizeof(int), 16, fp); + int32_t dumpVals[16] = {fEvent, + (int32_t)is, + (int32_t)ip, + (int32_t)cluster.GetPadRow(), + (int32_t)pad64, + (int32_t)time64, + (int32_t)sigmaPad64, + (int32_t)sigmaTime64, + (int32_t)cluster.GetQMax(), + (int32_t)cluster.GetCharge(), + (int32_t)(cluster.GetFlagEdge() * 4 + cluster.GetFlagSplitPad() * 2 + cluster.GetFlagSplitTime()), + (int32_t)clusterTrack.fID, + (int32_t)pad64res, + (int32_t)time64res, + (int32_t)clusterTrack.fAverageQTot, + (int32_t)clusterTrack.fAverageQMax}; + fwrite(dumpVals, sizeof(int32_t), 16, fp); } if (fPrintClustersScaled) { - HLTImportant("Event %d Slice %d, Patch %d, Row %d, Pad %d, Time %d, SPad %d, STime %d, QMax %d, QTot %d, SplitPad %d, SplitTime %d, Edge %d, TrackID %d, PadRes %d, TimeRes %d AvgTot %d AvgMax %d", fEvent, is, ip, (int)cluster.GetPadRow(), (int)pad64, (int)time64, (int)sigmaPad64, - (int)sigmaTime64, (int)cluster.GetQMax(), (int)cluster.GetCharge(), (int)cluster.GetFlagSplitPad(), (int)cluster.GetFlagSplitTime(), (int)cluster.GetFlagEdge(), (int)clusterTrack.fID, (int)pad64res, (int)time64res, (int)clusterTrack.fAverageQTot, - (int)clusterTrack.fAverageQMax); + HLTImportant("Event %d Slice %d, Patch %d, Row %d, Pad %d, Time %d, SPad %d, STime %d, QMax %d, QTot %d, SplitPad %d, SplitTime %d, Edge %d, TrackID %d, PadRes %d, TimeRes %d AvgTot %d AvgMax %d", fEvent, is, ip, (int32_t)cluster.GetPadRow(), (int32_t)pad64, (int32_t)time64, (int32_t)sigmaPad64, + (int32_t)sigmaTime64, (int32_t)cluster.GetQMax(), (int32_t)cluster.GetCharge(), (int32_t)cluster.GetFlagSplitPad(), (int32_t)cluster.GetFlagSplitTime(), (int32_t)cluster.GetFlagEdge(), (int32_t)clusterTrack.fID, (int32_t)pad64res, (int32_t)time64res, (int32_t)clusterTrack.fAverageQTot, + (int32_t)clusterTrack.fAverageQMax); } } diff --git a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h index 5860fa44eff44..2b58755217a61 100644 --- a/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h +++ b/GPU/GPUTracking/DataCompression/AliHLTTPCClusterStatComponent.h @@ -38,39 +38,39 @@ class AliHLTTPCClusterStatComponent : public AliHLTProcessor, public AliOptionPa /** destructor */ virtual ~AliHLTTPCClusterStatComponent(); - static const unsigned int NSLICES = 36; - static const unsigned int NPATCHES = 6; + static const uint32_t NSLICES = 36; + static const uint32_t NPATCHES = 6; struct AliHLTTPCTrackHelperStruct { - int fID; + int32_t fID; const AliHLTExternalTrackParam* fTrack; float fResidualPad; float fResidualTime; bool fFirstHit; - long fAverageQMax; - long fAverageQTot; + int64_t fAverageQMax; + int64_t fAverageQTot; }; // interface methods of base class const char* GetComponentID() { return "TPCClusterStat"; }; void GetInputDataTypes(AliHLTComponentDataTypeList& list); AliHLTComponentDataType GetOutputDataType(); - void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); AliHLTComponent* Spawn() { return new AliHLTTPCClusterStatComponent; } - static void TransformReverse(int slice, int row, float y, float z, float padtime[]); - static void TransformForward(int slice, int row, float pad, float time, float xyz[]); + static void TransformReverse(int32_t slice, int32_t row, float y, float z, float padtime[]); + static void TransformForward(int32_t slice, int32_t row, float pad, float time, float xyz[]); - void PrintDumpClustersScaled(int is, int ip, AliHLTTPCRawCluster& cluster, AliHLTTPCClusterXYZ& clusterTransformed, AliHLTTPCTrackHelperStruct& clusterTrack); + void PrintDumpClustersScaled(int32_t is, int32_t ip, AliHLTTPCRawCluster& cluster, AliHLTTPCClusterXYZ& clusterTransformed, AliHLTTPCTrackHelperStruct& clusterTrack); protected: // interface methods of base class - int DoInit(int argc, const char** argv); - int DoDeinit(); - int DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks); + int32_t DoInit(int argc, const char** argv); + int32_t DoDeinit(); + int32_t DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks); using AliHLTProcessor::DoEvent; - int ProcessOption(TString option, TString value); + int32_t ProcessOption(TString option, TString value); private: /** copy constructor prohibited */ @@ -80,15 +80,15 @@ class AliHLTTPCClusterStatComponent : public AliHLTProcessor, public AliOptionPa GPUCA_NAMESPACE::gpu::GPUParam* mSliceParam; - int fTotal, fEdge, fSplitPad, fSplitTime, fSplitPadTime, fSplitPadOrTime, fAssigned; //! + int32_t fTotal, fEdge, fSplitPad, fSplitTime, fSplitPadTime, fSplitPadOrTime, fAssigned; //! - int fCompressionStudy; //! - int fPrintClusters; //! - int fPrintClustersScaled; //! - int fDumpClusters; //! - int fAggregate; //! - int fSort; //! - int fEvent; + int32_t fCompressionStudy; //! + int32_t fPrintClusters; //! + int32_t fPrintClustersScaled; //! + int32_t fDumpClusters; //! + int32_t fAggregate; //! + int32_t fSort; //! + int32_t fEvent; FILE* fp; diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h b/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h index 2599f305c3541..8e80f3223d04c 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h @@ -23,7 +23,7 @@ namespace gpu { struct GPUTPCClusterRejection { template - static constexpr inline bool GetProtectionStatus(int attach, bool& physics, bool& protect, T* counts = nullptr, S* mev200 = nullptr) + static constexpr inline bool GetProtectionStatus(int32_t attach, bool& physics, bool& protect, T* counts = nullptr, S* mev200 = nullptr) { (void)counts; // Avoid incorrect -Wunused-but-set-parameter warning (void)mev200; @@ -61,7 +61,7 @@ struct GPUTPCClusterRejection { } } - static constexpr inline bool GetIsRejected(int attach) + static constexpr inline bool GetIsRejected(int32_t attach) { bool physics = false, protect = false; return GetProtectionStatus(attach, physics, protect); diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx index 9db4b9758dbce..4490c160b2139 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx @@ -26,7 +26,7 @@ using namespace GPUCA_NAMESPACE::gpu; namespace { typedef std::vector HuffCode; -typedef std::map HuffCodeMap; +typedef std::map HuffCodeMap; class INode { @@ -56,20 +56,20 @@ class InternalNode : public INode class LeafNode : public INode { public: - const unsigned int c; + const uint32_t c; - LeafNode(double v, unsigned int w) : INode(v), c(w) {} + LeafNode(double v, uint32_t w) : INode(v), c(w) {} }; struct NodeCmp { bool operator()(const INode* lhs, const INode* rhs) const { return lhs->f > rhs->f; } }; -INode* BuildTree(const double* frequencies, unsigned int UniqueSymbols) +INode* BuildTree(const double* frequencies, uint32_t UniqueSymbols) { std::priority_queue, NodeCmp> trees; - for (unsigned int i = 0; i < UniqueSymbols; ++i) { + for (uint32_t i = 0; i < UniqueSymbols; ++i) { if (frequencies[i] != 0) { trees.push(new LeafNode(frequencies[i], i)); } @@ -105,7 +105,7 @@ void GenerateCodes(const INode* node, const HuffCode& prefix, HuffCodeMap& outCo void GPUTPCClusterStatistics::RunStatistics(const o2::tpc::ClusterNativeAccess* clustersNative, const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param) { - unsigned int decodingErrors = 0; + uint32_t decodingErrors = 0; o2::tpc::ClusterNativeAccess clustersNativeDecoded; std::vector clusterBuffer; GPUInfo("Compression statistics, decoding: %d attached (%d tracks), %d unattached", clustersCompressed->nAttachedClusters, clustersCompressed->nTracks, clustersCompressed->nUnattachedClusters); @@ -113,15 +113,15 @@ void GPUTPCClusterStatistics::RunStatistics(const o2::tpc::ClusterNativeAccess* mDecoder.decompress(clustersCompressed, clustersNativeDecoded, allocator, param, true); std::vector tmpClusters; if (param.rec.tpc.rejectionStrategy == GPUSettings::RejectionNone) { // verification does not make sense if we reject clusters during compression - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { if (clustersNative->nClusters[i][j] != clustersNativeDecoded.nClusters[i][j]) { GPUError("Number of clusters mismatch slice %u row %u: expected %d v.s. decoded %d", i, j, clustersNative->nClusters[i][j], clustersNativeDecoded.nClusters[i][j]); decodingErrors++; continue; } tmpClusters.resize(clustersNative->nClusters[i][j]); - for (unsigned int k = 0; k < clustersNative->nClusters[i][j]; k++) { + for (uint32_t k = 0; k < clustersNative->nClusters[i][j]; k++) { tmpClusters[k] = clustersNative->clusters[i][j][k]; if (param.rec.tpc.compressionTypeMask & GPUSettings::CompressionTruncate) { GPUTPCCompression::truncateSignificantBitsChargeMax(tmpClusters[k].qMax, param); @@ -131,13 +131,13 @@ void GPUTPCClusterStatistics::RunStatistics(const o2::tpc::ClusterNativeAccess* } } std::sort(tmpClusters.begin(), tmpClusters.end()); - for (unsigned int k = 0; k < clustersNative->nClusters[i][j]; k++) { + for (uint32_t k = 0; k < clustersNative->nClusters[i][j]; k++) { const o2::tpc::ClusterNative& c1 = tmpClusters[k]; const o2::tpc::ClusterNative& c2 = clustersNativeDecoded.clusters[i][j][k]; if (c1.timeFlagsPacked != c2.timeFlagsPacked || c1.padPacked != c2.padPacked || c1.sigmaTimePacked != c2.sigmaTimePacked || c1.sigmaPadPacked != c2.sigmaPadPacked || c1.qMax != c2.qMax || c1.qTot != c2.qTot) { if (decodingErrors++ < 100) { - GPUWarning("Cluster mismatch: slice %2u row %3u hit %5u: %6d %3d %4d %3d %3d %4d %4d", i, j, k, (int)c1.getTimePacked(), (int)c1.getFlags(), (int)c1.padPacked, (int)c1.sigmaTimePacked, (int)c1.sigmaPadPacked, (int)c1.qMax, (int)c1.qTot); - GPUWarning("%45s %6d %3d %4d %3d %3d %4d %4d", "", (int)c2.getTimePacked(), (int)c2.getFlags(), (int)c2.padPacked, (int)c2.sigmaTimePacked, (int)c2.sigmaPadPacked, (int)c2.qMax, (int)c2.qTot); + GPUWarning("Cluster mismatch: slice %2u row %3u hit %5u: %6d %3d %4d %3d %3d %4d %4d", i, j, k, (int32_t)c1.getTimePacked(), (int32_t)c1.getFlags(), (int32_t)c1.padPacked, (int32_t)c1.sigmaTimePacked, (int32_t)c1.sigmaPadPacked, (int32_t)c1.qMax, (int32_t)c1.qTot); + GPUWarning("%45s %6d %3d %4d %3d %3d %4d %4d", "", (int32_t)c2.getTimePacked(), (int32_t)c2.getFlags(), (int32_t)c2.padPacked, (int32_t)c2.sigmaTimePacked, (int32_t)c2.sigmaPadPacked, (int32_t)c2.qMax, (int32_t)c2.qTot); } } } @@ -172,8 +172,8 @@ void GPUTPCClusterStatistics::RunStatistics(const o2::tpc::ClusterNativeAccess* FillStatistic(mPtimeDiffU, clustersCompressed->timeDiffU, clustersCompressed->nUnattachedClusters); FillStatistic(mPsigmaPadU, clustersCompressed->sigmaPadU, clustersCompressed->nUnattachedClusters); FillStatistic(mPsigmaTimeU, clustersCompressed->sigmaTimeU, clustersCompressed->nUnattachedClusters); - FillStatistic(mPnTrackClusters, clustersCompressed->nTrackClusters, clustersCompressed->nTracks); - FillStatistic(mPnSliceRowClusters, clustersCompressed->nSliceRowClusters, clustersCompressed->nSliceRows); + FillStatistic(mPnTrackClusters, clustersCompressed->nTrackClusters, clustersCompressed->nTracks); + FillStatistic(mPnSliceRowClusters, clustersCompressed->nSliceRowClusters, clustersCompressed->nSliceRows); FillStatisticCombined(mPsigmaA, clustersCompressed->sigmaPadA, clustersCompressed->sigmaTimeA, clustersCompressed->nAttachedClusters, P_MAX_SIGMA); FillStatisticCombined(mPsigmaU, clustersCompressed->sigmaPadU, clustersCompressed->sigmaTimeU, clustersCompressed->nUnattachedClusters, P_MAX_SIGMA); FillStatisticCombined(mPQA, clustersCompressed->qMaxA, clustersCompressed->qTotA, clustersCompressed->nAttachedClusters, P_MAX_QMAX); @@ -225,10 +225,10 @@ void GPUTPCClusterStatistics::Finish() GPUInfo("Combined Sigma: %6.4f --> %6.4f (%6.4f%%)", eSigma, eSigmaCombined, eSigma > 1e-3 ? (100. * (eSigma - eSigmaCombined) / eSigma) : 0.f); GPUInfo("Combined Q: %6.4f --> %6.4f (%6.4f%%)", eQ, eQCombined, eQ > 1e-3 ? (100. * (eQ - eQCombined) / eQ) : 0.f); - printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'ld clusters)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, (long)mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); + printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'ld clusters)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, (int64_t)mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); } -float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bool count) +float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bool count) { double entropy = 0.; double huffmanSize = 0; @@ -236,11 +236,11 @@ float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bo std::vector prob(p.size()); double log2 = log(2.); size_t total = 0; - for (unsigned int i = 0; i < p.size(); i++) { + for (uint32_t i = 0; i < p.size(); i++) { total += p[i]; } if (total) { - for (unsigned int i = 0; i < prob.size(); i++) { + for (uint32_t i = 0; i < prob.size(); i++) { if (p[i]) { prob[i] = (double)p[i] / total; double I = -log(prob[i]) / log2; @@ -265,20 +265,20 @@ float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bo mHuffman += huffmanSize * total; } } - GPUInfo("Size: %30s: Entropy %7.4f Huffman %7.4f (Count) %9ld", name, entropy, huffmanSize, (long)total); + GPUInfo("Size: %30s: Entropy %7.4f Huffman %7.4f (Count) %9ld", name, entropy, huffmanSize, (int64_t)total); return entropy; } -template -void GPUTPCClusterStatistics::FillStatistic(std::vector& p, const T* ptr, size_t n) +template +void GPUTPCClusterStatistics::FillStatistic(std::vector& p, const T* ptr, size_t n) { for (size_t i = 0; i < n; i++) { - unsigned int val = ptr[i]; + uint32_t val = ptr[i]; if (val >= p.size()) { if (I) { p.resize(val + 1); } else { - GPUError("Invalid Value: %d >= %d", val, (int)p.size()); + GPUError("Invalid Value: %d >= %d", val, (int32_t)p.size()); continue; } } @@ -286,16 +286,16 @@ void GPUTPCClusterStatistics::FillStatistic(std::vector& p, const T* ptr, s } } -template -void GPUTPCClusterStatistics::FillStatisticCombined(std::vector& p, const T* ptr1, const S* ptr2, size_t n, int max1) +template +void GPUTPCClusterStatistics::FillStatisticCombined(std::vector& p, const T* ptr1, const S* ptr2, size_t n, int32_t max1) { for (size_t i = 0; i < n; i++) { - unsigned int val = ptr1[i] + ptr2[i] * max1; + uint32_t val = ptr1[i] + ptr2[i] * max1; if (val >= p.size()) { if (I) { p.resize(val + 1); } else { - GPUError("Invalid Value: %d >= %d", val, (int)p.size()); + GPUError("Invalid Value: %d >= %d", val, (int32_t)p.size()); continue; } } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.h b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.h index 7e14f4704a635..a07857bbcd0e3 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.h @@ -33,56 +33,56 @@ class GPUTPCClusterStatistics void RunStatistics(const o2::tpc::ClusterNativeAccess* clustersNative, const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param){}; void Finish(){}; #else - static constexpr unsigned int NSLICES = GPUCA_NSLICES; + static constexpr uint32_t NSLICES = GPUCA_NSLICES; void RunStatistics(const o2::tpc::ClusterNativeAccess* clustersNative, const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param); void Finish(); protected: - template - void FillStatistic(std::vector& p, const T* ptr, size_t n); - template - void FillStatisticCombined(std::vector& p, const T* ptr1, const S* ptr2, size_t n, int max1); - float Analyze(std::vector& p, const char* name, bool count = true); + template + void FillStatistic(std::vector& p, const T* ptr, size_t n); + template + void FillStatisticCombined(std::vector& p, const T* ptr1, const S* ptr2, size_t n, int32_t max1); + float Analyze(std::vector& p, const char* name, bool count = true); TPCClusterDecompressor mDecoder; bool mDecodingError = false; - static constexpr unsigned int P_MAX_QMAX = GPUTPCCompression::P_MAX_QMAX; - static constexpr unsigned int P_MAX_QTOT = GPUTPCCompression::P_MAX_QTOT; - static constexpr unsigned int P_MAX_TIME = GPUTPCCompression::P_MAX_TIME; - static constexpr unsigned int P_MAX_PAD = GPUTPCCompression::P_MAX_PAD; - static constexpr unsigned int P_MAX_SIGMA = GPUTPCCompression::P_MAX_SIGMA; - static constexpr unsigned int P_MAX_FLAGS = GPUTPCCompression::P_MAX_FLAGS; - static constexpr unsigned int P_MAX_QPT = GPUTPCCompression::P_MAX_QPT; + static constexpr uint32_t P_MAX_QMAX = GPUTPCCompression::P_MAX_QMAX; + static constexpr uint32_t P_MAX_QTOT = GPUTPCCompression::P_MAX_QTOT; + static constexpr uint32_t P_MAX_TIME = GPUTPCCompression::P_MAX_TIME; + static constexpr uint32_t P_MAX_PAD = GPUTPCCompression::P_MAX_PAD; + static constexpr uint32_t P_MAX_SIGMA = GPUTPCCompression::P_MAX_SIGMA; + static constexpr uint32_t P_MAX_FLAGS = GPUTPCCompression::P_MAX_FLAGS; + static constexpr uint32_t P_MAX_QPT = GPUTPCCompression::P_MAX_QPT; - std::vector mPqTotA = std::vector(P_MAX_QTOT, 0); - std::vector mPqMaxA = std::vector(P_MAX_QMAX, 0); - std::vector mPflagsA = std::vector(P_MAX_FLAGS, 0); - std::vector mProwDiffA = std::vector(GPUCA_ROW_COUNT, 0); - std::vector mPsliceLegDiffA = std::vector(GPUCA_NSLICES * 2, 0); - std::vector mPpadResA = std::vector(P_MAX_PAD, 0); - std::vector mPtimeResA = std::vector(P_MAX_TIME, 0); - std::vector mPsigmaPadA = std::vector(P_MAX_SIGMA, 0); - std::vector mPsigmaTimeA = std::vector(P_MAX_SIGMA, 0); - std::vector mPqPtA = std::vector(P_MAX_QPT, 0); - std::vector mProwA = std::vector(GPUCA_ROW_COUNT, 0); - std::vector mPsliceA = std::vector(GPUCA_NSLICES, 0); - std::vector mPtimeA = std::vector(P_MAX_TIME, 0); - std::vector mPpadA = std::vector(P_MAX_PAD, 0); - std::vector mPqTotU = std::vector(P_MAX_QTOT, 0); - std::vector mPqMaxU = std::vector(P_MAX_QMAX, 0); - std::vector mPflagsU = std::vector(P_MAX_FLAGS, 0); - std::vector mPpadDiffU = std::vector(P_MAX_PAD, 0); - std::vector mPtimeDiffU = std::vector(P_MAX_TIME, 0); - std::vector mPsigmaPadU = std::vector(P_MAX_SIGMA, 0); - std::vector mPsigmaTimeU = std::vector(P_MAX_SIGMA, 0); - std::vector mPnTrackClusters; - std::vector mPnSliceRowClusters; - std::vector mPsigmaU = std::vector(P_MAX_SIGMA * P_MAX_SIGMA, 0); - std::vector mPsigmaA = std::vector(P_MAX_SIGMA * P_MAX_SIGMA, 0); - std::vector mPQU = std::vector(P_MAX_QMAX * P_MAX_QTOT, 0); - std::vector mPQA = std::vector(P_MAX_QMAX * P_MAX_QTOT, 0); - std::vector mProwSliceA = std::vector(GPUCA_ROW_COUNT * GPUCA_NSLICES * 2, 0); + std::vector mPqTotA = std::vector(P_MAX_QTOT, 0); + std::vector mPqMaxA = std::vector(P_MAX_QMAX, 0); + std::vector mPflagsA = std::vector(P_MAX_FLAGS, 0); + std::vector mProwDiffA = std::vector(GPUCA_ROW_COUNT, 0); + std::vector mPsliceLegDiffA = std::vector(GPUCA_NSLICES * 2, 0); + std::vector mPpadResA = std::vector(P_MAX_PAD, 0); + std::vector mPtimeResA = std::vector(P_MAX_TIME, 0); + std::vector mPsigmaPadA = std::vector(P_MAX_SIGMA, 0); + std::vector mPsigmaTimeA = std::vector(P_MAX_SIGMA, 0); + std::vector mPqPtA = std::vector(P_MAX_QPT, 0); + std::vector mProwA = std::vector(GPUCA_ROW_COUNT, 0); + std::vector mPsliceA = std::vector(GPUCA_NSLICES, 0); + std::vector mPtimeA = std::vector(P_MAX_TIME, 0); + std::vector mPpadA = std::vector(P_MAX_PAD, 0); + std::vector mPqTotU = std::vector(P_MAX_QTOT, 0); + std::vector mPqMaxU = std::vector(P_MAX_QMAX, 0); + std::vector mPflagsU = std::vector(P_MAX_FLAGS, 0); + std::vector mPpadDiffU = std::vector(P_MAX_PAD, 0); + std::vector mPtimeDiffU = std::vector(P_MAX_TIME, 0); + std::vector mPsigmaPadU = std::vector(P_MAX_SIGMA, 0); + std::vector mPsigmaTimeU = std::vector(P_MAX_SIGMA, 0); + std::vector mPnTrackClusters; + std::vector mPnSliceRowClusters; + std::vector mPsigmaU = std::vector(P_MAX_SIGMA * P_MAX_SIGMA, 0); + std::vector mPsigmaA = std::vector(P_MAX_SIGMA * P_MAX_SIGMA, 0); + std::vector mPQU = std::vector(P_MAX_QMAX * P_MAX_QTOT, 0); + std::vector mPQA = std::vector(P_MAX_QMAX * P_MAX_QTOT, 0); + std::vector mProwSliceA = std::vector(GPUCA_ROW_COUNT * GPUCA_NSLICES * 2, 0); double mEntropy = 0; double mHuffman = 0; diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx index 979656c53db97..f37f817a51822 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx @@ -56,7 +56,7 @@ void* GPUTPCCompression::SetPointersOutput(void* mem) } template -void GPUTPCCompression::SetPointersCompressedClusters(void*& mem, T& c, unsigned int nClA, unsigned int nTr, unsigned int nClU, bool reducedClA) +void GPUTPCCompression::SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA) { computePointerWithAlignment(mem, c.qTotU, nClU); // Do not reorder, qTotU ist used as first address in GPUChainTracking::RunTPCCompression computePointerWithAlignment(mem, c.qMaxU, nClU); @@ -67,7 +67,7 @@ void GPUTPCCompression::SetPointersCompressedClusters(void*& mem, T& c, unsigned computePointerWithAlignment(mem, c.sigmaTimeU, nClU); computePointerWithAlignment(mem, c.nSliceRowClusters, GPUCA_ROW_COUNT * NSLICES); - unsigned int nClAreduced = reducedClA ? nClA - nTr : nClA; + uint32_t nClAreduced = reducedClA ? nClA - nTr : nClA; if (!(mRec->GetParam().rec.tpc.compressionTypeMask & GPUSettings::CompressionTrackModel)) { return; // Track model disabled, do not allocate memory @@ -106,7 +106,7 @@ void GPUTPCCompression::RegisterMemoryAllocation() if (mRec->GetProcessingSettings().tpcCompressionGatherMode == 3) { mMemoryResOutputGPU = mRec->RegisterMemoryAllocation(this, &GPUTPCCompression::SetPointersOutputGPU, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_GPU | GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_STACK, "TPCCompressionOutputGPU"); } - unsigned int stackScratch = (mRec->GetProcessingSettings().tpcCompressionGatherMode != 3) ? GPUMemoryResource::MEMORY_STACK : 0; + uint32_t stackScratch = (mRec->GetProcessingSettings().tpcCompressionGatherMode != 3) ? GPUMemoryResource::MEMORY_STACK : 0; if (mRec->GetProcessingSettings().tpcCompressionGatherMode < 2) { mRec->RegisterMemoryAllocation(this, &GPUTPCCompression::SetPointersOutput, GPUMemoryResource::MEMORY_OUTPUT | stackScratch, "TPCCompressionOutput"); } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h index 04dc218921729..ce525f175e616 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h @@ -58,26 +58,26 @@ class GPUTPCCompression : public GPUProcessor void* SetPointersMemory(void* mem); #endif - static constexpr unsigned int P_MAX_QMAX = 1 << 10; - static constexpr unsigned int P_MAX_QTOT = 5 * 5 * P_MAX_QMAX; - static constexpr unsigned int P_MAX_TIME = 1 << 24; - static constexpr unsigned int P_MAX_PAD = 1 << 16; - static constexpr unsigned int P_MAX_SIGMA = 1 << 8; - static constexpr unsigned int P_MAX_FLAGS = 1 << 8; - static constexpr unsigned int P_MAX_QPT = 1 << 8; - - GPUd() static void truncateSignificantBitsCharge(unsigned short& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QTOT); } - GPUd() static void truncateSignificantBitsChargeMax(unsigned short& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QMAX); } - GPUd() static void truncateSignificantBitsWidth(unsigned char& width, const GPUParam& param) { truncateSignificantBits(width, param.rec.tpc.sigBitsWidth, P_MAX_SIGMA); } + static constexpr uint32_t P_MAX_QMAX = 1 << 10; + static constexpr uint32_t P_MAX_QTOT = 5 * 5 * P_MAX_QMAX; + static constexpr uint32_t P_MAX_TIME = 1 << 24; + static constexpr uint32_t P_MAX_PAD = 1 << 16; + static constexpr uint32_t P_MAX_SIGMA = 1 << 8; + static constexpr uint32_t P_MAX_FLAGS = 1 << 8; + static constexpr uint32_t P_MAX_QPT = 1 << 8; + + GPUd() static void truncateSignificantBitsCharge(uint16_t& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QTOT); } + GPUd() static void truncateSignificantBitsChargeMax(uint16_t& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QMAX); } + GPUd() static void truncateSignificantBitsWidth(uint8_t& width, const GPUParam& param) { truncateSignificantBits(width, param.rec.tpc.sigBitsWidth, P_MAX_SIGMA); } protected: struct memory { - unsigned int nStoredTracks = 0; - unsigned int nStoredAttachedClusters = 0; - unsigned int nStoredUnattachedClusters = 0; + uint32_t nStoredTracks = 0; + uint32_t nStoredAttachedClusters = 0; + uint32_t nStoredUnattachedClusters = 0; }; - constexpr static unsigned int NSLICES = GPUCA_NSLICES; + constexpr static uint32_t NSLICES = GPUCA_NSLICES; o2::tpc::CompressedClustersPtrs mPtrs; o2::tpc::CompressedClusters* mOutput = nullptr; @@ -85,43 +85,43 @@ class GPUTPCCompression : public GPUProcessor o2::tpc::CompressedClustersFlat* mOutputFlat = nullptr; memory* mMemory = nullptr; - unsigned int* mAttachedClusterFirstIndex = nullptr; - unsigned char* mClusterStatus = nullptr; + uint32_t* mAttachedClusterFirstIndex = nullptr; + uint8_t* mClusterStatus = nullptr; - unsigned int mMaxTracks = 0; - unsigned int mMaxClusters = 0; - unsigned int mMaxTrackClusters = 0; - unsigned int mMaxClustersInCache = 0; + uint32_t mMaxTracks = 0; + uint32_t mMaxClusters = 0; + uint32_t mMaxTrackClusters = 0; + uint32_t mMaxClustersInCache = 0; size_t mMaxClusterFactorBase1024 = 0; template - void SetPointersCompressedClusters(void*& mem, T& c, unsigned int nClA, unsigned int nTr, unsigned int nClU, bool reducedClA); + void SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA); template - GPUd() static void truncateSignificantBits(T& val, unsigned int nBits, unsigned int max); + GPUd() static void truncateSignificantBits(T& val, uint32_t nBits, uint32_t max); - short mMemoryResOutputHost = -1; - short mMemoryResOutputGPU = -1; + int16_t mMemoryResOutputHost = -1; + int16_t mMemoryResOutputGPU = -1; }; template -GPUdi() void GPUTPCCompression::truncateSignificantBits(T& v, unsigned int nBits, unsigned int max) +GPUdi() void GPUTPCCompression::truncateSignificantBits(T& v, uint32_t nBits, uint32_t max) { if (nBits == 0) { return; } - unsigned int val = v; - unsigned int ldz = sizeof(unsigned int) * 8 - CAMath::Clz(val); + uint32_t val = v; + uint32_t ldz = sizeof(uint32_t) * 8 - CAMath::Clz(val); if (val && ldz > nBits) { if (val & (1 << (ldz - nBits - 1))) { val += (1 << (ldz - nBits - 1)); - ldz = sizeof(unsigned int) * 8 - CAMath::Clz(val); + ldz = sizeof(uint32_t) * 8 - CAMath::Clz(val); } val &= ((1 << ldz) - 1) ^ ((1 << (ldz - nBits)) - 1); if (val >= max) { val = max - 1; } - // GPUInfo("CHANGING X %x --> %x", (unsigned int) v, val); + // GPUInfo("CHANGING X %x --> %x", (uint32_t) v, val); v = val; } } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx index 8d68509e42473..79bf98e41ffb9 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx @@ -26,35 +26,35 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; template <> -GPUdii() void GPUTPCCompressionKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) +GPUdii() void GPUTPCCompressionKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) { const GPUTrackingInOutPointers& GPUrestrict() ioPtrs = processors.ioPtrs; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = ioPtrs.clustersNative; GPUTPCCompression& GPUrestrict() compressor = processors.tpcCompressor; const GPUParam& GPUrestrict() param = processors.param; - unsigned char lastLeg = 0; - int myTrack = 0; - for (unsigned int i = get_global_id(0); i < ioPtrs.nMergedTracks; i += get_global_size(0)) { + uint8_t lastLeg = 0; + int32_t myTrack = 0; + for (uint32_t i = get_global_id(0); i < ioPtrs.nMergedTracks; i += get_global_size(0)) { GPUbarrierWarp(); const GPUTPCGMMergedTrack& GPUrestrict() trk = ioPtrs.mergedTracks[i]; if (!trk.OK()) { continue; } bool rejectTrk = CAMath::Abs(trk.GetParam().GetQPt() * processors.param.qptB5Scaler) > processors.param.rec.tpc.rejectQPtB5 || trk.MergedLooper(); - unsigned int nClustersStored = 0; + uint32_t nClustersStored = 0; CompressedClustersPtrs& GPUrestrict() c = compressor.mPtrs; - unsigned char lastRow = 0, lastSlice = 0; + uint8_t lastRow = 0, lastSlice = 0; GPUTPCCompressionTrackModel track; float zOffset = 0; - for (int k = trk.NClusters() - 1; k >= 0; k--) { + for (int32_t k = trk.NClusters() - 1; k >= 0; k--) { const GPUTPCGMMergedTrackHit& GPUrestrict() hit = ioPtrs.mergedTrackHits[trk.FirstClusterRef() + k]; if (hit.state & GPUTPCGMMergedTrackHit::flagReject) { continue; } - int hitId = hit.num; - int attach = ioPtrs.mergedTrackHitAttachment[hitId]; + int32_t hitId = hit.num; + int32_t attach = ioPtrs.mergedTrackHitAttachment[hitId]; if ((attach & gputpcgmmergertypes::attachTrackMask) != i) { continue; // Main attachment to different track } @@ -85,9 +85,9 @@ GPUdii() void GPUTPCCompressionKernels::Thread 0 ? 254 : 0); + uint8_t qpt = fabs(trk.GetParam().GetQPt()) < 20.f ? (trk.GetParam().GetQPt() * (127.f / 20.f) + 127.5f) : (trk.GetParam().GetQPt() > 0 ? 254 : 0); zOffset = z; track.Init(x, y, z - zOffset, param.SliceParam[hit.slice].Alpha, qpt, param); @@ -100,8 +100,8 @@ GPUdii() void GPUTPCCompressionKernels::Thread row) { @@ -121,8 +121,8 @@ GPUdii() void GPUTPCCompressionKernels::Thread -GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<0>::operator()(unsigned int a, unsigned int b) const +GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<0>::operator()(uint32_t a, uint32_t b) const { return mClsPtr[a].getTimePacked() < mClsPtr[b].getTimePacked(); } template <> -GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<1>::operator()(unsigned int a, unsigned int b) const +GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<1>::operator()(uint32_t a, uint32_t b) const { return mClsPtr[a].padPacked < mClsPtr[b].padPacked; } template <> -GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<2>::operator()(unsigned int a, unsigned int b) const +GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<2>::operator()(uint32_t a, uint32_t b) const { if (mClsPtr[a].getTimePacked() >> 3 == mClsPtr[b].getTimePacked() >> 3) { return mClsPtr[a].padPacked < mClsPtr[b].padPacked; @@ -169,7 +169,7 @@ GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<2>::opera } template <> -GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<3>::operator()(unsigned int a, unsigned int b) const +GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<3>::operator()(uint32_t a, uint32_t b) const { if (mClsPtr[a].padPacked >> 3 == mClsPtr[b].padPacked >> 3) { return mClsPtr[a].getTimePacked() < mClsPtr[b].getTimePacked(); @@ -178,31 +178,31 @@ GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<3>::opera } template <> -GPUdii() void GPUTPCCompressionKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { const GPUTrackingInOutPointers& GPUrestrict() ioPtrs = processors.ioPtrs; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = ioPtrs.clustersNative; GPUTPCCompression& GPUrestrict() compressor = processors.tpcCompressor; GPUParam& GPUrestrict() param = processors.param; - unsigned int* sortBuffer = smem.sortBuffer; - for (int iSliceRow = iBlock; iSliceRow < GPUCA_NSLICES * GPUCA_ROW_COUNT; iSliceRow += nBlocks) { - const unsigned int iSlice = iSliceRow / GPUCA_ROW_COUNT; - const unsigned int iRow = iSliceRow % GPUCA_ROW_COUNT; - const unsigned int idOffset = clusters->clusterOffset[iSlice][iRow]; - const unsigned int idOffsetOut = clusters->clusterOffset[iSlice][iRow] * compressor.mMaxClusterFactorBase1024 / 1024; - const unsigned int idOffsetOutMax = ((const unsigned int*)clusters->clusterOffset[iSlice])[iRow + 1] * compressor.mMaxClusterFactorBase1024 / 1024; // Array out of bounds access is ok, since it goes to the correct nClustersTotal + uint32_t* sortBuffer = smem.sortBuffer; + for (int32_t iSliceRow = iBlock; iSliceRow < GPUCA_NSLICES * GPUCA_ROW_COUNT; iSliceRow += nBlocks) { + const uint32_t iSlice = iSliceRow / GPUCA_ROW_COUNT; + const uint32_t iRow = iSliceRow % GPUCA_ROW_COUNT; + const uint32_t idOffset = clusters->clusterOffset[iSlice][iRow]; + const uint32_t idOffsetOut = clusters->clusterOffset[iSlice][iRow] * compressor.mMaxClusterFactorBase1024 / 1024; + const uint32_t idOffsetOutMax = ((const uint32_t*)clusters->clusterOffset[iSlice])[iRow + 1] * compressor.mMaxClusterFactorBase1024 / 1024; // Array out of bounds access is ok, since it goes to the correct nClustersTotal if (iThread == nThreads - 1) { smem.nCount = 0; } - unsigned int totalCount = 0; + uint32_t totalCount = 0; GPUbarrier(); CompressedClustersPtrs& GPUrestrict() c = compressor.mPtrs; - const unsigned int nn = GPUCommonMath::nextMultipleOf(clusters->nClusters[iSlice][iRow]); - for (unsigned int i = iThread; i < nn + nThreads; i += nThreads) { - const int idx = idOffset + i; - int cidx = 0; + const uint32_t nn = GPUCommonMath::nextMultipleOf(clusters->nClusters[iSlice][iRow]); + for (uint32_t i = iThread; i < nn + nThreads; i += nThreads) { + const int32_t idx = idOffset + i; + int32_t cidx = 0; do { if (i >= clusters->nClusters[iSlice][iRow]) { break; @@ -210,7 +210,7 @@ GPUdii() void GPUTPCCompressionKernels::Thread processors.param.rec.tpc.rejectQPtB5 || trk.MergedLooper()) { break; @@ -231,8 +231,8 @@ GPUdii() void GPUTPCCompressionKernels::Thread idOffsetOutMax) { if (iThread == nThreads - 1) { compressor.raiseError(GPUErrors::ERROR_COMPRESSION_ROW_HIT_OVERFLOW, iSlice * 1000 + iRow, idOffsetOut + totalCount + count, idOffsetOutMax); @@ -270,15 +270,15 @@ GPUdii() void GPUTPCCompressionKernels::Threadclusters[iSlice][iRow][sortBuffer[j]]; - int preId = j != 0 ? (int)sortBuffer[j - 1] : (totalCount != 0 ? (int)smem.lastIndex : -1); + int32_t preId = j != 0 ? (int32_t)sortBuffer[j - 1] : (totalCount != 0 ? (int32_t)smem.lastIndex : -1); GPUTPCCompression_EncodeUnattached(param.rec.tpc.compressionTypeMask, orgCl, c.timeDiffU[outidx], c.padDiffU[outidx], preId == -1 ? nullptr : &clusters->clusters[iSlice][iRow][preId]); - unsigned short qtot = orgCl.qTot, qmax = orgCl.qMax; - unsigned char sigmapad = orgCl.sigmaPadPacked, sigmatime = orgCl.sigmaTimePacked; + uint16_t qtot = orgCl.qTot, qmax = orgCl.qMax; + uint8_t sigmapad = orgCl.sigmaPadPacked, sigmatime = orgCl.sigmaTimePacked; if (param.rec.tpc.compressionTypeMask & GPUSettings::CompressionTruncate) { compressor.truncateSignificantBitsChargeMax(qmax, param); compressor.truncateSignificantBitsCharge(qtot, param); @@ -312,19 +312,19 @@ GPUdii() void GPUTPCCompressionKernels::Thread -GPUdi() GPUTPCCompressionGatherKernels::Vec32* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int iWarp) +GPUdi() GPUTPCCompressionGatherKernels::Vec32* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int32_t iWarp) { return buf32[iWarp]; } template <> -GPUdi() GPUTPCCompressionGatherKernels::Vec64* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int iWarp) +GPUdi() GPUTPCCompressionGatherKernels::Vec64* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int32_t iWarp) { return buf64[iWarp]; } template <> -GPUdi() GPUTPCCompressionGatherKernels::Vec128* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int iWarp) +GPUdi() GPUTPCCompressionGatherKernels::Vec128* GPUTPCCompressionGatherKernels::GPUSharedMemory::getBuffer(int32_t iWarp) { return buf128[iWarp]; } @@ -341,65 +341,65 @@ GPUdi() bool GPUTPCCompressionGatherKernels::isAlignedTo(const S* ptr) } template <> -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(unsigned char* GPUrestrict() dst, const unsigned char* GPUrestrict() src, unsigned int size, int nThreads, int iThread) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint8_t* GPUrestrict() dst, const uint8_t* GPUrestrict() src, uint32_t size, int32_t nThreads, int32_t iThread) { - CONSTEXPR const int vec128Elems = CpyVector::Size; - CONSTEXPR const int vec64Elems = CpyVector::Size; - CONSTEXPR const int vec32Elems = CpyVector::Size; - CONSTEXPR const int vec16Elems = CpyVector::Size; + CONSTEXPR const int32_t vec128Elems = CpyVector::Size; + CONSTEXPR const int32_t vec64Elems = CpyVector::Size; + CONSTEXPR const int32_t vec32Elems = CpyVector::Size; + CONSTEXPR const int32_t vec16Elems = CpyVector::Size; if (size >= uint(nThreads * vec128Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec64Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec32Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec16Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); } } template <> -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(unsigned short* GPUrestrict() dst, const unsigned short* GPUrestrict() src, unsigned int size, int nThreads, int iThread) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint16_t* GPUrestrict() dst, const uint16_t* GPUrestrict() src, uint32_t size, int32_t nThreads, int32_t iThread) { - CONSTEXPR const int vec128Elems = CpyVector::Size; - CONSTEXPR const int vec64Elems = CpyVector::Size; - CONSTEXPR const int vec32Elems = CpyVector::Size; + CONSTEXPR const int32_t vec128Elems = CpyVector::Size; + CONSTEXPR const int32_t vec64Elems = CpyVector::Size; + CONSTEXPR const int32_t vec32Elems = CpyVector::Size; if (size >= uint(nThreads * vec128Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec64Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec32Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); } } template <> -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(unsigned int* GPUrestrict() dst, const unsigned int* GPUrestrict() src, unsigned int size, int nThreads, int iThread) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint32_t* GPUrestrict() dst, const uint32_t* GPUrestrict() src, uint32_t size, int32_t nThreads, int32_t iThread) { - CONSTEXPR const int vec128Elems = CpyVector::Size; - CONSTEXPR const int vec64Elems = CpyVector::Size; + CONSTEXPR const int32_t vec128Elems = CpyVector::Size; + CONSTEXPR const int32_t vec64Elems = CpyVector::Size; if (size >= uint(nThreads * vec128Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else if (size >= uint(nThreads * vec64Elems)) { - compressorMemcpyVectorised(dst, src, size, nThreads, iThread); + compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); } } template -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyVectorised(Scalar* dst, const Scalar* src, unsigned int size, int nThreads, int iThread) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyVectorised(Scalar* dst, const Scalar* src, uint32_t size, int32_t nThreads, int32_t iThread) { if (not isAlignedTo(dst)) { size_t dsti = reinterpret_cast(dst); - int offset = (alignof(BaseVector) - dsti % alignof(BaseVector)) / sizeof(Scalar); + int32_t offset = (alignof(BaseVector) - dsti % alignof(BaseVector)) / sizeof(Scalar); compressorMemcpyBasic(dst, src, offset, nThreads, iThread); src += offset; dst += offset; @@ -409,56 +409,56 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyVectorised(Scalar* BaseVector* GPUrestrict() dstAligned = reinterpret_cast(dst); using CpyVec = CpyVector; - unsigned int sizeAligned = size / CpyVec::Size; + uint32_t sizeAligned = size / CpyVec::Size; if (isAlignedTo(src)) { const BaseVector* GPUrestrict() srcAligned = reinterpret_cast(src); compressorMemcpyBasic(dstAligned, srcAligned, sizeAligned, nThreads, iThread); } else { - for (unsigned int i = iThread; i < sizeAligned; i += nThreads) { + for (uint32_t i = iThread; i < sizeAligned; i += nThreads) { CpyVec buf; - for (unsigned int j = 0; j < CpyVec::Size; j++) { + for (uint32_t j = 0; j < CpyVec::Size; j++) { buf.elems[j] = src[i * CpyVec::Size + j]; } dstAligned[i] = buf.all; } } - int leftovers = size % CpyVec::Size; + int32_t leftovers = size % CpyVec::Size; compressorMemcpyBasic(dst + size - leftovers, src + size - leftovers, leftovers, nThreads, iThread); } template -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, unsigned int size, int nThreads, int iThread, int nBlocks, int iBlock) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, uint32_t size, int32_t nThreads, int32_t iThread, int32_t nBlocks, int32_t iBlock) { - unsigned int start = (size + nBlocks - 1) / nBlocks * iBlock + iThread; - unsigned int end = CAMath::Min(size, (size + nBlocks - 1) / nBlocks * (iBlock + 1)); - for (unsigned int i = start; i < end; i += nThreads) { + uint32_t start = (size + nBlocks - 1) / nBlocks * iBlock + iThread; + uint32_t end = CAMath::Min(size, (size + nBlocks - 1) / nBlocks * (iBlock + 1)); + for (uint32_t i = start; i < end; i += nThreads) { dst[i] = src[i]; } } template -GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBuffered(V* buf, T* GPUrestrict() dst, const T* GPUrestrict() src, const S* GPUrestrict() nums, const unsigned int* GPUrestrict() srcOffsets, unsigned int nEntries, int nLanes, int iLane, int diff, size_t scaleBase1024) +GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBuffered(V* buf, T* GPUrestrict() dst, const T* GPUrestrict() src, const S* GPUrestrict() nums, const uint32_t* GPUrestrict() srcOffsets, uint32_t nEntries, int32_t nLanes, int32_t iLane, int32_t diff, size_t scaleBase1024) { - int shmPos = 0; - unsigned int dstOffset = 0; + int32_t shmPos = 0; + uint32_t dstOffset = 0; V* GPUrestrict() dstAligned = nullptr; T* bufT = reinterpret_cast(buf); - CONSTEXPR const int bufSize = GPUCA_WARP_SIZE; - CONSTEXPR const int bufTSize = bufSize * sizeof(V) / sizeof(T); + CONSTEXPR const int32_t bufSize = GPUCA_WARP_SIZE; + CONSTEXPR const int32_t bufTSize = bufSize * sizeof(V) / sizeof(T); - for (unsigned int i = 0; i < nEntries; i++) { - unsigned int srcPos = 0; - unsigned int srcOffset = (srcOffsets[i] * scaleBase1024 / 1024) + diff; - unsigned int srcSize = nums[i] - diff; + for (uint32_t i = 0; i < nEntries; i++) { + uint32_t srcPos = 0; + uint32_t srcOffset = (srcOffsets[i] * scaleBase1024 / 1024) + diff; + uint32_t srcSize = nums[i] - diff; if (dstAligned == nullptr) { if (not isAlignedTo(dst)) { size_t dsti = reinterpret_cast(dst); - unsigned int offset = (alignof(V) - dsti % alignof(V)) / sizeof(T); - offset = CAMath::Min(offset, srcSize); + uint32_t offset = (alignof(V) - dsti % alignof(V)) / sizeof(T); + offset = CAMath::Min(offset, srcSize); compressorMemcpyBasic(dst, src + srcOffset, offset, nLanes, iLane); dst += offset; srcPos += offset; @@ -468,9 +468,9 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBuffered(V* buf, T* } } while (srcPos < srcSize) { - unsigned int shmElemsLeft = bufTSize - shmPos; - unsigned int srcElemsLeft = srcSize - srcPos; - unsigned int size = CAMath::Min(srcElemsLeft, shmElemsLeft); + uint32_t shmElemsLeft = bufTSize - shmPos; + uint32_t srcElemsLeft = srcSize - srcPos; + uint32_t size = CAMath::Min(srcElemsLeft, shmElemsLeft); compressorMemcpyBasic(bufT + shmPos, src + srcOffset + srcPos, size, nLanes, iLane); srcPos += size; shmPos += size; @@ -490,19 +490,19 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpyBuffered(V* buf, T* } template -GPUdi() unsigned int GPUTPCCompressionGatherKernels::calculateWarpOffsets(GPUSharedMemory& smem, T* nums, unsigned int start, unsigned int end, int nWarps, int iWarp, int nLanes, int iLane) +GPUdi() uint32_t GPUTPCCompressionGatherKernels::calculateWarpOffsets(GPUSharedMemory& smem, T* nums, uint32_t start, uint32_t end, int32_t nWarps, int32_t iWarp, int32_t nLanes, int32_t iLane) { - unsigned int blockOffset = 0; - int iThread = nLanes * iWarp + iLane; - int nThreads = nLanes * nWarps; - unsigned int blockStart = work_group_broadcast(start, 0); - for (unsigned int i = iThread; i < blockStart; i += nThreads) { + uint32_t blockOffset = 0; + int32_t iThread = nLanes * iWarp + iLane; + int32_t nThreads = nLanes * nWarps; + uint32_t blockStart = work_group_broadcast(start, 0); + for (uint32_t i = iThread; i < blockStart; i += nThreads) { blockOffset += nums[i]; } blockOffset = work_group_reduce_add(blockOffset); - unsigned int offset = 0; - for (unsigned int i = start + iLane; i < end; i += nLanes) { + uint32_t offset = 0; + for (uint32_t i = start + iLane; i < end; i += nLanes) { offset += nums[i]; } offset = work_group_scan_inclusive_add(offset); @@ -517,29 +517,29 @@ GPUdi() unsigned int GPUTPCCompressionGatherKernels::calculateWarpOffsets(GPUSha } template <> -GPUdii() void GPUTPCCompressionGatherKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { GPUTPCCompression& GPUrestrict() compressor = processors.tpcCompressor; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = processors.ioPtrs.clustersNative; - int nWarps = nThreads / GPUCA_WARP_SIZE; - int iWarp = iThread / GPUCA_WARP_SIZE; + int32_t nWarps = nThreads / GPUCA_WARP_SIZE; + int32_t iWarp = iThread / GPUCA_WARP_SIZE; - int nLanes = GPUCA_WARP_SIZE; - int iLane = iThread % GPUCA_WARP_SIZE; + int32_t nLanes = GPUCA_WARP_SIZE; + int32_t iLane = iThread % GPUCA_WARP_SIZE; if (iBlock == 0) { - unsigned int nRows = compressor.NSLICES * GPUCA_ROW_COUNT; - unsigned int rowsPerWarp = (nRows + nWarps - 1) / nWarps; - unsigned int rowStart = rowsPerWarp * iWarp; - unsigned int rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); + uint32_t nRows = compressor.NSLICES * GPUCA_ROW_COUNT; + uint32_t rowsPerWarp = (nRows + nWarps - 1) / nWarps; + uint32_t rowStart = rowsPerWarp * iWarp; + uint32_t rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); if (rowStart >= nRows) { rowStart = 0; rowEnd = 0; } - unsigned int rowsOffset = calculateWarpOffsets(smem, compressor.mPtrs.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); + uint32_t rowsOffset = calculateWarpOffsets(smem, compressor.mPtrs.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); compressorMemcpy(compressor.mOutput->nSliceRowClusters, compressor.mPtrs.nSliceRowClusters, compressor.NSLICES * GPUCA_ROW_COUNT, nThreads, iThread); compressorMemcpy(compressor.mOutput->nTrackClusters, compressor.mPtrs.nTrackClusters, compressor.mMemory->nStoredTracks, nThreads, iThread); @@ -549,16 +549,16 @@ GPUdii() void GPUTPCCompressionGatherKernels::ThreadtimeA, compressor.mPtrs.timeA, compressor.mMemory->nStoredTracks, nThreads, iThread); compressorMemcpy(compressor.mOutput->padA, compressor.mPtrs.padA, compressor.mMemory->nStoredTracks, nThreads, iThread); - unsigned int sliceStart = rowStart / GPUCA_ROW_COUNT; - unsigned int sliceEnd = rowEnd / GPUCA_ROW_COUNT; + uint32_t sliceStart = rowStart / GPUCA_ROW_COUNT; + uint32_t sliceEnd = rowEnd / GPUCA_ROW_COUNT; - unsigned int sliceRowStart = rowStart % GPUCA_ROW_COUNT; - unsigned int sliceRowEnd = rowEnd % GPUCA_ROW_COUNT; + uint32_t sliceRowStart = rowStart % GPUCA_ROW_COUNT; + uint32_t sliceRowEnd = rowEnd % GPUCA_ROW_COUNT; - for (unsigned int i = sliceStart; i <= sliceEnd && i < compressor.NSLICES; i++) { - for (unsigned int j = ((i == sliceStart) ? sliceRowStart : 0); j < ((i == sliceEnd) ? sliceRowEnd : GPUCA_ROW_COUNT); j++) { - unsigned int nClusters = compressor.mPtrs.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; - unsigned int clusterOffsetInCache = clusters->clusterOffset[i][j] * compressor.mMaxClusterFactorBase1024 / 1024; + for (uint32_t i = sliceStart; i <= sliceEnd && i < compressor.NSLICES; i++) { + for (uint32_t j = ((i == sliceStart) ? sliceRowStart : 0); j < ((i == sliceEnd) ? sliceRowEnd : GPUCA_ROW_COUNT); j++) { + uint32_t nClusters = compressor.mPtrs.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; + uint32_t clusterOffsetInCache = clusters->clusterOffset[i][j] * compressor.mMaxClusterFactorBase1024 / 1024; compressorMemcpy(compressor.mOutput->qTotU + rowsOffset, compressor.mPtrs.qTotU + clusterOffsetInCache, nClusters, nLanes, iLane); compressorMemcpy(compressor.mOutput->qMaxU + rowsOffset, compressor.mPtrs.qMaxU + clusterOffsetInCache, nClusters, nLanes, iLane); compressorMemcpy(compressor.mOutput->flagsU + rowsOffset, compressor.mPtrs.flagsU + clusterOffsetInCache, nClusters, nLanes, iLane); @@ -572,19 +572,19 @@ GPUdii() void GPUTPCCompressionGatherKernels::ThreadnStoredTracks + nWarps - 1) / nWarps; - unsigned int trackStart = tracksPerWarp * iWarp; - unsigned int trackEnd = CAMath::Min(compressor.mMemory->nStoredTracks, trackStart + tracksPerWarp); + uint32_t tracksPerWarp = (compressor.mMemory->nStoredTracks + nWarps - 1) / nWarps; + uint32_t trackStart = tracksPerWarp * iWarp; + uint32_t trackEnd = CAMath::Min(compressor.mMemory->nStoredTracks, trackStart + tracksPerWarp); if (trackStart >= compressor.mMemory->nStoredTracks) { trackStart = 0; trackEnd = 0; } - unsigned int tracksOffset = calculateWarpOffsets(smem, compressor.mPtrs.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); + uint32_t tracksOffset = calculateWarpOffsets(smem, compressor.mPtrs.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); - for (unsigned int i = trackStart; i < trackEnd; i += nLanes) { - unsigned int nTrackClusters = 0; - unsigned int srcOffset = 0; + for (uint32_t i = trackStart; i < trackEnd; i += nLanes) { + uint32_t nTrackClusters = 0; + uint32_t srcOffset = 0; if (i + iLane < trackEnd) { nTrackClusters = compressor.mPtrs.nTrackClusters[i + iLane]; @@ -593,12 +593,12 @@ GPUdii() void GPUTPCCompressionGatherKernels::ThreadqTotA + tracksOffset, compressor.mPtrs.qTotA + srcOffset, nTrackClusters, nLanes, iLane); compressorMemcpy(compressor.mOutput->qMaxA + tracksOffset, compressor.mPtrs.qMaxA + srcOffset, nTrackClusters, nLanes, iLane); compressorMemcpy(compressor.mOutput->flagsA + tracksOffset, compressor.mPtrs.flagsA + srcOffset, nTrackClusters, nLanes, iLane); @@ -618,47 +618,47 @@ GPUdii() void GPUTPCCompressionGatherKernels::Thread -GPUdii() void GPUTPCCompressionGatherKernels::gatherBuffered(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::gatherBuffered(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { GPUTPCCompression& GPUrestrict() compressor = processors.tpcCompressor; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = processors.ioPtrs.clustersNative; - int nWarps = nThreads / GPUCA_WARP_SIZE; - int iWarp = iThread / GPUCA_WARP_SIZE; + int32_t nWarps = nThreads / GPUCA_WARP_SIZE; + int32_t iWarp = iThread / GPUCA_WARP_SIZE; - int nGlobalWarps = nWarps * nBlocks; - int iGlobalWarp = nWarps * iBlock + iWarp; + int32_t nGlobalWarps = nWarps * nBlocks; + int32_t iGlobalWarp = nWarps * iBlock + iWarp; - int nLanes = GPUCA_WARP_SIZE; - int iLane = iThread % GPUCA_WARP_SIZE; + int32_t nLanes = GPUCA_WARP_SIZE; + int32_t iLane = iThread % GPUCA_WARP_SIZE; auto& input = compressor.mPtrs; auto* output = compressor.mOutput; - unsigned int nRows = compressor.NSLICES * GPUCA_ROW_COUNT; - unsigned int rowsPerWarp = (nRows + nGlobalWarps - 1) / nGlobalWarps; - unsigned int rowStart = rowsPerWarp * iGlobalWarp; - unsigned int rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); + uint32_t nRows = compressor.NSLICES * GPUCA_ROW_COUNT; + uint32_t rowsPerWarp = (nRows + nGlobalWarps - 1) / nGlobalWarps; + uint32_t rowStart = rowsPerWarp * iGlobalWarp; + uint32_t rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); if (rowStart >= nRows) { rowStart = 0; rowEnd = 0; } rowsPerWarp = rowEnd - rowStart; - unsigned int rowsOffset = calculateWarpOffsets(smem, input.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); + uint32_t rowsOffset = calculateWarpOffsets(smem, input.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); - unsigned int nStoredTracks = compressor.mMemory->nStoredTracks; - unsigned int tracksPerWarp = (nStoredTracks + nGlobalWarps - 1) / nGlobalWarps; - unsigned int trackStart = tracksPerWarp * iGlobalWarp; - unsigned int trackEnd = CAMath::Min(nStoredTracks, trackStart + tracksPerWarp); + uint32_t nStoredTracks = compressor.mMemory->nStoredTracks; + uint32_t tracksPerWarp = (nStoredTracks + nGlobalWarps - 1) / nGlobalWarps; + uint32_t trackStart = tracksPerWarp * iGlobalWarp; + uint32_t trackEnd = CAMath::Min(nStoredTracks, trackStart + tracksPerWarp); if (trackStart >= nStoredTracks) { trackStart = 0; trackEnd = 0; } tracksPerWarp = trackEnd - trackStart; - unsigned int tracksOffset = calculateWarpOffsets(smem, input.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); + uint32_t tracksOffset = calculateWarpOffsets(smem, input.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); if (iBlock == 0) { compressorMemcpyBasic(output->nSliceRowClusters, input.nSliceRowClusters, compressor.NSLICES * GPUCA_ROW_COUNT, nThreads, iThread); @@ -670,8 +670,8 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherBuffered(int nBlocks, int nT compressorMemcpyBasic(output->padA, input.padA, compressor.mMemory->nStoredTracks, nThreads, iThread); } - const unsigned int* clusterOffsets = &clusters->clusterOffset[0][0] + rowStart; - const unsigned int* nSliceRowClusters = input.nSliceRowClusters + rowStart; + const uint32_t* clusterOffsets = &clusters->clusterOffset[0][0] + rowStart; + const uint32_t* nSliceRowClusters = input.nSliceRowClusters + rowStart; auto* buf = smem.getBuffer(iWarp); @@ -683,8 +683,8 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherBuffered(int nBlocks, int nT compressorMemcpyBuffered(buf, output->sigmaPadU + rowsOffset, input.sigmaPadU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); compressorMemcpyBuffered(buf, output->sigmaTimeU + rowsOffset, input.sigmaTimeU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); - const unsigned short* nTrackClustersPtr = input.nTrackClusters + trackStart; - const unsigned int* aClsFstIdx = compressor.mAttachedClusterFirstIndex + trackStart; + const uint16_t* nTrackClustersPtr = input.nTrackClusters + trackStart; + const uint32_t* aClsFstIdx = compressor.mAttachedClusterFirstIndex + trackStart; compressorMemcpyBuffered(buf, output->qTotA + tracksOffset, input.qTotA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); compressorMemcpyBuffered(buf, output->qMaxA + tracksOffset, input.qMaxA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); @@ -693,24 +693,24 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherBuffered(int nBlocks, int nT compressorMemcpyBuffered(buf, output->sigmaTimeA + tracksOffset, input.sigmaTimeA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); // First index stored with track - unsigned int tracksOffsetDiff = tracksOffset - trackStart; + uint32_t tracksOffsetDiff = tracksOffset - trackStart; compressorMemcpyBuffered(buf, output->rowDiffA + tracksOffsetDiff, input.rowDiffA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); compressorMemcpyBuffered(buf, output->sliceLegDiffA + tracksOffsetDiff, input.sliceLegDiffA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); compressorMemcpyBuffered(buf, output->padResA + tracksOffsetDiff, input.padResA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); compressorMemcpyBuffered(buf, output->timeResA + tracksOffsetDiff, input.timeResA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); } -GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { GPUTPCCompression& GPUrestrict() compressor = processors.tpcCompressor; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = processors.ioPtrs.clustersNative; const auto& input = compressor.mPtrs; auto* output = compressor.mOutput; - const int nWarps = nThreads / GPUCA_WARP_SIZE; - const int iWarp = iThread / GPUCA_WARP_SIZE; - const int nLanes = GPUCA_WARP_SIZE; - const int iLane = iThread % GPUCA_WARP_SIZE; + const int32_t nWarps = nThreads / GPUCA_WARP_SIZE; + const int32_t iWarp = iThread / GPUCA_WARP_SIZE; + const int32_t nLanes = GPUCA_WARP_SIZE; + const int32_t iLane = iThread % GPUCA_WARP_SIZE; auto* buf = smem.getBuffer(iWarp); if (iBlock == 0) { @@ -722,22 +722,22 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int nBlocks, int nThre compressorMemcpyBasic(output->timeA, input.timeA, compressor.mMemory->nStoredTracks, nThreads, iThread); compressorMemcpyBasic(output->padA, input.padA, compressor.mMemory->nStoredTracks, nThreads, iThread); } else if (iBlock & 1) { - const unsigned int nGlobalWarps = nWarps * (nBlocks - 1) / 2; - const unsigned int iGlobalWarp = nWarps * (iBlock - 1) / 2 + iWarp; + const uint32_t nGlobalWarps = nWarps * (nBlocks - 1) / 2; + const uint32_t iGlobalWarp = nWarps * (iBlock - 1) / 2 + iWarp; - const unsigned int nRows = compressor.NSLICES * GPUCA_ROW_COUNT; - unsigned int rowsPerWarp = (nRows + nGlobalWarps - 1) / nGlobalWarps; - unsigned int rowStart = rowsPerWarp * iGlobalWarp; - unsigned int rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); + const uint32_t nRows = compressor.NSLICES * GPUCA_ROW_COUNT; + uint32_t rowsPerWarp = (nRows + nGlobalWarps - 1) / nGlobalWarps; + uint32_t rowStart = rowsPerWarp * iGlobalWarp; + uint32_t rowEnd = CAMath::Min(nRows, rowStart + rowsPerWarp); if (rowStart >= nRows) { rowStart = 0; rowEnd = 0; } rowsPerWarp = rowEnd - rowStart; - const unsigned int rowsOffset = calculateWarpOffsets(smem, input.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); - const unsigned int* clusterOffsets = &clusters->clusterOffset[0][0] + rowStart; - const unsigned int* nSliceRowClusters = input.nSliceRowClusters + rowStart; + const uint32_t rowsOffset = calculateWarpOffsets(smem, input.nSliceRowClusters, rowStart, rowEnd, nWarps, iWarp, nLanes, iLane); + const uint32_t* clusterOffsets = &clusters->clusterOffset[0][0] + rowStart; + const uint32_t* nSliceRowClusters = input.nSliceRowClusters + rowStart; compressorMemcpyBuffered(buf, output->qTotU + rowsOffset, input.qTotU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); compressorMemcpyBuffered(buf, output->qMaxU + rowsOffset, input.qMaxU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); @@ -747,22 +747,22 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int nBlocks, int nThre compressorMemcpyBuffered(buf, output->sigmaPadU + rowsOffset, input.sigmaPadU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); compressorMemcpyBuffered(buf, output->sigmaTimeU + rowsOffset, input.sigmaTimeU, nSliceRowClusters, clusterOffsets, rowsPerWarp, nLanes, iLane, 0, compressor.mMaxClusterFactorBase1024); } else { - const unsigned int nGlobalWarps = nWarps * (nBlocks - 1) / 2; - const unsigned int iGlobalWarp = nWarps * (iBlock / 2 - 1) + iWarp; + const uint32_t nGlobalWarps = nWarps * (nBlocks - 1) / 2; + const uint32_t iGlobalWarp = nWarps * (iBlock / 2 - 1) + iWarp; - const unsigned int nStoredTracks = compressor.mMemory->nStoredTracks; - unsigned int tracksPerWarp = (nStoredTracks + nGlobalWarps - 1) / nGlobalWarps; - unsigned int trackStart = tracksPerWarp * iGlobalWarp; - unsigned int trackEnd = CAMath::Min(nStoredTracks, trackStart + tracksPerWarp); + const uint32_t nStoredTracks = compressor.mMemory->nStoredTracks; + uint32_t tracksPerWarp = (nStoredTracks + nGlobalWarps - 1) / nGlobalWarps; + uint32_t trackStart = tracksPerWarp * iGlobalWarp; + uint32_t trackEnd = CAMath::Min(nStoredTracks, trackStart + tracksPerWarp); if (trackStart >= nStoredTracks) { trackStart = 0; trackEnd = 0; } tracksPerWarp = trackEnd - trackStart; - const unsigned int tracksOffset = calculateWarpOffsets(smem, input.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); - const unsigned short* nTrackClustersPtr = input.nTrackClusters + trackStart; - const unsigned int* aClsFstIdx = compressor.mAttachedClusterFirstIndex + trackStart; + const uint32_t tracksOffset = calculateWarpOffsets(smem, input.nTrackClusters, trackStart, trackEnd, nWarps, iWarp, nLanes, iLane); + const uint16_t* nTrackClustersPtr = input.nTrackClusters + trackStart; + const uint32_t* aClsFstIdx = compressor.mAttachedClusterFirstIndex + trackStart; compressorMemcpyBuffered(buf, output->qTotA + tracksOffset, input.qTotA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); compressorMemcpyBuffered(buf, output->qMaxA + tracksOffset, input.qMaxA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); @@ -771,7 +771,7 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int nBlocks, int nThre compressorMemcpyBuffered(buf, output->sigmaTimeA + tracksOffset, input.sigmaTimeA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 0); // First index stored with track - unsigned int tracksOffsetDiff = tracksOffset - trackStart; + uint32_t tracksOffsetDiff = tracksOffset - trackStart; compressorMemcpyBuffered(buf, output->rowDiffA + tracksOffsetDiff, input.rowDiffA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); compressorMemcpyBuffered(buf, output->sliceLegDiffA + tracksOffsetDiff, input.sliceLegDiffA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); compressorMemcpyBuffered(buf, output->padResA + tracksOffsetDiff, input.padResA, nTrackClustersPtr, aClsFstIdx, tracksPerWarp, nLanes, iLane, 1); @@ -780,25 +780,25 @@ GPUdii() void GPUTPCCompressionGatherKernels::gatherMulti(int nBlocks, int nThre } template <> -GPUdii() void GPUTPCCompressionGatherKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { gatherBuffered(nBlocks, nThreads, iBlock, iThread, smem, processors); } template <> -GPUdii() void GPUTPCCompressionGatherKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { gatherBuffered(nBlocks, nThreads, iBlock, iThread, smem, processors); } template <> -GPUdii() void GPUTPCCompressionGatherKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { gatherBuffered(nBlocks, nThreads, iBlock, iThread, smem, processors); } template <> -GPUdii() void GPUTPCCompressionGatherKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCCompressionGatherKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { gatherMulti(nBlocks, nThreads, iBlock, iThread, smem, processors); } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h index 8cd29903dd00a..5186b16c49be3 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.h @@ -29,26 +29,26 @@ class GPUTPCCompressionKernels : public GPUKernelTemplate public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::TPCCompression; } - enum K : int { + enum K : int32_t { step0attached = 0, step1unattached = 1, }; - struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { - GPUAtomic(unsigned int) nCount; - unsigned int lastIndex; - unsigned int sortBuffer[GPUCA_TPC_COMP_CHUNK_SIZE]; + struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + GPUAtomic(uint32_t) nCount; + uint32_t lastIndex; + uint32_t sortBuffer[GPUCA_TPC_COMP_CHUNK_SIZE]; }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); - template + template class GPUTPCCompressionKernels_Compare { public: GPUhdi() GPUTPCCompressionKernels_Compare(const o2::tpc::ClusterNative* p) : mClsPtr(p) {} - GPUd() bool operator()(unsigned int a, unsigned int b) const; + GPUd() bool operator()(uint32_t a, uint32_t b) const; protected: const o2::tpc::ClusterNative* mClsPtr; @@ -59,7 +59,7 @@ class GPUTPCCompressionGatherKernels : public GPUKernelTemplate { public: - enum K : int { + enum K : int32_t { unbuffered, buffered32, buffered64, @@ -67,25 +67,25 @@ class GPUTPCCompressionGatherKernels : public GPUKernelTemplate multiBlock }; - using Vec16 = unsigned short; - using Vec32 = unsigned int; - using Vec64 = unsigned long; + using Vec16 = uint16_t; + using Vec32 = uint32_t; + using Vec64 = uint64_t; using Vec128 = uint4; - struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { union { - unsigned int warpOffset[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)]; + uint32_t warpOffset[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)]; Vec32 buf32[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; Vec64 buf64[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; Vec128 buf128[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; struct { - unsigned int sizes[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; - unsigned int srcOffsets[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; + uint32_t sizes[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; + uint32_t srcOffsets[GPUCA_GET_WARP_COUNT(GPUCA_LB_COMPRESSION_GATHER)][GPUCA_WARP_SIZE]; } unbuffered; }; template - GPUdi() V* getBuffer(int iWarp); + GPUdi() V* getBuffer(int32_t iWarp); }; template @@ -97,31 +97,31 @@ class GPUTPCCompressionGatherKernels : public GPUKernelTemplate Scalar elems[Size]; }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); template GPUdi() static bool isAlignedTo(const S* ptr); template - GPUdi() static void compressorMemcpy(GPUgeneric() T* dst, GPUgeneric() const T* src, unsigned int size, int nThreads, int iThread); + GPUdi() static void compressorMemcpy(GPUgeneric() T* dst, GPUgeneric() const T* src, uint32_t size, int32_t nThreads, int32_t iThread); template - GPUdi() static void compressorMemcpyVectorised(Scalar* dst, const Scalar* src, unsigned int size, int nThreads, int iThread); + GPUdi() static void compressorMemcpyVectorised(Scalar* dst, const Scalar* src, uint32_t size, int32_t nThreads, int32_t iThread); template - GPUdi() static void compressorMemcpyBasic(T* dst, const T* src, unsigned int size, int nThreads, int iThread, int nBlocks = 1, int iBlock = 0); + GPUdi() static void compressorMemcpyBasic(T* dst, const T* src, uint32_t size, int32_t nThreads, int32_t iThread, int32_t nBlocks = 1, int32_t iBlock = 0); template - GPUdi() static void compressorMemcpyBuffered(V* buf, T* dst, const T* src, const S* nums, const unsigned int* srcOffets, unsigned int nEntries, int nLanes, int iLane, int diff = 0, size_t scaleBase1024 = 1024); + GPUdi() static void compressorMemcpyBuffered(V* buf, T* dst, const T* src, const S* nums, const uint32_t* srcOffets, uint32_t nEntries, int32_t nLanes, int32_t iLane, int32_t diff = 0, size_t scaleBase1024 = 1024); template - GPUdi() static unsigned int calculateWarpOffsets(GPUSharedMemory& smem, T* nums, unsigned int start, unsigned int end, int nWarps, int iWarp, int nLanes, int iLane); + GPUdi() static uint32_t calculateWarpOffsets(GPUSharedMemory& smem, T* nums, uint32_t start, uint32_t end, int32_t nWarps, int32_t iWarp, int32_t nLanes, int32_t iLane); template - GPUdii() static void gatherBuffered(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + GPUdii() static void gatherBuffered(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); - GPUdii() static void gatherMulti(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + GPUdii() static void gatherMulti(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.inc b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.inc index 468fe25d217ca..3a644925bdd37 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.inc +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.inc @@ -20,10 +20,10 @@ namespace o2::gpu { -GPUdii() void GPUTPCCompression_EncodeUnattached(unsigned char nComppressionModes, const o2::tpc::ClusterNative& orgCl, unsigned int& outTime, unsigned short& outPad, const o2::tpc::ClusterNative* orgClPre = nullptr) +GPUdii() void GPUTPCCompression_EncodeUnattached(uint8_t nComppressionModes, const o2::tpc::ClusterNative& orgCl, uint32_t& outTime, uint16_t& outPad, const o2::tpc::ClusterNative* orgClPre = nullptr) { if (nComppressionModes & GPUSettings::CompressionDifferences) { - unsigned int lastTime = 0, lastPad = 0; + uint32_t lastTime = 0, lastPad = 0; if (orgClPre) { lastPad = orgClPre->padPacked; lastTime = orgClPre->getTimePacked(); diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.cxx index 69b0d70f9ea88..f8fe18e915f28 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.cxx @@ -23,7 +23,7 @@ using namespace GPUCA_NAMESPACE::gpu; // encoded with the old version!!! #ifdef GPUCA_COMPRESSION_TRACK_MODEL_MERGER -GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, unsigned char qPt, const GPUParam& GPUrestrict() param) +GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param) { mProp.SetMaterialTPC(); mProp.SetMaxSinPhi(GPUCA_MAX_SIN_PHI); @@ -44,22 +44,22 @@ GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float a // GPUInfo("Initialized: x %f y %f z %f alpha %f qPt %f", x, y, z, alpha, mTrk.QPt()); } -GPUd() int GPUTPCCompressionTrackModel::Propagate(float x, float alpha) +GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha) { - int retVal = mProp.PropagateToXAlpha(x, alpha, true); + int32_t retVal = mProp.PropagateToXAlpha(x, alpha, true); // GPUInfo("Propagated to: x %f y %f z %f alpha %f qPt %f", x, mTrk.Y(), mTrk.Z(), alpha, mTrk.QPt()); return retVal; } -GPUd() int GPUTPCCompressionTrackModel::Filter(float y, float z, int iRow) +GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow) { mTrk.ConstrainSinPhi(); - int retVal = mProp.Update(y, z, iRow, *mParam, 0, 0, nullptr, false, false, 0.f); + int32_t retVal = mProp.Update(y, z, iRow, *mParam, 0, 0, nullptr, false, false, 0.f); // GPUInfo("Filtered with %f %f: y %f z %f qPt %f", y, z, mTrk.Y(), mTrk.Z(), mTrk.QPt()); return retVal; } -GPUd() int GPUTPCCompressionTrackModel::Mirror() +GPUd() int32_t GPUTPCCompressionTrackModel::Mirror() { mProp.Mirror(true); // GPUInfo("Mirrored: y %f z %f qPt %f", mTrk.Y(), mTrk.Z(), mTrk.QPt()); @@ -71,7 +71,7 @@ GPUd() int GPUTPCCompressionTrackModel::Mirror() #include "GPUTPCTrackLinearisation.h" #include "GPUTPCTracker.h" -GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, unsigned char qPt, const GPUParam& GPUrestrict() param) +GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param) { mTrk.InitParam(); mTrk.SetX(x); @@ -85,35 +85,35 @@ GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float a // GPUInfo("Initialized: x %f y %f z %f alpha %f qPt %f", x, y, z, alpha, mTrk.QPt()); } -GPUd() int GPUTPCCompressionTrackModel::Propagate(float x, float alpha) +GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha) { GPUTPCTrackLinearisation t0(mTrk); if (alpha != mAlpha && !mTrk.Rotate(alpha, t0, GPUCA_MAX_SIN_PHI)) { return 2; } - int retVal = !mTrk.TransportToX(x, t0, mParam->bzCLight, GPUCA_MAX_SIN_PHI); + int32_t retVal = !mTrk.TransportToX(x, t0, mParam->bzCLight, GPUCA_MAX_SIN_PHI); // GPUInfo("Propagated to: x %f y %f z %f alpha %f qPt %f", x, mTrk.Y(), mTrk.Z(), alpha, mTrk.QPt()); return retVal; } -GPUd() int GPUTPCCompressionTrackModel::Filter(float y, float z, int iRow) +GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow) { mTrk.ConstrainSinPhi(); float err2Y, err2Z; GPUTPCTracker::GetErrors2Seeding(*mParam, iRow, mTrk, -1.f, err2Y, err2Z); - int retVal = !mTrk.Filter(y, z, err2Y, err2Z, GPUCA_MAX_SIN_PHI, false); + int32_t retVal = !mTrk.Filter(y, z, err2Y, err2Z, GPUCA_MAX_SIN_PHI, false); // GPUInfo("Filtered with %f %f: y %f z %f qPt %f", y, z, mTrk.Y(), mTrk.Z(), mTrk.QPt()); return retVal; } -GPUd() int GPUTPCCompressionTrackModel::Mirror() +GPUd() int32_t GPUTPCCompressionTrackModel::Mirror() { return 1; } #else // Default internal track model for compression -GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, unsigned char qPt, const GPUParam& GPUrestrict() param) +GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& GPUrestrict() param) { // initialize track model mX = x; @@ -144,7 +144,7 @@ GPUd() void GPUTPCCompressionTrackModel::Init(float x, float y, float z, float a calculateMaterialCorrection(); } -GPUd() int GPUTPCCompressionTrackModel::Propagate(float x, float alpha) +GPUd() int32_t GPUTPCCompressionTrackModel::Propagate(float x, float alpha) { // constrain sin(phi) if (mP[2] > MaxSinPhi) { @@ -179,7 +179,7 @@ GPUd() int GPUTPCCompressionTrackModel::Propagate(float x, float alpha) return followLinearization(t0e, mBz, dLp); } -GPUd() int GPUTPCCompressionTrackModel::Filter(float y, float z, int iRow) +GPUd() int32_t GPUTPCCompressionTrackModel::Filter(float y, float z, int32_t iRow) { // apply kalman filter update with measurement y/z float err2Y, err2Z; @@ -290,7 +290,7 @@ GPUd() int GPUTPCCompressionTrackModel::Filter(float y, float z, int iRow) return 0; } -GPUd() int GPUTPCCompressionTrackModel::Mirror() +GPUd() int32_t GPUTPCCompressionTrackModel::Mirror() { float dy = -2.f * mTrk.q * mTrk.px / mBz; float dS; // path in XY @@ -391,7 +391,7 @@ GPUd() void GPUTPCCompressionTrackModel::changeDirection() mC[11] = -mC[11]; } -GPUd() int GPUTPCCompressionTrackModel::rotateToAlpha(float newAlpha) +GPUd() int32_t GPUTPCCompressionTrackModel::rotateToAlpha(float newAlpha) { // // Rotate the track coordinate system in XY to the angle newAlpha @@ -540,7 +540,7 @@ GPUd() int GPUTPCCompressionTrackModel::rotateToAlpha(float newAlpha) return 0; } -GPUd() int GPUTPCCompressionTrackModel::propagateToXBzLightNoUpdate(PhysicalTrackModel& t, float x, float Bz, float& dLp) +GPUd() int32_t GPUTPCCompressionTrackModel::propagateToXBzLightNoUpdate(PhysicalTrackModel& t, float x, float Bz, float& dLp) { // // transport the track to X=x in magnetic field B = ( 0, 0, Bz[kG*0.000299792458] ) @@ -610,7 +610,7 @@ GPUd() bool GPUTPCCompressionTrackModel::setDirectionAlongX(PhysicalTrackModel& return 1; } -GPUd() int GPUTPCCompressionTrackModel::followLinearization(const PhysicalTrackModel& t0e, float Bz, float dLp) +GPUd() int32_t GPUTPCCompressionTrackModel::followLinearization(const PhysicalTrackModel& t0e, float Bz, float dLp) { // t0e is alrerady extrapolated t0 @@ -887,10 +887,10 @@ GPUd() float GPUTPCCompressionTrackModel::approximateBetheBloch(float beta2) return ret; } -GPUd() void GPUTPCCompressionTrackModel::getClusterErrors2(int iRow, float z, float sinPhi, float DzDs, float& ErrY2, float& ErrZ2) const +GPUd() void GPUTPCCompressionTrackModel::getClusterErrors2(int32_t iRow, float z, float sinPhi, float DzDs, float& ErrY2, float& ErrZ2) const { // Only O2 geometry considered at the moment. Is AliRoot geometry support needed? - int rowType = iRow < 97 ? (iRow < 63 ? 0 : 1) : (iRow < 127 ? 2 : 3); + int32_t rowType = iRow < 97 ? (iRow < 63 ? 0 : 1) : (iRow < 127 ? 2 : 3); if (rowType > 2) { rowType = 2; // TODO: Add type 3 } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h index 141e79b37b67d..8003b388e1a68 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h @@ -44,10 +44,10 @@ constexpr float MaxSinPhi = 0.999f; class GPUTPCCompressionTrackModel { public: - GPUd() void Init(float x, float y, float z, float alpha, unsigned char qPt, const GPUParam& proc); - GPUd() int Propagate(float x, float alpha); - GPUd() int Filter(float y, float z, int iRow); - GPUd() int Mirror(); + GPUd() void Init(float x, float y, float z, float alpha, uint8_t qPt, const GPUParam& proc); + GPUd() int32_t Propagate(float x, float alpha); + GPUd() int32_t Filter(float y, float z, int32_t iRow); + GPUd() int32_t Mirror(); #if defined(GPUCA_COMPRESSION_TRACK_MODEL_MERGER) || defined(GPUCA_COMPRESSION_TRACK_MODEL_SLICETRACKER) GPUd() float X() const @@ -91,13 +91,13 @@ class GPUTPCCompressionTrackModel // helper functions for standalone propagation and update methods GPUd() void updatePhysicalTrackValues(PhysicalTrackModel& trk); GPUd() void changeDirection(); - GPUd() int rotateToAlpha(float newAlpha); - GPUd() int propagateToXBzLightNoUpdate(PhysicalTrackModel& t, float x, float Bz, float& dLp); + GPUd() int32_t rotateToAlpha(float newAlpha); + GPUd() int32_t propagateToXBzLightNoUpdate(PhysicalTrackModel& t, float x, float Bz, float& dLp); GPUd() bool setDirectionAlongX(PhysicalTrackModel& t); - GPUd() int followLinearization(const PhysicalTrackModel& t0e, float Bz, float dLp); + GPUd() int32_t followLinearization(const PhysicalTrackModel& t0e, float Bz, float dLp); GPUd() void calculateMaterialCorrection(); GPUd() float approximateBetheBloch(float beta2); - GPUd() void getClusterErrors2(int iRow, float z, float sinPhi, float DzDs, float& ErrY2, float& ErrZ2) const; + GPUd() void getClusterErrors2(int32_t iRow, float z, float sinPhi, float DzDs, float& ErrY2, float& ErrZ2) const; GPUd() void resetCovariance(); #endif @@ -141,7 +141,7 @@ class GPUTPCCompressionTrackModel float mAlpha; float mP[5]; float mC[15]; - int mNDF = -5; + int32_t mNDF = -5; float mCosAlpha; float mSinAlpha; diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx index 1d71594523b35..4039ebb0c100d 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx @@ -30,7 +30,7 @@ void* GPUTPCDecompression::SetPointersInputGPU(void* mem) } template -void GPUTPCDecompression::SetPointersCompressedClusters(void*& mem, T& c, unsigned int nClA, unsigned int nTr, unsigned int nClU, bool reducedClA) +void GPUTPCDecompression::SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA) { computePointerWithAlignment(mem, c.qTotU, nClU); // Do not reorder, qTotU ist used as first address in GPUChainTracking::RunTPCCompression computePointerWithAlignment(mem, c.qMaxU, nClU); @@ -41,7 +41,7 @@ void GPUTPCDecompression::SetPointersCompressedClusters(void*& mem, T& c, unsign computePointerWithAlignment(mem, c.sigmaTimeU, nClU); computePointerWithAlignment(mem, c.nSliceRowClusters, GPUCA_ROW_COUNT * NSLICES); - unsigned int nClAreduced = reducedClA ? nClA - nTr : nClA; + uint32_t nClAreduced = reducedClA ? nClA - nTr : nClA; if (!(mRec->GetParam().rec.tpc.compressionTypeMask & GPUSettings::CompressionTrackModel)) { return; // Track model disabled, do not allocate memory diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h index a8f058c62891e..49c73e6743d20 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h @@ -58,22 +58,22 @@ class GPUTPCDecompression : public GPUProcessor #endif protected: - constexpr static unsigned int NSLICES = GPUCA_NSLICES; + constexpr static uint32_t NSLICES = GPUCA_NSLICES; o2::tpc::CompressedClusters mInputGPU; - unsigned int mMaxNativeClustersPerBuffer; - unsigned int* mNativeClustersIndex; - unsigned int* mUnattachedClustersOffsets; - unsigned int* mAttachedClustersOffsets; + uint32_t mMaxNativeClustersPerBuffer; + uint32_t* mNativeClustersIndex; + uint32_t* mUnattachedClustersOffsets; + uint32_t* mAttachedClustersOffsets; o2::tpc::ClusterNative* mTmpNativeClusters; o2::tpc::ClusterNative* mNativeClustersBuffer; template - void SetPointersCompressedClusters(void*& mem, T& c, unsigned int nClA, unsigned int nTr, unsigned int nClU, bool reducedClA); + void SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA); - short mMemoryResInputGPU = -1; - short mResourceTmpIndexes = -1; - short mResourceTmpClustersOffsets = -1; + int16_t mMemoryResInputGPU = -1; + int16_t mResourceTmpIndexes = -1; + int16_t mResourceTmpClustersOffsets = -1; }; } // namespace GPUCA_NAMESPACE::gpu #endif // GPUTPCDECOMPRESSION_H diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index be3abfbdfa598..417b109cc80d3 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -22,30 +22,30 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; template <> -GPUdii() void GPUTPCDecompressionKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, int trackStart, int trackEnd) +GPUdii() void GPUTPCDecompressionKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, int32_t trackStart, int32_t trackEnd) { GPUTPCDecompression& GPUrestrict() decompressor = processors.tpcDecompressor; CompressedClusters& GPUrestrict() cmprClusters = decompressor.mInputGPU; const GPUParam& GPUrestrict() param = processors.param; - const unsigned int maxTime = (param.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1; + const uint32_t maxTime = (param.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1; - for (int i = trackStart + get_global_id(0); i < trackEnd; i += get_global_size(0)) { + for (int32_t i = trackStart + get_global_id(0); i < trackEnd; i += get_global_size(0)) { decompressTrack(cmprClusters, param, maxTime, i, decompressor.mAttachedClustersOffsets[i], decompressor); } } -GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cmprClusters, const GPUParam& param, const unsigned int maxTime, const unsigned int trackIndex, unsigned int clusterOffset, GPUTPCDecompression& decompressor) +GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t clusterOffset, GPUTPCDecompression& decompressor) { float zOffset = 0; - unsigned int slice = cmprClusters.sliceA[trackIndex]; - unsigned int row = cmprClusters.rowA[trackIndex]; + uint32_t slice = cmprClusters.sliceA[trackIndex]; + uint32_t row = cmprClusters.rowA[trackIndex]; GPUTPCCompressionTrackModel track; - unsigned int clusterIndex; + uint32_t clusterIndex; for (clusterIndex = 0; clusterIndex < cmprClusters.nTrackClusters[trackIndex]; clusterIndex++) { - unsigned int pad = 0, time = 0; + uint32_t pad = 0, time = 0; if (clusterIndex != 0) { - unsigned char tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; + uint8_t tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; bool changeLeg = (tmpSlice >= GPUCA_NSLICES); if (changeLeg) { tmpSlice -= GPUCA_NSLICES; @@ -69,7 +69,7 @@ GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cm if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { break; } - unsigned int timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; + uint32_t timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; if (timeTmp & 800000) { timeTmp |= 0xFF000000; } @@ -77,7 +77,7 @@ GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cm float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); pad = cmprClusters.padResA[clusterOffset - trackIndex - 1] + ClusterNative::packPad(tmpPad); time = time & 0xFFFFFF; - pad = (unsigned short)pad; + pad = (uint16_t)pad; if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 pad = 0; @@ -111,10 +111,10 @@ GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cm clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; } -GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const unsigned int clusterOffset, unsigned int slice, unsigned int row, unsigned int pad, unsigned int time, GPUTPCDecompression& decompressor) +GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) { - unsigned int tmpBufferIndex = computeLinearTmpBufferIndex(slice, row, decompressor.mMaxNativeClustersPerBuffer); - unsigned int currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); + uint32_t tmpBufferIndex = computeLinearTmpBufferIndex(slice, row, decompressor.mMaxNativeClustersPerBuffer); + uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); const ClusterNative c(time, cmprClusters.flagsA[clusterOffset], pad, cmprClusters.sigmaTimeA[clusterOffset], cmprClusters.sigmaPadA[clusterOffset], cmprClusters.qMaxA[clusterOffset], cmprClusters.qTotA[clusterOffset]); if (currentClusterIndex < decompressor.mMaxNativeClustersPerBuffer) { decompressor.mTmpNativeClusters[tmpBufferIndex + currentClusterIndex] = c; @@ -126,27 +126,27 @@ GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const o2 } template <> -GPUdii() void GPUTPCDecompressionKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, int sliceStart, int nSlices) +GPUdii() void GPUTPCDecompressionKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, int32_t sliceStart, int32_t nSlices) { GPUTPCDecompression& GPUrestrict() decompressor = processors.tpcDecompressor; CompressedClusters& GPUrestrict() cmprClusters = decompressor.mInputGPU; ClusterNative* GPUrestrict() clusterBuffer = decompressor.mNativeClustersBuffer; const ClusterNativeAccess* outputAccess = processors.ioPtrs.clustersNative; - unsigned int* offsets = decompressor.mUnattachedClustersOffsets; - for (int i = get_global_id(0); i < GPUCA_ROW_COUNT * nSlices; i += get_global_size(0)) { - unsigned int iRow = i % GPUCA_ROW_COUNT; - unsigned int iSlice = sliceStart + (i / GPUCA_ROW_COUNT); - const unsigned int linearIndex = iSlice * GPUCA_ROW_COUNT + iRow; - unsigned int tmpBufferIndex = computeLinearTmpBufferIndex(iSlice, iRow, decompressor.mMaxNativeClustersPerBuffer); + uint32_t* offsets = decompressor.mUnattachedClustersOffsets; + for (int32_t i = get_global_id(0); i < GPUCA_ROW_COUNT * nSlices; i += get_global_size(0)) { + uint32_t iRow = i % GPUCA_ROW_COUNT; + uint32_t iSlice = sliceStart + (i / GPUCA_ROW_COUNT); + const uint32_t linearIndex = iSlice * GPUCA_ROW_COUNT + iRow; + uint32_t tmpBufferIndex = computeLinearTmpBufferIndex(iSlice, iRow, decompressor.mMaxNativeClustersPerBuffer); ClusterNative* buffer = clusterBuffer + outputAccess->clusterOffset[iSlice][iRow]; if (decompressor.mNativeClustersIndex[linearIndex] != 0) { decompressorMemcpyBasic(buffer, decompressor.mTmpNativeClusters + tmpBufferIndex, decompressor.mNativeClustersIndex[linearIndex]); } ClusterNative* clout = buffer + decompressor.mNativeClustersIndex[linearIndex]; - unsigned int end = offsets[linearIndex] + ((linearIndex >= decompressor.mInputGPU.nSliceRows) ? 0 : decompressor.mInputGPU.nSliceRowClusters[linearIndex]); + uint32_t end = offsets[linearIndex] + ((linearIndex >= decompressor.mInputGPU.nSliceRows) ? 0 : decompressor.mInputGPU.nSliceRowClusters[linearIndex]); decompressHits(cmprClusters, offsets[linearIndex], end, clout); if (processors.param.rec.tpc.clustersShiftTimebins != 0.f) { - for (unsigned int k = 0; k < outputAccess->nClusters[iSlice][iRow]; k++) { + for (uint32_t k = 0; k < outputAccess->nClusters[iSlice][iRow]; k++) { auto& cl = buffer[k]; float t = cl.getTime() + processors.param.rec.tpc.clustersShiftTimebins; if (t < 0) { @@ -161,13 +161,13 @@ GPUdii() void GPUTPCDecompressionKernels::Thread -GPUdi() void GPUTPCDecompressionKernels::decompressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, unsigned int size) +GPUdi() void GPUTPCDecompressionKernels::decompressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, uint32_t size) { - for (unsigned int i = 0; i < size; i++) { + for (uint32_t i = 0; i < size; i++) { dst[i] = src[i]; } } template <> -GPUdii() void GPUTPCDecompressionUtilKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) +GPUdii() void GPUTPCDecompressionUtilKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) { ClusterNative* GPUrestrict() clusterBuffer = processors.tpcDecompressor.mNativeClustersBuffer; const ClusterNativeAccess* outputAccess = processors.ioPtrs.clustersNative; - for (unsigned int i = get_global_id(0); i < GPUCA_NSLICES * GPUCA_ROW_COUNT; i += get_global_size(0)) { - unsigned int slice = i / GPUCA_ROW_COUNT; - unsigned int row = i % GPUCA_ROW_COUNT; + for (uint32_t i = get_global_id(0); i < GPUCA_NSLICES * GPUCA_ROW_COUNT; i += get_global_size(0)) { + uint32_t slice = i / GPUCA_ROW_COUNT; + uint32_t row = i % GPUCA_ROW_COUNT; ClusterNative* buffer = clusterBuffer + outputAccess->clusterOffset[slice][row]; GPUCommonAlgorithm::sort(buffer, buffer + outputAccess->nClusters[slice][row]); } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h index 904dc5aabd2c4..941e745da40d9 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h @@ -38,35 +38,35 @@ class GPUTPCDecompressionKernels : public GPUKernelTemplate public: GPUhdi() constexpr static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::TPCDecompression; } - enum K : int { + enum K : int32_t { step0attached = 0, step1unattached = 1, }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, Args... args); - GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const unsigned int maxTime, const unsigned int trackIndex, unsigned int clusterOffset, GPUTPCDecompression& decompressor); - GPUdi() static o2::tpc::ClusterNative decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const unsigned int clusterOffset, unsigned int slice, unsigned int row, unsigned int pad, unsigned int time, GPUTPCDecompression& decompressor); - GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const unsigned int start, const unsigned int end, o2::tpc::ClusterNative* clusterNativeBuffer); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, Args... args); + GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t clusterOffset, GPUTPCDecompression& decompressor); + GPUdi() static o2::tpc::ClusterNative decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor); + GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, o2::tpc::ClusterNative* clusterNativeBuffer); - GPUd() static unsigned int computeLinearTmpBufferIndex(unsigned int slice, unsigned int row, unsigned int maxClustersPerBuffer) + GPUd() static uint32_t computeLinearTmpBufferIndex(uint32_t slice, uint32_t row, uint32_t maxClustersPerBuffer) { return slice * (GPUCA_ROW_COUNT * maxClustersPerBuffer) + row * maxClustersPerBuffer; } template - GPUdi() static void decompressorMemcpyBasic(T* dst, const T* src, unsigned int size); + GPUdi() static void decompressorMemcpyBasic(T* dst, const T* src, uint32_t size); }; class GPUTPCDecompressionUtilKernels : public GPUKernelTemplate { public: - enum K : int { + enum K : int32_t { sortPerSectorRow = 0, }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx index d829dc978c5ef..503f09c22af5c 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx @@ -25,7 +25,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -int TPCClusterDecompressor::decompress(const CompressedClustersFlat* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec) +int32_t TPCClusterDecompressor::decompress(const CompressedClustersFlat* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec) { CompressedClusters c; const CompressedClusters* p; @@ -38,7 +38,7 @@ int TPCClusterDecompressor::decompress(const CompressedClustersFlat* clustersCom return decompress(p, clustersNative, allocator, param, deterministicRec); } -int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec) +int32_t TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec) { if (clustersCompressed->nTracks && clustersCompressed->solenoidBz != -1e6f && clustersCompressed->solenoidBz != param.bzkG) { throw std::runtime_error("Configured solenoid Bz does not match value used for track model encoding"); @@ -48,13 +48,13 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres } std::vector clusters[NSLICES][GPUCA_ROW_COUNT]; std::atomic_flag locks[NSLICES][GPUCA_ROW_COUNT]; - for (unsigned int i = 0; i < NSLICES * GPUCA_ROW_COUNT; i++) { + for (uint32_t i = 0; i < NSLICES * GPUCA_ROW_COUNT; i++) { (&locks[0][0])[i].clear(); } - unsigned int offset = 0, lasti = 0; - const unsigned int maxTime = param.continuousMaxTimeBin > 0 ? ((param.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1) : TPC_MAX_TIME_BIN_TRIGGERED; + uint32_t offset = 0, lasti = 0; + const uint32_t maxTime = param.continuousMaxTimeBin > 0 ? ((param.continuousMaxTimeBin + 1) * ClusterNative::scaleTimePacked - 1) : TPC_MAX_TIME_BIN_TRIGGERED; GPUCA_OPENMP(parallel for firstprivate(offset, lasti)) - for (unsigned int i = 0; i < clustersCompressed->nTracks; i++) { + for (uint32_t i = 0; i < clustersCompressed->nTracks; i++) { if (i < lasti) { offset = lasti = 0; // dynamic OMP scheduling, need to reinitialize offset } @@ -66,11 +66,11 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres } size_t nTotalClusters = clustersCompressed->nAttachedClusters + clustersCompressed->nUnattachedClusters; ClusterNative* clusterBuffer = allocator(nTotalClusters); - unsigned int offsets[NSLICES][GPUCA_ROW_COUNT]; + uint32_t offsets[NSLICES][GPUCA_ROW_COUNT]; offset = 0; - unsigned int decodedAttachedClusters = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + uint32_t decodedAttachedClusters = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { clustersNative.nClusters[i][j] = clusters[i][j].size() + ((i * GPUCA_ROW_COUNT + j >= clustersCompressed->nSliceRows) ? 0 : clustersCompressed->nSliceRowClusters[i * GPUCA_ROW_COUNT + j]); offsets[i][j] = offset; offset += (i * GPUCA_ROW_COUNT + j >= clustersCompressed->nSliceRows) ? 0 : clustersCompressed->nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; @@ -83,17 +83,17 @@ int TPCClusterDecompressor::decompress(const CompressedClusters* clustersCompres clustersNative.clustersLinear = clusterBuffer; clustersNative.setOffsetPtrs(); GPUCA_OPENMP(parallel for) - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { ClusterNative* buffer = &clusterBuffer[clustersNative.clusterOffset[i][j]]; if (clusters[i][j].size()) { memcpy((void*)buffer, (const void*)clusters[i][j].data(), clusters[i][j].size() * sizeof(clusterBuffer[0])); } ClusterNative* clout = buffer + clusters[i][j].size(); - unsigned int end = offsets[i][j] + ((i * GPUCA_ROW_COUNT + j >= clustersCompressed->nSliceRows) ? 0 : clustersCompressed->nSliceRowClusters[i * GPUCA_ROW_COUNT + j]); + uint32_t end = offsets[i][j] + ((i * GPUCA_ROW_COUNT + j >= clustersCompressed->nSliceRows) ? 0 : clustersCompressed->nSliceRowClusters[i * GPUCA_ROW_COUNT + j]); decompressHits(clustersCompressed, offsets[i][j], end, clout); if (param.rec.tpc.clustersShiftTimebins != 0.f) { - for (unsigned int k = 0; k < clustersNative.nClusters[i][j]; k++) { + for (uint32_t k = 0; k < clustersNative.nClusters[i][j]; k++) { auto& cl = buffer[k]; float t = cl.getTime() + param.rec.tpc.clustersShiftTimebins; if (t < 0) { diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h index 79f14fe71e093..fc96f5fc72e28 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h @@ -32,14 +32,14 @@ struct GPUParam; class TPCClusterDecompressor { public: - static constexpr unsigned int NSLICES = GPUCA_NSLICES; - static int decompress(const o2::tpc::CompressedClustersFlat* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); - static int decompress(const o2::tpc::CompressedClusters* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); + static constexpr uint32_t NSLICES = GPUCA_NSLICES; + static int32_t decompress(const o2::tpc::CompressedClustersFlat* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); + static int32_t decompress(const o2::tpc::CompressedClusters* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); template - static void decompressTrack(const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param, const unsigned int maxTime, const unsigned int i, unsigned int& offset, Args&... args); + static void decompressTrack(const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param, const uint32_t maxTime, const uint32_t i, uint32_t& offset, Args&... args); template - static void decompressHits(const o2::tpc::CompressedClusters* clustersCompressed, const unsigned int start, const unsigned int end, Args&... args); + static void decompressHits(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t start, const uint32_t end, Args&... args); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc index f0cd648e0f49e..2ea75b21bf22e 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc @@ -24,20 +24,20 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const unsigned int offset, unsigned int slice, unsigned int row, unsigned int pad, unsigned int time, std::function func) +static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::function func) { const auto cluster = ClusterNative(time, clustersCompressed->flagsA[offset], pad, clustersCompressed->sigmaTimeA[offset], clustersCompressed->sigmaPadA[offset], clustersCompressed->qMaxA[offset], clustersCompressed->qTotA[offset]); func(cluster, offset); return cluster; } -static inline const auto& decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const unsigned int offset, unsigned int slice, unsigned int row, unsigned int pad, unsigned int time, std::vector& clusterVector) +static inline const auto& decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector& clusterVector) { clusterVector.emplace_back(time, clustersCompressed->flagsA[offset], pad, clustersCompressed->sigmaTimeA[offset], clustersCompressed->sigmaPadA[offset], clustersCompressed->qMaxA[offset], clustersCompressed->qTotA[offset]); return clusterVector.back(); } -static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const unsigned int offset, unsigned int slice, unsigned int row, unsigned int pad, unsigned int time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) +static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) { std::vector& clusterVector = clusters[slice][row]; auto& lock = locks[slice][row]; @@ -51,17 +51,17 @@ static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clust } template -inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* clustersCompressed, const GPUParam& param, const unsigned int maxTime, const unsigned int i, unsigned int& offset, Args&... args) +inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* clustersCompressed, const GPUParam& param, const uint32_t maxTime, const uint32_t i, uint32_t& offset, Args&... args) { float zOffset = 0; - unsigned int slice = clustersCompressed->sliceA[i]; - unsigned int row = clustersCompressed->rowA[i]; + uint32_t slice = clustersCompressed->sliceA[i]; + uint32_t row = clustersCompressed->rowA[i]; GPUTPCCompressionTrackModel track; - unsigned int j; + uint32_t j; for (j = 0; j < clustersCompressed->nTrackClusters[i]; j++) { - unsigned int pad = 0, time = 0; + uint32_t pad = 0, time = 0; if (j) { - unsigned char tmpSlice = clustersCompressed->sliceLegDiffA[offset - i - 1]; + uint8_t tmpSlice = clustersCompressed->sliceLegDiffA[offset - i - 1]; bool changeLeg = (tmpSlice >= NSLICES); if (changeLeg) { tmpSlice -= NSLICES; @@ -85,7 +85,7 @@ inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* cl if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { break; } - unsigned int timeTmp = clustersCompressed->timeResA[offset - i - 1]; + uint32_t timeTmp = clustersCompressed->timeResA[offset - i - 1]; if (timeTmp & 800000) { timeTmp |= 0xFF000000; } @@ -93,7 +93,7 @@ inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* cl float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); pad = clustersCompressed->padResA[offset - i - 1] + ClusterNative::packPad(tmpPad); time = time & 0xFFFFFF; - pad = (unsigned short)pad; + pad = (uint16_t)pad; if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 pad = 0; @@ -127,12 +127,12 @@ inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* cl offset += clustersCompressed->nTrackClusters[i] - j; } -static inline const auto& decompressHitsStore(const CompressedClusters* clustersCompressed, unsigned int k, unsigned int time, unsigned short pad, ClusterNative* &cl) +static inline const auto& decompressHitsStore(const CompressedClusters* clustersCompressed, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& cl) { return ((*(cl++) = ClusterNative(time, clustersCompressed->flagsU[k], pad, clustersCompressed->sigmaTimeU[k], clustersCompressed->sigmaPadU[k], clustersCompressed->qMaxU[k], clustersCompressed->qTotU[k]))); } -static inline auto decompressHitsStore(const CompressedClusters* clustersCompressed, unsigned int k, unsigned int time, unsigned short pad, std::function func) +static inline auto decompressHitsStore(const CompressedClusters* clustersCompressed, uint32_t k, uint32_t time, uint16_t pad, std::function func) { const auto cluster = ClusterNative(time, clustersCompressed->flagsU[k], pad, clustersCompressed->sigmaTimeU[k], clustersCompressed->sigmaPadU[k], clustersCompressed->qMaxU[k], clustersCompressed->qTotU[k]); func(cluster, k); @@ -140,16 +140,16 @@ static inline auto decompressHitsStore(const CompressedClusters* clustersCompres } template -inline void TPCClusterDecompressor::decompressHits(const CompressedClusters* clustersCompressed, const unsigned int start, const unsigned int end, Args&... args) +inline void TPCClusterDecompressor::decompressHits(const CompressedClusters* clustersCompressed, const uint32_t start, const uint32_t end, Args&... args) { - unsigned int time = 0; - unsigned short pad = 0; - for (unsigned int k = start; k < end; k++) { + uint32_t time = 0; + uint16_t pad = 0; + for (uint32_t k = start; k < end; k++) { /*if (cl >= clustersNative.clustersLinear + nTotalClusters) { throw std::runtime_error("Bad TPC CTF data, decoded more clusters than announced"); }*/ if (clustersCompressed->nComppressionModes & GPUSettings::CompressionDifferences) { - unsigned int timeTmp = clustersCompressed->timeDiffU[k]; + uint32_t timeTmp = clustersCompressed->timeDiffU[k]; if (timeTmp & 800000) { timeTmp |= 0xFF000000; } diff --git a/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx b/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx index d5aaa6c803069..0d7ca5c6209a4 100644 --- a/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx +++ b/GPU/GPUTracking/DataCompression/standalone-cluster-dump-entropy-analysed.cxx @@ -22,41 +22,41 @@ #include #include -const int sort_method = 1; // 0 No sorting, 1 sort after pad, 2 sort after time, 3/4 mixed methods favoring pad / time -const int slice_diff = 1; -const int row_diff = 1; -const int pad_diff = 1; -const int time_diff = 1; -const int res_diff = 0; -const int approximate_qtot = 0; -const int combine_maxtot = 1; -const int combine_sigmapadtime = 1; -const int track_based = 1; -const int track_avgtot = track_based && 0; -const int track_avgmax = track_based && 0; -const int track_diffqtot = track_based && 0; -const int track_diffqmax = track_based && 0; -const int track_separate_q = track_based && 1; -const int track_diffsigma = track_based && 0; -const int track_separate_sigma = track_based && 1; -const int truncate_bits = 1; -const int separate_slices = 0; -const int separate_patches = 0; -const int separate_sides = 0; -const int full_row_numbers = 1; -const int distinguish_rows = 0; -const int optimized_negative_values = 1; - -const int print_clusters = 0; +const int32_t sort_method = 1; // 0 No sorting, 1 sort after pad, 2 sort after time, 3/4 mixed methods favoring pad / time +const int32_t slice_diff = 1; +const int32_t row_diff = 1; +const int32_t pad_diff = 1; +const int32_t time_diff = 1; +const int32_t res_diff = 0; +const int32_t approximate_qtot = 0; +const int32_t combine_maxtot = 1; +const int32_t combine_sigmapadtime = 1; +const int32_t track_based = 1; +const int32_t track_avgtot = track_based && 0; +const int32_t track_avgmax = track_based && 0; +const int32_t track_diffqtot = track_based && 0; +const int32_t track_diffqmax = track_based && 0; +const int32_t track_separate_q = track_based && 1; +const int32_t track_diffsigma = track_based && 0; +const int32_t track_separate_sigma = track_based && 1; +const int32_t truncate_bits = 1; +const int32_t separate_slices = 0; +const int32_t separate_patches = 0; +const int32_t separate_sides = 0; +const int32_t full_row_numbers = 1; +const int32_t distinguish_rows = 0; +const int32_t optimized_negative_values = 1; + +const int32_t print_clusters = 0; const char* file = "clusters-pbpb.dump"; -const int max_clusters = 2000000; +const int32_t max_clusters = 2000000; -const int truncate_sigma = 3; -const int truncate_charge = 4; +const int32_t truncate_sigma = 3; +const int32_t truncate_charge = 4; -const int sort_pad_mixed_bins = 100; -const int sort_time_mixed_bins = 400; +const int32_t sort_pad_mixed_bins = 100; +const int32_t sort_time_mixed_bins = 400; #define EVENT 0 #define SLICE 1 @@ -90,11 +90,11 @@ const int sort_time_mixed_bins = 400; #define PAD_128 28 #define PAD_140 29 -const int rr = optimized_negative_values && 0 ? 13 : 14; // We can make them all 14 for convenience, the encoding will handle it +const int32_t rr = optimized_negative_values && 0 ? 13 : 14; // We can make them all 14 for convenience, the encoding will handle it -const unsigned int field_bits[] = {0, 6, 0, 8, 14, 15, 8, 8, 10, 16, 2, 0, 14, 15, 16, 10, 26, 16, 8, 8, 16, 26, 8, 8, rr, rr, rr, rr, rr, 14}; -const unsigned int significant_bits[] = {0, 6, 0, 8, 14, 15, truncate_sigma, truncate_sigma, truncate_charge, truncate_charge, 2, 0, 14, 15, truncate_charge, truncate_charge, 26, 16, truncate_sigma, truncate_sigma, 16, 26, 8, 8, rr, rr, rr, rr, rr, 14}; -const int nFields = sizeof(field_bits) / sizeof(field_bits[0]); +const uint32_t field_bits[] = {0, 6, 0, 8, 14, 15, 8, 8, 10, 16, 2, 0, 14, 15, 16, 10, 26, 16, 8, 8, 16, 26, 8, 8, rr, rr, rr, rr, rr, 14}; +const uint32_t significant_bits[] = {0, 6, 0, 8, 14, 15, truncate_sigma, truncate_sigma, truncate_charge, truncate_charge, 2, 0, 14, 15, truncate_charge, truncate_charge, 26, 16, truncate_sigma, truncate_sigma, 16, 26, 8, 8, rr, rr, rr, rr, rr, 14}; +const int32_t nFields = sizeof(field_bits) / sizeof(field_bits[0]); const char* field_names[] = {"event", "slice", "patch", "row", "pad", "time", "sigmaPad", "sigmaTime", "qmax", "qtot", "flagPadTime", "trackID", "resTrackPad", "resTrackTime", "trackQTot", "trackQMax", "qmaxtot", "sigmapadtime", "diffsigmapad", "diffsigmatime", "diffsigmapadtime", "tracktotmax", "trackfirstrow", "trackrow", "pad_80", "pad_92", "pad_104", "pad_116", "pad_128", "pad_140"}; @@ -102,28 +102,28 @@ const char* field_names[] = {"event", "slice", "patch", "row", "pad", "time", "s union cluster_struct { struct { - unsigned int event, slice, patch, row, pad, time, sigmaPad, sigmaTime, qmax, qtot, splitPadTime; - int trackID; - unsigned int resPad, resTime, avgtot, avgmax; + uint32_t event, slice, patch, row, pad, time, sigmaPad, sigmaTime, qmax, qtot, splitPadTime; + int32_t trackID; + uint32_t resPad, resTime, avgtot, avgmax; }; - unsigned int vals[16]; + uint32_t vals[16]; }; -int fgRows[6][2] = {{0, 30}, {30, 62}, {63, 90}, {90, 116}, {117, 139}, {139, 158}}; -int fgNRows[6] = {31, 33, 28, 27, 23, 20}; +int32_t fgRows[6][2] = {{0, 30}, {30, 62}, {63, 90}, {90, 116}, {117, 139}, {139, 158}}; +int32_t fgNRows[6] = {31, 33, 28, 27, 23, 20}; -int fgNPads[159] = {68, 68, 68, 68, 70, 70, 70, 72, 72, 72, 74, 74, 74, 76, 76, 76, 78, 78, 78, 80, 80, 80, 82, 82, 82, 84, 84, 84, 86, 86, 86, 88, 88, 88, 90, 90, 90, 92, 92, 92, 94, 94, 94, 96, 96, 96, 98, 98, 98, 100, 100, 100, 102, - 102, 102, 104, 104, 104, 106, 106, 106, 108, 108, 74, 76, 76, 76, 76, 78, 78, 78, 80, 80, 80, 80, 82, 82, 82, 84, 84, 84, 86, 86, 86, 86, 88, 88, 88, 90, 90, 90, 90, 92, 92, 92, 94, 94, 94, 96, 96, 96, 96, 98, 98, 98, 100, - 100, 100, 100, 102, 102, 102, 104, 104, 104, 106, 106, 106, 106, 108, 108, 108, 110, 110, 110, 110, 112, 112, 114, 114, 114, 116, 116, 118, 118, 120, 120, 122, 122, 122, 124, 124, 126, 126, 128, 128, 130, 130, 130, 132, 132, 134, 134, 136, 136, 138, 138, 138, 140}; +int32_t fgNPads[159] = {68, 68, 68, 68, 70, 70, 70, 72, 72, 72, 74, 74, 74, 76, 76, 76, 78, 78, 78, 80, 80, 80, 82, 82, 82, 84, 84, 84, 86, 86, 86, 88, 88, 88, 90, 90, 90, 92, 92, 92, 94, 94, 94, 96, 96, 96, 98, 98, 98, 100, 100, 100, 102, + 102, 102, 104, 104, 104, 106, 106, 106, 108, 108, 74, 76, 76, 76, 76, 78, 78, 78, 80, 80, 80, 80, 82, 82, 82, 84, 84, 84, 86, 86, 86, 86, 88, 88, 88, 90, 90, 90, 90, 92, 92, 92, 94, 94, 94, 96, 96, 96, 96, 98, 98, 98, 100, + 100, 100, 100, 102, 102, 102, 104, 104, 104, 106, 106, 106, 106, 108, 108, 108, 110, 110, 110, 110, 112, 112, 114, 114, 114, 116, 116, 118, 118, 120, 120, 122, 122, 122, 124, 124, 126, 126, 128, 128, 130, 130, 130, 132, 132, 134, 134, 136, 136, 138, 138, 138, 140}; -int fgNPadsMod[159] = {80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 116, 116, 116, 116, 116, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 128, 128, 128, 128, 128, 128, 128, 128, 128, 126, 126, 128, 128, 140, 140, 140, 140, 140, 134, 134, 140, 140, 140, 140, 140, 140}; +int32_t fgNPadsMod[159] = {80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 116, 116, 116, 116, 116, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 128, 128, 128, 128, 128, 128, 128, 128, 128, 126, 126, 128, 128, 140, 140, 140, 140, 140, 134, 134, 140, 140, 140, 140, 140, 140}; // ---------------------------------- HUFFMAN TREE typedef std::vector HuffCode; -typedef std::map HuffCodeMap; +typedef std::map HuffCodeMap; class INode { @@ -153,20 +153,20 @@ class InternalNode : public INode class LeafNode : public INode { public: - const unsigned int c; + const uint32_t c; - LeafNode(double f, unsigned int c) : INode(f), c(c) {} + LeafNode(double f, uint32_t c) : INode(f), c(c) {} }; struct NodeCmp { bool operator()(const INode* lhs, const INode* rhs) const { return lhs->f > rhs->f; } }; -INode* BuildTree(const double* frequencies, unsigned int UniqueSymbols) +INode* BuildTree(const double* frequencies, uint32_t UniqueSymbols) { std::priority_queue, NodeCmp> trees; - for (int i = 0; i < UniqueSymbols; ++i) { + for (int32_t i = 0; i < UniqueSymbols; ++i) { if (frequencies[i] != 0) { trees.push(new LeafNode(frequencies[i], i)); } @@ -211,9 +211,9 @@ bool clustercompare_timepad_mixed(cluster_struct a, cluster_struct b) { return ( bool clustercompare_inevent(cluster_struct a, cluster_struct b) { return (a.slice < b.slice || (a.slice == b.slice && a.patch < b.patch) || (a.slice == b.slice && a.patch == b.patch && a.row < b.row)); } -void do_diff(unsigned int& val, int& last, unsigned int bits, unsigned int maxval = 0) +void do_diff(uint32_t& val, int32_t& last, uint32_t bits, uint32_t maxval = 0) { - int tmp = val; + int32_t tmp = val; val -= last; if (maxval && optimized_negative_values) { while ((signed)val < 0) { @@ -225,10 +225,10 @@ void do_diff(unsigned int& val, int& last, unsigned int bits, unsigned int maxva last = tmp; } -unsigned int truncate(int j, unsigned int val) +uint32_t truncate(int32_t j, uint32_t val) { if (truncate_bits && field_bits[j] != significant_bits[j] && val) { - int ldz = sizeof(unsigned int) * 8 - __builtin_clz(val); + int32_t ldz = sizeof(uint32_t) * 8 - __builtin_clz(val); if (ldz > significant_bits[j]) { val &= ((1 << ldz) - 1) ^ ((1 << (ldz - significant_bits[j])) - 1); } @@ -236,7 +236,7 @@ unsigned int truncate(int j, unsigned int val) return (val); } -int main(int argc, char** argv) +int32_t main(int argc, char** argv) { FILE* fp; @@ -269,18 +269,18 @@ int main(int argc, char** argv) return (1); } - fprintf(stderr, "Reading %d clusters...", (int)nClusters); + fprintf(stderr, "Reading %d clusters...", (int32_t)nClusters); fread(clusters, sizeof(cluster_struct), nClusters, fp); fprintf(stderr, "Done\nSorting clusters..."); if (sort_method) { - int starti = 0; + int32_t starti = 0; if (!track_based) { fprintf(stderr, " (removing track ordering)..."); - int last_event = 0; - for (int i = 0; i <= nClusters; i++) { - int event = (i == nClusters ? -1 : clusters[i].event); + int32_t last_event = 0; + for (int32_t i = 0; i <= nClusters; i++) { + int32_t event = (i == nClusters ? -1 : clusters[i].event); if (last_event != event) { if (i - 1 > starti) { std::sort(clusters + starti, clusters + i - 1, clustercompare_inevent); @@ -292,9 +292,9 @@ int main(int argc, char** argv) } starti = 0; - int startrow = -1; - for (int i = 0; i <= nClusters; i++) { - int currow; + int32_t startrow = -1; + for (int32_t i = 0; i <= nClusters; i++) { + int32_t currow; if (i == nClusters) { currow = -1; } else if (track_based && clusters[i].trackID != -1) { @@ -323,22 +323,22 @@ int main(int argc, char** argv) fclose(fp); - long* histograms[nFields]; + int64_t* histograms[nFields]; double* probabilities[nFields]; - long counts[nFields]; - int used[nFields]; - for (int i = SLICE; i < nFields; i++) { + int64_t counts[nFields]; + int32_t used[nFields]; + for (int32_t i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID) { continue; } - histograms[i] = new long[1 << field_bits[i]]; + histograms[i] = new int64_t[1 << field_bits[i]]; probabilities[i] = new double[1 << field_bits[i]]; } double rawtotalbytes = 0; double entrototalbytes = 0; - for (int islice = 0; islice < 36; islice++) { - for (int ipatch = 0; ipatch < 6; ipatch++) { + for (int32_t islice = 0; islice < 36; islice++) { + for (int32_t ipatch = 0; ipatch < 6; ipatch++) { if (separate_slices) { printf("SLICE %d ", islice); } @@ -348,18 +348,18 @@ int main(int argc, char** argv) if (separate_slices || separate_patches) { printf("\n"); } - for (int i = SLICE; i < nFields; i++) { + for (int32_t i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID || i == PATCH) { continue; } - memset(histograms[i], 0, sizeof(long) * (1 << field_bits[i])); + memset(histograms[i], 0, sizeof(int64_t) * (1 << field_bits[i])); counts[i] = 0; used[i] = 0; } size_t nClustersUsed = 0; - int lastRow = 0, lastPad = 0, lastTime = 0, lastSlice = 0, lastResPad = 0, lastResTime = 0, lastQTot = 0, lastQMax = 0, lastSigmaPad = 0, lastSigmaTime = 0, lastTrack = -1, lastEvent = 0; + int32_t lastRow = 0, lastPad = 0, lastTime = 0, lastSlice = 0, lastResPad = 0, lastResTime = 0, lastQTot = 0, lastQMax = 0, lastSigmaPad = 0, lastSigmaTime = 0, lastTrack = -1, lastEvent = 0; for (size_t i = 0; i < nClusters; i++) { const cluster_struct& cluster_org = clusters[i]; @@ -376,7 +376,7 @@ int main(int argc, char** argv) } bool newTrack = lastTrack != cluster.trackID; - unsigned int dSigmaPad, dSigmaTime; + uint32_t dSigmaPad, dSigmaTime; if (cluster.event != lastEvent) { lastRow = lastPad = lastTime = lastSlice = 0; @@ -447,14 +447,14 @@ int main(int argc, char** argv) } if (track_avgtot && cluster.trackID != -1) { - int tmp = truncate(QTOT, cluster.qtot) - truncate(QTOT, cluster.avgtot); + int32_t tmp = truncate(QTOT, cluster.qtot) - truncate(QTOT, cluster.avgtot); if (newTrack) { cluster.qtot = truncate(QTOT, cluster.avgtot); } cluster.avgtot = tmp & ((1 << field_bits[QTOT]) - 1); } if (track_avgmax && cluster.trackID != -1) { - int tmp = cluster.qmax - cluster.avgmax; + int32_t tmp = cluster.qmax - cluster.avgmax; if (newTrack) { cluster.qmax = cluster.avgmax; } @@ -469,7 +469,7 @@ int main(int argc, char** argv) cluster.avgtot = cluster.qtot; } - for (int j = 0; j < sizeof(cluster_struct) / sizeof(unsigned int); j++) { + for (int32_t j = 0; j < sizeof(cluster_struct) / sizeof(uint32_t); j++) { if (approximate_qtot && (j == QTOT || j == AVG_TOT)) { continue; } @@ -487,7 +487,7 @@ int main(int argc, char** argv) cluster.sigmaTime, cluster.qtot, cluster.qmax, cluster.splitPadTime, cluster.resPad, cluster.resTime, cluster.avgtot, cluster.avgmax); } - for (int j = SLICE; j < nFields; j++) { + for (int32_t j = SLICE; j < nFields; j++) { bool forceStore = false; if (j == CLUSTER_ID || j == PATCH) { continue; @@ -542,7 +542,7 @@ int main(int argc, char** argv) if (j == ROW) { continue; } - int myj = newTrack ? ROW_TRACK_FIRST : ROW_TRACK; + int32_t myj = newTrack ? ROW_TRACK_FIRST : ROW_TRACK; if (j == myj) { histograms[myj][cluster.vals[ROW]]++; counts[myj]++; @@ -557,23 +557,23 @@ int main(int argc, char** argv) counts[j]++; } } else if (j == QMAX_QTOT && (!track_based || cluster.trackID == -1 || (((track_avgmax == 0 && track_avgtot == 0 && track_diffqmax == 0 && track_diffqtot == 0) || newTrack) && track_separate_q == 0))) { - int val = (cluster.qtot << field_bits[QMAX]) | cluster.qmax; + int32_t val = (cluster.qtot << field_bits[QMAX]) | cluster.qmax; histograms[j][val]++; counts[j]++; } else if (((track_avgmax || track_avgtot || track_diffqmax || track_diffqtot) && !newTrack || track_separate_q) && cluster.trackID != -1 && j == AVG_TOT_MAX) { - int val = (cluster.avgtot << field_bits[QMAX]) | cluster.avgmax; + int32_t val = (cluster.avgtot << field_bits[QMAX]) | cluster.avgmax; histograms[j][val]++; counts[j]++; } else if (j == SIGMA_PAD_TIME && (!track_based || cluster.trackID == -1 || (track_diffsigma == 0 && track_separate_sigma == 0))) { - int val = (cluster.sigmaTime << field_bits[SIGMA_PAD]) | cluster.sigmaPad; + int32_t val = (cluster.sigmaTime << field_bits[SIGMA_PAD]) | cluster.sigmaPad; histograms[j][val]++; counts[j]++; } else if ((track_diffsigma || track_separate_sigma) && cluster.trackID != -1 && j == DIFF_SIGMA_PAD_TIME) { - int val = (dSigmaPad << field_bits[SIGMA_PAD]) | dSigmaTime; + int32_t val = (dSigmaPad << field_bits[SIGMA_PAD]) | dSigmaTime; histograms[j][val]++; counts[j]++; } else if (distinguish_rows && j >= PAD_80 && j <= PAD_140) { - int myj = fgNPads[cluster_org.row + fgRows[cluster.patch][0]]; + int32_t myj = fgNPads[cluster_org.row + fgRows[cluster.patch][0]]; myj = (myj - (80 - 11)) / 12; myj += PAD_80; if (myj == j) { @@ -594,7 +594,7 @@ int main(int argc, char** argv) double log2 = log(2.); double entropies[nFields]; double huffmanSizes[nFields]; - for (int i = SLICE; i < nFields; i++) { + for (int32_t i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID || i == PATCH) { continue; } @@ -602,7 +602,7 @@ int main(int argc, char** argv) double huffmanSize = 0; if (counts[i]) { - for (int j = 0; j < (1 << field_bits[i]); j++) { + for (int32_t j = 0; j < (1 << field_bits[i]); j++) { // printf("Field %d/%s Value %d Entries %ld\n", i, field_names[i], j, histograms[i][j]); probabilities[i][j] = (double)histograms[i][j] / (double)counts[i]; @@ -629,9 +629,9 @@ int main(int argc, char** argv) huffmanSizes[i] = huffmanSize; } - int rawBits = 0; + int32_t rawBits = 0; double entroTotal = 0., huffmanTotal = 0.; - for (int i = SLICE; i < nFields; i++) { + for (int32_t i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID || i == PATCH) { continue; } @@ -663,7 +663,7 @@ int main(int argc, char** argv) used[i] = 1; } } - for (int i = SLICE; i < nFields; i++) { + for (int32_t i = SLICE; i < nFields; i++) { if (field_bits[i] == 0) { continue; } @@ -697,7 +697,7 @@ int main(int argc, char** argv) } printf("Exiting\n"); - for (int i = SLICE; i < nFields; i++) { + for (int32_t i = SLICE; i < nFields; i++) { if (i == CLUSTER_ID || i == PATCH) { continue; } diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx index e153d16e72d43..a632bf361498c 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx @@ -191,34 +191,34 @@ void CalibdEdxContainer::setZeroSupresssionThreshold(const CalDet& thresh mThresholdMap = thresholdMapTmp; } -CalDet CalibdEdxContainer::processThresholdMap(const CalDet& thresholdMap, const float maxThreshold, const int nPadsInRowCl, const int nPadsInPadCl) const +CalDet CalibdEdxContainer::processThresholdMap(const CalDet& thresholdMap, const float maxThreshold, const int32_t nPadsInRowCl, const int32_t nPadsInPadCl) const { CalDet thresholdMapProcessed(thresholdMap); - for (unsigned int sector = 0; sector < Mapper::NSECTORS; ++sector) { - for (unsigned int region = 0; region < Mapper::NREGIONS; ++region) { - const int maxRow = Mapper::ROWSPERREGION[region] - 1; - for (int lrow = 0; lrow <= maxRow; ++lrow) { + for (uint32_t sector = 0; sector < Mapper::NSECTORS; ++sector) { + for (uint32_t region = 0; region < Mapper::NREGIONS; ++region) { + const int32_t maxRow = Mapper::ROWSPERREGION[region] - 1; + for (int32_t lrow = 0; lrow <= maxRow; ++lrow) { // find first row of the cluster - const int rowStart = std::clamp(lrow - nPadsInRowCl, 0, maxRow); - const int rowEnd = std::clamp(lrow + nPadsInRowCl, 0, maxRow); - const int addPadsStart = Mapper::ADDITIONALPADSPERROW[region][lrow]; + const int32_t rowStart = std::clamp(lrow - nPadsInRowCl, 0, maxRow); + const int32_t rowEnd = std::clamp(lrow + nPadsInRowCl, 0, maxRow); + const int32_t addPadsStart = Mapper::ADDITIONALPADSPERROW[region][lrow]; - for (unsigned int pad = 0; pad < Mapper::PADSPERROW[region][lrow]; ++pad) { + for (uint32_t pad = 0; pad < Mapper::PADSPERROW[region][lrow]; ++pad) { float sumThr = 0; - int countThr = 0; + int32_t countThr = 0; // loop ove the rows from the cluster - for (int rowCl = rowStart; rowCl <= rowEnd; ++rowCl) { + for (int32_t rowCl = rowStart; rowCl <= rowEnd; ++rowCl) { // shift local pad in row in case current row from the cluster has more pads in the row - const int addPadsCl = Mapper::ADDITIONALPADSPERROW[region][rowCl]; - const int diffAddPads = addPadsCl - addPadsStart; - const int padClCentre = pad + diffAddPads; - - const int maxPad = Mapper::PADSPERROW[region][rowCl] - 1; - const int padStart = std::clamp(padClCentre - nPadsInPadCl, 0, maxPad); - const int padEnd = std::clamp(padClCentre + nPadsInPadCl, 0, maxPad); - for (int padCl = padStart; padCl <= padEnd; ++padCl) { - const int globalPad = Mapper::getGlobalPadNumber(rowCl, padCl, region); + const int32_t addPadsCl = Mapper::ADDITIONALPADSPERROW[region][rowCl]; + const int32_t diffAddPads = addPadsCl - addPadsStart; + const int32_t padClCentre = pad + diffAddPads; + + const int32_t maxPad = Mapper::PADSPERROW[region][rowCl] - 1; + const int32_t padStart = std::clamp(padClCentre - nPadsInPadCl, 0, maxPad); + const int32_t padEnd = std::clamp(padClCentre + nPadsInPadCl, 0, maxPad); + for (int32_t padCl = padStart; padCl <= padEnd; ++padCl) { + const int32_t globalPad = Mapper::getGlobalPadNumber(rowCl, padCl, region); // skip for current cluster position as the charge there is not effected from the thresold if (padCl == pad && rowCl == lrow) { continue; @@ -234,7 +234,7 @@ CalDet CalibdEdxContainer::processThresholdMap(const CalDet& thres } } const float meanThresold = sumThr / countThr; - const int globalPad = Mapper::getGlobalPadNumber(lrow, pad, region); + const int32_t globalPad = Mapper::getGlobalPadNumber(lrow, pad, region); thresholdMapProcessed.setValue(sector, globalPad, meanThresold); } } @@ -265,8 +265,8 @@ void CalibdEdxContainer::setDefaultZeroSupresssionThreshold() const float defaultVal = getMinZeroSupresssionThreshold() + (getMaxZeroSupresssionThreshold() - getMinZeroSupresssionThreshold()) / 2; mThresholdMap.setMinCorrectionFactor(defaultVal - 0.1f); mThresholdMap.setMaxCorrectionFactor(defaultVal + 0.1f); - for (int sector = 0; sector < o2::tpc::constants::MAXSECTOR; ++sector) { - for (unsigned short globPad = 0; globPad < TPC_PADS_IN_SECTOR; ++globPad) { + for (int32_t sector = 0; sector < o2::tpc::constants::MAXSECTOR; ++sector) { + for (uint16_t globPad = 0; globPad < TPC_PADS_IN_SECTOR; ++globPad) { mThresholdMap.setGainCorrection(sector, globPad, defaultVal); } } diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h index d860d1c0d340b..152bb67daacc5 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.h @@ -34,7 +34,7 @@ namespace o2::tpc { /// flags to set which corrections will be loaded from the CCDB -enum class CalibsdEdx : unsigned short { +enum class CalibsdEdx : uint16_t { CalTopologySpline = 1 << 0, ///< flag for a topology correction using splines CalTopologyPol = 1 << 1, ///< flag for a topology correction using polynomials CalThresholdMap = 1 << 2, ///< flag for using threshold map @@ -43,11 +43,11 @@ enum class CalibsdEdx : unsigned short { CalTimeGain = 1 << 5, ///< flag for residual dE/dx time dependent gain correction }; -inline CalibsdEdx operator|(CalibsdEdx a, CalibsdEdx b) { return static_cast(static_cast(a) | static_cast(b)); } +inline CalibsdEdx operator|(CalibsdEdx a, CalibsdEdx b) { return static_cast(static_cast(a) | static_cast(b)); } -inline CalibsdEdx operator&(CalibsdEdx a, CalibsdEdx b) { return static_cast(static_cast(a) & static_cast(b)); } +inline CalibsdEdx operator&(CalibsdEdx a, CalibsdEdx b) { return static_cast(static_cast(a) & static_cast(b)); } -inline CalibsdEdx operator~(CalibsdEdx a) { return static_cast(~static_cast(a)); } +inline CalibsdEdx operator~(CalibsdEdx a) { return static_cast(~static_cast(a)); } /// /// This container class contains all necessary corrections for the dE/dx @@ -83,7 +83,7 @@ class CalibdEdxContainer : public o2::gpu::FlatObject /// \param relTime relative time position of the cluster /// \param threshold zero supression threshold /// \param charge charge of the cluster - GPUd() float getTopologyCorrection(const int region, const ChargeType chargeT, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime, const float threshold, const float charge) const + GPUd() float getTopologyCorrection(const int32_t region, const ChargeType chargeT, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime, const float threshold, const float charge) const { return mCalibTrackTopologyPol ? mCalibTrackTopologyPol->getCorrection(region, chargeT, tanTheta, sinPhi, z, relPad, relTime, threshold, charge) : (mCalibTrackTopologySpline ? mCalibTrackTopologySpline->getCorrection(region, chargeT, tanTheta, sinPhi, z) : getDefaultTopologyCorrection(tanTheta, sinPhi)); } @@ -92,7 +92,7 @@ class CalibdEdxContainer : public o2::gpu::FlatObject /// \param region region of the TPC /// \param chargeT type of the charge (qMax or qTot) /// \param x coordinates where the correction is evaluated - GPUd() float getTopologyCorrection(const int region, const ChargeType chargeT, float x[]) const + GPUd() float getTopologyCorrection(const int32_t region, const ChargeType chargeT, float x[]) const { return mCalibTrackTopologyPol ? mCalibTrackTopologyPol->getCorrection(region, chargeT, x) : (mCalibTrackTopologySpline ? mCalibTrackTopologySpline->getCorrection(region, chargeT, x) : getDefaultTopologyCorrection(x[0], x[1])); } @@ -112,22 +112,22 @@ class CalibdEdxContainer : public o2::gpu::FlatObject /// \return returns zero supression threshold /// \param sector tpc sector /// \param row global pad row - GPUd() float getZeroSupressionThreshold(const int sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mThresholdMap.getGainCorrection(sector, row, pad); } + GPUd() float getZeroSupressionThreshold(const int32_t sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mThresholdMap.getGainCorrection(sector, row, pad); } /// \return returns gain from the full gain map /// \param sector tpc sector /// \param row global pad row - GPUd() float getGain(const int sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mGainMap.getGainCorrection(sector, row, pad); } + GPUd() float getGain(const int32_t sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mGainMap.getGainCorrection(sector, row, pad); } /// \return returns gain from residual gain map /// \param sector tpc sector /// \param row global pad row - GPUd() float getResidualGain(const int sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mGainMapResidual.getGainCorrection(sector, row, pad); } + GPUd() float getResidualGain(const int32_t sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mGainMapResidual.getGainCorrection(sector, row, pad); } /// \return returns if channel is tagged by the dead map /// \param sector tpc sector /// \param row global pad row - GPUd() bool isDead(const int sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mDeadChannelMap.isSet(sector, row, pad); } + GPUd() bool isDead(const int32_t sector, const gpu::tpccf::Row row, const gpu::tpccf::Pad pad) const { return mDeadChannelMap.isSet(sector, row, pad); } /// \return returns the residual dE/dx correction for the cluster charge /// \param stack ID of the GEM stack @@ -277,7 +277,7 @@ class CalibdEdxContainer : public o2::gpu::FlatObject /// \param maxThreshold max threshold value which will be considered for averaging /// \param nPadsInRowCl number of pads in row direction which will be taken into account (+- nPadsInRowCl) /// \param nPadsInPadCl number of pads in pad direction which will be taken into account (+- nPadsInPadCl) - CalDet processThresholdMap(const CalDet& thresholdMap, const float maxThreshold, const int nPadsInRowCl = 2, const int nPadsInPadCl = 2) const; + CalDet processThresholdMap(const CalDet& thresholdMap, const float maxThreshold, const int32_t nPadsInRowCl = 2, const int32_t nPadsInPadCl = 2) const; #endif #ifndef GPUCA_ALIROOT_LIB diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx index 76285ffc231b2..548bbafae686d 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx @@ -20,14 +20,14 @@ using namespace o2::tpc; #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation -void CalibdEdxTrackTopologyPol::dumpToTree(const unsigned int nSamplingPoints[/* Dim */], const char* outName) const +void CalibdEdxTrackTopologyPol::dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName) const { - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { const auto treename = getPolyName(i, ChargeType::Max); mCalibPolsqMax[i].dumpToTree(nSamplingPoints, outName, treename.data(), false); } - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { const auto treename = getPolyName(i, ChargeType::Tot); mCalibPolsqTot[i].dumpToTree(nSamplingPoints, outName, treename.data(), false); } @@ -39,17 +39,17 @@ void CalibdEdxTrackTopologyPol::cloneFromObject(const CalibdEdxTrackTopologyPol& const char* oldFlatBufferPtr = obj.mFlatBufferPtr; FlatObject::cloneFromObject(obj, newFlatBufferPtr); - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { char* buffer = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mCalibPolsqTot[i].getFlatBufferPtr()); mCalibPolsqTot[i].cloneFromObject(obj.mCalibPolsqTot[i], buffer); } - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { char* buffer = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mCalibPolsqMax[i].getFlatBufferPtr()); mCalibPolsqMax[i].cloneFromObject(obj.mCalibPolsqMax[i], buffer); } - for (int i = 0; i < FFits; ++i) { + for (int32_t i = 0; i < FFits; ++i) { mScalingFactorsqTot[i] = obj.mScalingFactorsqTot[i]; mScalingFactorsqMax[i] = obj.mScalingFactorsqMax[i]; } @@ -66,7 +66,7 @@ void CalibdEdxTrackTopologyPol::moveBufferTo(char* newFlatBufferPtr) void CalibdEdxTrackTopologyPol::destroy() { - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { mCalibPolsqTot[i].destroy(); mCalibPolsqMax[i].destroy(); } @@ -77,12 +77,12 @@ void CalibdEdxTrackTopologyPol::setActualBufferAddress(char* actualFlatBufferPtr { FlatObject::setActualBufferAddress(actualFlatBufferPtr); size_t offset = 0; - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { offset = alignSize(offset, mCalibPolsqTot[i].getBufferAlignmentBytes()); mCalibPolsqTot[i].setActualBufferAddress(mFlatBufferPtr + offset); offset += mCalibPolsqTot[i].getFlatBufferSize(); } - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { offset = alignSize(offset, mCalibPolsqMax[i].getBufferAlignmentBytes()); mCalibPolsqMax[i].setActualBufferAddress(mFlatBufferPtr + offset); offset += mCalibPolsqMax[i].getFlatBufferSize(); @@ -91,11 +91,11 @@ void CalibdEdxTrackTopologyPol::setActualBufferAddress(char* actualFlatBufferPtr void CalibdEdxTrackTopologyPol::setFutureBufferAddress(char* futureFlatBufferPtr) { - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { char* buffer = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mCalibPolsqTot[i].getFlatBufferPtr()); mCalibPolsqTot[i].setFutureBufferAddress(buffer); } - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { char* buffer = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mCalibPolsqMax[i].getFlatBufferPtr()); mCalibPolsqMax[i].setFutureBufferAddress(buffer); } @@ -112,12 +112,12 @@ void CalibdEdxTrackTopologyPol::construct() size_t offsets1[FFits]; size_t offsets2[FFits]; - for (int index = 0; index < FFits; ++index) { + for (int32_t index = 0; index < FFits; ++index) { buffSize = alignSize(buffSize, mCalibPolsqTot[index].getBufferAlignmentBytes()); offsets1[index] = buffSize; buffSize += mCalibPolsqTot[index].getFlatBufferSize(); } - for (int index = 0; index < FFits; ++index) { + for (int32_t index = 0; index < FFits; ++index) { buffSize = alignSize(buffSize, mCalibPolsqMax[index].getBufferAlignmentBytes()); offsets2[index] = buffSize; buffSize += mCalibPolsqMax[index].getFlatBufferSize(); @@ -125,18 +125,18 @@ void CalibdEdxTrackTopologyPol::construct() FlatObject::finishConstruction(buffSize); - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { mCalibPolsqTot[i].moveBufferTo(mFlatBufferPtr + offsets1[i]); } - for (unsigned int i = 0; i < FFits; i++) { + for (uint32_t i = 0; i < FFits; i++) { mCalibPolsqMax[i].moveBufferTo(mFlatBufferPtr + offsets2[i]); } } void CalibdEdxTrackTopologyPol::setDefaultPolynomials() { - for (int i = 0; i < FFits; ++i) { - const unsigned int n[FDim]{6, 5, 5, 5, 5}; + for (int32_t i = 0; i < FFits; ++i) { + const uint32_t n[FDim]{6, 5, 5, 5, 5}; // z tan(theta) sin(phi) |relPad| relTime const float minqMax[FDim]{0, 0, 0, 0, -0.5f}; @@ -190,15 +190,15 @@ void CalibdEdxTrackTopologyPol::setFromContainer(const CalibdEdxTrackTopologyPol return; } - for (int i = 0; i < FFits; ++i) { + for (int32_t i = 0; i < FFits; ++i) { mCalibPolsqTot[i].setFromContainer(container.mCalibPols[i]); } - for (int i = 0; i < FFits; ++i) { + for (int32_t i = 0; i < FFits; ++i) { mCalibPolsqMax[i].setFromContainer(container.mCalibPols[FFits + i]); } - for (int i = 0; i < FFits; ++i) { + for (int32_t i = 0; i < FFits; ++i) { mScalingFactorsqTot[i] = container.mScalingFactorsqTot[i]; mScalingFactorsqMax[i] = container.mScalingFactorsqMax[i]; } @@ -220,7 +220,7 @@ void CalibdEdxTrackTopologyPol::loadFromFile(const char* fileName, const char* n void CalibdEdxTrackTopologyPol::setPolynomialsFromFile(TFile& inpf) { - for (int ireg = 0; ireg < FFits; ++ireg) { + for (int32_t ireg = 0; ireg < FFits; ++ireg) { const auto polnameqTot = getPolyName(ireg, ChargeType::Tot); mCalibPolsqTot[ireg].loadFromFile(inpf, polnameqTot.data()); const auto polnameqMax = getPolyName(ireg, ChargeType::Max); @@ -229,7 +229,7 @@ void CalibdEdxTrackTopologyPol::setPolynomialsFromFile(TFile& inpf) construct(); } -std::string CalibdEdxTrackTopologyPol::getPolyName(const int region, const ChargeType charge) +std::string CalibdEdxTrackTopologyPol::getPolyName(const int32_t region, const ChargeType charge) { const std::string typeName[2] = {"qMax", "qTot"}; const std::string polname = fmt::format("polynomial_{}_region{}", typeName[charge], region).data(); diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h index 2431e28bd2de0..ff053e1f4bf48 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h @@ -65,7 +65,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \param region region of the TPC /// \param charge correction for maximum or total charge /// \param x coordinates where the correction is evaluated - GPUd() float getCorrection(const int region, const ChargeType charge, float x[/*inpXdim*/]) const { return (charge == ChargeType::Tot) ? mCalibPolsqTot[region].eval(x) : mCalibPolsqMax[region].eval(x); } + GPUd() float getCorrection(const int32_t region, const ChargeType charge, float x[/*inpXdim*/]) const { return (charge == ChargeType::Tot) ? mCalibPolsqTot[region].eval(x) : mCalibPolsqMax[region].eval(x); } /// \return returns the track topology correction /// \param region region of the TPC @@ -77,7 +77,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \param relTime relative time position of the track /// \param threshold zero supression threshold /// \param charge charge of the cluster - GPUd() float getCorrection(const int region, const ChargeType chargeT, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime, const float threshold, const float charge) const + GPUd() float getCorrection(const int32_t region, const ChargeType chargeT, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime, const float threshold, const float charge) const { const float corr = (chargeT == ChargeType::Tot) ? getCorrectionqTot(region, tanTheta, sinPhi, z, threshold, charge) : getCorrectionqMax(region, tanTheta, sinPhi, z, relPad, relTime); return corr; @@ -91,7 +91,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \param z z position of the cluster /// \param threshold zero supression threshold /// \param charge charge of the cluster - GPUd() float getCorrectionqTot(const int region, const float tanTheta, const float sinPhi, const float z, const float threshold, const float charge) const + GPUd() float getCorrectionqTot(const int32_t region, const float tanTheta, const float sinPhi, const float z, const float threshold, const float charge) const { float x[]{z, tanTheta, sinPhi, threshold, charge}; const float corr = mScalingFactorsqTot[region] * mCalibPolsqTot[region].eval(x); @@ -105,7 +105,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \param z z position of the cluster /// \param relPad absolute relative pad position of the track /// \param relTime relative time position of the track - GPUd() float getCorrectionqMax(const int region, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime) const + GPUd() float getCorrectionqMax(const int32_t region, const float tanTheta, const float sinPhi, const float z, const float relPad, const float relTime) const { float x[]{z, tanTheta, sinPhi, relPad, relTime}; const float corr = mScalingFactorsqMax[region] * mCalibPolsqMax[region].eval(x); @@ -114,39 +114,39 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// returns the minimum zero supression threshold for which the polynomials are valid /// \param region region of the TPC - GPUd() float getMinThreshold(const int region = 0) const { return mCalibPolsqTot[region].getXMin(3); }; + GPUd() float getMinThreshold(const int32_t region = 0) const { return mCalibPolsqTot[region].getXMin(3); }; /// returns the maximum zero supression threshold for which the polynomials are valid /// \param region region of the TPC - GPUd() float getMaxThreshold(const int region = 0) const { return mCalibPolsqTot[region].getXMax(3); }; + GPUd() float getMaxThreshold(const int32_t region = 0) const { return mCalibPolsqTot[region].getXMax(3); }; /// \return returns the the scaling factors for the polynomials for qTot /// \param region region of the scaling factor - GPUd() float getScalingFactorqTot(const int region) const { return mScalingFactorsqTot[region]; }; + GPUd() float getScalingFactorqTot(const int32_t region) const { return mScalingFactorsqTot[region]; }; /// \return returns the the scaling factors for the polynomials for qMax /// \param region region of the scaling factor - GPUd() float getScalingFactorqMax(const int region) const { return mScalingFactorsqMax[region]; }; + GPUd() float getScalingFactorqMax(const int32_t region) const { return mScalingFactorsqMax[region]; }; #if !defined(GPUCA_GPUCODE) && defined(GPUCA_HAVE_O2HEADERS) /// \return returns polynomial for qTot /// \param region region of the TPC - const auto& getPolyqTot(const int region) const { return mCalibPolsqTot[region]; } + const auto& getPolyqTot(const int32_t region) const { return mCalibPolsqTot[region]; } /// \return returns polynomial for qMax /// \param region region of the TPC - const auto& getPolyqMax(const int region) const { return mCalibPolsqMax[region]; } + const auto& getPolyqMax(const int32_t region) const { return mCalibPolsqMax[region]; } #ifndef GPUCA_STANDALONE /// set the the scaling factors for the polynomials for qTot /// \param factor scaling factor /// \param region region of the scaling factor - void setScalingFactorqTot(const float factor, const int region) { mScalingFactorsqTot[region] = factor; }; + void setScalingFactorqTot(const float factor, const int32_t region) { mScalingFactorsqTot[region] = factor; }; /// set the the scaling factors for the polynomials for qMax /// \param factor scaling factor /// \param region region of the scaling factor - void setScalingFactorqMax(const float factor, const int region) { mScalingFactorsqMax[region] = factor; }; + void setScalingFactorqMax(const float factor, const int32_t region) { mScalingFactorsqMax[region] = factor; }; /// write a class object to the file /// \param outf file where the object will be written to @@ -165,7 +165,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// dump the correction to a tree for visualisation /// \param nSamplingPoints number of sampling points per dimension /// \param outName name of the output file - void dumpToTree(const unsigned int nSamplingPoints[/* Dim */], const char* outName = "track_topology_corr_debug.root") const; + void dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName = "track_topology_corr_debug.root") const; /// sets the polynomials from an input file. The names of the objects have to be the same as in the getPolyName() function /// \param inpf file where the polynomials are stored @@ -178,7 +178,7 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// \return returns the name of the polynomial object which can be read in with the setPolynomialsFromFile() function /// \param region region of the TPC /// \param charge correction for maximum or total charge - static std::string getPolyName(const int region, const ChargeType charge); + static std::string getPolyName(const int32_t region, const ChargeType charge); #endif /// ========== FlatObject functionality, see FlatObject class for description ================= @@ -202,9 +202,9 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject /// ================================================================================================ private: - constexpr static int FFits{10}; ///< total number of fits: 10 regions * 2 charge types - constexpr static int FDim{5}; ///< dimensions of polynomials - constexpr static int FDegree{3}; ///< degree of polynomials + constexpr static int32_t FFits{10}; ///< total number of fits: 10 regions * 2 charge types + constexpr static int32_t FDim{5}; ///< dimensions of polynomials + constexpr static int32_t FDegree{3}; ///< degree of polynomials o2::gpu::NDPiecewisePolynomials mCalibPolsqTot[FFits]; ///< polynomial objects storage for the polynomials for qTot o2::gpu::NDPiecewisePolynomials mCalibPolsqMax[FFits]; ///< polynomial objects storage for the polynomials for qMax float mScalingFactorsqTot[FFits]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; ///< value which is used to scale the result of the polynomial for qTot (can be used for normalization) diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx index 04aef9a1817c7..4c6e750355397 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx @@ -46,21 +46,21 @@ CalibdEdxTrackTopologySpline& CalibdEdxTrackTopologySpline::operator=(const Cali return *this; } -void CalibdEdxTrackTopologySpline::recreate(const int nKnots[]) +void CalibdEdxTrackTopologySpline::recreate(const int32_t nKnots[]) { /// Default constructor FlatObject::startConstruction(); - int buffSize = 0; - int offsets1[FSplines]; - int offsets2[FSplines]; - for (unsigned int i = 0; i < FSplines; i++) { + int32_t buffSize = 0; + int32_t offsets1[FSplines]; + int32_t offsets2[FSplines]; + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqMax[i].recreate(nKnots); buffSize = alignSize(buffSize, mCalibSplinesqMax[i].getBufferAlignmentBytes()); offsets1[i] = buffSize; buffSize += mCalibSplinesqMax[i].getFlatBufferSize(); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqTot[i].recreate(nKnots); buffSize = alignSize(buffSize, mCalibSplinesqTot[i].getBufferAlignmentBytes()); offsets2[i] = buffSize; @@ -69,10 +69,10 @@ void CalibdEdxTrackTopologySpline::recreate(const int nKnots[]) FlatObject::finishConstruction(buffSize); - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqMax[i].moveBufferTo(mFlatBufferPtr + offsets1[i]); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqTot[i].moveBufferTo(mFlatBufferPtr + offsets2[i]); } } @@ -84,19 +84,19 @@ void CalibdEdxTrackTopologySpline::cloneFromObject(const CalibdEdxTrackTopologyS const char* oldFlatBufferPtr = obj.mFlatBufferPtr; FlatObject::cloneFromObject(obj, newFlatBufferPtr); - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { char* buffer = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mCalibSplinesqMax[i].getFlatBufferPtr()); mCalibSplinesqMax[i].cloneFromObject(obj.mCalibSplinesqMax[i], buffer); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { char* buffer = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mCalibSplinesqTot[i].getFlatBufferPtr()); mCalibSplinesqTot[i].cloneFromObject(obj.mCalibSplinesqTot[i], buffer); } mMaxTanTheta = obj.mMaxTanTheta; mMaxSinPhi = obj.mMaxSinPhi; - for (unsigned int i = 0; i < FSplines; ++i) { + for (uint32_t i = 0; i < FSplines; ++i) { mScalingFactorsqTot[i] = obj.mScalingFactorsqTot[i]; mScalingFactorsqMax[i] = obj.mScalingFactorsqMax[i]; } @@ -115,7 +115,7 @@ void CalibdEdxTrackTopologySpline::moveBufferTo(char* newFlatBufferPtr) void CalibdEdxTrackTopologySpline::destroy() { /// See FlatObject for description - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqMax[i].destroy(); mCalibSplinesqTot[i].destroy(); } @@ -127,13 +127,13 @@ void CalibdEdxTrackTopologySpline::setActualBufferAddress(char* actualFlatBuffer /// See FlatObject for description FlatObject::setActualBufferAddress(actualFlatBufferPtr); - int offset = 0; - for (unsigned int i = 0; i < FSplines; i++) { + int32_t offset = 0; + for (uint32_t i = 0; i < FSplines; i++) { offset = alignSize(offset, mCalibSplinesqMax[i].getBufferAlignmentBytes()); mCalibSplinesqMax[i].setActualBufferAddress(mFlatBufferPtr + offset); offset += mCalibSplinesqMax[i].getFlatBufferSize(); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { offset = alignSize(offset, mCalibSplinesqTot[i].getBufferAlignmentBytes()); mCalibSplinesqTot[i].setActualBufferAddress(mFlatBufferPtr + offset); offset += mCalibSplinesqTot[i].getFlatBufferSize(); @@ -144,11 +144,11 @@ void CalibdEdxTrackTopologySpline::setFutureBufferAddress(char* futureFlatBuffer { /// See FlatObject for description - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { char* buffer = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mCalibSplinesqMax[i].getFlatBufferPtr()); mCalibSplinesqMax[i].setFutureBufferAddress(buffer); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { char* buffer = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mCalibSplinesqTot[i].getFlatBufferPtr()); mCalibSplinesqTot[i].setFutureBufferAddress(buffer); } @@ -173,7 +173,7 @@ void CalibdEdxTrackTopologySpline::setFromFile(TFile& inpf, const char* name) LOGP(info, "CalibdEdxTrackTopologySpline sucessfully loaded from file"); } -int CalibdEdxTrackTopologySpline::writeToFile(TFile& outf, const char* name) +int32_t CalibdEdxTrackTopologySpline::writeToFile(TFile& outf, const char* name) { /// write a class object to the file LOGP(info, "Warnings when writting to file can be ignored"); @@ -184,9 +184,9 @@ void CalibdEdxTrackTopologySpline::setDefaultSplines() { FlatObject::startConstruction(); - int buffSize = 0; - int offsets1[FSplines]; - int offsets2[FSplines]; + int32_t buffSize = 0; + int32_t offsets1[FSplines]; + int32_t offsets2[FSplines]; auto defaultF = [&](const double x[], double f[]) { f[0] = 1.f; @@ -194,12 +194,12 @@ void CalibdEdxTrackTopologySpline::setDefaultSplines() double xMin[FDimX]{}; double xMax[FDimX]{}; - for (int iDimX = 0; iDimX < FDimX; ++iDimX) { + for (int32_t iDimX = 0; iDimX < FDimX; ++iDimX) { xMin[iDimX] = 0; xMax[iDimX] = 1; } - for (unsigned int ireg = 0; ireg < FSplines; ++ireg) { + for (uint32_t ireg = 0; ireg < FSplines; ++ireg) { SplineType splineTmpqMax; splineTmpqMax.approximateFunction(xMin, xMax, defaultF); mCalibSplinesqMax[ireg] = splineTmpqMax; @@ -208,7 +208,7 @@ void CalibdEdxTrackTopologySpline::setDefaultSplines() buffSize += mCalibSplinesqMax[ireg].getFlatBufferSize(); } - for (unsigned int ireg = 0; ireg < FSplines; ++ireg) { + for (uint32_t ireg = 0; ireg < FSplines; ++ireg) { SplineType splineTmpqTot; splineTmpqTot.approximateFunction(xMin, xMax, defaultF); mCalibSplinesqTot[ireg] = splineTmpqTot; @@ -219,10 +219,10 @@ void CalibdEdxTrackTopologySpline::setDefaultSplines() FlatObject::finishConstruction(buffSize); - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqMax[i].moveBufferTo(mFlatBufferPtr + offsets1[i]); } - for (unsigned int i = 0; i < FSplines; i++) { + for (uint32_t i = 0; i < FSplines; i++) { mCalibSplinesqTot[i].moveBufferTo(mFlatBufferPtr + offsets2[i]); } } @@ -243,7 +243,7 @@ inline void CalibdEdxTrackTopologySpline::setRangesFromFile(TFile& inpf) } } -std::string CalibdEdxTrackTopologySpline::getSplineName(const int region, const ChargeType charge) +std::string CalibdEdxTrackTopologySpline::getSplineName(const int32_t region, const ChargeType charge) { const std::string typeName[2] = {"qMax", "qTot"}; const std::string polname = fmt::format("spline_{}_region{}", typeName[charge], region).data(); diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h index 84d52c4272364..563872fb90d4d 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h @@ -59,11 +59,11 @@ namespace o2::tpc /// angleY = sqrt( snp2 * sec2 ) /// /// relative pad position -/// relPadPos = COG_Pad - int(COG_Pad + 0.5f); +/// relPadPos = COG_Pad - int32_t(COG_Pad + 0.5f); /// -0.5fsteps, (unsigned int)workflow->stepsGPUMask, (unsigned int)workflow->inputs, (unsigned int)workflow->outputs); + printf("\n\tReconstruction steps / inputs / outputs:\n\tReco Steps = 0x%08x\n\tReco Steps GPU = 0x%08x\n\tInputs = 0x%08x\n\tOutputs = 0x%08x\n", (uint32_t)workflow->steps, (uint32_t)workflow->stepsGPUMask, (uint32_t)workflow->inputs, (uint32_t)workflow->outputs); } } diff --git a/GPU/GPUTracking/DataTypes/GPUDataTypes.cxx b/GPU/GPUTracking/DataTypes/GPUDataTypes.cxx index 3ede5a6de3747..11680c3de118f 100644 --- a/GPU/GPUTracking/DataTypes/GPUDataTypes.cxx +++ b/GPU/GPUTracking/DataTypes/GPUDataTypes.cxx @@ -23,7 +23,7 @@ constexpr const char* const GPUDataTypes::GENERAL_STEP_NAMES[]; GPUDataTypes::DeviceType GPUDataTypes::GetDeviceType(const char* type) { - for (unsigned int i = 1; i < sizeof(DEVICE_TYPE_NAMES) / sizeof(DEVICE_TYPE_NAMES[0]); i++) { + for (uint32_t i = 1; i < sizeof(DEVICE_TYPE_NAMES) / sizeof(DEVICE_TYPE_NAMES[0]); i++) { if (strcmp(DEVICE_TYPE_NAMES[i], type) == 0) { return (DeviceType)i; } diff --git a/GPU/GPUTracking/DataTypes/GPUDataTypes.h b/GPU/GPUTracking/DataTypes/GPUDataTypes.h index b16d8c15f9985..c746dc1af5a0b 100644 --- a/GPU/GPUTracking/DataTypes/GPUDataTypes.h +++ b/GPU/GPUTracking/DataTypes/GPUDataTypes.h @@ -117,7 +117,7 @@ namespace gpu #ifdef GPUCA_NOCOMPAT_ALLOPENCL #include "utils/bitfield.h" #define ENUM_CLASS class -#define ENUM_UINT : unsigned int +#define ENUM_UINT : uint32_t #define GPUCA_RECO_STEP GPUDataTypes::RecoStep #else #define ENUM_CLASS @@ -181,13 +181,13 @@ class GPUDataTypes static constexpr const char* const DEVICE_TYPE_NAMES[] = {"INVALID", "CPU", "CUDA", "HIP", "OCL", "OCL2"}; static constexpr const char* const RECO_STEP_NAMES[] = {"TPC Transformation", "TPC Sector Tracking", "TPC Track Merging and Fit", "TPC Compression", "TRD Tracking", "ITS Tracking", "TPC dEdx Computation", "TPC Cluster Finding", "TPC Decompression", "Global Refit"}; static constexpr const char* const GENERAL_STEP_NAMES[] = {"Prepare", "QA"}; - typedef bitfield RecoStepField; - typedef bitfield InOutTypeField; - constexpr static int N_RECO_STEPS = sizeof(GPUDataTypes::RECO_STEP_NAMES) / sizeof(GPUDataTypes::RECO_STEP_NAMES[0]); - constexpr static int N_GENERAL_STEPS = sizeof(GPUDataTypes::GENERAL_STEP_NAMES) / sizeof(GPUDataTypes::GENERAL_STEP_NAMES[0]); + typedef bitfield RecoStepField; + typedef bitfield InOutTypeField; + constexpr static int32_t N_RECO_STEPS = sizeof(GPUDataTypes::RECO_STEP_NAMES) / sizeof(GPUDataTypes::RECO_STEP_NAMES[0]); + constexpr static int32_t N_GENERAL_STEPS = sizeof(GPUDataTypes::GENERAL_STEP_NAMES) / sizeof(GPUDataTypes::GENERAL_STEP_NAMES[0]); #endif #ifdef GPUCA_NOCOMPAT - static constexpr unsigned int NSLICES = 36; + static constexpr uint32_t NSLICES = 36; #endif static DeviceType GetDeviceType(const char* type); }; @@ -230,25 +230,25 @@ typedef GPUCalibObjectsTemplate GPUCalibObjects; // NOTE: These 2 mu typedef GPUCalibObjectsTemplate GPUCalibObjectsConst; struct GPUTrackingInOutZS { - static constexpr unsigned int NSLICES = GPUDataTypes::NSLICES; - static constexpr unsigned int NENDPOINTS = 20; + static constexpr uint32_t NSLICES = GPUDataTypes::NSLICES; + static constexpr uint32_t NENDPOINTS = 20; struct GPUTrackingInOutZSSlice { const void* const* zsPtr[NENDPOINTS]; - const unsigned int* nZSPtr[NENDPOINTS]; - unsigned int count[NENDPOINTS]; + const uint32_t* nZSPtr[NENDPOINTS]; + uint32_t count[NENDPOINTS]; }; struct GPUTrackingInOutZSCounts { - unsigned int count[NSLICES][NENDPOINTS] = {}; + uint32_t count[NSLICES][NENDPOINTS] = {}; }; struct GPUTrackingInOutZSMeta { void* ptr[NSLICES][NENDPOINTS]; - unsigned int n[NSLICES][NENDPOINTS]; + uint32_t n[NSLICES][NENDPOINTS]; }; GPUTrackingInOutZSSlice slice[NSLICES]; }; struct GPUTrackingInOutDigits { - static constexpr unsigned int NSLICES = GPUDataTypes::NSLICES; + static constexpr uint32_t NSLICES = GPUDataTypes::NSLICES; const o2::tpc::Digit* tpcDigits[NSLICES] = {nullptr}; size_t nTPCDigits[NSLICES] = {0}; const GPUTPCDigitsMCInput* tpcDigitsMC = nullptr; @@ -258,91 +258,91 @@ struct GPUTrackingInOutPointers { GPUTrackingInOutPointers() = default; // TPC - static constexpr unsigned int NSLICES = GPUDataTypes::NSLICES; + static constexpr uint32_t NSLICES = GPUDataTypes::NSLICES; const GPUTrackingInOutZS* tpcZS = nullptr; const GPUTrackingInOutDigits* tpcPackedDigits = nullptr; const GPUTPCClusterData* clusterData[NSLICES] = {nullptr}; - unsigned int nClusterData[NSLICES] = {0}; + uint32_t nClusterData[NSLICES] = {0}; const AliHLTTPCRawCluster* rawClusters[NSLICES] = {nullptr}; - unsigned int nRawClusters[NSLICES] = {0}; + uint32_t nRawClusters[NSLICES] = {0}; const o2::tpc::ClusterNativeAccess* clustersNative = nullptr; const GPUTPCTrack* sliceTracks[NSLICES] = {nullptr}; - unsigned int nSliceTracks[NSLICES] = {0}; + uint32_t nSliceTracks[NSLICES] = {0}; const GPUTPCHitId* sliceClusters[NSLICES] = {nullptr}; - unsigned int nSliceClusters[NSLICES] = {0}; + uint32_t nSliceClusters[NSLICES] = {0}; const AliHLTTPCClusterMCLabel* mcLabelsTPC = nullptr; - unsigned int nMCLabelsTPC = 0; + uint32_t nMCLabelsTPC = 0; const GPUTPCMCInfo* mcInfosTPC = nullptr; - unsigned int nMCInfosTPC = 0; + uint32_t nMCInfosTPC = 0; const GPUTPCMCInfoCol* mcInfosTPCCol = nullptr; - unsigned int nMCInfosTPCCol = 0; + uint32_t nMCInfosTPCCol = 0; const GPUTPCGMMergedTrack* mergedTracks = nullptr; - unsigned int nMergedTracks = 0; + uint32_t nMergedTracks = 0; const GPUTPCGMMergedTrackHit* mergedTrackHits = nullptr; const GPUTPCGMMergedTrackHitXYZ* mergedTrackHitsXYZ = nullptr; - unsigned int nMergedTrackHits = 0; - const unsigned int* mergedTrackHitAttachment = nullptr; - const unsigned char* mergedTrackHitStates = nullptr; + uint32_t nMergedTrackHits = 0; + const uint32_t* mergedTrackHitAttachment = nullptr; + const uint8_t* mergedTrackHitStates = nullptr; const o2::tpc::TrackTPC* outputTracksTPCO2 = nullptr; - unsigned int nOutputTracksTPCO2 = 0; - const unsigned int* outputClusRefsTPCO2 = nullptr; - unsigned int nOutputClusRefsTPCO2 = 0; + uint32_t nOutputTracksTPCO2 = 0; + const uint32_t* outputClusRefsTPCO2 = nullptr; + uint32_t nOutputClusRefsTPCO2 = 0; const o2::MCCompLabel* outputTracksTPCO2MC = nullptr; const o2::tpc::CompressedClustersFlat* tpcCompressedClusters = nullptr; // TPC links - int* tpcLinkITS = nullptr; - int* tpcLinkTRD = nullptr; - int* tpcLinkTOF = nullptr; + int32_t* tpcLinkITS = nullptr; + int32_t* tpcLinkTRD = nullptr; + int32_t* tpcLinkTOF = nullptr; const o2::track::TrackParCov** globalTracks = nullptr; float* globalTrackTimes = nullptr; - unsigned int nGlobalTracks = 0; + uint32_t nGlobalTracks = 0; // TRD const GPUTRDTrackletWord* trdTracklets = nullptr; const GPUTRDSpacePoint* trdSpacePoints = nullptr; - unsigned int nTRDTracklets = 0; + uint32_t nTRDTracklets = 0; const GPUTRDTrackGPU* trdTracks = nullptr; const GPUTRDTrack* trdTracksO2 = nullptr; - unsigned int nTRDTracks = 0; + uint32_t nTRDTracks = 0; const float* trdTriggerTimes = nullptr; - const int* trdTrackletIdxFirst = nullptr; - const char* trdTrigRecMask = nullptr; - unsigned int nTRDTriggerRecords = 0; + const int32_t* trdTrackletIdxFirst = nullptr; + const uint8_t* trdTrigRecMask = nullptr; + uint32_t nTRDTriggerRecords = 0; const GPUTRDTrack* trdTracksITSTPCTRD = nullptr; - unsigned int nTRDTracksITSTPCTRD = 0; + uint32_t nTRDTracksITSTPCTRD = 0; const GPUTRDTrack* trdTracksTPCTRD = nullptr; - unsigned int nTRDTracksTPCTRD = 0; + uint32_t nTRDTracksTPCTRD = 0; // TOF const o2::tof::Cluster* tofClusters = nullptr; - unsigned int nTOFClusters = 0; + uint32_t nTOFClusters = 0; const o2::dataformats::MatchInfoTOF* itstpctofMatches = nullptr; - unsigned int nITSTPCTOFMatches = 0; + uint32_t nITSTPCTOFMatches = 0; const o2::dataformats::MatchInfoTOF* itstpctrdtofMatches = nullptr; - unsigned int nITSTPCTRDTOFMatches = 0; + uint32_t nITSTPCTRDTOFMatches = 0; const o2::dataformats::MatchInfoTOF* tpctrdtofMatches = nullptr; - unsigned int nTPCTRDTOFMatches = 0; + uint32_t nTPCTRDTOFMatches = 0; const o2::dataformats::MatchInfoTOF* tpctofMatches = nullptr; - unsigned int nTPCTOFMatches = 0; + uint32_t nTPCTOFMatches = 0; // ITS const o2::itsmft::CompClusterExt* itsCompClusters = nullptr; const o2::dataformats::MCTruthContainer* itsClusterMC = nullptr; const o2::BaseCluster* itsClusters = nullptr; - unsigned int nItsClusters = 0; + uint32_t nItsClusters = 0; const o2::itsmft::ROFRecord* itsClusterROF = nullptr; - unsigned int nItsClusterROF = 0; + uint32_t nItsClusterROF = 0; const o2::its::TrackITS* itsTracks = nullptr; const o2::MCCompLabel* itsTrackMC = nullptr; - unsigned int nItsTracks = 0; - const int* itsTrackClusIdx = nullptr; + uint32_t nItsTracks = 0; + const int32_t* itsTrackClusIdx = nullptr; const o2::itsmft::ROFRecord* itsTrackROF = nullptr; - unsigned int nItsTrackROF = 0; + uint32_t nItsTrackROF = 0; // TPC-ITS const o2::dataformats::TrackTPCITS* tracksTPCITSO2 = nullptr; - unsigned int nTracksTPCITSO2 = 0; + uint32_t nTracksTPCITSO2 = 0; // Common const GPUSettingsTF* settingsTF = nullptr; diff --git a/GPU/GPUTracking/DataTypes/GPUMemorySizeScalers.h b/GPU/GPUTracking/DataTypes/GPUMemorySizeScalers.h index 4d535fbe84c64..8b3d19295e989 100644 --- a/GPU/GPUTracking/DataTypes/GPUMemorySizeScalers.h +++ b/GPU/GPUTracking/DataTypes/GPUMemorySizeScalers.h @@ -78,10 +78,10 @@ struct GPUMemorySizeScalers { inline size_t NTPCTracklets(size_t tpcHits) { return getValue(tpcMaxTracklets, NTPCStartHits(tpcHits) * tpcTrackletsPerStartHit); } inline size_t NTPCTrackletHits(size_t tpcHits) { return getValue(tpcMaxTrackletHits, hitOffset + tpcHits * tpcTrackletHitsPerHit); } inline size_t NTPCSectorTracks(size_t tpcHits) { return getValue(tpcMaxSectorTracks, tpcHits * tpcSectorTracksPerHit); } - inline size_t NTPCSectorTrackHits(size_t tpcHits, unsigned char withRejection = 0) { return getValue(tpcMaxSectorTrackHits, tpcHits * (withRejection ? tpcSectorTrackHitsPerHitWithRejection : tpcSectorTrackHitsPerHit)); } + inline size_t NTPCSectorTrackHits(size_t tpcHits, uint8_t withRejection = 0) { return getValue(tpcMaxSectorTrackHits, tpcHits * (withRejection ? tpcSectorTrackHitsPerHitWithRejection : tpcSectorTrackHitsPerHit)); } inline size_t NTPCMergedTracks(size_t tpcSliceTracks) { return getValue(tpcMaxMergedTracks, tpcSliceTracks * (conservative ? 1.0 : tpcMergedTrackPerSliceTrack)); } inline size_t NTPCMergedTrackHits(size_t tpcSliceTrackHitss) { return getValue(tpcMaxMergedTrackHits, tpcSliceTrackHitss * tpcMergedTrackHitPerSliceHit); } - inline size_t NTPCUnattachedHitsBase1024(int type) { return (returnMaxVal || conservative) ? 1024 : std::min(1024, tpcCompressedUnattachedHitsBase1024[type] * factor * temporaryFactor); } + inline size_t NTPCUnattachedHitsBase1024(int32_t type) { return (returnMaxVal || conservative) ? 1024 : std::min(1024, tpcCompressedUnattachedHitsBase1024[type] * factor * temporaryFactor); } }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h index 5c5a770f81be3..802306e996553 100644 --- a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h +++ b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h @@ -26,7 +26,7 @@ struct GPUNewCalibValues { bool newSolenoidField = false; bool newContinuousMaxTimeBin = false; float solenoidField = 0.f; - unsigned int continuousMaxTimeBin = 0; + uint32_t continuousMaxTimeBin = 0; void updateFrom(const GPUNewCalibValues* from); }; diff --git a/GPU/GPUTracking/DataTypes/GPUO2FakeClasses.h b/GPU/GPUTracking/DataTypes/GPUO2FakeClasses.h index 073d5e74c21ae..8e6fc4854d900 100644 --- a/GPU/GPUTracking/DataTypes/GPUO2FakeClasses.h +++ b/GPU/GPUTracking/DataTypes/GPUO2FakeClasses.h @@ -39,31 +39,31 @@ class TrackTPC class CalibdEdxContainer { public: - static bool isDead(int slice, int row, int pad) { return false; } + static bool isDead(int32_t slice, int32_t row, int32_t pad) { return false; } }; struct ClusterNative { GPUd() static float getTime() { return 0.f; } GPUd() static float getPad() { return 0.f; } - GPUd() static int getFlags() { return 0; } - GPUd() static void setTimeFlags(float t, int f) {} + GPUd() static int32_t getFlags() { return 0; } + GPUd() static void setTimeFlags(float t, int32_t f) {} GPUd() static void setPad(float p) {} GPUd() static void setSigmaTime(float s) {} GPUd() static void setSigmaPad(float s) {} - unsigned char qTot, qMax; + uint8_t qTot, qMax; }; struct ClusterNativeAccess { const ClusterNative* clustersLinear; const ClusterNative* clusters[GPUCA_NSLICES][GPUCA_ROW_COUNT]; - unsigned int nClusters[GPUCA_NSLICES][GPUCA_ROW_COUNT]; - unsigned int nClustersSector[GPUCA_NSLICES]; - unsigned int clusterOffset[GPUCA_NSLICES][GPUCA_ROW_COUNT]; - unsigned int nClustersTotal; + uint32_t nClusters[GPUCA_NSLICES][GPUCA_ROW_COUNT]; + uint32_t nClustersSector[GPUCA_NSLICES]; + uint32_t clusterOffset[GPUCA_NSLICES][GPUCA_ROW_COUNT]; + uint32_t nClustersTotal; void setOffsetPtrs() {} }; #ifndef __OPENCL__ struct TPCZSHDR { - static const unsigned int TPC_ZS_PAGE_SIZE = 8192; + static const uint32_t TPC_ZS_PAGE_SIZE = 8192; }; #endif } // namespace tpc diff --git a/GPU/GPUTracking/DataTypes/GPUOutputControl.h b/GPU/GPUTracking/DataTypes/GPUOutputControl.h index 291850b60468b..58eaf161f865f 100644 --- a/GPU/GPUTracking/DataTypes/GPUOutputControl.h +++ b/GPU/GPUTracking/DataTypes/GPUOutputControl.h @@ -80,7 +80,7 @@ struct GPUTrackingOutputs { static constexpr size_t count() { return sizeof(GPUTrackingOutputs) / sizeof(GPUOutputControl); } GPUOutputControl* asArray() { return (GPUOutputControl*)this; } size_t getIndex(const GPUOutputControl& v) { return &v - (const GPUOutputControl*)this; } - static int getIndex(GPUOutputControl GPUTrackingOutputs::*v) { return &(((GPUTrackingOutputs*)(0x10000))->*v) - (GPUOutputControl*)(0x10000); } + static int32_t getIndex(GPUOutputControl GPUTrackingOutputs::*v) { return &(((GPUTrackingOutputs*)(0x10000))->*v) - (GPUOutputControl*)(0x10000); } }; } // namespace gpu diff --git a/GPU/GPUTracking/DataTypes/GPUSettings.h b/GPU/GPUTracking/DataTypes/GPUSettings.h index 448646c22a2eb..69f3ff67cf257 100644 --- a/GPU/GPUTracking/DataTypes/GPUSettings.h +++ b/GPU/GPUTracking/DataTypes/GPUSettings.h @@ -46,38 +46,38 @@ class GPUSettings RejectionStrategyB = 2 }; #if !defined(__OPENCL__) || defined(__OPENCLCPP__) - static CONSTEXPR const unsigned int TPC_MAX_TF_TIME_BIN = ((256 * 3564 + 2 * 8 - 2) / 8); + static CONSTEXPR const uint32_t TPC_MAX_TF_TIME_BIN = ((256 * 3564 + 2 * 8 - 2) / 8); #endif }; #ifdef GPUCA_NOCOMPAT // Settings describing the global run parameters struct GPUSettingsGRP { - // All new members must be sizeof(int) resp. sizeof(float) for alignment reasons!, default value for newly added members for old data will be 0. + // All new members must be sizeof(int32_t) resp. sizeof(float) for alignment reasons!, default value for newly added members for old data will be 0. float solenoidBzNominalGPU = -5.00668f; // solenoid field strength - int constBz = 0; // for test-MC events with constant Bz - int homemadeEvents = 0; // Toy-MC events - int continuousMaxTimeBin = 0; // 0 for triggered events, -1 for default TF length - int needsClusterer = 0; // Set to true if the data requires the clusterizer - int doCompClusterDecode = 0; // Set to true if the data contains compressed TPC clusters + int32_t constBz = 0; // for test-MC events with constant Bz + int32_t homemadeEvents = 0; // Toy-MC events + int32_t continuousMaxTimeBin = 0; // 0 for triggered events, -1 for default TF length + int32_t needsClusterer = 0; // Set to true if the data requires the clusterizer + int32_t doCompClusterDecode = 0; // Set to true if the data contains compressed TPC clusters }; // Parameters of the current time frame struct GPUSettingsTF { - int hasTfStartOrbit = 0; - int tfStartOrbit = 0; - int hasRunStartOrbit = 0; - int runStartOrbit = 0; - int hasSimStartOrbit = 0; - int simStartOrbit = 0; - int hasNHBFPerTF = 0; - int nHBFPerTF = 0; + int32_t hasTfStartOrbit = 0; + int32_t tfStartOrbit = 0; + int32_t hasRunStartOrbit = 0; + int32_t runStartOrbit = 0; + int32_t hasSimStartOrbit = 0; + int32_t simStartOrbit = 0; + int32_t hasNHBFPerTF = 0; + int32_t nHBFPerTF = 0; }; // Settings defining the setup of the GPUReconstruction processing (basically selecting the device / class instance) struct GPUSettingsDeviceBackend { - unsigned int deviceType = GPUDataTypes::DeviceType::CPU; // Device type, shall use GPUDataTypes::DEVICE_TYPE constants, e.g. CPU / CUDA - char forceDeviceType = true; // Fail if device initialization fails, otherwise falls back to CPU + uint32_t deviceType = GPUDataTypes::DeviceType::CPU; // Device type, shall use GPUDataTypes::DEVICE_TYPE constants, e.g. CPU / CUDA + uint8_t forceDeviceType = 1; // Fail if device initialization fails, otherwise falls back to CPU GPUReconstruction* master = nullptr; // GPUReconstruction master object }; #endif diff --git a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx index 9b388bb0260e5..475b7888a150d 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx +++ b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.cxx @@ -17,16 +17,16 @@ using namespace GPUCA_NAMESPACE::gpu; -GPUd() unsigned int GPUTPCClusterOccupancyMapBin::getNBins(const GPUParam& param) +GPUd() uint32_t GPUTPCClusterOccupancyMapBin::getNBins(const GPUParam& param) { if (param.rec.tpc.occupancyMapTimeBins == 0) { return 0; } - unsigned int maxTimeBin = param.par.continuousTracking ? param.continuousMaxTimeBin : TPC_MAX_TIME_BIN_TRIGGERED; + uint32_t maxTimeBin = param.par.continuousTracking ? param.continuousMaxTimeBin : TPC_MAX_TIME_BIN_TRIGGERED; return (maxTimeBin + param.rec.tpc.occupancyMapTimeBins) / param.rec.tpc.occupancyMapTimeBins; // Not -1, since maxTimeBin is allowed } -GPUd() unsigned int GPUTPCClusterOccupancyMapBin::getTotalSize(const GPUParam& param) +GPUd() uint32_t GPUTPCClusterOccupancyMapBin::getTotalSize(const GPUParam& param) { return getNBins(param) * sizeof(GPUTPCClusterOccupancyMapBin); } diff --git a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.h b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.h index b6f7950ff6917..ac76fd6e32a41 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.h +++ b/GPU/GPUTracking/DataTypes/GPUTPCClusterOccupancyMap.h @@ -22,10 +22,10 @@ namespace GPUCA_NAMESPACE::gpu { struct GPUParam; struct GPUTPCClusterOccupancyMapBin { - unsigned short bin[GPUCA_NSLICES][GPUCA_ROW_COUNT]; + uint16_t bin[GPUCA_NSLICES][GPUCA_ROW_COUNT]; - GPUd() static unsigned int getNBins(const GPUParam& param); - GPUd() static unsigned int getTotalSize(const GPUParam& param); + GPUd() static uint32_t getNBins(const GPUParam& param); + GPUd() static uint32_t getTotalSize(const GPUParam& param); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataTypes/GPUTPCGMMergedTrackHit.h b/GPU/GPUTracking/DataTypes/GPUTPCGMMergedTrackHit.h index 3505759e49701..771385d24e60a 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCGMMergedTrackHit.h +++ b/GPU/GPUTracking/DataTypes/GPUTPCGMMergedTrackHit.h @@ -22,11 +22,11 @@ namespace GPUCA_NAMESPACE namespace gpu { struct GPUTPCGMMergedTrackHit { - unsigned int num; - unsigned char slice, row, leg, state; + uint32_t num; + uint8_t slice, row, leg, state; #ifdef GPUCA_ALIROOT_LIB float x, y, z; - unsigned short amp; + uint16_t amp; #endif // NOTE: the lower states must match those from ClusterNative! @@ -45,7 +45,7 @@ struct GPUTPCGMMergedTrackHit { struct GPUTPCGMMergedTrackHitXYZ { float x, y, z; - unsigned short amp; + uint16_t amp; #ifdef GPUCA_TPC_RAW_PROPAGATE_PAD_ROW_TIME float pad; float time; diff --git a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.cxx b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.cxx index 2a1a4cc3a97c9..cb367a0f4b416 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.cxx +++ b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.cxx @@ -36,7 +36,7 @@ void GPUTPCGMPolynomialField::Print() const << " == " << mNominalBz / kCLight << " [kG]" << endl; cout << " TpcBx[NTPCM] = { "; - for (int i = 0; i < NTPCM; i++) { + for (int32_t i = 0; i < NTPCM; i++) { cout << mTpcBx[i]; if (i < NTPCM - 1) { cout << ", "; @@ -46,7 +46,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " TpcBy[NTPCM] = { "; - for (int i = 0; i < NTPCM; i++) { + for (int32_t i = 0; i < NTPCM; i++) { cout << mTpcBy[i]; if (i < NTPCM - 1) { cout << ", "; @@ -56,7 +56,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " TpcBz[NTPCM] = { "; - for (int i = 0; i < NTPCM; i++) { + for (int32_t i = 0; i < NTPCM; i++) { cout << mTpcBz[i]; if (i < NTPCM - 1) { cout << ", "; @@ -69,7 +69,7 @@ void GPUTPCGMPolynomialField::Print() const << endl; cout << " TrdBx[NTRDM] = { "; - for (int i = 0; i < NTRDM; i++) { + for (int32_t i = 0; i < NTRDM; i++) { cout << mTrdBx[i]; if (i < NTRDM - 1) { cout << ", "; @@ -79,7 +79,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " TrdBy[NTRDM] = { "; - for (int i = 0; i < NTRDM; i++) { + for (int32_t i = 0; i < NTRDM; i++) { cout << mTrdBy[i]; if (i < NTRDM - 1) { cout << ", "; @@ -89,7 +89,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " TrdBz[NTRDM] = { "; - for (int i = 0; i < NTRDM; i++) { + for (int32_t i = 0; i < NTRDM; i++) { cout << mTrdBz[i]; if (i < NTRDM - 1) { cout << ", "; @@ -102,7 +102,7 @@ void GPUTPCGMPolynomialField::Print() const << endl; cout << " ItsBx[NITSM] = { "; - for (int i = 0; i < NITSM; i++) { + for (int32_t i = 0; i < NITSM; i++) { cout << mItsBx[i]; if (i < NITSM - 1) { cout << ", "; @@ -112,7 +112,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " ItsBy[NITSM] = { "; - for (int i = 0; i < NITSM; i++) { + for (int32_t i = 0; i < NITSM; i++) { cout << mItsBy[i]; if (i < NITSM - 1) { cout << ", "; @@ -122,7 +122,7 @@ void GPUTPCGMPolynomialField::Print() const } cout << " ItsBz[NITSM] = { "; - for (int i = 0; i < NITSM; i++) { + for (int32_t i = 0; i < NITSM; i++) { cout << mItsBz[i]; if (i < NITSM - 1) { cout << ", "; diff --git a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h index 448b9d48a9c3e..a7e38bc31fc14 100644 --- a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h +++ b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h @@ -56,9 +56,9 @@ class GPUTPCGMPolynomialField void Print() const; - static CONSTEXPR const int NTPCM = 10; // number of coefficients - static CONSTEXPR const int NTRDM = 20; // number of coefficients for the TRD field - static CONSTEXPR const int NITSM = 10; // number of coefficients for the ITS field + static CONSTEXPR const int32_t NTPCM = 10; // number of coefficients + static CONSTEXPR const int32_t NTRDM = 20; // number of coefficients for the TRD field + static CONSTEXPR const int32_t NITSM = 10; // number of coefficients for the ITS field GPUd() static void GetPolynomsTpc(float x, float y, float z, float f[NTPCM]); GPUd() static void GetPolynomsTrd(float x, float y, float z, float f[NTRDM]); @@ -99,17 +99,17 @@ class GPUTPCGMPolynomialField inline void GPUTPCGMPolynomialField::Reset() { mNominalBz = 0.f; - for (int i = 0; i < NTPCM; i++) { + for (int32_t i = 0; i < NTPCM; i++) { mTpcBx[i] = 0.f; mTpcBy[i] = 0.f; mTpcBz[i] = 0.f; } - for (int i = 0; i < NTRDM; i++) { + for (int32_t i = 0; i < NTRDM; i++) { mTrdBx[i] = 0.f; mTrdBy[i] = 0.f; mTrdBz[i] = 0.f; } - for (int i = 0; i < NITSM; i++) { + for (int32_t i = 0; i < NITSM; i++) { mItsBx[i] = 0.f; mItsBy[i] = 0.f; mItsBz[i] = 0.f; @@ -121,7 +121,7 @@ inline void GPUTPCGMPolynomialField::SetFieldNominal(float nominalBz) { mNominal inline void GPUTPCGMPolynomialField::SetFieldTpc(const float* Bx, const float* By, const float* Bz) { if (Bx && By && Bz) { - for (int i = 0; i < NTPCM; i++) { + for (int32_t i = 0; i < NTPCM; i++) { mTpcBx[i] = Bx[i]; mTpcBy[i] = By[i]; mTpcBz[i] = Bz[i]; @@ -132,7 +132,7 @@ inline void GPUTPCGMPolynomialField::SetFieldTpc(const float* Bx, const float* B inline void GPUTPCGMPolynomialField::SetFieldTrd(const float* Bx, const float* By, const float* Bz) { if (Bx && By && Bz) { - for (int i = 0; i < NTRDM; i++) { + for (int32_t i = 0; i < NTRDM; i++) { mTrdBx[i] = Bx[i]; mTrdBy[i] = By[i]; mTrdBz[i] = Bz[i]; @@ -143,7 +143,7 @@ inline void GPUTPCGMPolynomialField::SetFieldTrd(const float* Bx, const float* B inline void GPUTPCGMPolynomialField::SetFieldIts(const float* Bx, const float* By, const float* Bz) { if (Bx && By && Bz) { - for (int i = 0; i < NITSM; i++) { + for (int32_t i = 0; i < NITSM; i++) { mItsBx[i] = Bx[i]; mItsBy[i] = By[i]; mItsBz[i] = Bz[i]; @@ -173,8 +173,8 @@ GPUdi() void GPUTPCGMPolynomialField::GetField(float x, float y, float z, float* const float f[NTPCM - 1] = {x, y, z, x * x, x * y, x * z, y * y, y * z, z * z}; float bx = mTpcBx[0], by = mTpcBy[0], bz = mTpcBz[0]; - for (int i = NTPCM - 1; i--;) { - // for (int i=0;i= GPUCA_NSLICES / 2) ? -u : u; } - GPUd() static float LinearTime2Z(int slice, float time) + GPUd() static float LinearTime2Z(int32_t slice, float time) { const float v = 250.f - time * FACTOR_T2Z; // Used in compression, must remain constant at 250cm! return (slice >= GPUCA_NSLICES / 2) ? -v : v; } - GPUd() float LinearY2Pad(int slice, int row, float y) const + GPUd() float LinearY2Pad(int32_t slice, int32_t row, float y) const { const float u = (slice >= GPUCA_NSLICES / 2) ? -y : y; return u / PadWidth(row) + 0.5f * mNPads[row]; } - GPUd() static float LinearZ2Time(int slice, float z) + GPUd() static float LinearZ2Time(int32_t slice, float z) { const float v = (slice >= GPUCA_NSLICES / 2) ? -z : z; return (250.f - v) * FACTOR_Z2T; // Used in compression, must remain constant at 250cm diff --git a/GPU/GPUTracking/DataTypes/GPUTRDInterfaceO2Track.h b/GPU/GPUTracking/DataTypes/GPUTRDInterfaceO2Track.h index f9998809a186b..86bf799e1fb17 100644 --- a/GPU/GPUTracking/DataTypes/GPUTRDInterfaceO2Track.h +++ b/GPU/GPUTracking/DataTypes/GPUTRDInterfaceO2Track.h @@ -56,10 +56,10 @@ class trackInterface : public o2::track::TrackParCov { setX(x); setAlpha(alpha); - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { setParam(param[i], i); } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { setCov(cov[i], i); } } @@ -75,12 +75,12 @@ class trackInterface : public o2::track::TrackParCov GPUdi() bool CheckNumericalQuality() const { return true; } - GPUdi() void setPileUpDistance(unsigned char bwd, unsigned char fwd) { setUserField((((unsigned short)bwd) << 8) | fwd); } + GPUdi() void setPileUpDistance(uint8_t bwd, uint8_t fwd) { setUserField((((uint16_t)bwd) << 8) | fwd); } GPUdi() bool hasPileUpInfo() const { return getUserField() != 0; } GPUdi() bool hasPileUpInfoBothSides() const { return getPileUpDistanceBwd() > 0 && getPileUpDistanceFwd() > 0; } - GPUdi() unsigned char getPileUpDistanceBwd() const { return getUserField() >> 8; } - GPUdi() unsigned char getPileUpDistanceFwd() const { return getUserField() & 255; } - GPUdi() unsigned short getPileUpSpan() const { return ((unsigned short)getPileUpDistanceBwd()) + getPileUpDistanceFwd(); } + GPUdi() uint8_t getPileUpDistanceBwd() const { return getUserField() >> 8; } + GPUdi() uint8_t getPileUpDistanceFwd() const { return getUserField() & 255; } + GPUdi() uint16_t getPileUpSpan() const { return ((uint16_t)getPileUpDistanceBwd()) + getPileUpDistanceFwd(); } GPUdi() float getPileUpMean() const { return hasPileUpInfoBothSides() ? 0.5f * (getPileUpDistanceFwd() + getPileUpDistanceBwd()) : getPileUpDistanceFwd() + getPileUpDistanceBwd(); } GPUdi() float getPileUpTimeShiftMUS() const { return getPileUpMean() * o2::constants::lhc::LHCBunchSpacingMUS; } GPUdi() float getPileUpTimeErrorMUS() const { return getPileUpSpan() * o2::constants::lhc::LHCBunchSpacingMUS / 3.4641016f; } diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrack.h b/GPU/GPUTracking/DataTypes/GPUTRDTrack.h index d99f65965f62e..437dd32154beb 100644 --- a/GPU/GPUTracking/DataTypes/GPUTRDTrack.h +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrack.h @@ -75,20 +75,20 @@ class GPUTRDTrack_t : public T GPUd() GPUTRDTrack_t& operator=(const GPUTRDTrack_t& t); // attach a tracklet to this track; this overwrites the mFlags flag to true for this layer - GPUd() void addTracklet(int iLayer, int idx) { mAttachedTracklets[iLayer] = idx; } + GPUd() void addTracklet(int32_t iLayer, int32_t idx) { mAttachedTracklets[iLayer] = idx; } // getters - GPUd() int getNlayersFindable() const; - GPUd() int getTrackletIndex(int iLayer) const { return mAttachedTracklets[iLayer]; } - GPUd() unsigned int getRefGlobalTrackIdRaw() const { return mRefGlobalTrackId; } + GPUd() int32_t getNlayersFindable() const; + GPUd() int32_t getTrackletIndex(int32_t iLayer) const { return mAttachedTracklets[iLayer]; } + GPUd() uint32_t getRefGlobalTrackIdRaw() const { return mRefGlobalTrackId; } // This method is only defined in TrackTRD.h and is intended to be used only with that TRD track type GPUd() o2::dataformats::GlobalTrackID getRefGlobalTrackId() const; - GPUd() short getCollisionId() const { return mCollisionId; } - GPUd() int getNtracklets() const + GPUd() int16_t getCollisionId() const { return mCollisionId; } + GPUd() int32_t getNtracklets() const { // returns number of tracklets attached to this track - int retVal = 0; - for (int iLy = 0; iLy < kNLayers; ++iLy) { + int32_t retVal = 0; + for (int32_t iLy = 0; iLy < kNLayers; ++iLy) { if (mAttachedTracklets[iLy] >= 0) { ++retVal; } @@ -98,32 +98,32 @@ class GPUTRDTrack_t : public T GPUd() float getChi2() const { return mChi2; } GPUd() float getSignal() const { return mSignal; } - GPUd() unsigned char getIsCrossingNeighbor() const { return mIsCrossingNeighbor; } - GPUd() bool getIsCrossingNeighbor(int iLayer) const { return mIsCrossingNeighbor & (1 << iLayer); } + GPUd() uint8_t getIsCrossingNeighbor() const { return mIsCrossingNeighbor; } + GPUd() bool getIsCrossingNeighbor(int32_t iLayer) const { return mIsCrossingNeighbor & (1 << iLayer); } GPUd() bool getHasNeighbor() const { return mIsCrossingNeighbor & (1 << 6); } GPUd() bool getHasPadrowCrossing() const { return mIsCrossingNeighbor & (1 << 7); } GPUd() float getReducedChi2() const { return getNlayersFindable() == 0 ? mChi2 : mChi2 / getNlayersFindable(); } GPUd() bool getIsStopped() const { return (mFlags >> kStopFlag) & 0x1; } GPUd() bool getIsAmbiguous() const { return (mFlags >> kAmbiguousFlag) & 0x1; } - GPUd() bool getIsFindable(int iLayer) const { return (mFlags >> iLayer) & 0x1; } - GPUd() int getNmissingConsecLayers(int iLayer) const; - GPUd() int getIsPenaltyAdded(int iLayer) const { return getIsFindable(iLayer) && getTrackletIndex(iLayer) < 0; } + GPUd() bool getIsFindable(int32_t iLayer) const { return (mFlags >> iLayer) & 0x1; } + GPUd() int32_t getNmissingConsecLayers(int32_t iLayer) const; + GPUd() int32_t getIsPenaltyAdded(int32_t iLayer) const { return getIsFindable(iLayer) && getTrackletIndex(iLayer) < 0; } // for AliRoot compatibility. To be removed once HLT/global/AliHLTGlobalEsdConverterComponent.cxx does not require them anymore - GPUd() int GetTPCtrackId() const { return mRefGlobalTrackId; } + GPUd() int32_t GetTPCtrackId() const { return mRefGlobalTrackId; } GPUd() bool GetIsStopped() const { return getIsStopped(); } - GPUd() int GetNtracklets() const { return getNtracklets(); } + GPUd() int32_t GetNtracklets() const { return getNtracklets(); } // setters - GPUd() void setRefGlobalTrackIdRaw(unsigned int id) { mRefGlobalTrackId = id; } + GPUd() void setRefGlobalTrackIdRaw(uint32_t id) { mRefGlobalTrackId = id; } // This method is only defined in TrackTRD.h and is intended to be used only with that TRD track type GPUd() void setRefGlobalTrackId(o2::dataformats::GlobalTrackID id); - GPUd() void setCollisionId(short id) { mCollisionId = id; } - GPUd() void setIsFindable(int iLayer) { mFlags |= (1U << iLayer); } + GPUd() void setCollisionId(int16_t id) { mCollisionId = id; } + GPUd() void setIsFindable(int32_t iLayer) { mFlags |= (1U << iLayer); } GPUd() void setIsStopped() { mFlags |= (1U << kStopFlag); } GPUd() void setIsAmbiguous() { mFlags |= (1U << kAmbiguousFlag); } GPUd() void setChi2(float chi2) { mChi2 = chi2; } GPUd() void setSignal(float signal) { mSignal = signal; } - GPUd() void setIsCrossingNeighbor(int iLayer) { mIsCrossingNeighbor |= (1U << iLayer); } + GPUd() void setIsCrossingNeighbor(int32_t iLayer) { mIsCrossingNeighbor |= (1U << iLayer); } GPUd() void setHasNeighbor() { mIsCrossingNeighbor |= (1U << 6); } GPUd() void setHasPadrowCrossing() { mIsCrossingNeighbor |= (1U << 7); } @@ -134,11 +134,11 @@ class GPUTRDTrack_t : public T protected: float mChi2; // total chi2. float mSignal{-1.f}; // electron Likelihood for track - unsigned int mRefGlobalTrackId; // raw GlobalTrackID of the seeding track (either ITS-TPC or TPC) - int mAttachedTracklets[kNLayers]; // indices of the tracklets attached to this track; -1 means no tracklet in that layer - short mCollisionId; // the collision ID of the tracklets attached to this track; is used to retrieve the BC information for this track after the tracking is done - unsigned char mFlags; // bits 0 to 5 indicate whether track is findable in layer 0 to 5, bit 6 indicates an ambiguous track and bit 7 flags if the track is stopped in the TRD - unsigned char mIsCrossingNeighbor; // bits 0 to 5 indicate if a tracklet was either a neighboring tracklet (e.g. a potential split tracklet) or crossed a padrow, bit 6 indicates that a neighbor in any layer has been found and bit 7 if a padrow was crossed + uint32_t mRefGlobalTrackId; // raw GlobalTrackID of the seeding track (either ITS-TPC or TPC) + int32_t mAttachedTracklets[kNLayers]; // indices of the tracklets attached to this track; -1 means no tracklet in that layer + int16_t mCollisionId; // the collision ID of the tracklets attached to this track; is used to retrieve the BC information for this track after the tracking is done + uint8_t mFlags; // bits 0 to 5 indicate whether track is findable in layer 0 to 5, bit 6 indicates an ambiguous track and bit 7 flags if the track is stopped in the TRD + uint8_t mIsCrossingNeighbor; // bits 0 to 5 indicate if a tracklet was either a neighboring tracklet (e.g. a potential split tracklet) or crossed a padrow, bit 6 indicates that a neighbor in any layer has been found and bit 7 if a padrow was crossed private: GPUd() void initialize(); diff --git a/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc b/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc index bba48e6cfc7a1..44617680580f2 100644 --- a/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc +++ b/GPU/GPUTracking/DataTypes/GPUTRDTrack.inc @@ -34,7 +34,7 @@ GPUd() void GPUTRDTrack_t::initialize() mCollisionId = -1; mFlags = 0; mIsCrossingNeighbor = 0; - for (int i = 0; i < kNLayers; ++i) { + for (int32_t i = 0; i < kNLayers; ++i) { mAttachedTracklets[i] = -1; } } @@ -62,11 +62,11 @@ GPUd() void GPUTRDTrack_t::ConvertTo(GPUTRDTrackDataRecord& t) const t.fq1Pt = T::getQ2Pt(); t.mSinPhi = T::getSnp(); t.fTgl = T::getTgl(); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { t.fC[i] = T::getCov()[i]; } t.fTPCTrackID = getRefGlobalTrackIdRaw(); - for (int i = 0; i < kNLayers; i++) { + for (int32_t i = 0; i < kNLayers; i++) { t.fAttachedTracklets[i] = getTrackletIndex(i); } } @@ -84,7 +84,7 @@ GPUd() void GPUTRDTrack_t::ConvertFrom(const GPUTRDTrackDataRecord& t) mFlags = 0; mIsCrossingNeighbor = 0; mCollisionId = -1; - for (int iLayer = 0; iLayer < kNLayers; iLayer++) { + for (int32_t iLayer = 0; iLayer < kNLayers; iLayer++) { mAttachedTracklets[iLayer] = t.fAttachedTracklets[iLayer]; } } @@ -114,7 +114,7 @@ GPUd() GPUTRDTrack_t::GPUTRDTrack_t(const GPUTRDTrack_t& t) : T(t), mChi2(t.mChi2), mSignal(t.mSignal), mRefGlobalTrackId(t.mRefGlobalTrackId), mCollisionId(t.mCollisionId), mFlags(t.mFlags), mIsCrossingNeighbor(t.mIsCrossingNeighbor) { // copy constructor - for (int i = 0; i < kNLayers; ++i) { + for (int32_t i = 0; i < kNLayers; ++i) { mAttachedTracklets[i] = t.mAttachedTracklets[i]; } } @@ -140,18 +140,18 @@ GPUd() GPUTRDTrack_t& GPUTRDTrack_t::operator=(const GPUTRDTrack_t& t) mCollisionId = t.mCollisionId; mFlags = t.mFlags; mIsCrossingNeighbor = t.mIsCrossingNeighbor; - for (int i = 0; i < kNLayers; ++i) { + for (int32_t i = 0; i < kNLayers; ++i) { mAttachedTracklets[i] = t.mAttachedTracklets[i]; } return *this; } template -GPUd() int GPUTRDTrack_t::getNlayersFindable() const +GPUd() int32_t GPUTRDTrack_t::getNlayersFindable() const { // returns number of layers in which the track is in active area of TRD - int retVal = 0; - for (int iLy = 0; iLy < kNLayers; iLy++) { + int32_t retVal = 0; + for (int32_t iLy = 0; iLy < kNLayers; iLy++) { if ((mFlags >> iLy) & 0x1) { ++retVal; } @@ -160,11 +160,11 @@ GPUd() int GPUTRDTrack_t::getNlayersFindable() const } template -GPUd() int GPUTRDTrack_t::getNmissingConsecLayers(int iLayer) const +GPUd() int32_t GPUTRDTrack_t::getNmissingConsecLayers(int32_t iLayer) const { // returns number of consecutive layers in which the track was // inside the deadzone up to (and including) the given layer - int retVal = 0; + int32_t retVal = 0; while (!getIsFindable(iLayer)) { ++retVal; --iLayer; diff --git a/GPU/GPUTracking/DataTypes/GPUTriggerOutputs.h b/GPU/GPUTracking/DataTypes/GPUTriggerOutputs.h index 0a3208f8e67a7..76de1116999ff 100644 --- a/GPU/GPUTracking/DataTypes/GPUTriggerOutputs.h +++ b/GPU/GPUTracking/DataTypes/GPUTriggerOutputs.h @@ -32,9 +32,9 @@ struct GPUTriggerOutputs { struct hasher { size_t operator()(const o2::tpc::TriggerInfoDLBZS& key) const { - std::array tmp; + std::array tmp; memcpy((void*)tmp.data(), (const void*)&key, sizeof(key)); - std::hash std_hasher; + std::hash std_hasher; size_t result = 0; for (size_t i = 0; i < tmp.size(); ++i) { result ^= std_hasher(tmp[i]); @@ -51,7 +51,7 @@ struct GPUTriggerOutputs { }; std::unordered_set triggers; - static_assert(sizeof(o2::tpc::TriggerInfoDLBZS) % sizeof(unsigned int) == 0); + static_assert(sizeof(o2::tpc::TriggerInfoDLBZS) % sizeof(uint32_t) == 0); #endif }; diff --git a/GPU/GPUTracking/DataTypes/TPCPadBitMap.cxx b/GPU/GPUTracking/DataTypes/TPCPadBitMap.cxx index 82ddeecfb43f7..cb32cad984664 100644 --- a/GPU/GPUTracking/DataTypes/TPCPadBitMap.cxx +++ b/GPU/GPUTracking/DataTypes/TPCPadBitMap.cxx @@ -22,8 +22,8 @@ using namespace GPUCA_NAMESPACE::gpu; TPCPadBitMap::TPCPadBitMap() { GPUTPCGeometry geo{}; - int offset = 0; - for (int r = 0; r < GPUCA_ROW_COUNT; r++) { + int32_t offset = 0; + for (int32_t r = 0; r < GPUCA_ROW_COUNT; r++) { mPadOffsetPerRow[r] = offset; offset += geo.NPads(r); } @@ -39,8 +39,8 @@ TPCPadBitMap::TPCPadBitMap(const o2::tpc::CalDet& map) : TPCPadBitMap() void TPCPadBitMap::setFromMap(const o2::tpc::CalDet& map) { - for (int sector = 0; sector < o2::tpc::constants::MAXSECTOR; sector++) { - for (int p = 0; p < TPC_PADS_IN_SECTOR; p++) { + for (int32_t sector = 0; sector < o2::tpc::constants::MAXSECTOR; sector++) { + for (int32_t p = 0; p < TPC_PADS_IN_SECTOR; p++) { const auto val = map.getValue(sector, p); mBitMap[sector].set(p, val); } diff --git a/GPU/GPUTracking/DataTypes/TPCPadBitMap.h b/GPU/GPUTracking/DataTypes/TPCPadBitMap.h index 756c6df06d0f2..591ca927e57c5 100644 --- a/GPU/GPUTracking/DataTypes/TPCPadBitMap.h +++ b/GPU/GPUTracking/DataTypes/TPCPadBitMap.h @@ -37,27 +37,27 @@ struct TPCPadBitMap { void setFromMap(const o2::tpc::CalDet&); #endif - GPUdi() void set(int sector, tpccf::Row row, tpccf::Pad pad, bool c) + GPUdi() void set(int32_t sector, tpccf::Row row, tpccf::Pad pad, bool c) { mBitMap[sector].set(globalPad(row, pad), c); } - GPUdi() void set(int sector, unsigned short globalPad, bool c) + GPUdi() void set(int32_t sector, uint16_t globalPad, bool c) { mBitMap[sector].set(globalPad, c); } - GPUdi() bool isSet(int sector, tpccf::Row row, tpccf::Pad pad) const + GPUdi() bool isSet(int32_t sector, tpccf::Row row, tpccf::Pad pad) const { return mBitMap[sector].get(globalPad(row, pad)); } - GPUdi() bool isSet(int sector, unsigned short globalPad) const + GPUdi() bool isSet(int32_t sector, uint16_t globalPad) const { return mBitMap[sector].get(globalPad); } - GPUdi() unsigned short globalPad(tpccf::Row row, tpccf::Pad pad) const + GPUdi() uint16_t globalPad(tpccf::Row row, tpccf::Pad pad) const { return mPadOffsetPerRow[row] + pad; } @@ -67,14 +67,14 @@ struct TPCPadBitMap { class SectorBitMap { public: - using T = unsigned int; - static constexpr int NWORDS = (TPC_PADS_IN_SECTOR + sizeof(T) * 8 - 1) / sizeof(T); + using T = uint32_t; + static constexpr int32_t NWORDS = (TPC_PADS_IN_SECTOR + sizeof(T) * 8 - 1) / sizeof(T); GPUdi() SectorBitMap() { reset(); } - GPUdi() void set(unsigned short globalPad, bool c) + GPUdi() void set(uint16_t globalPad, bool c) { const auto word = globalPad / (sizeof(T) * 8); const auto pos = globalPad % (sizeof(T) * 8); @@ -82,7 +82,7 @@ struct TPCPadBitMap { mDeadChannelMap[word] = (mDeadChannelMap[word] & ~mask) | (T(c) << pos); } - GPUdi() bool get(unsigned short globalPad) const + GPUdi() bool get(uint16_t globalPad) const { const auto word = globalPad / (sizeof(T) * 8); const auto pos = globalPad % (sizeof(T) * 8); @@ -92,7 +92,7 @@ struct TPCPadBitMap { GPUd() void reset() { - for (int iword = 0; iword < NWORDS; ++iword) { + for (int32_t iword = 0; iword < NWORDS; ++iword) { mDeadChannelMap[iword] = 0; } } @@ -101,7 +101,7 @@ struct TPCPadBitMap { T mDeadChannelMap[NWORDS]; }; - unsigned short mPadOffsetPerRow[GPUCA_ROW_COUNT]; + uint16_t mPadOffsetPerRow[GPUCA_ROW_COUNT]; SectorBitMap mBitMap[GPUCA_NSLICES]; }; diff --git a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.cxx b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.cxx index 4ad3f36867341..198f6713a44a1 100644 --- a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.cxx +++ b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.cxx @@ -22,8 +22,8 @@ using namespace GPUCA_NAMESPACE::gpu; TPCPadGainCalib::TPCPadGainCalib() { GPUTPCGeometry geo{}; - int offset = 0; - for (int r = 0; r < GPUCA_ROW_COUNT; r++) { + int32_t offset = 0; + for (int32_t r = 0; r < GPUCA_ROW_COUNT; r++) { mPadOffsetPerRow[r] = offset; offset += geo.NPads(r); } @@ -46,8 +46,8 @@ TPCPadGainCalib::TPCPadGainCalib(const o2::tpc::CalDet& gainMap, const fl void TPCPadGainCalib::setFromMap(const o2::tpc::CalDet& gainMap, const bool inv) { - for (int sector = 0; sector < o2::tpc::constants::MAXSECTOR; sector++) { - for (int p = 0; p < TPC_PADS_IN_SECTOR; p++) { + for (int32_t sector = 0; sector < o2::tpc::constants::MAXSECTOR; sector++) { + for (int32_t p = 0; p < TPC_PADS_IN_SECTOR; p++) { const float gainVal = gainMap.getValue(sector, p); inv ? mGainCorrection[sector].set(p, (gainVal > 1.e-5f) ? 1.f / gainVal : 1.f) : mGainCorrection[sector].set(p, gainVal); } diff --git a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h index 6e54174a2059b..e7908a4b87efc 100644 --- a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h +++ b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h @@ -32,13 +32,13 @@ struct TPCPadGainCorrectionStepNum { }; template <> -struct TPCPadGainCorrectionStepNum { - static constexpr int value = 254; +struct TPCPadGainCorrectionStepNum { + static constexpr int32_t value = 254; }; template <> -struct TPCPadGainCorrectionStepNum { - static constexpr int value = 65534; +struct TPCPadGainCorrectionStepNum { + static constexpr int32_t value = 65534; }; struct TPCPadGainCalib { @@ -59,68 +59,68 @@ struct TPCPadGainCalib { #endif // Deal with pad gain correction from here on - GPUdi() void setGainCorrection(int sector, tpccf::Row row, tpccf::Pad pad, float c) + GPUdi() void setGainCorrection(int32_t sector, tpccf::Row row, tpccf::Pad pad, float c) { mGainCorrection[sector].set(globalPad(row, pad), c); } - GPUdi() void setGainCorrection(int sector, unsigned short globalPad, float c) + GPUdi() void setGainCorrection(int32_t sector, uint16_t globalPad, float c) { mGainCorrection[sector].set(globalPad, c); } - GPUdi() float getGainCorrection(int sector, tpccf::Row row, tpccf::Pad pad) const + GPUdi() float getGainCorrection(int32_t sector, tpccf::Row row, tpccf::Pad pad) const { return mGainCorrection[sector].get(globalPad(row, pad)); } - GPUdi() unsigned short globalPad(tpccf::Row row, tpccf::Pad pad) const + GPUdi() uint16_t globalPad(tpccf::Row row, tpccf::Pad pad) const { return mPadOffsetPerRow[row] + pad; } GPUdi() void setMinCorrectionFactor(const float minCorrectionFactor) { - for (int sector = 0; sector < GPUCA_NSLICES; sector++) { + for (int32_t sector = 0; sector < GPUCA_NSLICES; sector++) { mGainCorrection[sector].mMinCorrectionFactor = minCorrectionFactor; } } GPUdi() void setMaxCorrectionFactor(const float maxCorrectionFactor) { - for (int sector = 0; sector < GPUCA_NSLICES; sector++) { + for (int32_t sector = 0; sector < GPUCA_NSLICES; sector++) { mGainCorrection[sector].mMaxCorrectionFactor = maxCorrectionFactor; } } private: - template + template class SectorPadGainCorrection { public: float mMinCorrectionFactor = 0.f; float mMaxCorrectionFactor = 2.f; - constexpr static int NumOfSteps = TPCPadGainCorrectionStepNum::value; + constexpr static int32_t NumOfSteps = TPCPadGainCorrectionStepNum::value; GPUdi() SectorPadGainCorrection() { reset(); } - GPUdi() void set(unsigned short globalPad, float c) + GPUdi() void set(uint16_t globalPad, float c) { at(globalPad) = pack(c); } - GPUdi() float get(unsigned short globalPad) const + GPUdi() float get(uint16_t globalPad) const { return unpack(at(globalPad)); } GPUd() void reset() { - for (unsigned short p = 0; p < TPC_PADS_IN_SECTOR; p++) { + for (uint16_t p = 0; p < TPC_PADS_IN_SECTOR; p++) { set(p, 1.0f); } } @@ -142,19 +142,19 @@ struct TPCPadGainCalib { T mGainCorrection[TPC_PADS_IN_SECTOR]; - GPUdi() T& at(unsigned short globalPad) + GPUdi() T& at(uint16_t globalPad) { return mGainCorrection[globalPad]; } - GPUdi() const T& at(unsigned short globalPad) const + GPUdi() const T& at(uint16_t globalPad) const { return mGainCorrection[globalPad]; } }; - unsigned short mPadOffsetPerRow[GPUCA_ROW_COUNT]; - SectorPadGainCorrection mGainCorrection[GPUCA_NSLICES]; + uint16_t mPadOffsetPerRow[GPUCA_ROW_COUNT]; + SectorPadGainCorrection mGainCorrection[GPUCA_NSLICES]; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/Debug/GPUROOTDumpCore.cxx b/GPU/GPUTracking/Debug/GPUROOTDumpCore.cxx index 8007662ce6148..a0b560f119373 100644 --- a/GPU/GPUTracking/Debug/GPUROOTDumpCore.cxx +++ b/GPU/GPUTracking/Debug/GPUROOTDumpCore.cxx @@ -30,7 +30,7 @@ GPUROOTDumpCore::GPUROOTDumpCore(GPUROOTDumpCore::GPUROOTDumpCorePrivate) GPUROOTDumpCore::~GPUROOTDumpCore() { if (mFile) { - for (unsigned int i = 0; i < mBranches.size(); i++) { + for (uint32_t i = 0; i < mBranches.size(); i++) { mBranches[i]->write(); } mFile->Close(); diff --git a/GPU/GPUTracking/Definitions/GPUDef.h b/GPU/GPUTracking/Definitions/GPUDef.h index c7d9cb00d367c..abc6bb04291d3 100644 --- a/GPU/GPUTracking/Definitions/GPUDef.h +++ b/GPU/GPUTracking/Definitions/GPUDef.h @@ -22,9 +22,9 @@ #include "GPUDefOpenCL12Templates.h" #include "GPUCommonRtypes.h" -// Macros for masking ptrs in OpenCL kernel calls as unsigned long (The API only allows us to pass buffer objects) +// Macros for masking ptrs in OpenCL kernel calls as uint64_t (The API only allows us to pass buffer objects) #ifdef __OPENCL__ - #define GPUPtr1(a, b) unsigned long b + #define GPUPtr1(a, b) uint64_t b #define GPUPtr2(a, b) ((__global a) (a) b) #else #define GPUPtr1(a, b) a b @@ -41,9 +41,9 @@ #define CA_MAKE_SHARED_REF(vartype, varname, varglobal, varshared) const GPUsharedref() MEM_LOCAL(vartype) & __restrict__ varname = varshared; #define CA_SHARED_STORAGE(storage) storage #define CA_SHARED_CACHE(target, src, size) \ - static_assert((size) % sizeof(int) == 0, "Invalid shared cache size"); \ - for (unsigned int i_shared_cache = get_local_id(0); i_shared_cache < (size) / sizeof(int); i_shared_cache += get_local_size(0)) { \ - reinterpret_cast(target)[i_shared_cache] = reinterpret_cast(src)[i_shared_cache]; \ + static_assert((size) % sizeof(int32_t) == 0, "Invalid shared cache size"); \ + for (uint32_t i_shared_cache = get_local_id(0); i_shared_cache < (size) / sizeof(int32_t); i_shared_cache += get_local_size(0)) { \ + reinterpret_cast(target)[i_shared_cache] = reinterpret_cast(src)[i_shared_cache]; \ } #define CA_SHARED_CACHE_REF(target, src, size, reftype, ref) \ CA_SHARED_CACHE(target, src, size) \ diff --git a/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h b/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h index 9ab78d034d8bf..970e1b2926853 100644 --- a/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h +++ b/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h @@ -91,7 +91,7 @@ #define GPUCA_MERGER_SPLIT_LOOP_INTERPOLATION 1 #define GPUCA_TRACKLET_SELECTOR_SLICE_COUNT 1 #define GPUCA_NO_ATOMIC_PRECHECK 1 - #define GPUCA_DEDX_STORAGE_TYPE unsigned short + #define GPUCA_DEDX_STORAGE_TYPE uint16_t #define GPUCA_MERGER_INTERPOLATION_ERROR_TYPE half #define GPUCA_COMP_GATHER_KERNEL 4 #define GPUCA_COMP_GATHER_MODE 3 @@ -157,7 +157,7 @@ #define GPUCA_MERGER_SPLIT_LOOP_INTERPOLATION 1 #define GPUCA_TRACKLET_SELECTOR_SLICE_COUNT 1 #define GPUCA_NO_ATOMIC_PRECHECK 1 - #define GPUCA_DEDX_STORAGE_TYPE unsigned short + #define GPUCA_DEDX_STORAGE_TYPE uint16_t #define GPUCA_MERGER_INTERPOLATION_ERROR_TYPE half #define GPUCA_COMP_GATHER_KERNEL 4 #define GPUCA_COMP_GATHER_MODE 3 @@ -223,7 +223,7 @@ #define GPUCA_MERGER_SPLIT_LOOP_INTERPOLATION 1 #define GPUCA_TRACKLET_SELECTOR_SLICE_COUNT 1 #define GPUCA_NO_ATOMIC_PRECHECK 1 - #define GPUCA_DEDX_STORAGE_TYPE unsigned short + #define GPUCA_DEDX_STORAGE_TYPE uint16_t #define GPUCA_MERGER_INTERPOLATION_ERROR_TYPE half #define GPUCA_COMP_GATHER_KERNEL 4 #define GPUCA_COMP_GATHER_MODE 3 @@ -283,7 +283,7 @@ #define GPUCA_NO_ATOMIC_PRECHECK 1 #define GPUCA_COMP_GATHER_KERNEL 4 #define GPUCA_COMP_GATHER_MODE 3 - #define GPUCA_DEDX_STORAGE_TYPE unsigned short + #define GPUCA_DEDX_STORAGE_TYPE uint16_t #define GPUCA_MERGER_INTERPOLATION_ERROR_TYPE half // #define GPUCA_USE_TEXTURES #elif defined(GPUCA_GPUTYPE_OPENCL) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 26a6168faecbb..745e519fcc404 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -34,7 +34,7 @@ BeginNamespace(GPUCA_NAMESPACE) BeginNamespace(gpu) // Settings concerning the reconstruction, stored as parameters in GPU constant memory -// There must be no bool in here, use char, as sizeof(bool) is compiler dependent and fails on GPUs!!!!!! +// There must be no bool in here, use int8_t, as sizeof(bool) is compiler dependent and fails on GPUs!!!!!! BeginSubConfig(GPUSettingsRecTPC, tpc, configStandalone.rec, "RECTPC", 0, "Reconstruction settings", rec_tpc) AddOptionRTC(rejectQPtB5, float, 1.f / GPUCA_MIN_TRACK_PTB5_REJECT_DEFAULT, "", 0, "QPt threshold to reject clusters of TPC tracks (Inverse Pt, scaled to B=0.5T!!!)") AddOptionRTC(hitPickUpFactor, float, 1.f, "", 0, "multiplier for the combined cluster+track error during track following") @@ -60,8 +60,8 @@ AddOptionRTC(sysClusErrorMinDist, float, 1.5f, "", 0, "Systematic cluster error AddOptionRTC(sysClusErrorMaskError, float, 5.f, "", 0, "Systematic cluster error parameterization IFC Large Error for masking") AddOptionRTC(sysClusErrorC12Norm, float, 5.3333333e-06f, "", 0, "Systematic cluster for Sector C1/2 normalization") AddOptionRTC(sysClusErrorC12Box, float, 1.1e-05f, "", 0, "Systematic cluster for Sector C1/2 box size") -AddOptionRTC(minNClustersTrackSeed, int, -1, "", 0, "required min number of clusters on the track after track following (before merging)") -AddOptionRTC(minNClustersFinalTrack, int, -1, "", 0, "required min number of clusters on the final track") +AddOptionRTC(minNClustersTrackSeed, int32_t, -1, "", 0, "required min number of clusters on the track after track following (before merging)") +AddOptionRTC(minNClustersFinalTrack, int32_t, -1, "", 0, "required min number of clusters on the final track") AddOptionRTC(searchWindowDZDR, float, 2.5f, "", 0, "Use DZDR window for seeding instead of neighboursSearchArea") AddOptionRTC(trackReferenceX, float, 1000.f, "", 0, "Transport all tracks to this X after tracking (disabled if > 500, auto = 1000)") AddOptionRTC(zsThreshold, float, 2.0f, "", 0, "Zero-Suppression threshold") @@ -101,61 +101,61 @@ AddOptionRTC(rejectEdgeClustersMargin, float, 0.f, "", 0, "Margin in cm of Y pos AddOptionRTC(rejectEdgeClustersSigmaMargin, float, 0.f, "", 0, "Margin factor for trackSigmaY when rejecting edge clusters based on uncorrected track Y") AddOptionRTC(trackletMaxSharedFraction, float, 0.1f, "", 0, "Max fraction of shared clusters for tracklet") AddOptionRTC(trackletMinSharedNormFactor, float, 0.f, "", 0, "Max shared defined as trackletMinSharedNormFactor*max(current_nhits,trackletMinSharedNormFactor*minHits,1)") -AddOptionRTC(maxTimeBinAboveThresholdIn1000Bin, unsigned short, 500, "", 0, "Except pad from cluster finding if total number of charges in a fragment is above this baseline (disable = 0)") -AddOptionRTC(maxConsecTimeBinAboveThreshold, unsigned short, 200, "", 0, "Except pad from cluster finding if number of consecutive charges in a fragment is above this baseline (disable = 0)") -AddOptionRTC(noisyPadSaturationThreshold, unsigned short, 700, "", 0, "Threshold where a timebin is considered saturated, disabling the noisy pad check for that pad") -AddOptionRTC(occupancyMapTimeBins, unsigned short, 16, "", 0, "Number of timebins per histogram bin of occupancy map (0 = disable occupancy map)") -AddOptionRTC(occupancyMapTimeBinsAverage, unsigned short, 0, "", 0, "Number of timebins +/- to use for the averaging") -AddOptionRTC(trackFitCovLimit, unsigned short, 1000, "", 0, "Abort fit when y/z cov exceed the limit") -AddOptionRTC(addErrorsCECrossing, unsigned char, 0, "", 0, "Add additional custom track errors when crossing CE, 0 = no custom errors but att 0.5 to sigma_z^2, 1 = only to cov diagonal, 2 = preserve correlations") -AddOptionRTC(trackMergerMinPartHits, unsigned char, 10, "", 0, "Minimum hits of track part during track merging") -AddOptionRTC(trackMergerMinTotalHits, unsigned char, 20, "", 0, "Minimum total of track part during track merging") -AddOptionRTC(mergerCERowLimit, unsigned char, 5, "", 0, "Distance from first / last row in order to attempt merging accross CE") -AddOptionRTC(mergerLooperQPtB5Limit, unsigned char, 4, "", 0, "Min Q/Pt (@B=0.5T) to run special looper merging procedure") -AddOptionRTC(mergerLooperSecondHorizontalQPtB5Limit, unsigned char, 2, "", 0, "Min Q/Pt (@B=0.5T) to attempt second horizontal merge between slices after a vertical merge was found") -AddOptionRTC(trackFollowingMaxRowGap, unsigned char, 4, "", 0, "Maximum number of consecutive rows without hit in track following") -AddOptionRTC(trackFollowingMaxRowGapSeed, unsigned char, 2, "", 0, "Maximum number of consecutive rows without hit in track following during fit of seed") -AddOptionRTC(trackFitMaxRowMissedHard, unsigned char, 10, "", 0, "Hard limit for number of missed rows in fit / propagation") -AddOptionRTC(globalTrackingRowRange, unsigned char, 45, "", 0, "Number of rows from the upped/lower limit to search for global track candidates in for") -AddOptionRTC(globalTrackingMinRows, unsigned char, 10, "", 0, "Min num of rows an additional global track must span over") -AddOptionRTC(globalTrackingMinHits, unsigned char, 8, "", 0, "Min num of hits for an additional global track") -AddOptionRTC(noisyPadsQuickCheck, unsigned char, 1, "", 0, "Only check first fragment for noisy pads instead of all fragments (when test is enabled).") -AddOptionRTC(cfQMaxCutoff, unsigned char, 3, "", 0, "Cluster Finder rejects cluster with qmax below or equal to this threshold") -AddOptionRTC(cfQTotCutoff, unsigned char, 5, "", 0, "Cluster Finder rejects cluster with qtot below or equal to this threshold") -AddOptionRTC(cfQMaxCutoffSingleTime, unsigned char, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single time bin clusters") -AddOptionRTC(cfQMaxCutoffSinglePad, unsigned char, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single pad bin clusters") -AddOptionRTC(cfInnerThreshold, unsigned char, 0, "", 0, "Cluster Finder extends cluster if inner charge above this threshold") -AddOptionRTC(cfMinSplitNum, unsigned char, 1, "", 0, "Minimum number of split charges in a cluster for the cluster to be marked as split") -AddOptionRTC(cfNoiseSuppressionEpsilon, unsigned char, 10, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression") -AddOptionRTC(cfNoiseSuppressionEpsilonRelative, unsigned char, 76, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression, relative as fraction of 255") -AddOptionRTC(nWays, unsigned char, 3, "", 0, "Do N fit passes in final fit of merger") -AddOptionRTC(nWaysOuter, signed char, 0, "", 0, "Store outer param") -AddOptionRTC(trackFitRejectMode, signed char, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits, <0: reject at max -n hits") -AddOptionRTC(dEdxTruncLow, unsigned char, 2, "", 0, "Low truncation threshold, fraction of 128") -AddOptionRTC(dEdxTruncHigh, unsigned char, 77, "", 0, "High truncation threshold, fraction of 128") -AddOptionRTC(globalTracking, signed char, 1, "", 0, "Enable Global Tracking (prolong tracks to adjacent sectors to find short segments)") -AddOptionRTC(disableRefitAttachment, unsigned char, 0, "", 0, "Bitmask to disable certain attachment steps during refit (1: attachment, 2: propagation, 4: loop following, 8: mirroring)") -AddOptionRTC(rejectionStrategy, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression (0 = no, 1 = strategy A, 2 = strategy B)") -AddOptionRTC(mergeLoopersAfterburner, unsigned char, 1, "", 0, "Run afterburner for additional looper merging") -AddOptionRTC(compressionTypeMask, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits (1=truncate charge/width LSB, 2=differences, 4=track-model)") -AddOptionRTC(compressionSortOrder, unsigned char, GPUCA_NAMESPACE::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression (0 = time, 1 = pad, 2 = Z-time-pad, 3 = Z-pad-time, 4 = no sorting (use incoming order))") -AddOptionRTC(sigBitsCharge, unsigned char, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") -AddOptionRTC(sigBitsWidth, unsigned char, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") -AddOptionRTC(forceEarlyTransform, signed char, -1, "", 0, "Force early TPC transformation also for continuous data (-1 = auto)") -AddOptionRTC(dropLoopers, unsigned char, 0, "", 0, "Drop looping tracks starting from second loop") -AddOptionRTC(mergerCovSource, unsigned char, 2, "", 0, "Method to obtain covariance in track merger: 0 = simple filterErrors method, 1 = use cov from track following, 2 = refit (default)") -AddOptionRTC(mergerInterpolateErrors, unsigned char, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") -AddOptionRTC(mergeCE, unsigned char, 1, "", 0, "Merge tracks accross the central electrode") -AddOptionRTC(retryRefit, signed char, 1, "", 0, "Retry refit with seeding errors and without cluster rejection when fit fails (=2 means retry in same kernel, =1 for separate kernel") -AddOptionRTC(looperInterpolationInExtraPass, signed char, -1, "", 0, "Perform looper interpolation in an extra pass") -AddOptionRTC(mergerReadFromTrackerDirectly, signed char, 1, "", 0, "Forward data directly from tracker to merger on GPU") -AddOptionRTC(dropSecondaryLegsInOutput, signed char, 1, "", 0, "Do not store secondary legs of looping track in TrackTPC") -AddOptionRTC(enablePID, signed char, 1, "", 0, "Enable PID response") -AddOptionRTC(PID_useNsigma, signed char, 1, "", 0, "Use nSigma instead of absolute distance in PID response") -AddOptionRTC(adddEdxSubThresholdClusters, signed char, 1, "", 0, "Add sub threshold clusters in TPC dEdx computation") -AddOptionRTC(rejectEdgeClustersInSeeding, signed char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during seeding") -AddOptionRTC(rejectEdgeClustersInTrackFit, signed char, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit") -AddOptionArray(PID_remap, signed char, 9, (0, 1, 2, 3, 4, 5, 6, 7, 8), "", 0, "Remap Ipid to PID_reamp[Ipid] (no remap if<0)") // BUG: CUDA cannot yet hand AddOptionArrayRTC +AddOptionRTC(maxTimeBinAboveThresholdIn1000Bin, uint16_t, 500, "", 0, "Except pad from cluster finding if total number of charges in a fragment is above this baseline (disable = 0)") +AddOptionRTC(maxConsecTimeBinAboveThreshold, uint16_t, 200, "", 0, "Except pad from cluster finding if number of consecutive charges in a fragment is above this baseline (disable = 0)") +AddOptionRTC(noisyPadSaturationThreshold, uint16_t, 700, "", 0, "Threshold where a timebin is considered saturated, disabling the noisy pad check for that pad") +AddOptionRTC(occupancyMapTimeBins, uint16_t, 16, "", 0, "Number of timebins per histogram bin of occupancy map (0 = disable occupancy map)") +AddOptionRTC(occupancyMapTimeBinsAverage, uint16_t, 0, "", 0, "Number of timebins +/- to use for the averaging") +AddOptionRTC(trackFitCovLimit, uint16_t, 1000, "", 0, "Abort fit when y/z cov exceed the limit") +AddOptionRTC(addErrorsCECrossing, uint8_t, 0, "", 0, "Add additional custom track errors when crossing CE, 0 = no custom errors but att 0.5 to sigma_z^2, 1 = only to cov diagonal, 2 = preserve correlations") +AddOptionRTC(trackMergerMinPartHits, uint8_t, 10, "", 0, "Minimum hits of track part during track merging") +AddOptionRTC(trackMergerMinTotalHits, uint8_t, 20, "", 0, "Minimum total of track part during track merging") +AddOptionRTC(mergerCERowLimit, uint8_t, 5, "", 0, "Distance from first / last row in order to attempt merging accross CE") +AddOptionRTC(mergerLooperQPtB5Limit, uint8_t, 4, "", 0, "Min Q/Pt (@B=0.5T) to run special looper merging procedure") +AddOptionRTC(mergerLooperSecondHorizontalQPtB5Limit, uint8_t, 2, "", 0, "Min Q/Pt (@B=0.5T) to attempt second horizontal merge between slices after a vertical merge was found") +AddOptionRTC(trackFollowingMaxRowGap, uint8_t, 4, "", 0, "Maximum number of consecutive rows without hit in track following") +AddOptionRTC(trackFollowingMaxRowGapSeed, uint8_t, 2, "", 0, "Maximum number of consecutive rows without hit in track following during fit of seed") +AddOptionRTC(trackFitMaxRowMissedHard, uint8_t, 10, "", 0, "Hard limit for number of missed rows in fit / propagation") +AddOptionRTC(globalTrackingRowRange, uint8_t, 45, "", 0, "Number of rows from the upped/lower limit to search for global track candidates in for") +AddOptionRTC(globalTrackingMinRows, uint8_t, 10, "", 0, "Min num of rows an additional global track must span over") +AddOptionRTC(globalTrackingMinHits, uint8_t, 8, "", 0, "Min num of hits for an additional global track") +AddOptionRTC(noisyPadsQuickCheck, uint8_t, 1, "", 0, "Only check first fragment for noisy pads instead of all fragments (when test is enabled).") +AddOptionRTC(cfQMaxCutoff, uint8_t, 3, "", 0, "Cluster Finder rejects cluster with qmax below or equal to this threshold") +AddOptionRTC(cfQTotCutoff, uint8_t, 5, "", 0, "Cluster Finder rejects cluster with qtot below or equal to this threshold") +AddOptionRTC(cfQMaxCutoffSingleTime, uint8_t, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single time bin clusters") +AddOptionRTC(cfQMaxCutoffSinglePad, uint8_t, 0, "", 0, "Cluster Finder rejects cluster with qMax below or equal to this threshold for single pad or single pad bin clusters") +AddOptionRTC(cfInnerThreshold, uint8_t, 0, "", 0, "Cluster Finder extends cluster if inner charge above this threshold") +AddOptionRTC(cfMinSplitNum, uint8_t, 1, "", 0, "Minimum number of split charges in a cluster for the cluster to be marked as split") +AddOptionRTC(cfNoiseSuppressionEpsilon, uint8_t, 10, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression") +AddOptionRTC(cfNoiseSuppressionEpsilonRelative, uint8_t, 76, "", 0, "Cluster Finder: Difference between peak and charge for the charge to count as a minima during noise suppression, relative as fraction of 255") +AddOptionRTC(nWays, uint8_t, 3, "", 0, "Do N fit passes in final fit of merger") +AddOptionRTC(nWaysOuter, int8_t, 0, "", 0, "Store outer param") +AddOptionRTC(trackFitRejectMode, int8_t, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits, <0: reject at max -n hits") +AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") +AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") +AddOptionRTC(globalTracking, int8_t, 1, "", 0, "Enable Global Tracking (prolong tracks to adjacent sectors to find short segments)") +AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit (1: attachment, 2: propagation, 4: loop following, 8: mirroring)") +AddOptionRTC(rejectionStrategy, uint8_t, GPUCA_NAMESPACE::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression (0 = no, 1 = strategy A, 2 = strategy B)") +AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") +AddOptionRTC(compressionTypeMask, uint8_t, GPUCA_NAMESPACE::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits (1=truncate charge/width LSB, 2=differences, 4=track-model)") +AddOptionRTC(compressionSortOrder, uint8_t, GPUCA_NAMESPACE::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression (0 = time, 1 = pad, 2 = Z-time-pad, 3 = Z-pad-time, 4 = no sorting (use incoming order))") +AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") +AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") +AddOptionRTC(forceEarlyTransform, int8_t, -1, "", 0, "Force early TPC transformation also for continuous data (-1 = auto)") +AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") +AddOptionRTC(mergerCovSource, uint8_t, 2, "", 0, "Method to obtain covariance in track merger: 0 = simple filterErrors method, 1 = use cov from track following, 2 = refit (default)") +AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") +AddOptionRTC(mergeCE, uint8_t, 1, "", 0, "Merge tracks accross the central electrode") +AddOptionRTC(retryRefit, int8_t, 1, "", 0, "Retry refit with seeding errors and without cluster rejection when fit fails (=2 means retry in same kernel, =1 for separate kernel") +AddOptionRTC(looperInterpolationInExtraPass, int8_t, -1, "", 0, "Perform looper interpolation in an extra pass") +AddOptionRTC(mergerReadFromTrackerDirectly, int8_t, 1, "", 0, "Forward data directly from tracker to merger on GPU") +AddOptionRTC(dropSecondaryLegsInOutput, int8_t, 1, "", 0, "Do not store secondary legs of looping track in TrackTPC") +AddOptionRTC(enablePID, int8_t, 1, "", 0, "Enable PID response") +AddOptionRTC(PID_useNsigma, int8_t, 1, "", 0, "Use nSigma instead of absolute distance in PID response") +AddOptionRTC(adddEdxSubThresholdClusters, int8_t, 1, "", 0, "Add sub threshold clusters in TPC dEdx computation") +AddOptionRTC(rejectEdgeClustersInSeeding, int8_t, 0, "", 0, "Reject edge clusters based on uncorrected track Y during seeding") +AddOptionRTC(rejectEdgeClustersInTrackFit, int8_t, 0, "", 0, "Reject edge clusters based on uncorrected track Y during track fit") +AddOptionArray(PID_remap, int8_t, 9, (0, 1, 2, 3, 4, 5, 6, 7, 8), "", 0, "Remap Ipid to PID_reamp[Ipid] (no remap if<0)") // BUG: CUDA cannot yet hand AddOptionArrayRTC AddHelp("help", 'h') EndConfig() @@ -171,24 +171,24 @@ AddOptionRTC(extraRoadY, float, 5.f, "", 0, "Addition to search road around trac AddOptionRTC(extraRoadZ, float, 10.f, "", 0, "Addition to search road around track prolongation along Z in cm") AddOptionRTC(trkltResRPhiIdeal, float, 1.f, "", 0, "Optimal tracklet rphi resolution in cm (in case phi of track = lorentz angle)") AddOptionRTC(maxChi2Red, float, 99.f, "", 0, "maximum chi2 per attached tracklet for TRD tracks TODO: currently effectively disabled, requires tuning") -AddOptionRTC(applyDeflectionCut, unsigned char, 0, "", 0, "Set to 1 to enable tracklet selection based on deflection") -AddOptionRTC(stopTrkAfterNMissLy, unsigned char, 6, "", 0, "Abandon track following after N layers without a TRD match") -AddOptionRTC(nTrackletsMin, unsigned char, 3, "", 0, "Tracks with less attached tracklets are discarded after the tracking") -AddOptionRTC(matCorrType, unsigned char, 2, "", 0, "Material correction to use: 0 - none, 1 - TGeo, 2 - matLUT") -AddOptionRTC(pileupFwdNBC, unsigned char, 80, "", 0, "Post-trigger Pile-up integration time in BCs") -AddOptionRTC(pileupBwdNBC, unsigned char, 80, "", 0, "Pre-trigger Pile-up integration time in BCs") +AddOptionRTC(applyDeflectionCut, uint8_t, 0, "", 0, "Set to 1 to enable tracklet selection based on deflection") +AddOptionRTC(stopTrkAfterNMissLy, uint8_t, 6, "", 0, "Abandon track following after N layers without a TRD match") +AddOptionRTC(nTrackletsMin, uint8_t, 3, "", 0, "Tracks with less attached tracklets are discarded after the tracking") +AddOptionRTC(matCorrType, uint8_t, 2, "", 0, "Material correction to use: 0 - none, 1 - TGeo, 2 - matLUT") +AddOptionRTC(pileupFwdNBC, uint8_t, 80, "", 0, "Post-trigger Pile-up integration time in BCs") +AddOptionRTC(pileupBwdNBC, uint8_t, 80, "", 0, "Pre-trigger Pile-up integration time in BCs") AddHelp("help", 'h') EndConfig() BeginSubConfig(GPUSettingsRec, rec, configStandalone, "REC", 0, "Reconstruction settings", rec) AddOptionRTC(maxTrackQPtB5, float, 1.f / GPUCA_MIN_TRACK_PTB5_DEFAULT, "", 0, "required max Q/Pt (==min Pt) of tracks") -AddOptionRTC(nonConsecutiveIDs, signed char, false, "", 0, "Non-consecutive cluster IDs as in HLT, disables features that need access to slice data in TPC merger") -AddOptionRTC(fwdTPCDigitsAsClusters, unsigned char, 0, "", 0, "Forward TPC digits as clusters (if they pass the ZS threshold)") -AddOptionRTC(bz0Pt10MeV, unsigned char, 60, "", 0, "Nominal Pt to set when bz = 0 (in 10 MeV)") -AddOptionRTC(fitInProjections, signed char, -1, "", 0, "Fit in projection, -1 to enable full fit for all but passes but the first one") -AddOptionRTC(fitPropagateBzOnly, signed char, -1, "", 0, "Propagate using Bz only for n passes") -AddOptionRTC(useMatLUT, signed char, 0, "", 0, "Use material lookup table for TPC refit") -AddOptionRTC(trackingRefitGPUModel, signed char, 1, "", 0, "Use GPU track model for the Global Track Refit") +AddOptionRTC(nonConsecutiveIDs, int8_t, false, "", 0, "Non-consecutive cluster IDs as in HLT, disables features that need access to slice data in TPC merger") +AddOptionRTC(fwdTPCDigitsAsClusters, uint8_t, 0, "", 0, "Forward TPC digits as clusters (if they pass the ZS threshold)") +AddOptionRTC(bz0Pt10MeV, uint8_t, 60, "", 0, "Nominal Pt to set when bz = 0 (in 10 MeV)") +AddOptionRTC(fitInProjections, int8_t, -1, "", 0, "Fit in projection, -1 to enable full fit for all but passes but the first one") +AddOptionRTC(fitPropagateBzOnly, int8_t, -1, "", 0, "Propagate using Bz only for n passes") +AddOptionRTC(useMatLUT, int8_t, 0, "", 0, "Use material lookup table for TPC refit") +AddOptionRTC(trackingRefitGPUModel, int8_t, 1, "", 0, "Use GPU track model for the Global Track Refit") AddCustomCPP(void SetMinTrackPtB5(float v) { maxTrackQPtB5 = v > 0.001f ? (1.f / v) : (1.f / 0.001f); }) AddSubConfig(GPUSettingsRecTPC, tpc) AddSubConfig(GPUSettingsRecTRD, trd) @@ -200,10 +200,10 @@ EndConfig() BeginSubConfig(GPUSettingsProcessingRTC, rtc, configStandalone.proc, "RTC", 0, "Processing settings", proc_rtc) AddOption(cacheOutput, bool, false, "", 0, "Cache RTC compilation results") AddOption(optConstexpr, bool, true, "", 0, "Replace constant variables by static constexpr expressions") -AddOption(optSpecialCode, signed char, -1, "", 0, "Insert GPUCA_RTC_SPECIAL_CODE special code during RTC") +AddOption(optSpecialCode, int8_t, -1, "", 0, "Insert GPUCA_RTC_SPECIAL_CODE special code during RTC") AddOption(compilePerKernel, bool, true, "", 0, "Run one RTC compilation per kernel") AddOption(enable, bool, false, "", 0, "Use RTC to optimize GPU code") -AddOption(runTest, int, 0, "", 0, "Do not run the actual benchmark, but just test RTC compilation (1 full test, 2 test only compilation)") +AddOption(runTest, int32_t, 0, "", 0, "Do not run the actual benchmark, but just test RTC compilation (1 full test, 2 test only compilation)") AddOption(cacheMutex, bool, true, "", 0, "Use a file lock to serialize access to the cache folder") AddOption(ignoreCacheValid, bool, false, "", 0, "If set, allows to use RTC cached code files even if they are not valid for the current source code / parameters") AddHelp("help", 'h') @@ -217,73 +217,73 @@ AddHelp("help", 'h') EndConfig() BeginSubConfig(GPUSettingsProcessing, proc, configStandalone, "PROC", 0, "Processing settings", proc) -AddOption(platformNum, int, -1, "", 0, "Platform to use, in case the backend provides multiple platforms (-1 = auto-select)") -AddOption(deviceNum, int, -1, "gpuDevice", 0, "Set GPU device to use (-1: automatic, -2: for round-robin usage in timeslice-pipeline)") +AddOption(platformNum, int32_t, -1, "", 0, "Platform to use, in case the backend provides multiple platforms (-1 = auto-select)") +AddOption(deviceNum, int32_t, -1, "gpuDevice", 0, "Set GPU device to use (-1: automatic, -2: for round-robin usage in timeslice-pipeline)") AddOption(gpuDeviceOnly, bool, false, "", 0, "Use only GPU as device (i.e. no CPU for OpenCL)") AddOption(globalInitMutex, bool, false, "", 0, "Use global mutex to synchronize initialization of multiple GPU instances") -AddOption(stuckProtection, int, 0, "", 0, "Timeout in us, When AMD GPU is stuck, just continue processing and skip tracking, do not crash or stall the chain") -AddOption(trdNCandidates, int, 3, "", 0, "Number of branching track candidates for single input track during propagation") +AddOption(stuckProtection, int32_t, 0, "", 0, "Timeout in us, When AMD GPU is stuck, just continue processing and skip tracking, do not crash or stall the chain") +AddOption(trdNCandidates, int32_t, 3, "", 0, "Number of branching track candidates for single input track during propagation") AddOption(trdTrackModelO2, bool, false, "", 0, "Use O2 track model instead of GPU track model for TRD tracking") -AddOption(debugLevel, int, -1, "debug", 'd', "Set debug level (-2 = silent, -1 = autoselect (-2 for O2, 0 for standalone))") -AddOption(allocDebugLevel, int, 0, "allocDebug", 0, "Some debug output for memory allocations (without messing with normal debug level)") -AddOption(debugMask, int, 262143, "", 0, "Mask for debug output dumps to file") +AddOption(debugLevel, int32_t, -1, "debug", 'd', "Set debug level (-2 = silent, -1 = autoselect (-2 for O2, 0 for standalone))") +AddOption(allocDebugLevel, int32_t, 0, "allocDebug", 0, "Some debug output for memory allocations (without messing with normal debug level)") +AddOption(debugMask, int32_t, 262143, "", 0, "Mask for debug output dumps to file") AddOption(checkKernelFailures, bool, false, "", 0, "Synchronize after each kernel call and identify failing kernels") -AddOption(deterministicGPUReconstruction, int, -1, "", 0, "Make CPU and GPU debug output comparable (sort / skip concurrent parts), -1 = automatic if debugLevel >= 6") +AddOption(deterministicGPUReconstruction, int32_t, -1, "", 0, "Make CPU and GPU debug output comparable (sort / skip concurrent parts), -1 = automatic if debugLevel >= 6") AddOption(showOutputStat, bool, false, "", 0, "Print some track output statistics") AddOption(runCompressionStatistics, bool, false, "compressionStat", 0, "Run statistics and verification for cluster compression") -AddOption(resetTimers, signed char, 1, "", 0, "Reset timers every event") +AddOption(resetTimers, int8_t, 1, "", 0, "Reset timers every event") AddOption(deviceTimers, bool, true, "", 0, "Use device timers instead of host-based time measurement") AddOption(keepAllMemory, bool, false, "", 0, "Allocate all memory on both device and host, and do not reuse") AddOption(keepDisplayMemory, bool, false, "", 0, "Like keepAllMemory, but only for memory required for event display") AddOption(disableMemoryReuse, bool, false, "", 0, "Disable memory reusage (for debugging only)") -AddOption(memoryAllocationStrategy, signed char, 0, "", 0, "Memory Allocation Stragegy (0 = auto, 1 = individual allocations, 2 = single global allocation)") -AddOption(forceMemoryPoolSize, unsigned long, 1, "memSize", 0, "Force size of allocated GPU / page locked host memory", min(0ul)) -AddOption(forceHostMemoryPoolSize, unsigned long, 0, "hostMemSize", 0, "Force size of allocated host page locked host memory (overriding memSize)", min(0ul)) +AddOption(memoryAllocationStrategy, int8_t, 0, "", 0, "Memory Allocation Stragegy (0 = auto, 1 = individual allocations, 2 = single global allocation)") +AddOption(forceMemoryPoolSize, uint64_t, 1, "memSize", 0, "Force size of allocated GPU / page locked host memory", min(0ul)) +AddOption(forceHostMemoryPoolSize, uint64_t, 0, "hostMemSize", 0, "Force size of allocated host page locked host memory (overriding memSize)", min(0ul)) AddOption(memoryScalingFactor, float, 1.f, "", 0, "Factor to apply to all memory scalers") AddOption(conservativeMemoryEstimate, bool, false, "", 0, "Use some more conservative defaults for larger buffers during TPC processing") -AddOption(tpcInputWithClusterRejection, unsigned char, 0, "", 0, "Indicate whether the TPC input is CTF data with cluster rejection, to tune buffer estimations") -AddOption(forceMaxMemScalers, unsigned long, 0, "", 0, "Force using the maximum values for all buffers, Set a value n > 1 to rescale all maximums to a memory size of n") +AddOption(tpcInputWithClusterRejection, uint8_t, 0, "", 0, "Indicate whether the TPC input is CTF data with cluster rejection, to tune buffer estimations") +AddOption(forceMaxMemScalers, uint64_t, 0, "", 0, "Force using the maximum values for all buffers, Set a value n > 1 to rescale all maximums to a memory size of n") AddOption(registerStandaloneInputMemory, bool, false, "registerInputMemory", 0, "Automatically register input memory buffers for the GPU") -AddOption(ompThreads, int, -1, "omp", 't', "Number of OMP threads to run (-1: all)", min(-1), message("Using %s OMP threads")) -AddOption(ompKernels, unsigned char, 2, "", 0, "Parallelize with OMP inside kernels instead of over slices, 2 for nested parallelization over TPC sectors and inside kernels") +AddOption(ompThreads, int32_t, -1, "omp", 't', "Number of OMP threads to run (-1: all)", min(-1), message("Using %s OMP threads")) +AddOption(ompKernels, uint8_t, 2, "", 0, "Parallelize with OMP inside kernels instead of over slices, 2 for nested parallelization over TPC sectors and inside kernels") AddOption(ompAutoNThreads, bool, true, "", 0, "Auto-adjust number of OMP threads, decreasing the number for small input data") -AddOption(nDeviceHelperThreads, int, 1, "", 0, "Number of CPU helper threads for CPU processing") -AddOption(nStreams, signed char, 8, "", 0, "Number of GPU streams / command queues") -AddOption(nTPCClustererLanes, signed char, -1, "", 0, "Number of TPC clusterers that can run in parallel (-1 = autoset)") -AddOption(overrideClusterizerFragmentLen, int, -1, "", 0, "Force the cluster max fragment len to a certain value (-1 = autodetect)") -AddOption(trackletSelectorSlices, signed char, -1, "", 0, "Number of slices to processes in parallel at max") -AddOption(trackletConstructorInPipeline, signed char, -1, "", 0, "Run tracklet constructor in the pipeline") -AddOption(trackletSelectorInPipeline, signed char, -1, "", 0, "Run tracklet selector in the pipeline") +AddOption(nDeviceHelperThreads, int32_t, 1, "", 0, "Number of CPU helper threads for CPU processing") +AddOption(nStreams, int8_t, 8, "", 0, "Number of GPU streams / command queues") +AddOption(nTPCClustererLanes, int8_t, -1, "", 0, "Number of TPC clusterers that can run in parallel (-1 = autoset)") +AddOption(overrideClusterizerFragmentLen, int32_t, -1, "", 0, "Force the cluster max fragment len to a certain value (-1 = autodetect)") +AddOption(trackletSelectorSlices, int8_t, -1, "", 0, "Number of slices to processes in parallel at max") +AddOption(trackletConstructorInPipeline, int8_t, -1, "", 0, "Run tracklet constructor in the pipeline") +AddOption(trackletSelectorInPipeline, int8_t, -1, "", 0, "Run tracklet selector in the pipeline") AddOption(fullMergerOnGPU, bool, true, "", 0, "Perform full TPC track merging on GPU instead of only refit") AddOption(delayedOutput, bool, true, "", 0, "Delay output to be parallel to track fit") -AddOption(mergerSortTracks, signed char, -1, "", 0, "Sort track indizes for GPU track fit") -AddOption(alternateBorderSort, signed char, -1, "", 0, "Alternative implementation for sorting of border tracks") -AddOption(tpcCompressionGatherMode, signed char, -1, "", 0, "TPC Compressed Clusters Gather Mode (0: DMA transfer gather gpu to host, 1: serial DMA to host and gather by copy on CPU, 2. gather via GPU kernal DMA access, 3. gather on GPU via kernel, dma afterwards") -AddOption(tpcCompressionGatherModeKernel, signed char, -1, "", 0, "TPC Compressed Clusters Gather Mode Kernel (0: unbufferd, 1-3: buffered, 4: multi-block)") +AddOption(mergerSortTracks, int8_t, -1, "", 0, "Sort track indizes for GPU track fit") +AddOption(alternateBorderSort, int8_t, -1, "", 0, "Alternative implementation for sorting of border tracks") +AddOption(tpcCompressionGatherMode, int8_t, -1, "", 0, "TPC Compressed Clusters Gather Mode (0: DMA transfer gather gpu to host, 1: serial DMA to host and gather by copy on CPU, 2. gather via GPU kernal DMA access, 3. gather on GPU via kernel, dma afterwards") +AddOption(tpcCompressionGatherModeKernel, int8_t, -1, "", 0, "TPC Compressed Clusters Gather Mode Kernel (0: unbufferd, 1-3: buffered, 4: multi-block)") AddOption(tpccfGatherKernel, bool, true, "", 0, "Use a kernel instead of the DMA engine to gather the clusters") AddOption(doublePipeline, bool, false, "", 0, "Double pipeline mode") AddOption(doublePipelineClusterizer, bool, true, "", 0, "Include the input data of the clusterizer in the double-pipeline") -AddOption(prefetchTPCpageScan, signed char, 0, "", 0, "Prefetch Data for TPC page scan in CPU cache") +AddOption(prefetchTPCpageScan, int8_t, 0, "", 0, "Prefetch Data for TPC page scan in CPU cache") AddOption(runMC, bool, false, "", 0, "Process MC labels") -AddOption(runQA, int, 0, "qa", 'q', "Enable tracking QA (negative number to provide bitmask for QA tasks)", message("Running QA: %s"), def(1)) +AddOption(runQA, int32_t, 0, "qa", 'q', "Enable tracking QA (negative number to provide bitmask for QA tasks)", message("Running QA: %s"), def(1)) AddOption(qcRunFraction, float, 100.f, "", 0, "Percentage of events to process with QC") AddOption(outputSharedClusterMap, bool, false, "", 0, "Ship optional shared cluster map as output for further use") AddOption(disableTPCNoisyPadFilter, bool, false, "", 0, "Disables all TPC noisy pad filters (Not the normal noise filter!)") -AddOption(createO2Output, signed char, 2, "", 0, "Create Track output in O2 format (2 = skip non-O2 output in GPU track format (reverts to =1 if QA is requested))") +AddOption(createO2Output, int8_t, 2, "", 0, "Create Track output in O2 format (2 = skip non-O2 output in GPU track format (reverts to =1 if QA is requested))") AddOption(clearO2OutputFromGPU, bool, false, "", 0, "Free the GPU memory used for O2 output after copying to host, prevents further O2 processing on the GPU") AddOption(ignoreNonFatalGPUErrors, bool, false, "", 0, "Continue running after having received non fatal GPU errors, e.g. abort due to overflow") -AddOption(tpcIncreasedMinClustersPerRow, unsigned int, 0, "", 0, "Impose a minimum buffer size for the clustersPerRow during TPC clusterization") +AddOption(tpcIncreasedMinClustersPerRow, uint32_t, 0, "", 0, "Impose a minimum buffer size for the clustersPerRow during TPC clusterization") AddOption(noGPUMemoryRegistration, bool, false, "", 0, "Do not register input / output memory for GPU dma transfer") AddOption(o2PropagatorUseGPUField, bool, true, "", 0, "Makes the internal O2 propagator use the fast GPU polynomial b field approximation") AddOption(willProvideO2PropagatorLate, bool, false, "", 0, "Disable check for availability of o2 propagator and MatLUT at initialization") -AddOption(calibObjectsExtraMemorySize, unsigned int, 10u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") -AddOption(fastTransformObjectsMinMemorySize, unsigned int, 400u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") -AddOption(lateO2MatLutProvisioningSize, unsigned int, 0u, "", 0, "Memory size to reserve for late provisioning of matlut table") +AddOption(calibObjectsExtraMemorySize, uint32_t, 10u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") +AddOption(fastTransformObjectsMinMemorySize, uint32_t, 400u * 1024 * 1024, "", 0, "Extra spare memory added for calibration object buffer, to allow fow updates with larger objects") +AddOption(lateO2MatLutProvisioningSize, uint32_t, 0u, "", 0, "Memory size to reserve for late provisioning of matlut table") AddOption(throttleAlarms, bool, false, "", 0, "Throttle rate at which alarms are sent to the InfoLogger in online runs") AddOption(outputSanityCheck, bool, false, "", 0, "Run some simple sanity checks finding errors in the output") -AddOption(tpcSingleSector, int, -1, "", 0, "Restrict TPC processing to a single sector") -AddOption(tpcDownscaledEdx, unsigned char, 0, "", 0, "If != 0, downscale dEdx processing (if enabled) to x %") -AddOption(tpcMaxAttachedClustersPerSectorRow, unsigned int, 51000, "", 0, "Maximum number of TPC attached clusters which can be decoded per SectorRow") +AddOption(tpcSingleSector, int32_t, -1, "", 0, "Restrict TPC processing to a single sector") +AddOption(tpcDownscaledEdx, uint8_t, 0, "", 0, "If != 0, downscale dEdx processing (if enabled) to x %") +AddOption(tpcMaxAttachedClustersPerSectorRow, uint32_t, 51000, "", 0, "Maximum number of TPC attached clusters which can be decoded per SectorRow") AddOption(tpcUseOldCPUDecoding, bool, false, "", 0, "Enable old CPU-based TPC decoding") AddOption(RTCcacheFolder, std::string, "./rtccache/", "", 0, "Folder in which the cache file is stored") AddOption(RTCprependCommand, std::string, "", "", 0, "Prepend RTC compilation commands by this string") @@ -299,7 +299,7 @@ EndConfig() #ifndef GPUCA_GPUCODE_DEVICE // Light settings concerning the event display (can be changed without rebuilding vertices) BeginSubConfig(GPUSettingsDisplayLight, light, configStandalone.display, "GLL", 'g', "Light OpenGL display settings", display_light) -AddOption(animationMode, int, 0, "", 0, "") +AddOption(animationMode, int32_t, 0, "", 0, "") AddOption(smoothPoints, bool, true, "", 0, "Apply smoothing to points") AddOption(smoothLines, bool, false, "", 0, "Apply smoothing to lines") AddOption(depthBuffer, bool, false, "", 0, "Enable Z-buffer") @@ -311,14 +311,14 @@ AddOption(drawTracklets, bool, false, "", 0, "Highlight tracklets") AddOption(drawTracks, bool, false, "", 0, "Highlight sector tracks") AddOption(drawGlobalTracks, bool, false, "", 0, "Highlight global sector tracks prolonged into adjacent sector") AddOption(drawFinal, bool, false, "", 0, "Highlight final tracks") -AddOption(excludeClusters, int, 0, "", 0, "Exclude clusters from selected draw objects from display, (2 = exclude clusters but still show tracks)") -AddOption(drawSlice, int, -1, "", 0, "Show individual slice") -AddOption(drawRelatedSlices, int, 0, "", 0, "Show related slices (if drawSlice != -1)") -AddOption(drawGrid, int, 0, "", 0, "Highlight grid") -AddOption(propagateTracks, int, 0, "", 0, "Propagate final tracks further (inward / outward / show MC tracks)") -AddOption(showCollision, int, -1, "", 0, "Show only individual collision") -AddOption(colorCollisions, int, 0, "", 0, "Distinguish collisions in timeframe by color") -AddOption(colorClusters, int, 1, "", 0, "Color clusters belonging to track objects") +AddOption(excludeClusters, int32_t, 0, "", 0, "Exclude clusters from selected draw objects from display, (2 = exclude clusters but still show tracks)") +AddOption(drawSlice, int32_t, -1, "", 0, "Show individual slice") +AddOption(drawRelatedSlices, int32_t, 0, "", 0, "Show related slices (if drawSlice != -1)") +AddOption(drawGrid, int32_t, 0, "", 0, "Highlight grid") +AddOption(propagateTracks, int32_t, 0, "", 0, "Propagate final tracks further (inward / outward / show MC tracks)") +AddOption(showCollision, int32_t, -1, "", 0, "Show only individual collision") +AddOption(colorCollisions, int32_t, 0, "", 0, "Distinguish collisions in timeframe by color") +AddOption(colorClusters, int32_t, 1, "", 0, "Color clusters belonging to track objects") AddOption(pointSize, float, 2.0f, "", 0, "Set point size") AddOption(lineWidth, float, 1.4f, "", 0, "Set line width") AddOption(drawTPC, bool, true, "", 0, "Enable drawing TPC data") @@ -327,8 +327,8 @@ AddOption(drawTOF, bool, true, "", 0, "Enabale drawing TOF data") AddOption(drawITS, bool, true, "", 0, "Enabale drawing ITS data") AddOption(drawField, bool, false, "", 0, "Enable drawing magnetic field") AddOption(bFieldStepSize, float, 5.0f, "", 0, "Set field line step size") -AddOption(bFieldStepCount, int, 100, "", 0, "Set field line step count") -AddOption(bFieldLinesCount, int, 2000, "", 0, "Set field lines count") +AddOption(bFieldStepCount, int32_t, 100, "", 0, "Set field line step count") +AddOption(bFieldLinesCount, int32_t, 2000, "", 0, "Set field lines count") AddOption(invertColors, bool, false, "", 0, "Invert colors") AddHelp("help", 'h') EndConfig() @@ -344,14 +344,14 @@ AddOption(propagateLoopers, bool, false, "", 0, "Enabale propagation of loopers" AddOption(clustersOnly, bool, false, "", 0, "Visualize clusters only") AddOption(clustersOnNominalRow, bool, false, "", 0, "Show clusters at nominal x of pad row for early-transformed data") AddOption(separateGlobalTracks, bool, false, "", 0, "Separate global tracks") -AddOption(markClusters, int, 0, "", 0, "Mark clusters") -AddOption(markFakeClusters, int, 0, "", 0, "Mark fake clusters") -AddOption(markAdjacentClusters, int, 0, "", 0, "Mark adjacent clusters") -AddOption(hideRejectedClusters, int, 1, "", 0, "Hide rejected clusters") -AddOption(hideRejectedTracks, int, 1, "", 0, "Hide rejected tracks") -AddOption(hideUnmatchedClusters, int, 0, "", 0, "Hide unmatched clusters") -AddOption(trackFilter, int, 0, "", 0, "Apply filter on tracks to be displayed") -AddOption(projectXY, int, 0, "", 0, "Project everything on the XY-plane") +AddOption(markClusters, int32_t, 0, "", 0, "Mark clusters") +AddOption(markFakeClusters, int32_t, 0, "", 0, "Mark fake clusters") +AddOption(markAdjacentClusters, int32_t, 0, "", 0, "Mark adjacent clusters") +AddOption(hideRejectedClusters, int32_t, 1, "", 0, "Hide rejected clusters") +AddOption(hideRejectedTracks, int32_t, 1, "", 0, "Hide rejected tracks") +AddOption(hideUnmatchedClusters, int32_t, 0, "", 0, "Hide unmatched clusters") +AddOption(trackFilter, int32_t, 0, "", 0, "Apply filter on tracks to be displayed") +AddOption(projectXY, int32_t, 0, "", 0, "Project everything on the XY-plane") AddOption(xAdd, float, 0, "", 0, "Separate sectors, increase X coordinate") AddOption(zAdd, float, 0, "", 0, "Separate sides, increase Z coordinate") AddHelp("help", 'h') @@ -361,25 +361,25 @@ EndConfig() BeginSubConfig(GPUSettingsDisplayRenderer, renderer, configStandalone.display, "GLR", 'g', "Camera / window / renderer OpenGL display settings", display_camera) AddOption(camLookOrigin, bool, false, "", 0, "Make the camera look at the origin") AddOption(camYUp, bool, false, "", 0, "Orient the camera such that the y-axis is always upwards") -AddOption(cameraMode, int, 0, "", 0, "Camera mode") +AddOption(cameraMode, int32_t, 0, "", 0, "Camera mode") AddOption(fullScreen, bool, false, "", 0, "Full Screen") AddOption(maximized, bool, false, "", 0, "Full Screen") AddOption(openGLCore, bool, false, "", 0, "Use renderer path for OpenGL core profile") -AddOption(drawQualityMSAA, int, 0, "", 0, "MultiSample Anti Aliasing") -AddOption(drawQualityDownsampleFSAA, int, 0, "", 0, "Downsampling Anti Aliasing") +AddOption(drawQualityMSAA, int32_t, 0, "", 0, "MultiSample Anti Aliasing") +AddOption(drawQualityDownsampleFSAA, int32_t, 0, "", 0, "Downsampling Anti Aliasing") AddOption(drawQualityVSync, bool, true, "", 0, "Enable Vertical Sync") -AddOption(maxFPSRate, int, 0, "", 0, "Do not limit FPS but run at maximum possible rate") +AddOption(maxFPSRate, int32_t, 0, "", 0, "Do not limit FPS but run at maximum possible rate") AddOption(useGLIndirectDraw, bool, true, "", 0, "Use OpenGL indirect draws to reduce number of draw calls") -AddOption(screenshotScaleFactor, int, 1, "", 0, "Resolution scale factor when taking screenshots") -AddOption(fov, int, 45, "", 0, "Display FOV") +AddOption(screenshotScaleFactor, int32_t, 1, "", 0, "Resolution scale factor when taking screenshots") +AddOption(fov, int32_t, 45, "", 0, "Display FOV") AddHelp("help", 'h') EndConfig() // Vulkan Display Settings BeginSubConfig(GPUSettingsDisplayVulkan, vulkan, configStandalone.display, "GLV", 0, "Vulkan display settings", display_vulkan) -AddOption(nFramesInFlight, int, 0, "", 0, "Max number of render frames in flight (0 = as many as swapchain images)") +AddOption(nFramesInFlight, int32_t, 0, "", 0, "Max number of render frames in flight (0 = as many as swapchain images)") AddOption(uniformBuffersInDeviceMemory, bool, 1, "", 0, "Have uniform buffers in host-accessible device memory") -AddOption(forceDevice, int, -1, "", 0, "Force Vulkan device number to use") +AddOption(forceDevice, int32_t, -1, "", 0, "Force Vulkan device number to use") AddHelp("help", 'h') EndConfig() @@ -387,8 +387,8 @@ EndConfig() BeginSubConfig(GPUSettingsDisplay, display, configStandalone, "GL", 'g', "OpenGL display settings", display) AddOption(showTPCTracksFromO2Format, bool, false, "", 0, "Use TPC tracks in O2 output format instead of GPU format") AddOption(font, std::string, "monospace", "", 0, "Font (search patter used for Fontconfig)") -AddOption(fontSize, int, 14, "", 0, "Font size") -AddOption(smoothFont, int, -1, "", 0, "Smoth font when rendering (-1 for auto-select based on size") +AddOption(fontSize, int32_t, 14, "", 0, "Font size") +AddOption(smoothFont, int32_t, -1, "", 0, "Smoth font when rendering (-1 for auto-select based on size") AddOption(noFreetype, bool, false, "", 0, "Do not use Freetype for font rendering (can only draw text if supported by frontend)") AddOption(displayRenderer, std::string, "auto", "renderer", 0, "Renderer for event display: opengl | vulkan | auto") AddOption(displayFrontend, std::string, "auto", "displayFrontend", 0, "Frontend to use for event display: auto | win32 | x11 | glut | glfw | wayland") @@ -411,12 +411,12 @@ AddOption(strict, bool, true, "", 0, "Strict QA mode: Only consider resolution o AddOption(qpt, float, 10.f, "", 0, "Set cut for Q/Pt", def(2.f)) AddOption(maxResX, float, 1e6f, "", 0, "Maxmimum X (~radius) for reconstructed track position to take into accound for resolution QA in cm") AddOption(recThreshold, float, 0.9f, "", 0, "Compute the efficiency including impure tracks with fake contamination") -AddOption(resPrimaries, int, 0, "", 0, "0: Resolution for all tracks, 1: only for primary tracks, 2: only for non-primaries", def(1)) -AddOption(filterCharge, int, 0, "", 0, "Filter for positive (+1) or negative (-1) charge") -AddOption(filterPID, int, -1, "", 0, "Filter for Particle Type (0 Electron, 1 Muon, 2 Pion, 3 Kaon, 4 Proton)") +AddOption(resPrimaries, int32_t, 0, "", 0, "0: Resolution for all tracks, 1: only for primary tracks, 2: only for non-primaries", def(1)) +AddOption(filterCharge, int32_t, 0, "", 0, "Filter for positive (+1) or negative (-1) charge") +AddOption(filterPID, int32_t, -1, "", 0, "Filter for Particle Type (0 Electron, 1 Muon, 2 Pion, 3 Kaon, 4 Proton)") AddOption(nativeFitResolutions, bool, false, "", 0, "Create resolution histograms in the native fit units (sin(phi), tan(lambda), Q/Pt)") AddOption(enableLocalOutput, bool, true, "", 0, "Enable normal output to local PDF files / console") -AddOption(dumpToROOT, int, 0, "", 0, "Dump all clusters and tracks to a ROOT file, 1 = combined TNTUple dump, 2 = also individual cluster / track branch dump") +AddOption(dumpToROOT, int32_t, 0, "", 0, "Dump all clusters and tracks to a ROOT file, 1 = combined TNTUple dump, 2 = also individual cluster / track branch dump") AddOption(writeMCLabels, bool, false, "", 0, "Store mc labels to file for later matching") AddOption(writeRootFiles, bool, false, "", 0, "Create ROOT canvas files") AddOptionVec(matchMCLabels, std::string, "", 0, "Read labels from files and match them, only process tracks where labels differ") @@ -425,7 +425,7 @@ AddOption(noMC, bool, false, "", 0, "Force running QA without MC labels even if AddOption(shipToQC, bool, false, "", 0, "Do not write output files but ship histograms for QC") AddOption(shipToQCAsCanvas, bool, false, "", 0, "Send TCanvases with full layout to QC instead of individual histograms") AddOption(clusterRejectionHistograms, bool, false, "", 0, "Fill histograms with cluster rejection statistics") -AddOption(histMaxNClusters, unsigned int, 500000000, "", 0, "Maximum number of clusters in rejection histograms") +AddOption(histMaxNClusters, uint32_t, 500000000, "", 0, "Maximum number of clusters in rejection histograms") AddShortcut("compare", 0, "--QAinput", "Compare QA histograms", "--qa", "--QAinputHistogramsOnly") AddHelp("help", 'h') EndConfig() @@ -433,28 +433,28 @@ EndConfig() #ifdef BeginConfig // Settings concerning the standlone timeframe from run 2 events assembly tool BeginSubConfig(GPUSettingsTFSim, TF, configStandalone, "TF", 't', "Timeframe settings") -AddOption(nMerge, int, 0, "", 0, "Merge n events in a timeframe", min(0)) +AddOption(nMerge, int32_t, 0, "", 0, "Merge n events in a timeframe", min(0)) AddOption(averageDistance, float, 50.f, "", 0, "Average distance in cm of events merged into timeframe", min(0.f)) AddOption(randomizeDistance, bool, true, "", 0, "Randomize distance around average distance of merged events") AddOption(shiftFirstEvent, bool, true, "", 0, "Also shift the first event in z when merging events to a timeframe") -AddOption(bunchSim, int, 0, "", 0, "Simulate correct bunch interactions instead of placing only the average number of events. A value [n] > 1 sets TFlen for [n] collisions in average. (Incompatible to TFmerge)") -AddOption(bunchCount, int, 12, "", 0, "Number of bunches per trainsort") -AddOption(bunchSpacing, int, 50, "", 0, "Spacing between benches in ns") -AddOption(bunchTrainCount, int, 48, "", 0, "Number of bunch trains") -AddOption(abortGapTime, int, (3000), "", 0, "Length of abort gap in ns") -AddOption(interactionRate, int, 50000, "", 0, "Instantaneous interaction rate") -AddOption(timeFrameLen, long, (1000000000 / 44), "", 'l', "Timeframe len in ns") +AddOption(bunchSim, int32_t, 0, "", 0, "Simulate correct bunch interactions instead of placing only the average number of events. A value [n] > 1 sets TFlen for [n] collisions in average. (Incompatible to TFmerge)") +AddOption(bunchCount, int32_t, 12, "", 0, "Number of bunches per trainsort") +AddOption(bunchSpacing, int32_t, 50, "", 0, "Spacing between benches in ns") +AddOption(bunchTrainCount, int32_t, 48, "", 0, "Number of bunch trains") +AddOption(abortGapTime, int32_t, (3000), "", 0, "Length of abort gap in ns") +AddOption(interactionRate, int32_t, 50000, "", 0, "Instantaneous interaction rate") +AddOption(timeFrameLen, int64_t, (1000000000 / 44), "", 'l', "Timeframe len in ns") AddOption(noBorder, bool, false, "", 0, "Do not simulate border effects (partial events)") -AddOption(noEventRepeat, int, 0, "", 0, "0: Place random events, 1: Place events in timeframe one after another, 2: Place random events but do not repat", def(1)) -AddOption(nTotalEventsInTF, int, 0, "", 0, "Total number of collisions to be placed in the interior of all time frames (excluding borders)") -AddOption(eventStride, int, 0, "", 0, "Do not select random event, but walk over array of events in stride steps") +AddOption(noEventRepeat, int32_t, 0, "", 0, "0: Place random events, 1: Place events in timeframe one after another, 2: Place random events but do not repat", def(1)) +AddOption(nTotalEventsInTF, int32_t, 0, "", 0, "Total number of collisions to be placed in the interior of all time frames (excluding borders)") +AddOption(eventStride, int32_t, 0, "", 0, "Do not select random event, but walk over array of events in stride steps") AddOption(overlayRaw, bool, false, "", 0, "Overlay raw TPC data instead of spatial clusters") AddHelp("help", 'h') EndConfig() // Settings concerning standalone toy event generator BeginSubConfig(GPUSettingsEG, EG, configStandalone, "EG", 0, "Event generator settings") -AddOption(numberOfTracks, int, 1, "", 0, "Number of tracks per generated event") +AddOption(numberOfTracks, int32_t, 1, "", 0, "Number of tracks per generated event") AddHelp("help", 'h') EndConfig() @@ -466,45 +466,45 @@ AddOption(gpuType, std::string, "AUTO", "", 0, "GPU type (CUDA / HIP / OCL / OCL AddOption(runGPUforce, bool, true, "", 0, "Force usage of the specified GPU device type, no CPU fallback") AddOption(noprompt, bool, true, "", 0, "Do prompt for keypress before exiting") AddOption(continueOnError, bool, false, "", 0, "Continue processing after an error") -AddOption(seed, int, -1, "", 0, "Set srand seed (-1: random)") -AddOption(StartEvent, int, 0, "", 's', "First event to process", min(0)) -AddOption(nEvents, int, -1, "", 'n', "Number of events to process (-1; all)", min(0)) -AddOption(runs, int, 1, "runs", 'r', "Number of iterations to perform (repeat each event)", min(0)) -AddOption(runs2, int, 1, "runsExternal", 0, "Number of iterations to perform (repeat full processing)", min(1)) -AddOption(runsInit, int, 1, "", 0, "Number of initial iterations excluded from average", min(0)) +AddOption(seed, int32_t, -1, "", 0, "Set srand seed (-1: random)") +AddOption(StartEvent, int32_t, 0, "", 's', "First event to process", min(0)) +AddOption(nEvents, int32_t, -1, "", 'n', "Number of events to process (-1; all)", min(0)) +AddOption(runs, int32_t, 1, "runs", 'r', "Number of iterations to perform (repeat each event)", min(0)) +AddOption(runs2, int32_t, 1, "runsExternal", 0, "Number of iterations to perform (repeat full processing)", min(1)) +AddOption(runsInit, int32_t, 1, "", 0, "Number of initial iterations excluded from average", min(0)) AddOption(eventsDir, const char*, "pp", "events", 'e', "Directory with events to process", message("Reading events from Directory events/%s")) AddOption(noEvents, bool, false, "", 0, "Run without data (e.g. for field visualization)") -AddOption(eventDisplay, int, 0, "display", 'd', "Show standalone event display", def(1)) +AddOption(eventDisplay, int32_t, 0, "display", 'd', "Show standalone event display", def(1)) AddOption(eventGenerator, bool, false, "", 0, "Run event generator") AddOption(cont, bool, false, "", 0, "Process continuous timeframe data") -AddOption(outputcontrolmem, unsigned long, 0, "outputMemory", 0, "Use predefined output buffer of this size", min(0ul), message("Using %s bytes as output memory")) -AddOption(inputcontrolmem, unsigned long, 0, "inputMemory", 0, "Use predefined input buffer of this size", min(0ul), message("Using %s bytes as input memory")) -AddOption(cpuAffinity, int, -1, "", 0, "Pin CPU affinity to this CPU core", min(-1)) +AddOption(outputcontrolmem, uint64_t, 0, "outputMemory", 0, "Use predefined output buffer of this size", min(0ul), message("Using %s bytes as output memory")) +AddOption(inputcontrolmem, uint64_t, 0, "inputMemory", 0, "Use predefined input buffer of this size", min(0ul), message("Using %s bytes as input memory")) +AddOption(cpuAffinity, int32_t, -1, "", 0, "Pin CPU affinity to this CPU core", min(-1)) AddOption(fifoScheduler, bool, false, "", 0, "Use FIFO realtime scheduler", message("Setting FIFO scheduler: %s")) AddOption(fpe, bool, true, "", 0, "Trap on floating point exceptions") AddOption(flushDenormals, bool, true, "", 0, "Enable FTZ and DAZ (Flush all denormals to zero)") AddOption(solenoidBzNominalGPU, float, -1e6f, "", 0, "Field strength of solenoid Bz in kGaus") AddOption(constBz, bool, false, "", 0, "Force constand Bz") AddOption(overrideMaxTimebin, bool, false, "", 0, "Override max time bin setting for continuous data with max time bin in time frame") -AddOption(encodeZS, int, -1, "", 0, "Zero-Suppress TPC data", def(1)) -AddOption(zsFilter, int, -1, "", 0, "Apply Zero-Suppression when loading digits and remove those below threshold", def(1)) -AddOption(zsVersion, int, 2, "", 0, "ZS Version: 1 = 10-bit ADC row based, 2 = 12-bit ADC row based, 3 = improved link based, 4 = dense link based") +AddOption(encodeZS, int32_t, -1, "", 0, "Zero-Suppress TPC data", def(1)) +AddOption(zsFilter, int32_t, -1, "", 0, "Apply Zero-Suppression when loading digits and remove those below threshold", def(1)) +AddOption(zsVersion, int32_t, 2, "", 0, "ZS Version: 1 = 10-bit ADC row based, 2 = 12-bit ADC row based, 3 = improved link based, 4 = dense link based") AddOption(dumpEvents, bool, false, "", 0, "Dump events (after transformation such as encodeZS") AddOption(stripDumpedEvents, bool, false, "", 0, "Remove redundant inputs (e.g. digits and ZS) before dumping") -AddOption(printSettings, int, 0, "", 0, "Print all settings", def(1)) +AddOption(printSettings, int32_t, 0, "", 0, "Print all settings", def(1)) AddOption(memoryStat, bool, false, "", 0, "Print memory statistics") AddOption(testSyncAsync, bool, false, "syncAsync", 0, "Test first synchronous and then asynchronous processing") AddOption(testSync, bool, false, "sync", 0, "Test settings for synchronous phase") AddOption(timeFrameTime, bool, false, "tfTime", 0, "Print some debug information about time frame processing time") AddOption(controlProfiler, bool, false, "", 0, "Issues GPU profiler stop and start commands to profile only the relevant processing part") AddOption(preloadEvents, bool, false, "", 0, "Preload events into host memory before start processing") -AddOption(recoSteps, int, -1, "", 0, "Bitmask for RecoSteps") -AddOption(recoStepsGPU, int, -1, "", 0, "Bitmask for RecoSteps") -AddOption(runMerger, int, 1, "", 0, "Run track merging / refit", min(0), max(1)) -AddOption(runTRD, int, -1, "", 0, "Enable TRD processing") -AddOption(rundEdx, int, -1, "", 0, "Enable dEdx processing") -AddOption(runCompression, int, 1, "", 0, "Enable TPC Compression") -AddOption(runTransformation, int, 1, "", 0, "Enable TPC Transformation") +AddOption(recoSteps, int32_t, -1, "", 0, "Bitmask for RecoSteps") +AddOption(recoStepsGPU, int32_t, -1, "", 0, "Bitmask for RecoSteps") +AddOption(runMerger, int32_t, 1, "", 0, "Run track merging / refit", min(0), max(1)) +AddOption(runTRD, int32_t, -1, "", 0, "Enable TRD processing") +AddOption(rundEdx, int32_t, -1, "", 0, "Enable dEdx processing") +AddOption(runCompression, int32_t, 1, "", 0, "Enable TPC Compression") +AddOption(runTransformation, int32_t, 1, "", 0, "Enable TPC Transformation") AddOption(runRefit, bool, false, "", 0, "Enable final track refit") AddOption(setO2Settings, bool, false, "", 0, "Set O2 defaults for outerParam, output of shared cluster map, referenceX") AddHelp("help", 'h') @@ -523,13 +523,13 @@ EndConfig() BeginSubConfig(GPUSettingsO2, global, configStandalone, "O2", 0, "O2 workflow settings", global) AddOption(solenoidBzNominalGPU, float, -1e6f, "", 0, "Field strength of solenoid Bz in kGaus") AddOption(constBz, bool, false, "", 0, "force constant Bz for tests") -AddOption(continuousMaxTimeBin, int, 0, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for default of 23ms") +AddOption(continuousMaxTimeBin, int32_t, 0, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for default of 23ms") AddOption(deviceType, std::string, "CPU", "", 0, "Device type, CPU | CUDA | HIP | OCL1 | OCL2") AddOption(forceDeviceType, bool, true, "", 0, "force device type, otherwise allows fall-back to CPU") AddOption(synchronousProcessing, bool, false, "", 0, "Apply performance shortcuts for synchronous processing, disable unneeded steps") -AddOption(dump, int, 0, "", 0, "Dump events for standalone benchmark: 1 = dump events, 2 = dump events and skip processing in workflow") +AddOption(dump, int32_t, 0, "", 0, "Dump events for standalone benchmark: 1 = dump events, 2 = dump events and skip processing in workflow") AddOption(display, bool, false, "", 0, "Enable standalone gpu tracking visualizaion") -AddOption(rundEdx, int, -1, "", 0, "Enable/disable dEdx processing (-1 for autoselect)") +AddOption(rundEdx, int32_t, -1, "", 0, "Enable/disable dEdx processing (-1 for autoselect)") AddOption(dEdxSplineTopologyCorrFile, std::string, "", "", 0, "File name of the dE/dx spline track topology correction file") AddOption(dEdxCorrFile, std::string, "", "", 0, "File name of dEdx residual correction file") AddOption(dEdxPolTopologyCorrFile, std::string, "", "", 0, "File name of the dE/dx polynomial track topology correction") @@ -546,19 +546,19 @@ AddOption(gainCalibFile, std::string, "", "", 0, "File name of TPC pad gain cali AddOption(gainCalibDisableCCDB, bool, false, "", 0, "Disabling loading the TPC pad gain calibration from the CCDB") AddOption(thresholdCalibFile, std::string, "", "", 0, "File name of TPC zero supression threshold map") AddOption(allocateOutputOnTheFly, bool, true, "", 0, "Allocate shm output buffers on the fly, instead of using preallocated buffer with upper bound size") -AddOption(outputBufferSize, unsigned long, 200000000ul, "", 0, "Size of the output buffers to be allocated") +AddOption(outputBufferSize, uint64_t, 200000000ul, "", 0, "Size of the output buffers to be allocated") AddOption(mutexMemReg, bool, false, "", 0, "Global mutex to serialize GPU memory registration") -AddOption(printSettings, int, 0, "", 0, "Print all settings", def(1)) +AddOption(printSettings, int32_t, 0, "", 0, "Print all settings", def(1)) AddOption(gpuDisplayfilterMacro, std::string, "", "", 0, "File name of ROOT macro for GPU display filter") AddOption(benchmarkMemoryRegistration, bool, false, "", 0, "Time-benchmark for memory registration") -AddOption(registerSelectedSegmentIds, int, -1, "", 0, "Register only a specific managed shm segment id (-1 = all)") +AddOption(registerSelectedSegmentIds, int32_t, -1, "", 0, "Register only a specific managed shm segment id (-1 = all)") AddOption(disableCalibUpdates, bool, false, "", 0, "Disable all calibration updates") AddOption(partialOutputForNonFatalErrors, bool, false, "", 0, "In case of a non-fatal error that is ignored (ignoreNonFatalGPUErrors=true), forward the partial output that was created instead of shipping an empty TF") AddOption(checkFirstTfOrbit, bool, false, "", 0, "Check consistency of firstTfOrbit") AddOption(tpcTriggeredMode, bool, false, "", 0, "In case we have triggered TPC data, this must be set to true") AddOption(zsOnTheFlyDigitsFilter, bool, false, "", 0, "Run on the fly digits filter during zs encoding") -AddOption(dumpBadTFs, int, 0, "", 0, "Number of bad timeframes (with decoding / processing) errors to decode at max") -AddOption(dumpBadTFMode, int, 0, "", 0, "Type of dump to create: 0 = raw-reader compatible raw file, 1 = buffer-wise dump, 2 = standalone-benchmark compatible dump") +AddOption(dumpBadTFs, int32_t, 0, "", 0, "Number of bad timeframes (with decoding / processing) errors to decode at max") +AddOption(dumpBadTFMode, int32_t, 0, "", 0, "Type of dump to create: 0 = raw-reader compatible raw file, 1 = buffer-wise dump, 2 = standalone-benchmark compatible dump") EndConfig() #endif // GPUCA_O2_LIB #endif // !GPUCA_GPUCODE_DEVICE @@ -566,12 +566,12 @@ EndConfig() // Derrived parameters used in GPUParam BeginHiddenConfig(GPUSettingsParam, param) AddVariableRTC(dAlpha, float, 0.f) // angular size -AddVariableRTC(assumeConstantBz, signed char, 0) // Assume a constant magnetic field -AddVariableRTC(toyMCEventsFlag, signed char, 0) // events were build with home-made event generator -AddVariableRTC(continuousTracking, signed char, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding -AddVariableRTC(dodEdx, signed char, 0) // Do dEdx computation -AddVariableRTC(earlyTpcTransform, signed char, 0) // do Early TPC transformation -AddVariableRTC(debugLevel, signed char, 0) // Debug level +AddVariableRTC(assumeConstantBz, int8_t, 0) // Assume a constant magnetic field +AddVariableRTC(toyMCEventsFlag, int8_t, 0) // events were build with home-made event generator +AddVariableRTC(continuousTracking, int8_t, 0) // Continuous tracking, estimate bz and errors for abs(z) = 125cm during seeding +AddVariableRTC(dodEdx, int8_t, 0) // Do dEdx computation +AddVariableRTC(earlyTpcTransform, int8_t, 0) // do Early TPC transformation +AddVariableRTC(debugLevel, int8_t, 0) // Debug level EndConfig() EndNamespace() // gpu diff --git a/GPU/GPUTracking/Definitions/clusterFinderDefs.h b/GPU/GPUTracking/Definitions/clusterFinderDefs.h index fb5cd7a1fc0c7..5a4cfc2023588 100644 --- a/GPU/GPUTracking/Definitions/clusterFinderDefs.h +++ b/GPU/GPUTracking/Definitions/clusterFinderDefs.h @@ -18,10 +18,10 @@ #include "GPUDef.h" #ifndef __OPENCL__ -using uchar = unsigned char; +using uchar = uint8_t; #endif #ifdef __APPLE__ -using ulong = unsigned long; +using ulong = uint64_t; #endif /* #define CHARGEMAP_TIME_MAJOR_LAYOUT */ @@ -71,16 +71,16 @@ namespace GPUCA_NAMESPACE::gpu::tpccf { using SizeT = size_t; -using TPCTime = int; -using TPCFragmentTime = short; -using Pad = unsigned char; -using GlobalPad = short; -using Row = unsigned char; -using Cru = unsigned char; +using TPCTime = int32_t; +using TPCFragmentTime = int16_t; +using Pad = uint8_t; +using GlobalPad = int16_t; +using Row = uint8_t; +using Cru = uint8_t; using Charge = float; -using Delta = short; +using Delta = int16_t; using Delta2 = short2; using local_id = short2; diff --git a/GPU/GPUTracking/GPUTrackingLinkDef_Standalone.h b/GPU/GPUTracking/GPUTrackingLinkDef_Standalone.h index a7b91cc37ba4a..39b90430da7bc 100644 --- a/GPU/GPUTracking/GPUTrackingLinkDef_Standalone.h +++ b/GPU/GPUTracking/GPUTrackingLinkDef_Standalone.h @@ -25,7 +25,7 @@ #pragma link C++ class o2::tpc::TrackTPC + ; #pragma link C++ class o2::track::TrackParametrization < float> + ; #pragma link C++ class o2::track::TrackParametrizationWithError < float> + ; -#pragma link C++ class o2::dataformats::RangeReference < unsigned int, unsigned short> + ; +#pragma link C++ class o2::dataformats::RangeReference < uint32_t, uint16_t> + ; #pragma link C++ class o2::tpc::dEdxInfo + ; #pragma link C++ class o2::track::PID + ; diff --git a/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.cxx b/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.cxx index d85a4a9a183fb..e9b4bb758532b 100644 --- a/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.cxx +++ b/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.cxx @@ -82,7 +82,7 @@ void AliHLTGPUDumpComponent::GetInputDataTypes(vector& AliHLTComponentDataType AliHLTGPUDumpComponent::GetOutputDataType() { return AliHLTTPCDefinitions::RawClustersDataType(); } -void AliHLTGPUDumpComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) +void AliHLTGPUDumpComponent::GetOutputDataSize(uint64_t& constBase, double& inputMultiplier) { constBase = 10000; // minimum size inputMultiplier = 0.6; // size relative to input @@ -90,7 +90,7 @@ void AliHLTGPUDumpComponent::GetOutputDataSize(unsigned long& constBase, double& AliHLTComponent* AliHLTGPUDumpComponent::Spawn() { return new AliHLTGPUDumpComponent; } -int AliHLTGPUDumpComponent::DoInit(int argc, const char** argv) +int32_t AliHLTGPUDumpComponent::DoInit(int argc, const char** argv) { fSolenoidBz = GetBz(); fIsMC = TVirtualMC::GetMC(); @@ -157,11 +157,11 @@ int AliHLTGPUDumpComponent::DoInit(int argc, const char** argv) return 0; } -int AliHLTGPUDumpComponent::DoDeinit() { return 0; } +int32_t AliHLTGPUDumpComponent::DoDeinit() { return 0; } -int AliHLTGPUDumpComponent::Reconfigure(const char* cdbEntry, const char* chainId) { return 0; } +int32_t AliHLTGPUDumpComponent::Reconfigure(const char* cdbEntry, const char* chainId) { return 0; } -int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks) +int32_t AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks) { if (GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR)) { return 0; @@ -178,12 +178,12 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con const AliHLTTPCRawClusterData* clustersRaw[NSLICES][NPATCHES] = {nullptr}; bool labelsPresent = false; const GPUTRDTrackletWord* TRDtracklets = nullptr; - int nTRDTrackletsTotal = 0; + int32_t nTRDTrackletsTotal = 0; - for (unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++) { + for (uint64_t ndx = 0; ndx < evtData.fBlockCnt; ndx++) { const AliHLTComponentBlockData& pBlock = blocks[ndx]; - int slice = AliHLTTPCDefinitions::GetMinSliceNr(pBlock); - int patch = AliHLTTPCDefinitions::GetMinPatchNr(pBlock); + int32_t slice = AliHLTTPCDefinitions::GetMinSliceNr(pBlock); + int32_t patch = AliHLTTPCDefinitions::GetMinPatchNr(pBlock); if (pBlock.fDataType == AliHLTTPCDefinitions::RawClustersDataType()) { clustersRaw[slice][patch] = (const AliHLTTPCRawClusterData*)pBlock.fPtr; } else if (pBlock.fDataType == AliHLTTPCDefinitions::ClustersXYZDataType()) { @@ -200,18 +200,18 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con std::vector rawClusters[NSLICES]; std::vector clusterData[NSLICES]; - int nClustersTotal = 0; - for (int slice = 0; slice < NSLICES; slice++) { - int nClustersSliceTotal = 0; + int32_t nClustersTotal = 0; + for (int32_t slice = 0; slice < NSLICES; slice++) { + int32_t nClustersSliceTotal = 0; clusterData[slice].clear(); rawClusters[slice].clear(); - for (int patch = 0; patch < 6; patch++) { + for (int32_t patch = 0; patch < 6; patch++) { if (clustersXYZ[slice][patch]) { nClustersSliceTotal += clustersXYZ[slice][patch]->fCount; } } GPUTPCClusterData cluster; - for (int patch = 0; patch < 6; patch++) { + for (int32_t patch = 0; patch < 6; patch++) { if (clustersXYZ[slice][patch] != nullptr && clustersRaw[slice][patch] != nullptr) { const AliHLTTPCClusterXYZData& clXYZ = *clustersXYZ[slice][patch]; const AliHLTTPCRawClusterData& clRaw = *clustersRaw[slice][patch]; @@ -221,8 +221,8 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con continue; } - const int firstRow = AliHLTTPCGeometry::GetFirstRow(patch); - for (int ic = 0; ic < clXYZ.fCount; ic++) { + const int32_t firstRow = AliHLTTPCGeometry::GetFirstRow(patch); + for (int32_t ic = 0; ic < clXYZ.fCount; ic++) { const AliHLTTPCClusterXYZ& c = clXYZ.fClusters[ic]; const AliHLTTPCRawCluster& cRaw = clRaw.fClusters[ic]; if (fabsf(c.GetZ()) > 300) { @@ -250,16 +250,16 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con #endif AliHLTTPCRawCluster tmp = cRaw; tmp.fPadRow += firstRow; - if ((unsigned int)cluster.amp >= 25 * 1024) { - GPUError("Invalid cluster charge, truncating (%d >= %d)", (int)cluster.amp, 25 * 1024); + if ((uint32_t)cluster.amp >= 25 * 1024) { + GPUError("Invalid cluster charge, truncating (%d >= %d)", (int32_t)cluster.amp, 25 * 1024); cluster.amp = 25 * 1024 - 1; } - if ((unsigned int)tmp.GetCharge() >= 25 * 1024) { - GPUError("Invalid raw cluster charge, truncating (%d >= %d)", (int)tmp.GetCharge(), 25 * 1024); + if ((uint32_t)tmp.GetCharge() >= 25 * 1024) { + GPUError("Invalid raw cluster charge, truncating (%d >= %d)", (int32_t)tmp.GetCharge(), 25 * 1024); tmp.SetCharge(25 * 1024 - 1); } - if ((unsigned int)tmp.GetQMax() >= 1024) { - GPUError("Invalid raw cluster charge max, truncating (%d >= %d)", (int)tmp.GetQMax(), 1024); + if ((uint32_t)tmp.GetQMax() >= 1024) { + GPUError("Invalid raw cluster charge max, truncating (%d >= %d)", (int32_t)tmp.GetQMax(), 1024); tmp.SetQMax(1024 - 1); } clusterData[slice].emplace_back(cluster); @@ -269,7 +269,7 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con } } } - HLTDebug("Read %d->%d hits for slice %d", nClustersSliceTotal, (int)clusterData[slice].size(), slice); + HLTDebug("Read %d->%d hits for slice %d", nClustersSliceTotal, (int32_t)clusterData[slice].size(), slice); } if (nClustersTotal < 100) { @@ -277,12 +277,12 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con } fChain->ClearIOPointers(); - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { fChain->mIOPtrs.nClusterData[i] = clusterData[i].size(); fChain->mIOPtrs.clusterData[i] = clusterData[i].data(); fChain->mIOPtrs.nRawClusters[i] = rawClusters[i].size(); fChain->mIOPtrs.rawClusters[i] = rawClusters[i].data(); - HLTDebug("Slice %d - Clusters %d", i, (int)clusterData[i].size()); + HLTDebug("Slice %d - Clusters %d", i, (int32_t)clusterData[i].size()); } std::vector labels; @@ -290,14 +290,14 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con if (labelsPresent) { // Write cluster labels - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { GPUTPCClusterData* pCluster = clusterData[iSlice].data(); - for (unsigned int iPatch = 0; iPatch < NPATCHES; iPatch++) { + for (uint32_t iPatch = 0; iPatch < NPATCHES; iPatch++) { if (clusterLabels[iSlice][iPatch] == nullptr || clustersXYZ[iSlice][iPatch] == nullptr || clusterLabels[iSlice][iPatch]->fCount != clustersXYZ[iSlice][iPatch]->fCount) { continue; } const AliHLTTPCClusterXYZData& clXYZ = *clustersXYZ[iSlice][iPatch]; - for (int ic = 0; ic < clXYZ.fCount; ic++) { + for (int32_t ic = 0; ic < clXYZ.fCount; ic++) { if (pCluster->id != AliHLTTPCGeometry::CreateClusterID(iSlice, iPatch, ic)) { continue; } @@ -309,13 +309,13 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con } if (labels.size() != nClustersTotal) { - HLTFatal("Error getting cluster MC labels (%d labels, %d clusters)", (int)labels.size(), nClustersTotal); + HLTFatal("Error getting cluster MC labels (%d labels, %d clusters)", (int32_t)labels.size(), nClustersTotal); return (-EINVAL); } fChain->mIOPtrs.nMCLabelsTPC = labels.size(); fChain->mIOPtrs.mcLabelsTPC = labels.data(); - HLTDebug("Number of mc labels %d", (int)labels.size()); + HLTDebug("Number of mc labels %d", (int32_t)labels.size()); // Write MC tracks bool OK = false; @@ -329,7 +329,7 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con rl->LoadKinematics(); rl->LoadTrackRefs(); - int nTracks = rl->GetHeader()->GetNtrack(); + int32_t nTracks = rl->GetHeader()->GetNtrack(); mcInfo.resize(nTracks); AliStack* stack = rl->Stack(); @@ -348,15 +348,15 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con break; } - int nPrimaries = stack->GetNprimary(); + int32_t nPrimaries = stack->GetNprimary(); std::vector trackRefs(nTracks, nullptr); TClonesArray* tpcRefs = nullptr; branch->SetAddress(&tpcRefs); - int nr = TR->GetEntries(); - for (int r = 0; r < nr; r++) { + int32_t nr = TR->GetEntries(); + for (int32_t r = 0; r < nr; r++) { TR->GetEvent(r); - for (int i = 0; i < tpcRefs->GetEntriesFast(); i++) { + for (int32_t i = 0; i < tpcRefs->GetEntriesFast(); i++) { AliTrackReference* tpcRef = (AliTrackReference*)tpcRefs->UncheckedAt(i); if (tpcRef->DetectorId() != AliTrackReference::kTPC) { continue; @@ -374,7 +374,7 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con memset(mcInfo.data(), 0, nTracks * sizeof(mcInfo[0])); - for (int i = 0; i < nTracks; i++) { + for (int32_t i = 0; i < nTracks; i++) { mcInfo[i].pid = -100; TParticle* particle = (TParticle*)stack->Particle(i); if (particle == nullptr) { @@ -384,9 +384,9 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con continue; } - int charge = (int)particle->GetPDG()->Charge(); - int prim = stack->IsPhysicalPrimary(i); - int hasPrimDaughter = particle->GetFirstDaughter() != -1 && particle->GetFirstDaughter() < nPrimaries; + int32_t charge = (int32_t)particle->GetPDG()->Charge(); + int32_t prim = stack->IsPhysicalPrimary(i); + int32_t hasPrimDaughter = particle->GetFirstDaughter() != -1 && particle->GetFirstDaughter() < nPrimaries; mcInfo[i].charge = charge; mcInfo[i].prim = prim; @@ -423,7 +423,7 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con // if (ref) HLTImportant("Particle %d: Charge %d, Prim %d, PrimDaughter %d, Pt %f %f ref %p\n", i, charge, prim, hasPrimDaughter, ref->Pt(), particle->Pt(), ref); } - for (int i = 0; i < nTracks; i++) { + for (int32_t i = 0; i < nTracks; i++) { delete trackRefs[i]; } @@ -437,21 +437,21 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con fChain->mIOPtrs.nMCInfosTPC = mcInfo.size(); fChain->mIOPtrs.mcInfosTPC = mcInfo.data(); - static const GPUTPCMCInfoCol mcColInfo = {0, (unsigned int)mcInfo.size()}; + static const GPUTPCMCInfoCol mcColInfo = {0, (uint32_t)mcInfo.size()}; fChain->mIOPtrs.mcInfosTPCCol = &mcColInfo; fChain->mIOPtrs.nMCInfosTPCCol = 1; - HLTDebug("Number of MC infos: %d", (int)mcInfo.size()); + HLTDebug("Number of MC infos: %d", (int32_t)mcInfo.size()); } - unsigned int clusterNum = 0; - for (unsigned int slice = 0; slice < NSLICES; slice++) { - for (int k = 0; k < fChain->mIOPtrs.nClusterData[slice]; k++) { + uint32_t clusterNum = 0; + for (uint32_t slice = 0; slice < NSLICES; slice++) { + for (int32_t k = 0; k < fChain->mIOPtrs.nClusterData[slice]; k++) { clusterData[slice][k].id = clusterNum++; } } fChain->mIOPtrs.nTRDTracklets = nTRDTrackletsTotal; std::vector tracklets(nTRDTrackletsTotal); - for (int i = 0; i < nTRDTrackletsTotal; i++) { + for (int32_t i = 0; i < nTRDTrackletsTotal; i++) { tracklets[i] = TRDtracklets[i]; } std::sort(tracklets.data(), tracklets.data() + nTRDTrackletsTotal); @@ -459,19 +459,19 @@ int AliHLTGPUDumpComponent::DoEvent(const AliHLTComponentEventData& evtData, con fChain->mIOPtrs.nTRDTriggerRecords = 1; static float t = 0.f; - static int o = 0; + static int32_t o = 0; fChain->mIOPtrs.trdTriggerTimes = &t; fChain->mIOPtrs.trdTrackletIdxFirst = &o; - HLTDebug("Number of TRD tracklets: %d", (int)nTRDTrackletsTotal); + HLTDebug("Number of TRD tracklets: %d", (int32_t)nTRDTrackletsTotal); - static int nEvent = 0; + static int32_t nEvent = 0; char filename[256]; std::ofstream out; if (nEvent == 0) { std::unique_ptr fFastTransformIRS(new TPCFastTransform); - long TimeStamp = (getenv("DUMP_TIMESTAMP_SOR") && atoi(getenv("DUMP_TIMESTAMP_SOR"))) ? fInitTimestamp : GetTimeStamp(); + int64_t TimeStamp = (getenv("DUMP_TIMESTAMP_SOR") && atoi(getenv("DUMP_TIMESTAMP_SOR"))) ? fInitTimestamp : GetTimeStamp(); if (fIsMC && !fRecParam->GetUseCorrectionMap()) { TimeStamp = 0; } diff --git a/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.h b/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.h index 46d991bd481bd..4174b6b8aab46 100644 --- a/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.h +++ b/GPU/GPUTracking/Global/AliHLTGPUDumpComponent.h @@ -37,8 +37,8 @@ class GPUTPCClusterData; class AliHLTGPUDumpComponent : public AliHLTProcessor { public: - static const unsigned int NSLICES = 36; - static const unsigned int NPATCHES = 6; + static const uint32_t NSLICES = 36; + static const uint32_t NPATCHES = 6; AliHLTGPUDumpComponent(); @@ -50,14 +50,14 @@ class AliHLTGPUDumpComponent : public AliHLTProcessor const char* GetComponentID(); void GetInputDataTypes(vector& list); AliHLTComponentDataType GetOutputDataType(); - virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + virtual void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); AliHLTComponent* Spawn(); protected: - int DoInit(int argc, const char** argv); - int DoDeinit(); - int Reconfigure(const char* cdbEntry, const char* chainId); - int DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); + int32_t DoInit(int argc, const char** argv); + int32_t DoDeinit(); + int32_t Reconfigure(const char* cdbEntry, const char* chainId); + int32_t DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); private: float fSolenoidBz; @@ -69,7 +69,7 @@ class AliHLTGPUDumpComponent : public AliHLTProcessor AliRecoParam fOfflineRecoParam; AliTPCTransform* fOrigTransform; bool fIsMC; - long fInitTimestamp; + int64_t fInitTimestamp; }; #endif diff --git a/GPU/GPUTracking/Global/GPUChain.cxx b/GPU/GPUTracking/Global/GPUChain.cxx index b94e48d1e551c..6f6bf33f3c001 100644 --- a/GPU/GPUTracking/Global/GPUChain.cxx +++ b/GPU/GPUTracking/Global/GPUChain.cxx @@ -18,33 +18,33 @@ using namespace GPUCA_NAMESPACE::gpu; constexpr GPUChain::krnlRunRange GPUChain::krnlRunRangeNone; constexpr GPUChain::krnlEvent GPUChain::krnlEventNone; -GPUChain::krnlExec GPUChain::GetGrid(unsigned int totalItems, unsigned int nThreads, int stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGrid(uint32_t totalItems, uint32_t nThreads, int32_t stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) { - const unsigned int nBlocks = (totalItems + nThreads - 1) / nThreads; + const uint32_t nBlocks = (totalItems + nThreads - 1) / nThreads; return {nBlocks, nThreads, stream, d, st}; } -GPUChain::krnlExec GPUChain::GetGrid(unsigned int totalItems, int stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGrid(uint32_t totalItems, int32_t stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) { - return {(unsigned int)-1, totalItems, stream, d, st}; + return {(uint32_t)-1, totalItems, stream, d, st}; } -GPUChain::krnlExec GPUChain::GetGridBlk(unsigned int nBlocks, int stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGridBlk(uint32_t nBlocks, int32_t stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) { - return {(unsigned int)-2, nBlocks, stream, d, st}; + return {(uint32_t)-2, nBlocks, stream, d, st}; } -GPUChain::krnlExec GPUChain::GetGridBlkStep(unsigned int nBlocks, int stream, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGridBlkStep(uint32_t nBlocks, int32_t stream, GPUCA_RECO_STEP st) { - return {(unsigned int)-2, nBlocks, stream, GPUReconstruction::krnlDeviceType::Auto, st}; + return {(uint32_t)-2, nBlocks, stream, GPUReconstruction::krnlDeviceType::Auto, st}; } -GPUChain::krnlExec GPUChain::GetGridAuto(int stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGridAuto(int32_t stream, GPUReconstruction::krnlDeviceType d, GPUCA_RECO_STEP st) { - return {(unsigned int)-3, 0, stream, d, st}; + return {(uint32_t)-3, 0, stream, d, st}; } -GPUChain::krnlExec GPUChain::GetGridAutoStep(int stream, GPUCA_RECO_STEP st) +GPUChain::krnlExec GPUChain::GetGridAutoStep(int32_t stream, GPUCA_RECO_STEP st) { - return {(unsigned int)-3, 0, stream, GPUReconstruction::krnlDeviceType::Auto, st}; + return {(uint32_t)-3, 0, stream, GPUReconstruction::krnlDeviceType::Auto, st}; } diff --git a/GPU/GPUTracking/Global/GPUChain.h b/GPU/GPUTracking/Global/GPUChain.h index 21245a415a5cd..65de907d7798a 100644 --- a/GPU/GPUTracking/Global/GPUChain.h +++ b/GPU/GPUTracking/Global/GPUChain.h @@ -41,18 +41,18 @@ class GPUChain virtual ~GPUChain() = default; virtual void RegisterPermanentMemoryAndProcessors() = 0; virtual void RegisterGPUProcessors() = 0; - virtual int EarlyConfigure() { return 0; }; - virtual int Init() = 0; - virtual int PrepareEvent() = 0; - virtual int Finalize() = 0; - virtual int RunChain() = 0; + virtual int32_t EarlyConfigure() { return 0; }; + virtual int32_t Init() = 0; + virtual int32_t PrepareEvent() = 0; + virtual int32_t Finalize() = 0; + virtual int32_t RunChain() = 0; virtual void MemorySize(size_t& gpuMem, size_t& pageLockedHostMem) = 0; virtual void PrintMemoryStatistics(){}; - virtual int CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr) { return 0; } + virtual int32_t CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr) { return 0; } virtual bool SupportsDoublePipeline() { return false; } - virtual int FinalizePipelinedProcessing() { return 0; } + virtual int32_t FinalizePipelinedProcessing() { return 0; } - constexpr static int NSLICES = GPUReconstruction::NSLICES; + constexpr static int32_t NSLICES = GPUReconstruction::NSLICES; virtual void DumpSettings(const char* dir = "") {} virtual void ReadSettings(const char* dir = "") {} @@ -75,7 +75,7 @@ class GPUChain GPUReconstructionCPU* mRec; GPUChain(GPUReconstruction* rec) : mRec((GPUReconstructionCPU*)rec) {} - int GetThread(); + int32_t GetThread(); // Make functions from GPUReconstruction*** available inline GPUConstantMem* processors() { return mRec->processors(); } @@ -84,8 +84,8 @@ class GPUChain inline GPUParam& param() { return mRec->param(); } inline const GPUConstantMem* processors() const { return mRec->processors(); } inline GPUSettingsProcessing& ProcessingSettings() { return mRec->mProcessingSettings; } - inline void SynchronizeStream(int stream) { mRec->SynchronizeStream(stream); } - inline void SynchronizeEvents(deviceEvent* evList, int nEvents = 1) { mRec->SynchronizeEvents(evList, nEvents); } + inline void SynchronizeStream(int32_t stream) { mRec->SynchronizeStream(stream); } + inline void SynchronizeEvents(deviceEvent* evList, int32_t nEvents = 1) { mRec->SynchronizeEvents(evList, nEvents); } inline void SynchronizeEventAndRelease(deviceEvent& ev, bool doGPU = true) { if (doGPU) { @@ -101,8 +101,8 @@ class GPUChain cond = 2; } } - inline bool IsEventDone(deviceEvent* evList, int nEvents = 1) { return mRec->IsEventDone(evList, nEvents); } - inline void RecordMarker(deviceEvent ev, int stream) { mRec->RecordMarker(ev, stream); } + inline bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) { return mRec->IsEventDone(evList, nEvents); } + inline void RecordMarker(deviceEvent ev, int32_t stream) { mRec->RecordMarker(ev, stream); } virtual inline std::unique_ptr GetThreadContext() { return mRec->GetThreadContext(); } inline void SynchronizeGPU() { mRec->SynchronizeGPU(); } inline void ReleaseEvent(deviceEvent ev, bool doGPU = true) @@ -111,25 +111,25 @@ class GPUChain mRec->ReleaseEvent(ev); } } - inline void StreamWaitForEvents(int stream, deviceEvent* evList, int nEvents = 1) { mRec->StreamWaitForEvents(stream, evList, nEvents); } + inline void StreamWaitForEvents(int32_t stream, deviceEvent* evList, int32_t nEvents = 1) { mRec->StreamWaitForEvents(stream, evList, nEvents); } template - void RunHelperThreads(T function, GPUReconstructionHelpers::helperDelegateBase* functionCls, int count); + void RunHelperThreads(T function, GPUReconstructionHelpers::helperDelegateBase* functionCls, int32_t count); inline void WaitForHelperThreads() { mRec->WaitForHelperThreads(); } - inline int HelperError(int iThread) const { return mRec->HelperError(iThread); } - inline int HelperDone(int iThread) const { return mRec->HelperDone(iThread); } - inline void ResetHelperThreads(int helpers) { mRec->ResetHelperThreads(helpers); } - inline int GPUDebug(const char* state = "UNKNOWN", int stream = -1) { return mRec->GPUDebug(state, stream); } + inline int32_t HelperError(int32_t iThread) const { return mRec->HelperError(iThread); } + inline int32_t HelperDone(int32_t iThread) const { return mRec->HelperDone(iThread); } + inline void ResetHelperThreads(int32_t helpers) { mRec->ResetHelperThreads(helpers); } + inline int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1) { return mRec->GPUDebug(state, stream); } // nEvents is forced to 0 if evList == nullptr - inline void TransferMemoryResourceToGPU(RecoStep step, GPUMemoryResource* res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourceToGPU, res, stream, ev, evList, nEvents); } - inline void TransferMemoryResourceToHost(RecoStep step, GPUMemoryResource* res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourceToHost, res, stream, ev, evList, nEvents); } - inline void TransferMemoryResourcesToGPU(RecoStep step, GPUProcessor* proc, int stream = -1, bool all = false) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourcesToGPU, proc, stream, all); } - inline void TransferMemoryResourcesToHost(RecoStep step, GPUProcessor* proc, int stream = -1, bool all = false) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourcesToHost, proc, stream, all); } - inline void TransferMemoryResourceLinkToGPU(RecoStep step, short res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourceLinkToGPU, res, stream, ev, evList, nEvents); } - inline void TransferMemoryResourceLinkToHost(RecoStep step, short res, int stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourceLinkToHost, res, stream, ev, evList, nEvents); } + inline void TransferMemoryResourceToGPU(RecoStep step, GPUMemoryResource* res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourceToGPU, res, stream, ev, evList, nEvents); } + inline void TransferMemoryResourceToHost(RecoStep step, GPUMemoryResource* res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourceToHost, res, stream, ev, evList, nEvents); } + inline void TransferMemoryResourcesToGPU(RecoStep step, GPUProcessor* proc, int32_t stream = -1, bool all = false) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourcesToGPU, proc, stream, all); } + inline void TransferMemoryResourcesToHost(RecoStep step, GPUProcessor* proc, int32_t stream = -1, bool all = false) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourcesToHost, proc, stream, all); } + inline void TransferMemoryResourceLinkToGPU(RecoStep step, int16_t res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { timeCpy(step, true, &GPUReconstructionCPU::TransferMemoryResourceLinkToGPU, res, stream, ev, evList, nEvents); } + inline void TransferMemoryResourceLinkToHost(RecoStep step, int16_t res, int32_t stream = -1, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { timeCpy(step, false, &GPUReconstructionCPU::TransferMemoryResourceLinkToHost, res, stream, ev, evList, nEvents); } // Todo: retrieve step from proc, move kernelClass->GetStep to retrieve it from GetProcessor - inline void WriteToConstantMemory(RecoStep step, size_t offset, const void* src, size_t size, int stream = -1, deviceEvent* ev = nullptr) { timeCpy(step, true, &GPUReconstructionCPU::WriteToConstantMemory, offset, src, size, stream, ev); } - inline void GPUMemCpy(RecoStep step, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) { timeCpy(step, toGPU, &GPUReconstructionCPU::GPUMemCpy, dst, src, size, stream, toGPU, ev, evList, nEvents); } - inline void GPUMemCpyAlways(RecoStep step, void* dst, const void* src, size_t size, int stream, int toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int nEvents = 1) + inline void WriteToConstantMemory(RecoStep step, size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) { timeCpy(step, true, &GPUReconstructionCPU::WriteToConstantMemory, offset, src, size, stream, ev); } + inline void GPUMemCpy(RecoStep step, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { timeCpy(step, toGPU, &GPUReconstructionCPU::GPUMemCpy, dst, src, size, stream, toGPU, ev, evList, nEvents); } + inline void GPUMemCpyAlways(RecoStep step, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) { if (toGPU == -1) { memcpy(dst, src, size); @@ -139,12 +139,12 @@ class GPUChain } template - inline void AllocateIOMemoryHelper(unsigned int n, const T*& ptr, std::unique_ptr& u) + inline void AllocateIOMemoryHelper(uint32_t n, const T*& ptr, std::unique_ptr& u) { mRec->AllocateIOMemoryHelper(n, ptr, u); } template - inline unsigned int DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type) + inline uint32_t DumpData(FILE* fp, const T* const* entries, const S* num, InOutPointerType type) { return mRec->DumpData(fp, entries, num, type); } @@ -178,44 +178,44 @@ class GPUChain { mRec->ReadStructFromFile(file, obj); } - template - inline int runKernel(gpu_reconstruction_kernels::krnlSetup&& setup, Args&&... args) + template + inline int32_t runKernel(gpu_reconstruction_kernels::krnlSetup&& setup, Args&&... args) { return mRec->runKernel(std::forward(setup), std::forward(args)...); } - template + template gpu_reconstruction_kernels::krnlProperties getKernelProperties() { return mRec->getKernelProperties(); } - template - HighResTimer& getKernelTimer(RecoStep step, int num = 0, size_t addMemorySize = 0) + template + HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0) { return mRec->getKernelTimer(step, num, addMemorySize); } - template - HighResTimer& getTimer(const char* name, int num = -1) + template + HighResTimer& getTimer(const char* name, int32_t num = -1) { return mRec->getTimer(name, num); } // Get GRID with NBLOCKS minimal such that nThreads * NBLOCS >= totalItems - krnlExec GetGrid(unsigned int totalItems, unsigned int nThreads, int stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGrid(uint32_t totalItems, uint32_t nThreads, int32_t stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); // Get GRID with NBLOCKS minimal such that ideal number of threads * NBLOCKS >= totalItems - krnlExec GetGrid(unsigned int totalItems, int stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGrid(uint32_t totalItems, int32_t stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); // Get GRID with specified number of blocks, each block with ideal number of threads - krnlExec GetGridBlk(unsigned int nBlocks, int stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); - krnlExec GetGridBlkStep(unsigned int nBlocks, int stream, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGridBlk(uint32_t nBlocks, int32_t stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGridBlkStep(uint32_t nBlocks, int32_t stream, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); // Get GRID with ideal number of threads / blocks for GPU - krnlExec GetGridAuto(int stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); - krnlExec GetGridAutoStep(int stream, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGridAuto(int32_t stream, GPUReconstruction::krnlDeviceType d = GPUReconstruction::krnlDeviceType::Auto, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); + krnlExec GetGridAutoStep(int32_t stream, GPUCA_RECO_STEP st = GPUCA_RECO_STEP::NoRecoStep); - inline unsigned int BlockCount() const { return mRec->mBlockCount; } - inline unsigned int WarpSize() const { return mRec->mWarpSize; } - inline unsigned int ThreadCount() const { return mRec->mThreadCount; } + inline uint32_t BlockCount() const { return mRec->mBlockCount; } + inline uint32_t WarpSize() const { return mRec->mWarpSize; } + inline uint32_t ThreadCount() const { return mRec->mThreadCount; } inline size_t AllocateRegisteredMemory(GPUProcessor* proc) { return mRec->AllocateRegisteredMemory(proc); } - inline size_t AllocateRegisteredMemory(short res, GPUOutputControl* control = nullptr) { return mRec->AllocateRegisteredMemory(res, control); } + inline size_t AllocateRegisteredMemory(int16_t res, GPUOutputControl* control = nullptr) { return mRec->AllocateRegisteredMemory(res, control); } template inline void SetupGPUProcessor(T* proc, bool allocate) { @@ -224,33 +224,33 @@ class GPUChain inline GPUChain* GetNextChainInQueue() { return mRec->GetNextChainInQueue(); } - virtual int PrepareTextures() { return 0; } - virtual int DoStuckProtection(int stream, deviceEvent event) { return 0; } + virtual int32_t PrepareTextures() { return 0; } + virtual int32_t DoStuckProtection(int32_t stream, deviceEvent event) { return 0; } template - bool DoDebugAndDump(RecoStep step, int mask, T& processor, S T::*func, Args&&... args) + bool DoDebugAndDump(RecoStep step, int32_t mask, T& processor, S T::*func, Args&&... args) { return DoDebugAndDump(step, mask, true, processor, func, args...); } template - bool DoDebugAndDump(RecoStep step, int mask, bool transfer, T& processor, S T::*func, Args&&... args); + bool DoDebugAndDump(RecoStep step, int32_t mask, bool transfer, T& processor, S T::*func, Args&&... args); template - int runRecoStep(RecoStep step, S T::*func, Args... args); + int32_t runRecoStep(RecoStep step, S T::*func, Args... args); private: template - void timeCpy(RecoStep step, int toGPU, S T::*func, Args... args); + void timeCpy(RecoStep step, int32_t toGPU, S T::*func, Args... args); }; template -inline void GPUChain::RunHelperThreads(T function, GPUReconstructionHelpers::helperDelegateBase* functionCls, int count) +inline void GPUChain::RunHelperThreads(T function, GPUReconstructionHelpers::helperDelegateBase* functionCls, int32_t count) { - mRec->RunHelperThreads((int(GPUReconstructionHelpers::helperDelegateBase::*)(int, int, GPUReconstructionHelpers::helperParam*))function, functionCls, count); + mRec->RunHelperThreads((int32_t(GPUReconstructionHelpers::helperDelegateBase::*)(int32_t, int32_t, GPUReconstructionHelpers::helperParam*))function, functionCls, count); } template -inline void GPUChain::timeCpy(RecoStep step, int toGPU, S T::*func, Args... args) +inline void GPUChain::timeCpy(RecoStep step, int32_t toGPU, S T::*func, Args... args) { if (!Always && step != RecoStep::NoRecoStep && !(GetRecoStepsGPU() & step)) { return; @@ -258,7 +258,7 @@ inline void GPUChain::timeCpy(RecoStep step, int toGPU, S T::*func, Args... args HighResTimer* timer = nullptr; size_t* bytes = nullptr; if (mRec->mProcessingSettings.debugLevel >= 1 && toGPU >= 0) { // Todo: time special cases toGPU < 0 - int id = mRec->getRecoStepNum(step, false); + int32_t id = mRec->getRecoStepNum(step, false); if (id != -1) { auto& tmp = mRec->mTimersRecoSteps[id]; timer = toGPU ? &tmp.timerToGPU : &tmp.timerToHost; @@ -276,7 +276,7 @@ inline void GPUChain::timeCpy(RecoStep step, int toGPU, S T::*func, Args... args } template -bool GPUChain::DoDebugAndDump(GPUChain::RecoStep step, int mask, bool transfer, T& processor, S T::*func, Args&&... args) +bool GPUChain::DoDebugAndDump(GPUChain::RecoStep step, int32_t mask, bool transfer, T& processor, S T::*func, Args&&... args) { if (GetProcessingSettings().keepAllMemory) { if (transfer) { @@ -293,13 +293,13 @@ bool GPUChain::DoDebugAndDump(GPUChain::RecoStep step, int mask, bool transfer, } template -int GPUChain::runRecoStep(RecoStep step, S T::*func, Args... args) +int32_t GPUChain::runRecoStep(RecoStep step, S T::*func, Args... args) { if (GetRecoSteps().isSet(step)) { if (GetProcessingSettings().debugLevel >= 1) { mRec->getRecoStepTimer(step).Start(); } - int retVal = (reinterpret_cast(this)->*func)(args...); + int32_t retVal = (reinterpret_cast(this)->*func)(args...); if (GetProcessingSettings().debugLevel >= 1) { mRec->getRecoStepTimer(step).Stop(); } diff --git a/GPU/GPUTracking/Global/GPUChainITS.cxx b/GPU/GPUTracking/Global/GPUChainITS.cxx index 9e62b480bcac9..89e56bf2d4c22 100644 --- a/GPU/GPUTracking/Global/GPUChainITS.cxx +++ b/GPU/GPUTracking/Global/GPUChainITS.cxx @@ -43,7 +43,7 @@ GPUChainITS::~GPUChainITS() mITSVertexerTraits.reset(); } -GPUChainITS::GPUChainITS(GPUReconstruction* rec, unsigned int maxTracks) : GPUChain(rec), mMaxTracks(maxTracks) {} +GPUChainITS::GPUChainITS(GPUReconstruction* rec, uint32_t maxTracks) : GPUChain(rec), mMaxTracks(maxTracks) {} void GPUChainITS::RegisterPermanentMemoryAndProcessors() { mRec->RegisterGPUProcessor(&processors()->itsFitter, GetRecoStepsGPU() & RecoStep::ITSTracking); } @@ -60,7 +60,7 @@ void GPUChainITS::MemorySize(size_t& gpuMem, size_t& pageLockedHostMem) pageLockedHostMem = gpuMem; } -int GPUChainITS::Init() { return 0; } +int32_t GPUChainITS::Init() { return 0; } o2::its::TrackerTraits* GPUChainITS::GetITSTrackerTraits() { @@ -95,8 +95,8 @@ o2::its::TimeFrame* GPUChainITS::GetITSTimeframe() return mITSTimeFrame.get(); } -int GPUChainITS::PrepareEvent() { return 0; } +int32_t GPUChainITS::PrepareEvent() { return 0; } -int GPUChainITS::Finalize() { return 0; } +int32_t GPUChainITS::Finalize() { return 0; } -int GPUChainITS::RunChain() { return 0; } +int32_t GPUChainITS::RunChain() { return 0; } diff --git a/GPU/GPUTracking/Global/GPUChainITS.h b/GPU/GPUTracking/Global/GPUChainITS.h index cb365392f7272..7ef77da54285e 100644 --- a/GPU/GPUTracking/Global/GPUChainITS.h +++ b/GPU/GPUTracking/Global/GPUChainITS.h @@ -19,7 +19,7 @@ namespace o2::its { struct Cluster; -template +template class Road; class Cell; struct TrackingFrameInfo; @@ -37,10 +37,10 @@ class GPUChainITS : public GPUChain ~GPUChainITS() override; void RegisterPermanentMemoryAndProcessors() override; void RegisterGPUProcessors() override; - int Init() override; - int PrepareEvent() override; - int Finalize() override; - int RunChain() override; + int32_t Init() override; + int32_t PrepareEvent() override; + int32_t Finalize() override; + int32_t RunChain() override; void MemorySize(size_t& gpuMem, size_t& pageLockedHostMem) override; o2::its::TrackerTraits* GetITSTrackerTraits(); @@ -48,13 +48,13 @@ class GPUChainITS : public GPUChain o2::its::TimeFrame* GetITSTimeframe(); protected: - GPUChainITS(GPUReconstruction* rec, unsigned int maxTracks = GPUCA_MAX_ITS_FIT_TRACKS); + GPUChainITS(GPUReconstruction* rec, uint32_t maxTracks = GPUCA_MAX_ITS_FIT_TRACKS); std::unique_ptr mITSTrackerTraits; std::unique_ptr mITSVertexerTraits; std::unique_ptr mITSTimeFrame; std::unique_ptr mFrameworkAllocator; - unsigned int mMaxTracks; + uint32_t mMaxTracks; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index ba17b3e3ead54..d6fd370b3b330 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -66,7 +66,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; using namespace o2::trd; -GPUChainTracking::GPUChainTracking(GPUReconstruction* rec, unsigned int maxTPCHits, unsigned int maxTRDTracklets) : GPUChain(rec), mIOPtrs(processors()->ioPtrs), mInputsHost(new GPUTrackingInputProvider), mInputsShadow(new GPUTrackingInputProvider), mClusterNativeAccess(new ClusterNativeAccess), mTriggerBuffer(new GPUTriggerOutputs), mMaxTPCHits(maxTPCHits), mMaxTRDTracklets(maxTRDTracklets), mDebugFile(new std::ofstream) +GPUChainTracking::GPUChainTracking(GPUReconstruction* rec, uint32_t maxTPCHits, uint32_t maxTRDTracklets) : GPUChain(rec), mIOPtrs(processors()->ioPtrs), mInputsHost(new GPUTrackingInputProvider), mInputsShadow(new GPUTrackingInputProvider), mClusterNativeAccess(new ClusterNativeAccess), mTriggerBuffer(new GPUTriggerOutputs), mMaxTPCHits(maxTPCHits), mMaxTRDTracklets(maxTRDTracklets), mDebugFile(new std::ofstream) { ClearIOPointers(); mFlatObjectsShadow.mChainTracking = this; @@ -85,7 +85,7 @@ void GPUChainTracking::RegisterPermanentMemoryAndProcessors() mRec->RegisterGPUProcessor(mInputsHost.get(), mRec->IsGPU()); if (GetRecoSteps() & RecoStep::TPCSliceTracking) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mRec->RegisterGPUProcessor(&processors()->tpcTrackers[i], GetRecoStepsGPU() & RecoStep::TPCSliceTracking); } } @@ -109,7 +109,7 @@ void GPUChainTracking::RegisterPermanentMemoryAndProcessors() mRec->RegisterGPUProcessor(&processors()->tpcDecompressor, GetRecoStepsGPU() & RecoStep::TPCDecompression); } if (GetRecoSteps() & RecoStep::TPCClusterFinding) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mRec->RegisterGPUProcessor(&processors()->tpcClusterer[i], GetRecoStepsGPU() & RecoStep::TPCClusterFinding); } } @@ -130,7 +130,7 @@ void GPUChainTracking::RegisterGPUProcessors() } memcpy((void*)&processorsShadow()->trdTrackerGPU, (const void*)&processors()->trdTrackerGPU, sizeof(processors()->trdTrackerGPU)); if (GetRecoStepsGPU() & RecoStep::TPCSliceTracking) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mRec->RegisterGPUDeviceProcessor(&processorsShadow()->tpcTrackers[i], &processors()->tpcTrackers[i]); } } @@ -156,7 +156,7 @@ void GPUChainTracking::RegisterGPUProcessors() mRec->RegisterGPUDeviceProcessor(&processorsShadow()->tpcDecompressor, &processors()->tpcDecompressor); } if (GetRecoStepsGPU() & RecoStep::TPCClusterFinding) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mRec->RegisterGPUDeviceProcessor(&processorsShadow()->tpcClusterer[i], &processors()->tpcClusterer[i]); } } @@ -285,12 +285,12 @@ bool GPUChainTracking::ValidateSettings() GPUError("OMP Kernels require mergerReadFromTrackerDirectly"); return false; } - if (param().continuousMaxTimeBin > (int)GPUSettings::TPC_MAX_TF_TIME_BIN) { + if (param().continuousMaxTimeBin > (int32_t)GPUSettings::TPC_MAX_TF_TIME_BIN) { GPUError("configured max time bin exceeds 256 orbits"); return false; } if ((GetRecoStepsGPU() & RecoStep::TPCClusterFinding) && std::max(GetProcessingSettings().nTPCClustererLanes + 1, GetProcessingSettings().nTPCClustererLanes * 2) + (GetProcessingSettings().doublePipeline ? 1 : 0) > mRec->NStreams()) { - GPUError("NStreams (%d) must be > nTPCClustererLanes (%d)", mRec->NStreams(), (int)GetProcessingSettings().nTPCClustererLanes); + GPUError("NStreams (%d) must be > nTPCClustererLanes (%d)", mRec->NStreams(), (int32_t)GetProcessingSettings().nTPCClustererLanes); return false; } if (GetProcessingSettings().noGPUMemoryRegistration && GetProcessingSettings().tpcCompressionGatherMode != 3) { @@ -299,7 +299,7 @@ bool GPUChainTracking::ValidateSettings() } if (GetProcessingSettings().doublePipeline) { if (!GetRecoStepsOutputs().isOnlySet(GPUDataTypes::InOutType::TPCMergedTracks, GPUDataTypes::InOutType::TPCCompressedClusters, GPUDataTypes::InOutType::TPCClusters)) { - GPUError("Invalid outputs for double pipeline mode 0x%x", (unsigned int)GetRecoStepsOutputs()); + GPUError("Invalid outputs for double pipeline mode 0x%x", (uint32_t)GetRecoStepsOutputs()); return false; } if (((GetRecoStepsOutputs().isSet(GPUDataTypes::InOutType::TPCCompressedClusters) && mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::compressedClusters)] == nullptr) || @@ -324,7 +324,7 @@ bool GPUChainTracking::ValidateSettings() } if (GetRecoSteps() & RecoStep::TRDTracking) { if (GetProcessingSettings().trdTrackModelO2 && (GetProcessingSettings().createO2Output == 0 || param().rec.tpc.nWaysOuter == 0 || (GetMatLUT() == nullptr && !GetProcessingSettings().willProvideO2PropagatorLate))) { - GPUError("TRD tracking can only run on O2 TPC tracks if createO2Output is enabled (%d), nWaysOuter is set (%d), and matBudLUT is available (0x%p)", (int)GetProcessingSettings().createO2Output, (int)param().rec.tpc.nWaysOuter, (void*)GetMatLUT()); + GPUError("TRD tracking can only run on O2 TPC tracks if createO2Output is enabled (%d), nWaysOuter is set (%d), and matBudLUT is available (0x%p)", (int32_t)GetProcessingSettings().createO2Output, (int32_t)param().rec.tpc.nWaysOuter, (void*)GetMatLUT()); return false; } if ((GetRecoStepsGPU() & RecoStep::TRDTracking) && !GetProcessingSettings().trdTrackModelO2 && GetProcessingSettings().createO2Output > 1) { @@ -332,19 +332,19 @@ bool GPUChainTracking::ValidateSettings() return false; } if ((((GetRecoStepsGPU() & RecoStep::TRDTracking) && GetProcessingSettings().trdTrackModelO2) || ((GetRecoStepsGPU() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && (!GetProcessingSettings().o2PropagatorUseGPUField || (GetMatLUT() == nullptr && !GetProcessingSettings().willProvideO2PropagatorLate))) { - GPUError("Cannot use TRD tracking or Refit on GPU without GPU polynomial field map (%d) or matlut table (%p)", (int)GetProcessingSettings().o2PropagatorUseGPUField, (void*)GetMatLUT()); + GPUError("Cannot use TRD tracking or Refit on GPU without GPU polynomial field map (%d) or matlut table (%p)", (int32_t)GetProcessingSettings().o2PropagatorUseGPUField, (void*)GetMatLUT()); return false; } } return true; } -int GPUChainTracking::Init() +int32_t GPUChainTracking::Init() { const auto& threadContext = GetThreadContext(); if (GetProcessingSettings().debugLevel >= 1) { - printf("Enabled Reconstruction Steps: 0x%x (on GPU: 0x%x)", (int)GetRecoSteps().get(), (int)GetRecoStepsGPU().get()); - for (unsigned int i = 0; i < sizeof(GPUDataTypes::RECO_STEP_NAMES) / sizeof(GPUDataTypes::RECO_STEP_NAMES[0]); i++) { + printf("Enabled Reconstruction Steps: 0x%x (on GPU: 0x%x)", (int32_t)GetRecoSteps().get(), (int32_t)GetRecoStepsGPU().get()); + for (uint32_t i = 0; i < sizeof(GPUDataTypes::RECO_STEP_NAMES) / sizeof(GPUDataTypes::RECO_STEP_NAMES[0]); i++) { if (GetRecoSteps().isSet(1u << i)) { printf(" - %s", GPUDataTypes::RECO_STEP_NAMES[i]); if (GetRecoStepsGPU().isSet(1u << i)) { @@ -358,7 +358,7 @@ int GPUChainTracking::Init() return 1; } - for (unsigned int i = 0; i < mSubOutputControls.size(); i++) { + for (uint32_t i = 0; i < mSubOutputControls.size(); i++) { if (mSubOutputControls[i] == nullptr) { mSubOutputControls[i] = &mRec->OutputControl(); } @@ -401,7 +401,7 @@ int GPUChainTracking::Init() return 0; } -void GPUChainTracking::UpdateGPUCalibObjects(int stream, const GPUCalibObjectsConst* ptrMask) +void GPUChainTracking::UpdateGPUCalibObjects(int32_t stream, const GPUCalibObjectsConst* ptrMask) { if (processors()->calibObjects.fastTransform && (ptrMask == nullptr || ptrMask->fastTransform)) { memcpy((void*)mFlatObjectsShadow.mCalibObjects.fastTransform, (const void*)processors()->calibObjects.fastTransform, sizeof(*processors()->calibObjects.fastTransform)); @@ -465,12 +465,12 @@ void GPUChainTracking::UpdateGPUCalibObjects(int stream, const GPUCalibObjectsCo memcpy((void*)&processorsShadow()->calibObjects, (void*)&mFlatObjectsDevice.mCalibObjects, sizeof(mFlatObjectsDevice.mCalibObjects)); } -void GPUChainTracking::UpdateGPUCalibObjectsPtrs(int stream) +void GPUChainTracking::UpdateGPUCalibObjectsPtrs(int32_t stream) { WriteToConstantMemory(RecoStep::NoRecoStep, (char*)&processors()->calibObjects - (char*)processors(), &mFlatObjectsDevice.mCalibObjects, sizeof(mFlatObjectsDevice.mCalibObjects), stream); } -int GPUChainTracking::PrepareEvent() +int32_t GPUChainTracking::PrepareEvent() { mRec->MemoryScalers()->nTRDTracklets = mIOPtrs.nTRDTracklets; if (mIOPtrs.clustersNative) { @@ -483,7 +483,7 @@ int GPUChainTracking::PrepareEvent() return 0; } -int GPUChainTracking::ForceInitQA() +int32_t GPUChainTracking::ForceInitQA() { auto& qa = mQAFromForeignChain ? mQAFromForeignChain->mQA : mQA; if (!qa) { @@ -495,7 +495,7 @@ int GPUChainTracking::ForceInitQA() return 0; } -int GPUChainTracking::Finalize() +int32_t GPUChainTracking::Finalize() { if (GetProcessingSettings().runQA && GetQA()->IsInitialized() && !(mConfigQA && mConfigQA->shipToQC) && !mQAFromForeignChain) { GetQA()->UpdateChain(this); @@ -572,7 +572,7 @@ void GPUChainTracking::ClearIOPointers() void GPUChainTracking::AllocateIOMemory() { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { AllocateIOMemoryHelper(mIOPtrs.nClusterData[i], mIOPtrs.clusterData[i], mIOMem.clusterData[i]); AllocateIOMemoryHelper(mIOPtrs.nRawClusters[i], mIOPtrs.rawClusters[i], mIOMem.rawClusters[i]); AllocateIOMemoryHelper(mIOPtrs.nSliceTracks[i], mIOPtrs.sliceTracks[i], mIOMem.sliceTracks[i]); @@ -618,9 +618,9 @@ void GPUChainTracking::SetTRDGeometry(std::unique_ptr&& g processors()->calibObjects.trdGeometry = mTRDGeometryU.get(); } -int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) +int32_t GPUChainTracking::DoQueuedUpdates(int32_t stream, bool updateSlave) { - int retVal = 0; + int32_t retVal = 0; std::unique_ptr grp; const GPUSettingsProcessing* p = nullptr; std::lock_guard lk(mMutexUpdateCalib); @@ -650,7 +650,7 @@ int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) #endif void* const* pSrc = (void* const*)mNewCalibObjects.get(); void** pDst = (void**)&processors()->calibObjects; - for (unsigned int i = 0; i < sizeof(processors()->calibObjects) / sizeof(void*); i++) { + for (uint32_t i = 0; i < sizeof(processors()->calibObjects) / sizeof(void*); i++) { if (pSrc[i]) { pDst[i] = pSrc[i]; } @@ -672,7 +672,7 @@ int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) } } if (mRec->IsGPU()) { - std::array oldFlatPtrs, oldFlatPtrsDevice; + std::array oldFlatPtrs, oldFlatPtrsDevice; memcpy(oldFlatPtrs.data(), (void*)&mFlatObjectsShadow, oldFlatPtrs.size()); memcpy(oldFlatPtrsDevice.data(), (void*)&mFlatObjectsDevice, oldFlatPtrsDevice.size()); mRec->ResetRegisteredMemoryPointers(mFlatObjectsShadow.mMemoryResFlat); @@ -694,7 +694,7 @@ int GPUChainTracking::DoQueuedUpdates(int stream, bool updateSlave) return retVal; } -int GPUChainTracking::RunChain() +int32_t GPUChainTracking::RunChain() { if ((((GetRecoSteps() & RecoStep::TRDTracking) && !GetProcessingSettings().trdTrackModelO2 && !GetProcessingSettings().willProvideO2PropagatorLate) || ((GetRecoSteps() & RecoStep::Refit) && !param().rec.trackingRefitGPUModel)) && processors()->calibObjects.o2Propagator == nullptr) { GPUFatal("Cannot run TRD tracking or refit with o2 track model without o2 propagator"); // This check must happen during run, since o2::Propagator cannot be available during init @@ -713,7 +713,7 @@ int GPUChainTracking::RunChain() } } if (needQA) { - mFractionalQAEnabled = GetProcessingSettings().qcRunFraction == 100.f || (unsigned int)(rand() % 10000) < (unsigned int)(GetProcessingSettings().qcRunFraction * 100); + mFractionalQAEnabled = GetProcessingSettings().qcRunFraction == 100.f || (uint32_t)(rand() % 10000) < (uint32_t)(GetProcessingSettings().qcRunFraction * 100); } if (GetProcessingSettings().debugLevel >= 6) { *mDebugFile << "\n\nProcessing event " << mRec->getNEventsProcessed() << std::endl; @@ -757,7 +757,7 @@ int GPUChainTracking::RunChain() return 1; } - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { // GPUInfo("slice %d clusters %d tracks %d", i, mClusterData[i].NumberOfClusters(), processors()->tpcTrackers[i].Output()->NTracks()); processors()->tpcMerger.SetSliceData(i, param().rec.tpc.mergerReadFromTrackerDirectly ? nullptr : processors()->tpcTrackers[i].Output()); } @@ -804,7 +804,7 @@ int GPUChainTracking::RunChain() mRec->SetNOMPThreads(-1); } - int retVal = 0; + int32_t retVal = 0; if (CheckErrorCodes(false, false, mRec->getErrorCodeOutput())) { retVal = 3; if (!GetProcessingSettings().ignoreNonFatalGPUErrors) { @@ -815,11 +815,11 @@ int GPUChainTracking::RunChain() if (GetProcessingSettings().doublePipeline) { return retVal; } - int retVal2 = RunChainFinalize(); + int32_t retVal2 = RunChainFinalize(); return retVal2 ? retVal2 : retVal; } -int GPUChainTracking::RunChainFinalize() +int32_t GPUChainTracking::RunChainFinalize() { #ifdef GPUCA_HAVE_O2HEADERS if (mIOPtrs.clustersNative && (GetRecoSteps() & RecoStep::TPCCompression) && GetProcessingSettings().runCompressionStatistics) { @@ -839,7 +839,7 @@ int GPUChainTracking::RunChainFinalize() GetQA()->RunQA(!GetProcessingSettings().runQA); mRec->getGeneralStepTimer(GeneralStep::QA).Stop(); if (GetProcessingSettings().debugLevel == 0) { - GPUInfo("Total QA runtime: %d us", (int)(mRec->getGeneralStepTimer(GeneralStep::QA).GetElapsedTime() * 1000000)); + GPUInfo("Total QA runtime: %d us", (int32_t)(mRec->getGeneralStepTimer(GeneralStep::QA).GetElapsedTime() * 1000000)); } } @@ -868,7 +868,7 @@ int GPUChainTracking::RunChainFinalize() GPUInfo("Press key for next event!"); } - int iKey; + int32_t iKey; do { Sleep(10); if (GetProcessingSettings().eventDisplay->EnableSendKey()) { @@ -900,7 +900,7 @@ int GPUChainTracking::RunChainFinalize() return 0; } -int GPUChainTracking::FinalizePipelinedProcessing() +int32_t GPUChainTracking::FinalizePipelinedProcessing() { if (mPipelineFinalizationCtx) { { @@ -913,16 +913,16 @@ int GPUChainTracking::FinalizePipelinedProcessing() return RunChainFinalize(); } -int GPUChainTracking::HelperReadEvent(int iSlice, int threadId, GPUReconstructionHelpers::helperParam* par) { return ReadEvent(iSlice, threadId); } +int32_t GPUChainTracking::HelperReadEvent(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) { return ReadEvent(iSlice, threadId); } -int GPUChainTracking::HelperOutput(int iSlice, int threadId, GPUReconstructionHelpers::helperParam* par) +int32_t GPUChainTracking::HelperOutput(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) { if (param().rec.tpc.globalTracking) { - unsigned int tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); - unsigned int sliceLeft, sliceRight; + uint32_t tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); + uint32_t sliceLeft, sliceRight; GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(tmpSlice, sliceLeft, sliceRight); - while (mSliceSelectorReady < (int)tmpSlice || mSliceSelectorReady < (int)sliceLeft || mSliceSelectorReady < (int)sliceRight) { + while (mSliceSelectorReady < (int32_t)tmpSlice || mSliceSelectorReady < (int32_t)sliceLeft || mSliceSelectorReady < (int32_t)sliceRight) { if (par->reset) { return 1; } @@ -940,10 +940,10 @@ int GPUChainTracking::HelperOutput(int iSlice, int threadId, GPUReconstructionHe return 0; } -int GPUChainTracking::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::vector>* fillErrors) +int32_t GPUChainTracking::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::vector>* fillErrors) { - int retVal = 0; - for (int i = 0; i < 1 + (!cpuOnly && mRec->IsGPU()); i++) { + int32_t retVal = 0; + for (int32_t i = 0; i < 1 + (!cpuOnly && mRec->IsGPU()); i++) { if (i) { const auto& threadContext = GetThreadContext(); if (GetProcessingSettings().doublePipeline) { @@ -954,7 +954,7 @@ int GPUChainTracking::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::v } } if (processors()->errorCodes.hasError()) { - static int errorsShown = 0; + static int32_t errorsShown = 0; static bool quiet = false; static std::chrono::time_point silenceFrom; if (!quiet && errorsShown++ >= 10 && GetProcessingSettings().throttleAlarms && !forceShowErrors) { @@ -978,10 +978,10 @@ int GPUChainTracking::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::v processors()->errorCodes.printErrors(GetProcessingSettings().throttleAlarms && !forceShowErrors); } if (fillErrors) { - unsigned int nErrors = processors()->errorCodes.getNErrors(); - const unsigned int* pErrors = processors()->errorCodes.getErrorPtr(); - for (unsigned int j = 0; j < nErrors; j++) { - fillErrors->emplace_back(std::array{pErrors[4 * j], pErrors[4 * j + 1], pErrors[4 * j + 2], pErrors[4 * j + 3]}); + uint32_t nErrors = processors()->errorCodes.getNErrors(); + const uint32_t* pErrors = processors()->errorCodes.getErrorPtr(); + for (uint32_t j = 0; j < nErrors; j++) { + fillErrors->emplace_back(std::array{pErrors[4 * j], pErrors[4 * j + 1], pErrors[4 * j + 2], pErrors[4 * j + 3]}); } } } @@ -1006,7 +1006,7 @@ void GPUChainTracking::SetUpdateCalibObjects(const GPUCalibObjectsConst& obj, co if (mNewCalibObjects) { void* const* pSrc = (void* const*)&obj; void** pDst = (void**)mNewCalibObjects.get(); - for (unsigned int i = 0; i < sizeof(*mNewCalibObjects) / sizeof(void*); i++) { + for (uint32_t i = 0; i < sizeof(*mNewCalibObjects) / sizeof(void*); i++) { if (pSrc[i]) { pDst[i] = pSrc[i]; } diff --git a/GPU/GPUTracking/Global/GPUChainTracking.h b/GPU/GPUTracking/Global/GPUChainTracking.h index 81ed442c11412..b222d6180bdf2 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.h +++ b/GPU/GPUTracking/Global/GPUChainTracking.h @@ -76,16 +76,16 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega ~GPUChainTracking() override; void RegisterPermanentMemoryAndProcessors() override; void RegisterGPUProcessors() override; - int Init() override; - int PrepareEvent() override; - int Finalize() override; - int RunChain() override; + int32_t Init() override; + int32_t PrepareEvent() override; + int32_t Finalize() override; + int32_t RunChain() override; void MemorySize(size_t& gpuMem, size_t& pageLockedHostMem) override; - int CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr) override; + int32_t CheckErrorCodes(bool cpuOnly = false, bool forceShowErrors = false, std::vector>* fillErrors = nullptr) override; bool SupportsDoublePipeline() override { return true; } - int FinalizePipelinedProcessing() override; + int32_t FinalizePipelinedProcessing() override; void ClearErrorCodes(bool cpuOnly = false); - int DoQueuedUpdates(int stream, bool updateSlave = true); // Forces doing queue calib updates, don't call when you are not sure you are allowed to do so! + int32_t DoQueuedUpdates(int32_t stream, bool updateSlave = true); // Forces doing queue calib updates, don't call when you are not sure you are allowed to do so! bool QARanForTF() const { return mFractionalQAEnabled; } // Structures for input and output data @@ -97,7 +97,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega InOutMemory(InOutMemory&&); InOutMemory& operator=(InOutMemory&&); - std::unique_ptr tpcZSpages; + std::unique_ptr tpcZSpages; std::unique_ptr tpcZSpagesChar; // Same as above, but as char (needed for reading dumps, but deprecated, since alignment can be wrong) // TODO: Fix alignment std::unique_ptr tpcCompressedClusters; // TODO: Fix alignment std::unique_ptr tpcZSmeta; @@ -119,8 +119,8 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega std::unique_ptr trdTracklets; std::unique_ptr trdSpacePoints; std::unique_ptr trdTriggerTimes; - std::unique_ptr trdTrackletIdxFirst; - std::unique_ptr trdTrigRecMask; + std::unique_ptr trdTrackletIdxFirst; + std::unique_ptr trdTrigRecMask; std::unique_ptr trdTracks; std::unique_ptr clusterNativeMC; std::unique_ptr> clusterNativeMCView; @@ -137,15 +137,15 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega using GPUChain::DumpData; void DumpData(const char* filename); using GPUChain::ReadData; - int ReadData(const char* filename); + int32_t ReadData(const char* filename); void DumpSettings(const char* dir = "") override; void ReadSettings(const char* dir = "") override; // Converter / loader functions - int ConvertNativeToClusterData(); + int32_t ConvertNativeToClusterData(); void ConvertNativeToClusterDataLegacy(); void ConvertRun2RawToNative(); - void ConvertZSEncoder(int version); + void ConvertZSEncoder(int32_t version); void ConvertZSFilter(bool zs12bit); // Getters for external usage of tracker classes @@ -157,23 +157,23 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega GPUDisplayInterface* GetEventDisplay() { return mEventDisplay.get(); } const GPUQA* GetQA() const { return mQAFromForeignChain ? mQAFromForeignChain->mQA.get() : mQA.get(); } GPUQA* GetQA() { return mQAFromForeignChain ? mQAFromForeignChain->mQA.get() : mQA.get(); } - int ForceInitQA(); + int32_t ForceInitQA(); void SetQAFromForeignChain(GPUChainTracking* chain) { mQAFromForeignChain = chain; } const GPUSettingsDisplay* GetEventDisplayConfig() const { return mConfigDisplay; } const GPUSettingsQA* GetQAConfig() const { return mConfigQA; } // Processing functions - int RunTPCClusterizer(bool synchronizeOutput = true); - int ForwardTPCDigits(); - int RunTPCTrackingSlices(); - int RunTPCTrackingMerger(bool synchronizeOutput = true); - template - int RunTRDTracking(); - template - int DoTRDGPUTracking(T* externalInstance = nullptr); - int RunTPCCompression(); - int RunTPCDecompression(); - int RunRefit(); + int32_t RunTPCClusterizer(bool synchronizeOutput = true); + int32_t ForwardTPCDigits(); + int32_t RunTPCTrackingSlices(); + int32_t RunTPCTrackingMerger(bool synchronizeOutput = true); + template + int32_t RunTRDTracking(); + template + int32_t DoTRDGPUTracking(T* externalInstance = nullptr); + int32_t RunTPCCompression(); + int32_t RunTPCDecompression(); + int32_t RunRefit(); // Getters / setters for parameters const CorrectionMapsHelper* GetTPCTransformHelper() const { return processors()->calibObjects.fastTransformHelper; } @@ -194,7 +194,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega void SetCalibObjects(const GPUCalibObjects& obj) { memcpy((void*)&processors()->calibObjects, (const void*)&obj, sizeof(obj)); } void SetUpdateCalibObjects(const GPUCalibObjectsConst& obj, const GPUNewCalibValues& vals); void LoadClusterErrors(); - void SetSubOutputControl(int i, GPUOutputControl* v) { mSubOutputControls[i] = v; } + void SetSubOutputControl(int32_t i, GPUOutputControl* v) { mSubOutputControls[i] = v; } void SetFinalInputCallback(std::function v) { mWaitForFinalInputs = v; } const GPUSettingsDisplay* mConfigDisplay = nullptr; // Abstract pointer to Standalone Display Configuration Structure @@ -210,11 +210,11 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega char* mTpcTransformMShapeBuffer = nullptr; char* mdEdxSplinesBuffer = nullptr; char* mMatLUTBuffer = nullptr; - short mMemoryResFlat = -1; + int16_t mMemoryResFlat = -1; void* SetPointersFlatObjects(void* mem); }; - void UpdateGPUCalibObjects(int stream, const GPUCalibObjectsConst* ptrMask = nullptr); - void UpdateGPUCalibObjectsPtrs(int stream); + void UpdateGPUCalibObjects(int32_t stream, const GPUCalibObjectsConst* ptrMask = nullptr); + void UpdateGPUCalibObjectsPtrs(int32_t stream); struct eventStruct // Must consist only of void* ptr that will hold the GPU event ptrs! { @@ -231,14 +231,14 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega RecoStep step; }; - GPUChainTracking(GPUReconstruction* rec, unsigned int maxTPCHits = GPUCA_MAX_CLUSTERS, unsigned int maxTRDTracklets = GPUCA_MAX_TRD_TRACKLETS); + GPUChainTracking(GPUReconstruction* rec, uint32_t maxTPCHits = GPUCA_MAX_CLUSTERS, uint32_t maxTRDTracklets = GPUCA_MAX_TRD_TRACKLETS); - int ReadEvent(unsigned int iSlice, int threadId); - void WriteOutput(int iSlice, int threadId); - int GlobalTracking(unsigned int iSlice, int threadId, bool synchronizeOutput = true); + int32_t ReadEvent(uint32_t iSlice, int32_t threadId); + void WriteOutput(int32_t iSlice, int32_t threadId); + int32_t GlobalTracking(uint32_t iSlice, int32_t threadId, bool synchronizeOutput = true); - int PrepareProfile(); - int DoProfile(); + int32_t PrepareProfile(); + int32_t DoProfile(); void PrintMemoryRelations(); void PrintMemoryStatistics() override; void PrepareDebugOutput(); @@ -285,33 +285,33 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega std::unique_ptr mNewCalibValues; // Upper bounds for memory allocation - unsigned int mMaxTPCHits = 0; - unsigned int mMaxTRDTracklets = 0; + uint32_t mMaxTPCHits = 0; + uint32_t mMaxTRDTracklets = 0; // Debug std::unique_ptr mDebugFile; // Synchronization and Locks eventStruct* mEvents = nullptr; - VOLATILE int mSliceSelectorReady = 0; - std::array mWriteOutputDone; + VOLATILE int32_t mSliceSelectorReady = 0; + std::array mWriteOutputDone; std::vector mOutputQueue; private: - int RunChainFinalize(); + int32_t RunChainFinalize(); void SanityCheck(); - int RunTPCTrackingSlices_internal(); - int RunTPCClusterizer_prepare(bool restorePointers); + int32_t RunTPCTrackingSlices_internal(); + int32_t RunTPCClusterizer_prepare(bool restorePointers); #ifdef GPUCA_TPC_GEOMETRY_O2 - std::pair RunTPCClusterizer_transferZS(int iSlice, const CfFragment& fragment, int lane); - void RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clusterer, GPUTPCClusterFinder& clustererShadow, int stage, bool doGPU, int lane); - std::pair TPCClusterizerDecodeZSCount(unsigned int iSlice, const CfFragment& fragment); - std::pair TPCClusterizerDecodeZSCountUpdate(unsigned int iSlice, const CfFragment& fragment); - void TPCClusterizerEnsureZSOffsets(unsigned int iSlice, const CfFragment& fragment); + std::pair RunTPCClusterizer_transferZS(int32_t iSlice, const CfFragment& fragment, int32_t lane); + void RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clusterer, GPUTPCClusterFinder& clustererShadow, int32_t stage, bool doGPU, int32_t lane); + std::pair TPCClusterizerDecodeZSCount(uint32_t iSlice, const CfFragment& fragment); + std::pair TPCClusterizerDecodeZSCountUpdate(uint32_t iSlice, const CfFragment& fragment); + void TPCClusterizerEnsureZSOffsets(uint32_t iSlice, const CfFragment& fragment); #endif - void RunTPCTrackingMerger_MergeBorderTracks(char withinSlice, char mergeMode, GPUReconstruction::krnlDeviceType deviceType); - void RunTPCTrackingMerger_Resolve(char useOrigTrackParam, char mergeAll, GPUReconstruction::krnlDeviceType deviceType); + void RunTPCTrackingMerger_MergeBorderTracks(int8_t withinSlice, int8_t mergeMode, GPUReconstruction::krnlDeviceType deviceType); + void RunTPCTrackingMerger_Resolve(int8_t useOrigTrackParam, int8_t mergeAll, GPUReconstruction::krnlDeviceType deviceType); std::atomic_flag mLockAtomicOutputBuffer = ATOMIC_FLAG_INIT; std::mutex mMutexUpdateCalib; @@ -319,10 +319,10 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega GPUChainTrackingFinalContext* mPipelineNotifyCtx = nullptr; std::function mWaitForFinalInputs; - int HelperReadEvent(int iSlice, int threadId, GPUReconstructionHelpers::helperParam* par); - int HelperOutput(int iSlice, int threadId, GPUReconstructionHelpers::helperParam* par); + int32_t HelperReadEvent(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par); + int32_t HelperOutput(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par); - int OutputStream() const { return mRec->NStreams() - 2; } + int32_t OutputStream() const { return mRec->NStreams() - 2; } }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index 43569fc9f1e60..79804a7f5ffab 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -48,23 +48,23 @@ using namespace o2::tpc::constants; using namespace o2::dataformats; #ifdef GPUCA_TPC_GEOMETRY_O2 -std::pair GPUChainTracking::TPCClusterizerDecodeZSCountUpdate(unsigned int iSlice, const CfFragment& fragment) +std::pair GPUChainTracking::TPCClusterizerDecodeZSCountUpdate(uint32_t iSlice, const CfFragment& fragment) { bool doGPU = mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding; GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; GPUTPCClusterFinder::ZSOffset* o = processors()->tpcClusterer[iSlice].mPzsOffsets; - unsigned int digits = 0; - unsigned int pages = 0; - for (unsigned short j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + uint32_t digits = 0; + uint32_t pages = 0; + for (uint16_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { clusterer.mMinMaxCN[j] = mCFContext->fragmentData[fragment.index].minMaxCN[iSlice][j]; if (doGPU) { - unsigned short posInEndpoint = 0; - unsigned short pagesEndpoint = 0; - for (unsigned int k = clusterer.mMinMaxCN[j].zsPtrFirst; k < clusterer.mMinMaxCN[j].zsPtrLast; k++) { - const unsigned int pageFirst = (k == clusterer.mMinMaxCN[j].zsPtrFirst) ? clusterer.mMinMaxCN[j].zsPageFirst : 0; - const unsigned int pageLast = (k + 1 == clusterer.mMinMaxCN[j].zsPtrLast) ? clusterer.mMinMaxCN[j].zsPageLast : mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; - for (unsigned int l = pageFirst; l < pageLast; l++) { - unsigned short pageDigits = mCFContext->fragmentData[fragment.index].pageDigits[iSlice][j][posInEndpoint++]; + uint16_t posInEndpoint = 0; + uint16_t pagesEndpoint = 0; + for (uint32_t k = clusterer.mMinMaxCN[j].zsPtrFirst; k < clusterer.mMinMaxCN[j].zsPtrLast; k++) { + const uint32_t pageFirst = (k == clusterer.mMinMaxCN[j].zsPtrFirst) ? clusterer.mMinMaxCN[j].zsPageFirst : 0; + const uint32_t pageLast = (k + 1 == clusterer.mMinMaxCN[j].zsPtrLast) ? clusterer.mMinMaxCN[j].zsPageLast : mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; + for (uint32_t l = pageFirst; l < pageLast; l++) { + uint16_t pageDigits = mCFContext->fragmentData[fragment.index].pageDigits[iSlice][j][posInEndpoint++]; if (pageDigits) { *(o++) = GPUTPCClusterFinder::ZSOffset{digits, j, pagesEndpoint}; digits += pageDigits; @@ -95,26 +95,26 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo return {digits, pages}; } -void GPUChainTracking::TPCClusterizerEnsureZSOffsets(unsigned int iSlice, const CfFragment& fragment) +void GPUChainTracking::TPCClusterizerEnsureZSOffsets(uint32_t iSlice, const CfFragment& fragment) { GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; - unsigned int nAdcs = 0; - for (unsigned short endpoint = 0; endpoint < GPUTrackingInOutZS::NENDPOINTS; endpoint++) { + uint32_t nAdcs = 0; + for (uint16_t endpoint = 0; endpoint < GPUTrackingInOutZS::NENDPOINTS; endpoint++) { const auto& data = mCFContext->fragmentData[fragment.index]; - unsigned int pagesEndpoint = 0; - const unsigned int nAdcsExpected = data.nDigits[iSlice][endpoint]; - const unsigned int nPagesExpected = data.nPages[iSlice][endpoint]; + uint32_t pagesEndpoint = 0; + const uint32_t nAdcsExpected = data.nDigits[iSlice][endpoint]; + const uint32_t nPagesExpected = data.nPages[iSlice][endpoint]; - unsigned int nAdcDecoded = 0; + uint32_t nAdcDecoded = 0; const auto& zs = mIOPtrs.tpcZS->slice[iSlice]; - for (unsigned int i = data.minMaxCN[iSlice][endpoint].zsPtrFirst; i < data.minMaxCN[iSlice][endpoint].zsPtrLast; i++) { - const unsigned int pageFirst = (i == data.minMaxCN[iSlice][endpoint].zsPtrFirst) ? data.minMaxCN[iSlice][endpoint].zsPageFirst : 0; - const unsigned int pageLast = (i + 1 == data.minMaxCN[iSlice][endpoint].zsPtrLast) ? data.minMaxCN[iSlice][endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; - for (unsigned int j = pageFirst; j < pageLast; j++) { - const unsigned char* page = static_cast(zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE; + for (uint32_t i = data.minMaxCN[iSlice][endpoint].zsPtrFirst; i < data.minMaxCN[iSlice][endpoint].zsPtrLast; i++) { + const uint32_t pageFirst = (i == data.minMaxCN[iSlice][endpoint].zsPtrFirst) ? data.minMaxCN[iSlice][endpoint].zsPageFirst : 0; + const uint32_t pageLast = (i + 1 == data.minMaxCN[iSlice][endpoint].zsPtrLast) ? data.minMaxCN[iSlice][endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; + for (uint32_t j = pageFirst; j < pageLast; j++) { + const uint8_t* page = static_cast(zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE; const header::RAWDataHeader* rawDataHeader = reinterpret_cast(page); const TPCZSHDRV2* decHdr = reinterpret_cast(page + raw::RDHUtils::getMemorySize(*rawDataHeader) - sizeof(TPCZSHDRV2)); - const unsigned short nSamplesInPage = decHdr->nADCsamples; + const uint16_t nSamplesInPage = decHdr->nADCsamples; nAdcDecoded += nSamplesInPage; pagesEndpoint++; @@ -140,27 +140,27 @@ void GPUChainTracking::TPCClusterizerEnsureZSOffsets(unsigned int iSlice, const namespace { struct TPCCFDecodeScanTmp { - int zsPtrFirst, zsPageFirst, zsPtrLast, zsPageLast, hasData, pageCounter; + int32_t zsPtrFirst, zsPageFirst, zsPtrLast, zsPageLast, hasData, pageCounter; }; } // namespace -std::pair GPUChainTracking::TPCClusterizerDecodeZSCount(unsigned int iSlice, const CfFragment& fragment) +std::pair GPUChainTracking::TPCClusterizerDecodeZSCount(uint32_t iSlice, const CfFragment& fragment) { mRec->getGeneralStepTimer(GeneralStep::Prepare).Start(); - unsigned int nDigits = 0; - unsigned int nPages = 0; - unsigned int endpointAdcSamples[GPUTrackingInOutZS::NENDPOINTS]; + uint32_t nDigits = 0; + uint32_t nPages = 0; + uint32_t endpointAdcSamples[GPUTrackingInOutZS::NENDPOINTS]; memset(endpointAdcSamples, 0, sizeof(endpointAdcSamples)); bool doGPU = mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding; - int firstHBF = (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasTfStartOrbit) ? mIOPtrs.settingsTF->tfStartOrbit : (mIOPtrs.tpcZS->slice[iSlice].count[0] && mIOPtrs.tpcZS->slice[iSlice].nZSPtr[0][0]) ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0]) : 0; + int32_t firstHBF = (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasTfStartOrbit) ? mIOPtrs.settingsTF->tfStartOrbit : (mIOPtrs.tpcZS->slice[iSlice].count[0] && mIOPtrs.tpcZS->slice[iSlice].nZSPtr[0][0]) ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0]) : 0; - for (unsigned short j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint16_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { #ifndef GPUCA_NO_VC if (GetProcessingSettings().prefetchTPCpageScan >= 3 && j < GPUTrackingInOutZS::NENDPOINTS - 1) { - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j + 1]; k++) { - for (unsigned int l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j + 1][k]; l++) { - Vc::Common::prefetchMid(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j + 1][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE); - Vc::Common::prefetchMid(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j + 1][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j + 1]; k++) { + for (uint32_t l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j + 1][k]; l++) { + Vc::Common::prefetchMid(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j + 1][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE); + Vc::Common::prefetchMid(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j + 1][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); } } } @@ -169,27 +169,27 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo std::vector> fragments; fragments.reserve(mCFContext->nFragments); fragments.emplace_back(std::pair{fragment, {0, 0, 0, 0, 0, -1}}); - for (unsigned int i = 1; i < mCFContext->nFragments; i++) { + for (uint32_t i = 1; i < mCFContext->nFragments; i++) { fragments.emplace_back(std::pair{fragments.back().first.next(), {0, 0, 0, 0, 0, -1}}); } std::vector fragmentExtends(mCFContext->nFragments, false); - unsigned int firstPossibleFragment = 0; - unsigned int pageCounter = 0; - unsigned int emptyPages = 0; - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j]; k++) { - if (GetProcessingSettings().tpcSingleSector != -1 && GetProcessingSettings().tpcSingleSector != (int)iSlice) { + uint32_t firstPossibleFragment = 0; + uint32_t pageCounter = 0; + uint32_t emptyPages = 0; + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j]; k++) { + if (GetProcessingSettings().tpcSingleSector != -1 && GetProcessingSettings().tpcSingleSector != (int32_t)iSlice) { break; } nPages += mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; - for (unsigned int l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; l++) { + for (uint32_t l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; l++) { #ifndef GPUCA_NO_VC if (GetProcessingSettings().prefetchTPCpageScan >= 2 && l + 1 < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]) { - Vc::Common::prefetchForOneRead(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + (l + 1) * TPCZSHDR::TPC_ZS_PAGE_SIZE); - Vc::Common::prefetchForOneRead(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + (l + 1) * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); + Vc::Common::prefetchForOneRead(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + (l + 1) * TPCZSHDR::TPC_ZS_PAGE_SIZE); + Vc::Common::prefetchForOneRead(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + (l + 1) * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); } #endif - const unsigned char* const page = ((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE; + const uint8_t* const page = ((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE; const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)page; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { emptyPages++; @@ -206,18 +206,18 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo } errorShown = true; } - } else if (mCFContext->zsVersion != (int)hdr->version) { - GPUError("Received TPC ZS 8kb page of mixed versions, expected %d, received %d (linkid %d, feeCRU %d, feeEndpoint %d, feelinkid %d)", mCFContext->zsVersion, (int)hdr->version, (int)o2::raw::RDHUtils::getLinkID(*rdh), (int)rdh_utils::getCRU(*rdh), (int)rdh_utils::getEndPoint(*rdh), (int)rdh_utils::getLink(*rdh)); + } else if (mCFContext->zsVersion != (int32_t)hdr->version) { + GPUError("Received TPC ZS 8kb page of mixed versions, expected %d, received %d (linkid %d, feeCRU %d, feeEndpoint %d, feelinkid %d)", mCFContext->zsVersion, (int32_t)hdr->version, (int32_t)o2::raw::RDHUtils::getLinkID(*rdh), (int32_t)rdh_utils::getCRU(*rdh), (int32_t)rdh_utils::getEndPoint(*rdh), (int32_t)rdh_utils::getLink(*rdh)); constexpr size_t bufferSize = 3 * std::max(sizeof(*rdh), sizeof(*hdr)) + 1; char dumpBuffer[bufferSize]; for (size_t i = 0; i < sizeof(*rdh); i++) { // "%02X " guaranteed to be 3 chars + ending 0. - snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int)((unsigned char*)rdh)[i]); + snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int32_t)((uint8_t*)rdh)[i]); } GPUAlarm("RDH of page: %s", dumpBuffer); for (size_t i = 0; i < sizeof(*hdr); i++) { // "%02X " guaranteed to be 3 chars + ending 0. - snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int)((unsigned char*)hdr)[i]); + snprintf(dumpBuffer + 3 * i, 4, "%02X ", (int32_t)((uint8_t*)hdr)[i]); } GPUAlarm("Metainfo of page: %s", dumpBuffer); if (GetProcessingSettings().ignoreNonFatalGPUErrors) { @@ -241,8 +241,8 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo } nDigits += hdr->nADCsamples; endpointAdcSamples[j] += hdr->nADCsamples; - unsigned int timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; - unsigned int maxTimeBin = timeBin + hdr->nTimeBinSpan; + uint32_t timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + uint32_t maxTimeBin = timeBin + hdr->nTimeBinSpan; if (mCFContext->zsVersion >= ZSVersion::ZSVersionDenseLinkBased) { const TPCZSHDRV2* const hdr2 = (const TPCZSHDRV2*)hdr; if (hdr2->flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) { @@ -259,10 +259,10 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo extendsInNextPage = o2::raw::RDHUtils::getHeartBeatOrbit(*nextrdh) == o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) && o2::raw::RDHUtils::getMemorySize(*nextrdh) > sizeof(o2::header::RAWDataHeader); } } - while (firstPossibleFragment && (unsigned int)fragments[firstPossibleFragment - 1].first.last() > timeBin) { + while (firstPossibleFragment && (uint32_t)fragments[firstPossibleFragment - 1].first.last() > timeBin) { firstPossibleFragment--; } - auto handleExtends = [&](unsigned int ff) { + auto handleExtends = [&](uint32_t ff) { if (fragmentExtends[ff]) { if (doGPU) { // Only add extended page on GPU. On CPU the pages are in consecutive memory anyway. @@ -275,26 +275,26 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo } }; if (mCFContext->zsVersion >= ZSVersion::ZSVersionDenseLinkBased) { - for (unsigned int ff = 0; ff < firstPossibleFragment; ff++) { + for (uint32_t ff = 0; ff < firstPossibleFragment; ff++) { handleExtends(ff); } } - for (unsigned int f = firstPossibleFragment; f < mCFContext->nFragments; f++) { - if (timeBin < (unsigned int)fragments[f].first.last() && (unsigned int)fragments[f].first.first() <= maxTimeBin) { + for (uint32_t f = firstPossibleFragment; f < mCFContext->nFragments; f++) { + if (timeBin < (uint32_t)fragments[f].first.last() && (uint32_t)fragments[f].first.first() <= maxTimeBin) { if (!fragments[f].second.hasData) { fragments[f].second.hasData = 1; fragments[f].second.zsPtrFirst = k; fragments[f].second.zsPageFirst = l; } else { - if (pageCounter > (unsigned int)fragments[f].second.pageCounter + 1) { + if (pageCounter > (uint32_t)fragments[f].second.pageCounter + 1) { mCFContext->fragmentData[f].nPages[iSlice][j] += emptyPages + pageCounter - fragments[f].second.pageCounter - 1; - for (unsigned int k2 = fragments[f].second.zsPtrLast - 1; k2 <= k; k2++) { - for (unsigned int l2 = ((int)k2 == fragments[f].second.zsPtrLast - 1) ? fragments[f].second.zsPageLast : 0; l2 < (k2 < k ? mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k2] : l); l2++) { + for (uint32_t k2 = fragments[f].second.zsPtrLast - 1; k2 <= k; k2++) { + for (uint32_t l2 = ((int32_t)k2 == fragments[f].second.zsPtrLast - 1) ? fragments[f].second.zsPageLast : 0; l2 < (k2 < k ? mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k2] : l); l2++) { if (doGPU) { mCFContext->fragmentData[f].pageDigits[iSlice][j].emplace_back(0); } else { // CPU cannot skip unneeded pages, so we must keep space to store the invalid dummy clusters - const unsigned char* const pageTmp = ((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k2]) + l2 * TPCZSHDR::TPC_ZS_PAGE_SIZE; + const uint8_t* const pageTmp = ((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k2]) + l2 * TPCZSHDR::TPC_ZS_PAGE_SIZE; const o2::header::RAWDataHeader* rdhTmp = (const o2::header::RAWDataHeader*)pageTmp; if (o2::raw::RDHUtils::getMemorySize(*rdhTmp) != sizeof(o2::header::RAWDataHeader)) { const TPCZSHDR* const hdrTmp = (const TPCZSHDR*)(rdh_utils::getLink(o2::raw::RDHUtils::getFEEID(*rdhTmp)) == rdh_utils::DLBZSLinkID ? (pageTmp + o2::raw::RDHUtils::getMemorySize(*rdhTmp) - sizeof(TPCZSHDRV2)) : (pageTmp + sizeof(o2::header::RAWDataHeader))); @@ -306,7 +306,7 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo } else if (emptyPages) { mCFContext->fragmentData[f].nPages[iSlice][j] += emptyPages; if (doGPU) { - for (unsigned int m = 0; m < emptyPages; m++) { + for (uint32_t m = 0; m < emptyPages; m++) { mCFContext->fragmentData[f].pageDigits[iSlice][j].emplace_back(0); } } @@ -323,9 +323,9 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo fragmentExtends[f] = extendsInNextPage; } else { handleExtends(f); - if (timeBin < (unsigned int)fragments[f].first.last()) { + if (timeBin < (uint32_t)fragments[f].first.last()) { if (mCFContext->zsVersion >= ZSVersion::ZSVersionDenseLinkBased) { - for (unsigned int ff = f + 1; ff < mCFContext->nFragments; ff++) { + for (uint32_t ff = f + 1; ff < mCFContext->nFragments; ff++) { handleExtends(ff); } } @@ -338,7 +338,7 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo emptyPages = 0; } } - for (unsigned int f = 0; f < mCFContext->nFragments; f++) { + for (uint32_t f = 0; f < mCFContext->nFragments; f++) { mCFContext->fragmentData[f].minMaxCN[iSlice][j].zsPtrLast = fragments[f].second.zsPtrLast; mCFContext->fragmentData[f].minMaxCN[iSlice][j].zsPtrFirst = fragments[f].second.zsPtrFirst; mCFContext->fragmentData[f].minMaxCN[iSlice][j].zsPageLast = fragments[f].second.zsPageLast; @@ -349,16 +349,16 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo mCFContext->nPagesSector[iSlice] = nPages; mCFContext->nDigitsEndpointMax[iSlice] = 0; - for (unsigned int i = 0; i < GPUTrackingInOutZS::NENDPOINTS; i++) { + for (uint32_t i = 0; i < GPUTrackingInOutZS::NENDPOINTS; i++) { if (endpointAdcSamples[i] > mCFContext->nDigitsEndpointMax[iSlice]) { mCFContext->nDigitsEndpointMax[iSlice] = endpointAdcSamples[i]; } } - unsigned int nDigitsFragmentMax = 0; - for (unsigned int i = 0; i < mCFContext->nFragments; i++) { - unsigned int pagesInFragment = 0; - unsigned int digitsInFragment = 0; - for (unsigned short j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + uint32_t nDigitsFragmentMax = 0; + for (uint32_t i = 0; i < mCFContext->nFragments; i++) { + uint32_t pagesInFragment = 0; + uint32_t digitsInFragment = 0; + for (uint16_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { pagesInFragment += mCFContext->fragmentData[i].nPages[iSlice][j]; digitsInFragment += mCFContext->fragmentData[i].nDigits[iSlice][j]; } @@ -369,25 +369,25 @@ std::pair GPUChainTracking::TPCClusterizerDecodeZSCo return {nDigits, nDigitsFragmentMax}; } -void GPUChainTracking::RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clusterer, GPUTPCClusterFinder& clustererShadow, int stage, bool doGPU, int lane) +void GPUChainTracking::RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clusterer, GPUTPCClusterFinder& clustererShadow, int32_t stage, bool doGPU, int32_t lane) { auto& in = stage ? clustererShadow.mPpeakPositions : clustererShadow.mPpositions; auto& out = stage ? clustererShadow.mPfilteredPeakPositions : clustererShadow.mPpeakPositions; if (doGPU) { - const unsigned int iSlice = clusterer.mISlice; + const uint32_t iSlice = clusterer.mISlice; auto& count = stage ? clusterer.mPmemory->counters.nPeaks : clusterer.mPmemory->counters.nPositions; std::vector counts; - unsigned int nSteps = clusterer.getNSteps(count); + uint32_t nSteps = clusterer.getNSteps(count); if (nSteps > clusterer.mNBufs) { - GPUError("Clusterer buffers exceeded (%u > %u)", nSteps, (int)clusterer.mNBufs); + GPUError("Clusterer buffers exceeded (%u > %u)", nSteps, (int32_t)clusterer.mNBufs); exit(1); } size_t tmpCount = count; if (nSteps > 1) { - for (unsigned int i = 1; i < nSteps; i++) { + for (uint32_t i = 1; i < nSteps; i++) { counts.push_back(tmpCount); if (i == 1) { runKernel({GetGrid(tmpCount, clusterer.mScanWorkGroupSize, lane), {iSlice}}, i, stage); @@ -399,7 +399,7 @@ void GPUChainTracking::RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clust runKernel({GetGrid(tmpCount, clusterer.mScanWorkGroupSize, lane), {iSlice}}, nSteps, tmpCount); - for (unsigned int i = nSteps - 1; i > 1; i--) { + for (uint32_t i = nSteps - 1; i > 1; i--) { tmpCount = counts[i - 1]; runKernel({GetGrid(tmpCount - clusterer.mScanWorkGroupSize, clusterer.mScanWorkGroupSize, lane), {iSlice}}, i, clusterer.mScanWorkGroupSize, tmpCount); } @@ -419,7 +419,7 @@ void GPUChainTracking::RunTPCClusterizer_compactPeaks(GPUTPCClusterFinder& clust } } -std::pair GPUChainTracking::RunTPCClusterizer_transferZS(int iSlice, const CfFragment& fragment, int lane) +std::pair GPUChainTracking::RunTPCClusterizer_transferZS(int32_t iSlice, const CfFragment& fragment, int32_t lane) { bool doGPU = GetRecoStepsGPU() & RecoStep::TPCClusterFinding; if (mCFContext->abandonTimeframe) { @@ -429,14 +429,14 @@ std::pair GPUChainTracking::RunTPCClusterizer_transf if (doGPU) { GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; GPUTPCClusterFinder& clustererShadow = doGPU ? processorsShadow()->tpcClusterer[iSlice] : clusterer; - unsigned int nPagesSector = 0; - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - unsigned int nPages = 0; + uint32_t nPagesSector = 0; + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + uint32_t nPages = 0; mInputsHost->mPzsMeta->slice[iSlice].zsPtr[j] = &mInputsShadow->mPzsPtrs[iSlice * GPUTrackingInOutZS::NENDPOINTS + j]; mInputsHost->mPzsPtrs[iSlice * GPUTrackingInOutZS::NENDPOINTS + j] = clustererShadow.mPzs + (nPagesSector + nPages) * TPCZSHDR::TPC_ZS_PAGE_SIZE; - for (unsigned int k = clusterer.mMinMaxCN[j].zsPtrFirst; k < clusterer.mMinMaxCN[j].zsPtrLast; k++) { - const unsigned int min = (k == clusterer.mMinMaxCN[j].zsPtrFirst) ? clusterer.mMinMaxCN[j].zsPageFirst : 0; - const unsigned int max = (k + 1 == clusterer.mMinMaxCN[j].zsPtrLast) ? clusterer.mMinMaxCN[j].zsPageLast : mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; + for (uint32_t k = clusterer.mMinMaxCN[j].zsPtrFirst; k < clusterer.mMinMaxCN[j].zsPtrLast; k++) { + const uint32_t min = (k == clusterer.mMinMaxCN[j].zsPtrFirst) ? clusterer.mMinMaxCN[j].zsPageFirst : 0; + const uint32_t max = (k + 1 == clusterer.mMinMaxCN[j].zsPtrLast) ? clusterer.mMinMaxCN[j].zsPageLast : mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; if (max > min) { char* src = (char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k] + min * TPCZSHDR::TPC_ZS_PAGE_SIZE; char* ptrLast = (char*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[j][k] + (max - 1) * TPCZSHDR::TPC_ZS_PAGE_SIZE; @@ -455,10 +455,10 @@ std::pair GPUChainTracking::RunTPCClusterizer_transf return retVal; } -int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) +int32_t GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) { if (restorePointers) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { processors()->tpcClusterer[iSlice].mPzsOffsets = mCFContext->ptrSave[iSlice].zsOffsetHost; processorsShadow()->tpcClusterer[iSlice].mPzsOffsets = mCFContext->ptrSave[iSlice].zsOffsetDevice; processorsShadow()->tpcClusterer[iSlice].mPzs = mCFContext->ptrSave[iSlice].zsDevice; @@ -471,8 +471,8 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) if (mCFContext == nullptr) { mCFContext.reset(new GPUTPCCFChainContext); } - const short maxFragmentLen = GetProcessingSettings().overrideClusterizerFragmentLen; - const unsigned int maxAllowedTimebin = param().par.continuousTracking ? std::max(param().continuousMaxTimeBin, maxFragmentLen) : TPC_MAX_TIME_BIN_TRIGGERED; + const int16_t maxFragmentLen = GetProcessingSettings().overrideClusterizerFragmentLen; + const uint32_t maxAllowedTimebin = param().par.continuousTracking ? std::max(param().continuousMaxTimeBin, maxFragmentLen) : TPC_MAX_TIME_BIN_TRIGGERED; mCFContext->tpcMaxTimeBin = maxAllowedTimebin; const CfFragment fragmentMax{(tpccf::TPCTime)mCFContext->tpcMaxTimeBin + 1, maxFragmentLen}; mCFContext->prepare(mIOPtrs.tpcZS, fragmentMax); @@ -480,9 +480,9 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) mTriggerBuffer->triggers.clear(); } if (mIOPtrs.tpcZS) { - unsigned int nDigitsFragmentMax[NSLICES]; + uint32_t nDigitsFragmentMax[NSLICES]; mCFContext->zsVersion = -1; - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { if (mIOPtrs.tpcZS->slice[iSlice].count[0]) { const void* rdh = mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0]; if (rdh && o2::raw::RDHUtils::getVersion() > o2::raw::RDHUtils::getVersion(rdh)) { @@ -492,11 +492,11 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) } #ifndef GPUCA_NO_VC if (GetProcessingSettings().prefetchTPCpageScan >= 1 && iSlice < NSLICES - 1) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j]; k++) { - for (unsigned int l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; l++) { - Vc::Common::prefetchFar(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice + 1].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE); - Vc::Common::prefetchFar(((const unsigned char*)mIOPtrs.tpcZS->slice[iSlice + 1].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[iSlice].count[j]; k++) { + for (uint32_t l = 0; l < mIOPtrs.tpcZS->slice[iSlice].nZSPtr[j][k]; l++) { + Vc::Common::prefetchFar(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice + 1].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE); + Vc::Common::prefetchFar(((const uint8_t*)mIOPtrs.tpcZS->slice[iSlice + 1].zsPtr[j][k]) + l * TPCZSHDR::TPC_ZS_PAGE_SIZE + sizeof(o2::header::RAWDataHeader)); } } } @@ -507,10 +507,10 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits = x.first; mRec->MemoryScalers()->nTPCdigits += x.first; } - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - unsigned int nDigitsBase = nDigitsFragmentMax[iSlice]; - unsigned int threshold = 40000000; - unsigned int nDigitsScaled = nDigitsBase > threshold ? nDigitsBase : std::min((threshold + nDigitsBase) / 2, 2 * nDigitsBase); + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t nDigitsBase = nDigitsFragmentMax[iSlice]; + uint32_t threshold = 40000000; + uint32_t nDigitsScaled = nDigitsBase > threshold ? nDigitsBase : std::min((threshold + nDigitsBase) / 2, 2 * nDigitsBase); processors()->tpcClusterer[iSlice].SetNMaxDigits(processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits, mCFContext->nPagesFragmentMax, nDigitsScaled, mCFContext->nDigitsEndpointMax[iSlice]); if (mRec->IsGPU()) { processorsShadow()->tpcClusterer[iSlice].SetNMaxDigits(processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits, mCFContext->nPagesFragmentMax, nDigitsScaled, mCFContext->nDigitsEndpointMax[iSlice]); @@ -524,17 +524,17 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) } } } else { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - unsigned int nDigits = mIOPtrs.tpcPackedDigits->nTPCDigits[iSlice]; + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t nDigits = mIOPtrs.tpcPackedDigits->nTPCDigits[iSlice]; mRec->MemoryScalers()->nTPCdigits += nDigits; processors()->tpcClusterer[iSlice].SetNMaxDigits(nDigits, mCFContext->nPagesFragmentMax, nDigits, 0); } } if (mIOPtrs.tpcZS) { - GPUInfo("Event has %u 8kb TPC ZS pages (version %d), %ld digits", mCFContext->nPagesTotal, mCFContext->zsVersion, (long)mRec->MemoryScalers()->nTPCdigits); + GPUInfo("Event has %u 8kb TPC ZS pages (version %d), %ld digits", mCFContext->nPagesTotal, mCFContext->zsVersion, (int64_t)mRec->MemoryScalers()->nTPCdigits); } else { - GPUInfo("Event has %ld TPC Digits", (long)mRec->MemoryScalers()->nTPCdigits); + GPUInfo("Event has %ld TPC Digits", (int64_t)mRec->MemoryScalers()->nTPCdigits); } if (mCFContext->tpcMaxTimeBin > maxAllowedTimebin) { @@ -547,15 +547,15 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) } } - mCFContext->fragmentFirst = CfFragment{std::max(mCFContext->tpcMaxTimeBin + 1, maxFragmentLen), maxFragmentLen}; - for (int iSlice = 0; iSlice < GetProcessingSettings().nTPCClustererLanes && iSlice < NSLICES; iSlice++) { + mCFContext->fragmentFirst = CfFragment{std::max(mCFContext->tpcMaxTimeBin + 1, maxFragmentLen), maxFragmentLen}; + for (int32_t iSlice = 0; iSlice < GetProcessingSettings().nTPCClustererLanes && iSlice < NSLICES; iSlice++) { if (mIOPtrs.tpcZS && mCFContext->nPagesSector[iSlice] && mCFContext->zsVersion != -1) { mCFContext->nextPos[iSlice] = RunTPCClusterizer_transferZS(iSlice, mCFContext->fragmentFirst, GetProcessingSettings().nTPCClustererLanes + iSlice); } } if (mPipelineNotifyCtx && GetProcessingSettings().doublePipelineClusterizer) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { mCFContext->ptrSave[iSlice].zsOffsetHost = processors()->tpcClusterer[iSlice].mPzsOffsets; mCFContext->ptrSave[iSlice].zsOffsetDevice = processorsShadow()->tpcClusterer[iSlice].mPzsOffsets; mCFContext->ptrSave[iSlice].zsDevice = processorsShadow()->tpcClusterer[iSlice].mPzs; @@ -566,7 +566,7 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) #endif // TODO: Clusterizer not working with OCL1 (Clusterizer on CPU, Tracking on GPU) -int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) +int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) { if (param().rec.fwdTPCDigitsAsClusters) { return ForwardTPCDigits(); @@ -585,23 +585,23 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) mRec->MemoryScalers()->nTPCHits = mRec->MemoryScalers()->NTPCClusters(mRec->MemoryScalers()->nTPCdigits); float tpcHitLowOccupancyScalingFactor = 1.f; if (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasNHBFPerTF) { - unsigned int nHitsBase = mRec->MemoryScalers()->nTPCHits; - unsigned int threshold = 30000000 / 256 * mIOPtrs.settingsTF->nHBFPerTF; + uint32_t nHitsBase = mRec->MemoryScalers()->nTPCHits; + uint32_t threshold = 30000000 / 256 * mIOPtrs.settingsTF->nHBFPerTF; if (mIOPtrs.settingsTF->nHBFPerTF < 64) { threshold *= 2; } - mRec->MemoryScalers()->nTPCHits = std::max(nHitsBase, std::min(threshold, nHitsBase * 3.5f)); // Increase the buffer size for low occupancy data to compensate for noisy pads creating exceiive clusters + mRec->MemoryScalers()->nTPCHits = std::max(nHitsBase, std::min(threshold, nHitsBase * 3.5f)); // Increase the buffer size for low occupancy data to compensate for noisy pads creating exceiive clusters if (nHitsBase < threshold) { float maxFactor = mRec->MemoryScalers()->nTPCHits < threshold * 2 / 3 ? 3 : (mRec->MemoryScalers()->nTPCHits < threshold ? 2.25f : 1.75f); mRec->MemoryScalers()->temporaryFactor *= std::min(maxFactor, (float)threshold / nHitsBase); tpcHitLowOccupancyScalingFactor = std::min(3.5f, (float)threshold / nHitsBase); } } - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { processors()->tpcClusterer[iSlice].SetMaxData(mIOPtrs); // First iteration to set data sizes } mRec->ComputeReuseMax(nullptr); // Resolve maximums for shared buffers - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { SetupGPUProcessor(&processors()->tpcClusterer[iSlice], true); // Now we allocate } if (mPipelineNotifyCtx && GetProcessingSettings().doublePipelineClusterizer) { @@ -645,8 +645,8 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) mcLinearLabels.data.reserve(mRec->MemoryScalers()->nTPCHits); } - char transferRunning[NSLICES] = {0}; - unsigned int outputQueueStart = mOutputQueue.size(); + int8_t transferRunning[NSLICES] = {0}; + uint32_t outputQueueStart = mOutputQueue.size(); auto notifyForeignChainFinished = [this]() { if (mPipelineNotifyCtx) { @@ -660,21 +660,21 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) }; bool synchronizeCalibUpdate = false; - for (unsigned int iSliceBase = 0; iSliceBase < NSLICES; iSliceBase += GetProcessingSettings().nTPCClustererLanes) { + for (uint32_t iSliceBase = 0; iSliceBase < NSLICES; iSliceBase += GetProcessingSettings().nTPCClustererLanes) { std::vector laneHasData(GetProcessingSettings().nTPCClustererLanes, false); static_assert(NSLICES <= GPUCA_MAX_STREAMS, "Stream events must be able to hold all slices"); - const int maxLane = std::min(GetProcessingSettings().nTPCClustererLanes, NSLICES - iSliceBase); + const int32_t maxLane = std::min(GetProcessingSettings().nTPCClustererLanes, NSLICES - iSliceBase); for (CfFragment fragment = mCFContext->fragmentFirst; !fragment.isEnd(); fragment = fragment.next()) { if (GetProcessingSettings().debugLevel >= 3) { GPUInfo("Processing time bins [%d, %d) for sectors %d to %d", fragment.start, fragment.last(), iSliceBase, iSliceBase + GetProcessingSettings().nTPCClustererLanes - 1); } GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, GetProcessingSettings().nTPCClustererLanes))) - for (int lane = 0; lane < maxLane; lane++) { + for (int32_t lane = 0; lane < maxLane; lane++) { if (doGPU && fragment.index != 0) { SynchronizeStream(lane); // Don't overwrite charge map from previous iteration until cluster computation is finished } - unsigned int iSlice = iSliceBase + lane; + uint32_t iSlice = iSliceBase + lane; GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; GPUTPCClusterFinder& clustererShadow = doGPU ? processorsShadow()->tpcClusterer[iSlice] : clusterer; clusterer.mPmemory->counters.nPeaks = clusterer.mPmemory->counters.nClusters = 0; @@ -737,11 +737,11 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) GPUFatal("MC label container missing, sector %d", iSlice); } if (clusterer.mPinputLabels->getIndexedSize() != mIOPtrs.tpcPackedDigits->nTPCDigits[iSlice]) { - GPUFatal("MC label container has incorrect number of entries: %d expected, has %d\n", (int)mIOPtrs.tpcPackedDigits->nTPCDigits[iSlice], (int)clusterer.mPinputLabels->getIndexedSize()); + GPUFatal("MC label container has incorrect number of entries: %d expected, has %d\n", (int32_t)mIOPtrs.tpcPackedDigits->nTPCDigits[iSlice], (int32_t)clusterer.mPinputLabels->getIndexedSize()); } } - if (GetProcessingSettings().tpcSingleSector == -1 || GetProcessingSettings().tpcSingleSector == (int)iSlice) { + if (GetProcessingSettings().tpcSingleSector == -1 || GetProcessingSettings().tpcSingleSector == (int32_t)iSlice) { if (not mIOPtrs.tpcZS) { runKernel({GetGrid(1, lane), {iSlice}}, mIOPtrs.tpcZS == nullptr); TransferMemoryResourceLinkToHost(RecoStep::TPCClusterFinding, clusterer.mMemoryId, lane); @@ -752,9 +752,9 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } if (mIOPtrs.tpcZS) { - int firstHBF = (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasTfStartOrbit) ? mIOPtrs.settingsTF->tfStartOrbit : (mIOPtrs.tpcZS->slice[iSlice].count[0] && mIOPtrs.tpcZS->slice[iSlice].nZSPtr[0][0]) ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0]) - : 0; - unsigned int nBlocks = doGPU ? clusterer.mPmemory->counters.nPagesSubslice : GPUTrackingInOutZS::NENDPOINTS; + int32_t firstHBF = (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasTfStartOrbit) ? mIOPtrs.settingsTF->tfStartOrbit : (mIOPtrs.tpcZS->slice[iSlice].count[0] && mIOPtrs.tpcZS->slice[iSlice].nZSPtr[0][0]) ? o2::raw::RDHUtils::getHeartBeatOrbit(*(const o2::header::RAWDataHeader*)mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0]) + : 0; + uint32_t nBlocks = doGPU ? clusterer.mPmemory->counters.nPagesSubslice : GPUTrackingInOutZS::NENDPOINTS; switch (mCFContext->zsVersion) { default: @@ -775,14 +775,14 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } } GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, GetProcessingSettings().nTPCClustererLanes))) - for (int lane = 0; lane < maxLane; lane++) { - unsigned int iSlice = iSliceBase + lane; + for (int32_t lane = 0; lane < maxLane; lane++) { + uint32_t iSlice = iSliceBase + lane; if (doGPU) { SynchronizeStream(lane); } if (mIOPtrs.tpcZS) { CfFragment f = fragment.next(); - int nextSlice = iSlice; + int32_t nextSlice = iSlice; if (f.isEnd()) { nextSlice += GetProcessingSettings().nTPCClustererLanes; f = mCFContext->fragmentFirst; @@ -812,7 +812,7 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) checkForNoisyPads &= !GetProcessingSettings().disableTPCNoisyPadFilter; if (checkForNoisyPads) { - int nBlocks = TPC_PADS_IN_SECTOR / GPUTPCCFCheckPadBaseline::PadsPerCacheline; + int32_t nBlocks = TPC_PADS_IN_SECTOR / GPUTPCCFCheckPadBaseline::PadsPerCacheline; runKernel({GetGridBlk(nBlocks, lane), {iSlice}}); } @@ -827,8 +827,8 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 2, clusterer, &GPUTPCClusterFinder::DumpPeaksCompacted, *mDebugFile); } GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, GetProcessingSettings().nTPCClustererLanes))) - for (int lane = 0; lane < maxLane; lane++) { - unsigned int iSlice = iSliceBase + lane; + for (int32_t lane = 0; lane < maxLane; lane++) { + uint32_t iSlice = iSliceBase + lane; GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; GPUTPCClusterFinder& clustererShadow = doGPU ? processorsShadow()->tpcClusterer[iSlice] : clusterer; if (doGPU) { @@ -848,8 +848,8 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 3, clusterer, &GPUTPCClusterFinder::DumpSuppressedPeaksCompacted, *mDebugFile); } GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, GetProcessingSettings().nTPCClustererLanes))) - for (int lane = 0; lane < maxLane; lane++) { - unsigned int iSlice = iSliceBase + lane; + for (int32_t lane = 0; lane < maxLane; lane++) { + uint32_t iSlice = iSliceBase + lane; GPUTPCClusterFinder& clusterer = processors()->tpcClusterer[iSlice]; GPUTPCClusterFinder& clustererShadow = doGPU ? processorsShadow()->tpcClusterer[iSlice] : clusterer; if (doGPU) { @@ -877,7 +877,7 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) runKernel({GetGrid(clusterer.mPmemory->counters.nClusters, lane, GPUReconstruction::krnlDeviceType::CPU), {iSlice}}, 1); } if (GetProcessingSettings().debugLevel >= 3) { - GPUInfo("Sector %02d Fragment %02d Lane %d: Found clusters: digits %u peaks %u clusters %u", iSlice, fragment.index, lane, (int)clusterer.mPmemory->counters.nPositions, (int)clusterer.mPmemory->counters.nPeaks, (int)clusterer.mPmemory->counters.nClusters); + GPUInfo("Sector %02d Fragment %02d Lane %d: Found clusters: digits %u peaks %u clusters %u", iSlice, fragment.index, lane, (int32_t)clusterer.mPmemory->counters.nPositions, (int32_t)clusterer.mPmemory->counters.nPeaks, (int32_t)clusterer.mPmemory->counters.nClusters); } TransferMemoryResourcesToHost(RecoStep::TPCClusterFinding, &clusterer, lane); @@ -890,8 +890,8 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) size_t nClsFirst = nClsTotal; bool anyLaneHasData = false; - for (int lane = 0; lane < maxLane; lane++) { - unsigned int iSlice = iSliceBase + lane; + for (int32_t lane = 0; lane < maxLane; lane++) { + uint32_t iSlice = iSliceBase + lane; std::fill(&tmpNative->nClusters[iSlice][0], &tmpNative->nClusters[iSlice][0] + MAXGLOBALPADROW, 0); if (doGPU) { SynchronizeStream(lane); @@ -904,7 +904,7 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (buildNativeGPU && GetProcessingSettings().tpccfGatherKernel) { runKernel({GetGridBlk(GPUCA_ROW_COUNT, mRec->NStreams() - 1), {iSlice}}, &mInputsShadow->mPclusterNativeBuffer[nClsTotal]); } - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { if (nClsTotal + clusterer.mPclusterInRow[j] > mInputsHost->mNClusterNative) { clusterer.raiseError(GPUErrors::ERROR_CF_GLOBAL_CLUSTER_OVERFLOW, iSlice * 1000 + j, nClsTotal + clusterer.mPclusterInRow[j], mInputsHost->mNClusterNative); continue; @@ -938,7 +938,7 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) assert(propagateMCLabels ? mcLinearLabels.header.size() == nClsTotal : true); } if (propagateMCLabels) { - for (int lane = 0; lane < maxLane; lane++) { + for (int32_t lane = 0; lane < maxLane; lane++) { processors()->tpcClusterer[iSliceBase + lane].clearMCMemory(); } } @@ -950,15 +950,15 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } } - if (mWaitForFinalInputs && iSliceBase >= 21 && (int)iSliceBase < 21 + GetProcessingSettings().nTPCClustererLanes) { + if (mWaitForFinalInputs && iSliceBase >= 21 && (int32_t)iSliceBase < 21 + GetProcessingSettings().nTPCClustererLanes) { notifyForeignChainFinished(); } - if (mWaitForFinalInputs && iSliceBase >= 30 && (int)iSliceBase < 30 + GetProcessingSettings().nTPCClustererLanes) { + if (mWaitForFinalInputs && iSliceBase >= 30 && (int32_t)iSliceBase < 30 + GetProcessingSettings().nTPCClustererLanes) { mWaitForFinalInputs(); synchronizeCalibUpdate = DoQueuedUpdates(0, false); } } - for (int i = 0; i < GetProcessingSettings().nTPCClustererLanes; i++) { + for (int32_t i = 0; i < GetProcessingSettings().nTPCClustererLanes; i++) { if (transferRunning[i]) { ReleaseEvent(mEvents->stream[i], doGPU); } @@ -1004,7 +1004,7 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (buildNativeHost && buildNativeGPU && GetProcessingSettings().delayedOutput) { mInputsHost->mNClusterNative = mInputsShadow->mNClusterNative = nClsTotal; AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); - for (unsigned int i = outputQueueStart; i < mOutputQueue.size(); i++) { + for (uint32_t i = outputQueueStart; i < mOutputQueue.size(); i++) { mOutputQueue[i].dst = (char*)mInputsHost->mPclusterNativeOutput + (size_t)mOutputQueue[i].dst; } } @@ -1035,8 +1035,8 @@ int GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) SynchronizeStream(0); } if (buildNativeHost && (GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4)) { - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { std::sort(&mInputsHost->mPclusterNativeOutput[tmpNative->clusterOffset[i][j]], &mInputsHost->mPclusterNativeOutput[tmpNative->clusterOffset[i][j] + tmpNative->nClusters[i][j]]); } } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 69ce61f0d8b62..5f046f797f650 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -27,7 +27,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -int GPUChainTracking::RunTPCCompression() +int32_t GPUChainTracking::RunTPCCompression() { #ifdef GPUCA_HAVE_O2HEADERS mRec->PushNonPersistentMemory(qStr2Tag("TPCCOMPR")); @@ -79,7 +79,7 @@ int GPUChainTracking::RunTPCCompression() } const o2::tpc::CompressedClustersPtrs* P = nullptr; HighResTimer* gatherTimer = nullptr; - int outputStream = 0; + int32_t outputStream = 0; if (ProcessingSettings().doublePipeline) { SynchronizeStream(OutputStream()); // Synchronize output copies running in parallel from memory that might be released, only the following async copy from stacked memory is safe after the chain finishes. outputStream = OutputStream(); @@ -89,14 +89,14 @@ int GPUChainTracking::RunTPCCompression() void* devicePtr = mRec->getGPUPointer(Compressor.mOutputFlat); if (devicePtr != Compressor.mOutputFlat) { CompressedClustersPtrs& ptrs = *Compressor.mOutput; // We need to update the ptrs with the gpu-mapped version of the host address space - for (unsigned int i = 0; i < sizeof(ptrs) / sizeof(void*); i++) { + for (uint32_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) { reinterpret_cast(&ptrs)[i] = reinterpret_cast(&ptrs)[i] + (reinterpret_cast(devicePtr) - reinterpret_cast(Compressor.mOutputFlat)); } } } TransferMemoryResourcesToGPU(myStep, &Compressor, outputStream); - constexpr unsigned int nBlocksDefault = 2; - constexpr unsigned int nBlocksMulti = 1 + 2 * 200; + constexpr uint32_t nBlocksDefault = 2; + constexpr uint32_t nBlocksMulti = 1 + 2 * 200; switch (ProcessingSettings().tpcCompressionGatherModeKernel) { case 0: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); @@ -120,7 +120,7 @@ int GPUChainTracking::RunTPCCompression() getKernelTimer(RecoStep::TPCCompression, 0, outputSize); break; default: - GPUError("Invalid compression kernel %d selected.", (int)ProcessingSettings().tpcCompressionGatherModeKernel); + GPUError("Invalid compression kernel %d selected.", (int32_t)ProcessingSettings().tpcCompressionGatherModeKernel); return 1; } if (ProcessingSettings().tpcCompressionGatherMode == 3) { @@ -128,8 +128,8 @@ int GPUChainTracking::RunTPCCompression() char* deviceFlatPts = (char*)Compressor.mOutput->qTotU; if (GetProcessingSettings().doublePipeline) { const size_t blockSize = CAMath::nextMultipleOf<1024>(copySize / 30); - const unsigned int n = (copySize + blockSize - 1) / blockSize; - for (unsigned int i = 0; i < n; i++) { + const uint32_t n = (copySize + blockSize - 1) / blockSize; + for (uint32_t i = 0; i < n; i++) { GPUMemCpy(myStep, hostFlatPtr + i * blockSize, deviceFlatPts + i * blockSize, CAMath::Min(blockSize, copySize - i * blockSize), outputStream, false); } } else { @@ -137,7 +137,7 @@ int GPUChainTracking::RunTPCCompression() } } } else { - char direction = 0; + int8_t direction = 0; if (ProcessingSettings().tpcCompressionGatherMode == 0) { P = &CompressorShadow.mPtrs; } else if (ProcessingSettings().tpcCompressionGatherMode == 1) { @@ -149,10 +149,10 @@ int GPUChainTracking::RunTPCCompression() GPUMemCpyAlways(myStep, O->nSliceRowClusters, P->nSliceRowClusters, NSLICES * GPUCA_ROW_COUNT * sizeof(O->nSliceRowClusters[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->nTrackClusters, P->nTrackClusters, O->nTracks * sizeof(O->nTrackClusters[0]), outputStream, direction); SynchronizeStream(outputStream); - unsigned int offset = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - unsigned int srcOffset = mIOPtrs.clustersNative->clusterOffset[i][j] * Compressor.mMaxClusterFactorBase1024 / 1024; + uint32_t offset = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + uint32_t srcOffset = mIOPtrs.clustersNative->clusterOffset[i][j] * Compressor.mMaxClusterFactorBase1024 / 1024; GPUMemCpyAlways(myStep, O->qTotU + offset, P->qTotU + srcOffset, O->nSliceRowClusters[i * GPUCA_ROW_COUNT + j] * sizeof(O->qTotU[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->qMaxU + offset, P->qMaxU + srcOffset, O->nSliceRowClusters[i * GPUCA_ROW_COUNT + j] * sizeof(O->qMaxU[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->flagsU + offset, P->flagsU + srcOffset, O->nSliceRowClusters[i * GPUCA_ROW_COUNT + j] * sizeof(O->flagsU[0]), outputStream, direction); @@ -164,7 +164,7 @@ int GPUChainTracking::RunTPCCompression() } } offset = 0; - for (unsigned int i = 0; i < O->nTracks; i++) { + for (uint32_t i = 0; i < O->nTracks; i++) { GPUMemCpyAlways(myStep, O->qTotA + offset, P->qTotA + Compressor.mAttachedClusterFirstIndex[i], O->nTrackClusters[i] * sizeof(O->qTotA[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->qMaxA + offset, P->qMaxA + Compressor.mAttachedClusterFirstIndex[i], O->nTrackClusters[i] * sizeof(O->qMaxA[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->flagsA + offset, P->flagsA + Compressor.mAttachedClusterFirstIndex[i], O->nTrackClusters[i] * sizeof(O->flagsA[0]), outputStream, direction); @@ -203,7 +203,7 @@ int GPUChainTracking::RunTPCCompression() return 0; } -int GPUChainTracking::RunTPCDecompression() +int32_t GPUChainTracking::RunTPCDecompression() { #ifdef GPUCA_HAVE_O2HEADERS if (GetProcessingSettings().tpcUseOldCPUDecoding) { @@ -244,8 +244,8 @@ int GPUChainTracking::RunTPCDecompression() CompressedClusters& inputGPU = Decompressor.mInputGPU; CompressedClusters& inputGPUShadow = DecompressorShadow.mInputGPU; - int inputStream = 0; - int unattachedStream = mRec->NStreams() - 1; + int32_t inputStream = 0; + int32_t unattachedStream = mRec->NStreams() - 1; inputGPU.nAttachedClusters = cmprClsHost.nAttachedClusters; inputGPU.nUnattachedClusters = cmprClsHost.nUnattachedClusters; inputGPU.nTracks = cmprClsHost.nTracks; @@ -283,16 +283,16 @@ int GPUChainTracking::RunTPCDecompression() bool toGPU = true; runKernel({GetGridAutoStep(inputStream, RecoStep::TPCDecompression), krnlRunRangeNone, &mEvents->init}, DecompressorShadow.mNativeClustersIndex, NSLICES * GPUCA_ROW_COUNT * sizeof(DecompressorShadow.mNativeClustersIndex[0])); - int nStreams = doGPU ? mRec->NStreams() - 1 : 1; + int32_t nStreams = doGPU ? mRec->NStreams() - 1 : 1; if (cmprClsHost.nAttachedClusters != 0) { std::exclusive_scan(cmprClsHost.nTrackClusters, cmprClsHost.nTrackClusters + cmprClsHost.nTracks, Decompressor.mAttachedClustersOffsets, 0u); // computing clusters offsets for first kernel - for (int iStream = 0; iStream < nStreams; ++iStream) { - unsigned int startTrack = cmprClsHost.nTracks / nStreams * iStream; - unsigned int endTrack = cmprClsHost.nTracks / nStreams * (iStream + 1) + (iStream < nStreams - 1 ? 0 : cmprClsHost.nTracks % nStreams); // index of last track (excluded from computation) - unsigned int numTracks = endTrack - startTrack; - unsigned int* offsets = Decompressor.mAttachedClustersOffsets; - unsigned int numClusters = (endTrack == cmprClsHost.nTracks ? offsets[endTrack - 1] + cmprClsHost.nTrackClusters[endTrack - 1] : offsets[endTrack]) - offsets[startTrack]; - unsigned int numClustersRed = numClusters - numTracks; + for (int32_t iStream = 0; iStream < nStreams; ++iStream) { + uint32_t startTrack = cmprClsHost.nTracks / nStreams * iStream; + uint32_t endTrack = cmprClsHost.nTracks / nStreams * (iStream + 1) + (iStream < nStreams - 1 ? 0 : cmprClsHost.nTracks % nStreams); // index of last track (excluded from computation) + uint32_t numTracks = endTrack - startTrack; + uint32_t* offsets = Decompressor.mAttachedClustersOffsets; + uint32_t numClusters = (endTrack == cmprClsHost.nTracks ? offsets[endTrack - 1] + cmprClsHost.nTrackClusters[endTrack - 1] : offsets[endTrack]) - offsets[startTrack]; + uint32_t numClustersRed = numClusters - numTracks; GPUMemCpy(myStep, DecompressorShadow.mAttachedClustersOffsets + startTrack, Decompressor.mAttachedClustersOffsets + startTrack, numTracks * sizeof(Decompressor.mAttachedClustersOffsets[0]), iStream, toGPU); GPUMemCpy(myStep, inputGPUShadow.nTrackClusters + startTrack, cmprClsHost.nTrackClusters + startTrack, numTracks * sizeof(cmprClsHost.nTrackClusters[0]), iStream, toGPU); GPUMemCpy(myStep, inputGPUShadow.qTotA + offsets[startTrack], cmprClsHost.qTotA + offsets[startTrack], numClusters * sizeof(cmprClsHost.qTotA[0]), iStream, toGPU); @@ -329,12 +329,12 @@ int GPUChainTracking::RunTPCDecompression() WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); TransferMemoryResourceLinkToHost(RecoStep::TPCDecompression, Decompressor.mResourceTmpIndexes, inputStream, nullptr, mEvents->stream, nStreams); SynchronizeStream(inputStream); - unsigned int offset = 0; - unsigned int decodedAttachedClusters = 0; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - unsigned int linearIndex = i * GPUCA_ROW_COUNT + j; - unsigned int unattachedOffset = (linearIndex >= cmprClsHost.nSliceRows) ? 0 : cmprClsHost.nSliceRowClusters[linearIndex]; + uint32_t offset = 0; + uint32_t decodedAttachedClusters = 0; + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + uint32_t linearIndex = i * GPUCA_ROW_COUNT + j; + uint32_t unattachedOffset = (linearIndex >= cmprClsHost.nSliceRows) ? 0 : cmprClsHost.nSliceRowClusters[linearIndex]; (mClusterNativeAccess->nClusters)[i][j] = Decompressor.mNativeClustersIndex[linearIndex] + unattachedOffset; Decompressor.mUnattachedClustersOffsets[linearIndex] = offset; offset += unattachedOffset; @@ -357,11 +357,11 @@ int GPUChainTracking::RunTPCDecompression() mClusterNativeAccess->clustersLinear = mInputsHost->mPclusterNativeOutput; mClusterNativeAccess->setOffsetPtrs(); - unsigned int batchSize = doGPU ? 6 : NSLICES; - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice = iSlice + batchSize) { - int iStream = (iSlice / batchSize) % mRec->NStreams(); + uint32_t batchSize = doGPU ? 6 : NSLICES; + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice = iSlice + batchSize) { + int32_t iStream = (iSlice / batchSize) % mRec->NStreams(); runKernel({GetGridAuto(iStream), krnlRunRangeNone, {nullptr, &mEvents->single}}, iSlice, batchSize); - unsigned int copySize = std::accumulate(mClusterNativeAccess->nClustersSector + iSlice, mClusterNativeAccess->nClustersSector + iSlice + batchSize, 0u); + uint32_t copySize = std::accumulate(mClusterNativeAccess->nClustersSector + iSlice, mClusterNativeAccess->nClustersSector + iSlice + batchSize, 0u); GPUMemCpy(RecoStep::TPCDecompression, mInputsHost->mPclusterNativeOutput + mClusterNativeAccess->clusterOffset[iSlice][0], DecompressorShadow.mNativeClustersBuffer + mClusterNativeAccess->clusterOffset[iSlice][0], sizeof(Decompressor.mNativeClustersBuffer[0]) * copySize, iStream, false); } SynchronizeGPU(); @@ -370,8 +370,8 @@ int GPUChainTracking::RunTPCDecompression() runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; if (doGPU) { - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { ClusterNative* begin = mInputsHost->mPclusterNativeOutput + decoded->clusterOffset[i][j]; ClusterNative* end = begin + decoded->nClusters[i][j]; std::sort(begin, end); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index 0737456df2302..a8c3862ff61c6 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -25,9 +25,9 @@ using namespace GPUCA_NAMESPACE::gpu; -static inline unsigned int RGB(unsigned char r, unsigned char g, unsigned char b) { return (unsigned int)r | ((unsigned int)g << 8) | ((unsigned int)b << 16); } +static inline uint32_t RGB(uint8_t r, uint8_t g, uint8_t b) { return (uint32_t)r | ((uint32_t)g << 8) | ((uint32_t)b << 16); } -int GPUChainTracking::PrepareProfile() +int32_t GPUChainTracking::PrepareProfile() { #ifdef GPUCA_TRACKLET_CONSTRUCTOR_DO_PROFILE char* tmpMem = (char*)mRec->AllocateUnmanagedMemory(PROFILE_MAX_SIZE, GPUMemoryResource::MEMORY_GPU); @@ -37,7 +37,7 @@ int GPUChainTracking::PrepareProfile() return 0; } -int GPUChainTracking::DoProfile() +int32_t GPUChainTracking::DoProfile() { #ifdef GPUCA_TRACKLET_CONSTRUCTOR_DO_PROFILE std::unique_ptr stageAtSync{new char[PROFILE_MAX_SIZE]}; @@ -46,7 +46,7 @@ int GPUChainTracking::DoProfile() FILE* fp = fopen("profile.txt", "w+"); FILE* fp2 = fopen("profile.bmp", "w+b"); - const int bmpheight = 8192; + const int32_t bmpheight = 8192; BITMAPFILEHEADER bmpFH; BITMAPINFOHEADER bmpIH; memset(&bmpFH, 0, sizeof(bmpFH)); @@ -65,12 +65,12 @@ int GPUChainTracking::DoProfile() fwrite(&bmpFH, 1, sizeof(bmpFH), fp2); fwrite(&bmpIH, 1, sizeof(bmpIH), fp2); - int nEmptySync = 0; - for (unsigned int i = 0; i < bmpheight * ConstructorBlockCount() * ConstructorThreadCount(); i += ConstructorBlockCount() * ConstructorThreadCount()) { - int fEmpty = 1; - for (unsigned int j = 0; j < ConstructorBlockCount() * ConstructorThreadCount(); j++) { + int32_t nEmptySync = 0; + for (uint32_t i = 0; i < bmpheight * ConstructorBlockCount() * ConstructorThreadCount(); i += ConstructorBlockCount() * ConstructorThreadCount()) { + int32_t fEmpty = 1; + for (uint32_t j = 0; j < ConstructorBlockCount() * ConstructorThreadCount(); j++) { fprintf(fp, "%d\t", stageAtSync[i + j]); - int color = 0; + int32_t color = 0; if (stageAtSync[i + j] == 1) { color = RGB(255, 0, 0); } @@ -83,7 +83,7 @@ int GPUChainTracking::DoProfile() if (stageAtSync[i + j] == 4) { color = RGB(255, 255, 0); } - fwrite(&color, 1, sizeof(int), fp2); + fwrite(&color, 1, sizeof(int32_t), fp2); if (j > 0 && j % 32 == 0) { color = RGB(255, 255, 255); fwrite(&color, 1, 4, fp2); @@ -111,7 +111,7 @@ int GPUChainTracking::DoProfile() namespace { struct GPUChainTrackingMemUsage { - void add(unsigned long n, unsigned long bound) + void add(uint64_t n, uint64_t bound) { nMax = std::max(nMax, n); maxUse = std::max(n / std::max(bound, 1.), maxUse); @@ -119,14 +119,14 @@ struct GPUChainTrackingMemUsage { nBoundSum += bound; count++; } - unsigned long nMax; - unsigned long nSum = 0; - unsigned long nBoundSum = 0; + uint64_t nMax; + uint64_t nSum = 0; + uint64_t nBoundSum = 0; double maxUse = 0.; - unsigned int count = 0; + uint32_t count = 0; }; -void addToMap(std::string name, std::map& map, unsigned long n, unsigned long bound) +void addToMap(std::string name, std::map& map, uint64_t n, uint64_t bound) { GPUChainTrackingMemUsage& obj = map.insert({name, {}}).first->second; obj.add(n, bound); @@ -136,7 +136,7 @@ void addToMap(std::string name, std::map& void GPUChainTracking::PrintMemoryStatistics() { std::map usageMap; - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { #ifdef GPUCA_TPC_GEOMETRY_O2 addToMap("TPC Clusterer Sector Peaks", usageMap, processors()->tpcClusterer[i].mPmemory->counters.nPeaks, processors()->tpcClusterer[i].mNMaxPeaks); addToMap("TPC Clusterer Sector Clusters", usageMap, processors()->tpcClusterer[i].mPmemory->counters.nClusters, processors()->tpcClusterer[i].mNMaxClusters); @@ -169,7 +169,7 @@ void GPUChainTracking::PrintMemoryStatistics() void GPUChainTracking::PrintMemoryRelations() { - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { GPUInfo("MEMREL StartHits NCl %d NTrkl %d", processors()->tpcTrackers[i].NHitsTotal(), *processors()->tpcTrackers[i].NStartHits()); GPUInfo("MEMREL Tracklets NCl %d NTrkl %d", processors()->tpcTrackers[i].NHitsTotal(), *processors()->tpcTrackers[i].NTracklets()); GPUInfo("MEMREL Tracklets NCl %d NTrkl %d", processors()->tpcTrackers[i].NHitsTotal(), *processors()->tpcTrackers[i].NRowHits()); @@ -204,21 +204,21 @@ void GPUChainTracking::PrintDebugOutput() void GPUChainTracking::PrintOutputStat() { - int nTracks = 0, nAttachedClusters = 0, nAttachedClustersFitted = 0, nAdjacentClusters = 0; - unsigned int nCls = GetProcessingSettings().doublePipeline ? mIOPtrs.clustersNative->nClustersTotal : GetTPCMerger().NMaxClusters(); + int32_t nTracks = 0, nAttachedClusters = 0, nAttachedClustersFitted = 0, nAdjacentClusters = 0; + uint32_t nCls = GetProcessingSettings().doublePipeline ? mIOPtrs.clustersNative->nClustersTotal : GetTPCMerger().NMaxClusters(); if (ProcessingSettings().createO2Output > 1) { nTracks = mIOPtrs.nOutputTracksTPCO2; nAttachedClusters = mIOPtrs.nMergedTrackHits; } else { - for (unsigned int k = 0; k < mIOPtrs.nMergedTracks; k++) { + for (uint32_t k = 0; k < mIOPtrs.nMergedTracks; k++) { if (mIOPtrs.mergedTracks[k].OK()) { nTracks++; nAttachedClusters += mIOPtrs.mergedTracks[k].NClusters(); nAttachedClustersFitted += mIOPtrs.mergedTracks[k].NClustersFitted(); } } - for (unsigned int k = 0; k < nCls; k++) { - int attach = mIOPtrs.mergedTrackHitAttachment[k]; + for (uint32_t k = 0; k < nCls; k++) { + int32_t attach = mIOPtrs.mergedTrackHitAttachment[k]; if (attach & gputpcgmmergertypes::attachFlagMask) { nAdjacentClusters++; } @@ -227,9 +227,9 @@ void GPUChainTracking::PrintOutputStat() char trdText[1024] = ""; if (GetRecoSteps() & GPUDataTypes::RecoStep::TRDTracking) { - int nTRDTracks = 0; - int nTRDTracklets = 0; - for (unsigned int k = 0; k < mIOPtrs.nTRDTracks; k++) { + int32_t nTRDTracks = 0; + int32_t nTRDTracklets = 0; + for (uint32_t k = 0; k < mIOPtrs.nTRDTracks; k++) { if (mIOPtrs.trdTracksO2) { #ifdef GPUCA_HAVE_O2HEADERS auto& trk = mIOPtrs.trdTracksO2[k]; @@ -252,7 +252,7 @@ void GPUChainTracking::SanityCheck() #ifdef GPUCA_HAVE_O2HEADERS size_t nErrors = 0; - for (unsigned int i = 0; i < mIOPtrs.nOutputTracksTPCO2; i++) { + for (uint32_t i = 0; i < mIOPtrs.nOutputTracksTPCO2; i++) { const auto& trk = mIOPtrs.outputTracksTPCO2[i]; const auto& ref = trk.getClusterRef(); if (ref.getFirstEntry() > mIOPtrs.nOutputClusRefsTPCO2) { @@ -267,13 +267,13 @@ void GPUChainTracking::SanityCheck() continue; } } - for (int j = 0; j < trk.getNClusters(); j++) { + for (int32_t j = 0; j < trk.getNClusters(); j++) { uint8_t sector, row; uint32_t cl; trk.getClusterReference(mIOPtrs.outputClusRefsTPCO2, j, sector, row, cl); if (sector >= GPUCA_NSLICES || row >= GPUCA_ROW_COUNT) { if (nErrors++ < 1000) { - GPUError("Invalid sector / row %d / %d", (int)sector, (int)row); + GPUError("Invalid sector / row %d / %d", (int32_t)sector, (int32_t)row); continue; } } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingIO.cxx b/GPU/GPUTracking/Global/GPUChainTrackingIO.cxx index 347d64bb3aa51..16af17863bcb1 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingIO.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingIO.cxx @@ -60,7 +60,7 @@ using namespace o2::tpc; using namespace o2::trd; using namespace o2::dataformats; -static constexpr unsigned int DUMP_HEADER_SIZE = 4; +static constexpr uint32_t DUMP_HEADER_SIZE = 4; static constexpr char DUMP_HEADER[DUMP_HEADER_SIZE + 1] = "CAv1"; GPUChainTracking::InOutMemory::InOutMemory() = default; @@ -93,7 +93,7 @@ void GPUChainTracking::DumpData(const char* filename) if (DumpData(fp, mIOPtrs.tpcPackedDigits->tpcDigits, mIOPtrs.tpcPackedDigits->nTPCDigits, InOutPointerType::TPC_DIGIT) && mIOPtrs.tpcPackedDigits->tpcDigitsMC) { const char* ptrs[NSLICES]; size_t sizes[NSLICES]; - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { if (mIOPtrs.tpcPackedDigits->tpcDigitsMC->v[i]) { const auto& buffer = mIOPtrs.tpcPackedDigits->tpcDigitsMC->v[i]->getBuffer(); ptrs[i] = buffer.data(); @@ -108,9 +108,9 @@ void GPUChainTracking::DumpData(const char* filename) } if (mIOPtrs.tpcZS) { size_t total = 0; - for (int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { total += mIOPtrs.tpcZS->slice[i].nZSPtr[j][k]; } } @@ -119,9 +119,9 @@ void GPUChainTracking::DumpData(const char* filename) char* ptr = pages[0].data(); GPUTrackingInOutZS::GPUTrackingInOutZSCounts counts; total = 0; - for (int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { memcpy(&ptr[total * TPCZSHDR::TPC_ZS_PAGE_SIZE], mIOPtrs.tpcZS->slice[i].zsPtr[j][k], mIOPtrs.tpcZS->slice[i].nZSPtr[j][k] * TPCZSHDR::TPC_ZS_PAGE_SIZE); counts.count[i][j] += mIOPtrs.tpcZS->slice[i].nZSPtr[j][k]; total += mIOPtrs.tpcZS->slice[i].nZSPtr[j][k]; @@ -142,7 +142,7 @@ void GPUChainTracking::DumpData(const char* filename) DumpData(fp, &ptr, &size, InOutPointerType::TPC_COMPRESSED_CL); } if (mIOPtrs.settingsTF) { - unsigned int n = 1; + uint32_t n = 1; DumpData(fp, &mIOPtrs.settingsTF, &n, InOutPointerType::TF_SETTINGS); } #endif @@ -164,7 +164,7 @@ void GPUChainTracking::DumpData(const char* filename) fclose(fp); } -int GPUChainTracking::ReadData(const char* filename) +int32_t GPUChainTracking::ReadData(const char* filename) { ClearIOPointers(); FILE* fp = fopen(filename, "rb"); @@ -182,7 +182,7 @@ int GPUChainTracking::ReadData(const char* filename) GeometryType geo; r = fread(&geo, sizeof(geo), 1, fp); if (geo != GPUReconstruction::geometryType) { - GPUError("File has invalid geometry (%s v.s. %s)", GPUReconstruction::GEOMETRY_TYPE_NAMES[(int)geo], GPUReconstruction::GEOMETRY_TYPE_NAMES[(int)GPUReconstruction::geometryType]); + GPUError("File has invalid geometry (%s v.s. %s)", GPUReconstruction::GEOMETRY_TYPE_NAMES[(int32_t)geo], GPUReconstruction::GEOMETRY_TYPE_NAMES[(int32_t)GPUReconstruction::geometryType]); fclose(fp); return 1; } @@ -190,7 +190,7 @@ int GPUChainTracking::ReadData(const char* filename) ReadData(fp, mIOPtrs.clusterData, mIOPtrs.nClusterData, mIOMem.clusterData, InOutPointerType::CLUSTER_DATA, ptrClusterData); AliHLTTPCRawCluster* ptrRawClusters[NSLICES]; ReadData(fp, mIOPtrs.rawClusters, mIOPtrs.nRawClusters, mIOMem.rawClusters, InOutPointerType::RAW_CLUSTERS, ptrRawClusters); - int nClustersTotal = 0; + int32_t nClustersTotal = 0; #ifdef GPUCA_HAVE_O2HEADERS mIOMem.clusterNativeAccess.reset(new ClusterNativeAccess); if (ReadData(fp, &mIOMem.clusterNativeAccess->clustersLinear, &mIOMem.clusterNativeAccess->nClustersTotal, &mIOMem.clustersNative, InOutPointerType::CLUSTERS_NATIVE)) { @@ -211,7 +211,7 @@ int GPUChainTracking::ReadData(const char* filename) if (ReadData(fp, ptrs, sizes, mIOMem.tpcDigitsMC, InOutPointerType::TPC_DIGIT_MC)) { mIOMem.tpcDigitMCMap = std::make_unique(); mIOMem.tpcDigitMCView.reset(new ConstMCLabelContainerView[NSLICES]); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { if (sizes[i]) { mIOMem.tpcDigitMCView.get()[i] = gsl::span(ptrs[i], ptrs[i] + sizes[i]); mIOMem.tpcDigitMCMap->v[i] = mIOMem.tpcDigitMCView.get() + i; @@ -231,8 +231,8 @@ int GPUChainTracking::ReadData(const char* filename) mIOMem.tpcZSmeta.reset(new GPUTrackingInOutZS); mIOMem.tpcZSmeta2.reset(new GPUTrackingInOutZS::GPUTrackingInOutZSMeta); total = 0; - for (int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { mIOMem.tpcZSmeta2->ptr[i][j] = &ptrZSPages[total * TPCZSHDR::TPC_ZS_PAGE_SIZE]; mIOMem.tpcZSmeta->slice[i].zsPtr[j] = &mIOMem.tpcZSmeta2->ptr[i][j]; mIOMem.tpcZSmeta2->n[i][j] = counts.count[i][j]; @@ -246,7 +246,7 @@ int GPUChainTracking::ReadData(const char* filename) if (ReadData(fp, &ptr, &total, &mIOMem.tpcCompressedClusters, InOutPointerType::TPC_COMPRESSED_CL)) { mIOPtrs.tpcCompressedClusters = (const o2::tpc::CompressedClustersFlat*)ptr; } - unsigned int n; + uint32_t n; ReadData(fp, &mIOPtrs.settingsTF, &n, &mIOMem.settingsTF, InOutPointerType::TF_SETTINGS); #endif ReadData(fp, mIOPtrs.sliceTracks, mIOPtrs.nSliceTracks, mIOMem.sliceTracks, InOutPointerType::SLICE_OUT_TRACK); @@ -258,7 +258,7 @@ int GPUChainTracking::ReadData(const char* filename) ReadData(fp, &mIOPtrs.mergedTrackHits, &mIOPtrs.nMergedTrackHits, &mIOMem.mergedTrackHits, InOutPointerType::MERGED_TRACK_HIT); ReadData(fp, &mIOPtrs.trdTracks, &mIOPtrs.nTRDTracks, &mIOMem.trdTracks, InOutPointerType::TRD_TRACK); ReadData(fp, &mIOPtrs.trdTracklets, &mIOPtrs.nTRDTracklets, &mIOMem.trdTracklets, InOutPointerType::TRD_TRACKLET); - unsigned int dummy = 0; + uint32_t dummy = 0; ReadData(fp, &mIOPtrs.trdSpacePoints, &dummy, &mIOMem.trdSpacePoints, InOutPointerType::TRD_SPACEPOINT); ReadData(fp, &mIOPtrs.trdTriggerTimes, &mIOPtrs.nTRDTriggerRecords, &mIOMem.trdTriggerTimes, InOutPointerType::TRD_TRIGGERRECORDS); ReadData(fp, &mIOPtrs.trdTrackletIdxFirst, &mIOPtrs.nTRDTriggerRecords, &mIOMem.trdTrackletIdxFirst, InOutPointerType::TRD_TRIGGERRECORDS); @@ -273,21 +273,21 @@ int GPUChainTracking::ReadData(const char* filename) return 1; } (void)r; - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < mIOPtrs.nClusterData[i]; j++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < mIOPtrs.nClusterData[i]; j++) { ptrClusterData[i][j].id = nClustersTotal++; - if ((unsigned int)ptrClusterData[i][j].amp >= 25 * 1024) { - GPUError("Invalid cluster charge, truncating (%d >= %d)", (int)ptrClusterData[i][j].amp, 25 * 1024); + if ((uint32_t)ptrClusterData[i][j].amp >= 25 * 1024) { + GPUError("Invalid cluster charge, truncating (%d >= %d)", (int32_t)ptrClusterData[i][j].amp, 25 * 1024); ptrClusterData[i][j].amp = 25 * 1024 - 1; } } - for (unsigned int j = 0; j < mIOPtrs.nRawClusters[i]; j++) { - if ((unsigned int)mIOMem.rawClusters[i][j].GetCharge() >= 25 * 1024) { - GPUError("Invalid raw cluster charge, truncating (%d >= %d)", (int)ptrRawClusters[i][j].GetCharge(), 25 * 1024); + for (uint32_t j = 0; j < mIOPtrs.nRawClusters[i]; j++) { + if ((uint32_t)mIOMem.rawClusters[i][j].GetCharge() >= 25 * 1024) { + GPUError("Invalid raw cluster charge, truncating (%d >= %d)", (int32_t)ptrRawClusters[i][j].GetCharge(), 25 * 1024); ptrRawClusters[i][j].SetCharge(25 * 1024 - 1); } - if ((unsigned int)mIOPtrs.rawClusters[i][j].GetQMax() >= 1024) { - GPUError("Invalid raw cluster charge max, truncating (%d >= %d)", (int)ptrRawClusters[i][j].GetQMax(), 1024); + if ((uint32_t)mIOPtrs.rawClusters[i][j].GetQMax() >= 1024) { + GPUError("Invalid raw cluster charge max, truncating (%d >= %d)", (int32_t)ptrRawClusters[i][j].GetQMax(), 1024); ptrRawClusters[i][j].SetQMax(1024 - 1); } } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx index cd6de46b95c7a..67a9904a4222f 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx @@ -21,40 +21,40 @@ using namespace GPUCA_NAMESPACE::gpu; -void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(char withinSlice, char mergeMode, GPUReconstruction::krnlDeviceType deviceType) +void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(int8_t withinSlice, int8_t mergeMode, GPUReconstruction::krnlDeviceType deviceType) { GPUTPCGMMerger& Merger = processors()->tpcMerger; bool doGPUall = GetRecoStepsGPU() & RecoStep::TPCMerging && GetProcessingSettings().fullMergerOnGPU; GPUTPCGMMerger& MergerShadow = doGPUall ? processorsShadow()->tpcMerger : Merger; if (GetProcessingSettings().deterministicGPUReconstruction) { - unsigned int nBorderTracks = withinSlice == 1 ? NSLICES : (2 * NSLICES); + uint32_t nBorderTracks = withinSlice == 1 ? NSLICES : (2 * NSLICES); runKernel({{nBorderTracks, -WarpSize(), 0, deviceType}}, 0); } - unsigned int n = withinSlice == -1 ? NSLICES / 2 : NSLICES; + uint32_t n = withinSlice == -1 ? NSLICES / 2 : NSLICES; if (GetProcessingSettings().alternateBorderSort && (!mRec->IsGPU() || doGPUall)) { TransferMemoryResourceLinkToHost(RecoStep::TPCMerging, Merger.MemoryResMemory(), 0, &mEvents->init); RecordMarker(mEvents->single, 0); - for (unsigned int i = 0; i < n; i++) { - int stream = i % mRec->NStreams(); - runKernel({GetGridAuto(stream, deviceType), krnlRunRangeNone, {nullptr, stream && i < (unsigned int)mRec->NStreams() ? &mEvents->single : nullptr}}, i, withinSlice, mergeMode); + for (uint32_t i = 0; i < n; i++) { + int32_t stream = i % mRec->NStreams(); + runKernel({GetGridAuto(stream, deviceType), krnlRunRangeNone, {nullptr, stream && i < (uint32_t)mRec->NStreams() ? &mEvents->single : nullptr}}, i, withinSlice, mergeMode); } ReleaseEvent(mEvents->single); SynchronizeEventAndRelease(mEvents->init); - for (unsigned int i = 0; i < n; i++) { - int stream = i % mRec->NStreams(); - int n1, n2; + for (uint32_t i = 0; i < n; i++) { + int32_t stream = i % mRec->NStreams(); + int32_t n1, n2; GPUTPCGMBorderTrack *b1, *b2; - int jSlice; + int32_t jSlice; Merger.MergeBorderTracksSetup(n1, n2, b1, b2, jSlice, i, withinSlice, mergeMode); gputpcgmmergertypes::GPUTPCGMBorderRange* range1 = MergerShadow.BorderRange(i); gputpcgmmergertypes::GPUTPCGMBorderRange* range2 = MergerShadow.BorderRange(jSlice) + *processors()->tpcTrackers[jSlice].NTracks(); runKernel({{1, -WarpSize(), stream, deviceType}}, range1, n1, 0); runKernel({{1, -WarpSize(), stream, deviceType}}, range2, n2, 1); deviceEvent* e = nullptr; - int ne = 0; + int32_t ne = 0; if (i == n - 1) { // Synchronize all execution on stream 0 with the last kernel - ne = std::min(n, mRec->NStreams()); - for (int j = 1; j < ne; j++) { + ne = std::min(n, mRec->NStreams()); + for (int32_t j = 1; j < ne; j++) { RecordMarker(mEvents->slice[j], j); } e = &mEvents->slice[1]; @@ -64,11 +64,11 @@ void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(char withinSlice, runKernel({GetGridAuto(stream, deviceType), krnlRunRangeNone, {nullptr, e, ne}}, i, withinSlice, mergeMode); } } else { - for (unsigned int i = 0; i < n; i++) { + for (uint32_t i = 0; i < n; i++) { runKernel(GetGridAuto(0, deviceType), i, withinSlice, mergeMode); } runKernel({{2 * n, -WarpSize(), 0, deviceType}}, 0, withinSlice, mergeMode); - for (unsigned int i = 0; i < n; i++) { + for (uint32_t i = 0; i < n; i++) { runKernel(GetGridAuto(0, deviceType), i, withinSlice, mergeMode); } } @@ -76,7 +76,7 @@ void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(char withinSlice, mRec->ReturnVolatileDeviceMemory(); } -void GPUChainTracking::RunTPCTrackingMerger_Resolve(char useOrigTrackParam, char mergeAll, GPUReconstruction::krnlDeviceType deviceType) +void GPUChainTracking::RunTPCTrackingMerger_Resolve(int8_t useOrigTrackParam, int8_t mergeAll, GPUReconstruction::krnlDeviceType deviceType) { runKernel(GetGridAuto(0, deviceType)); runKernel(GetGridAuto(0, deviceType)); @@ -85,17 +85,17 @@ void GPUChainTracking::RunTPCTrackingMerger_Resolve(char useOrigTrackParam, char runKernel(GetGridAuto(0, deviceType), useOrigTrackParam, mergeAll); } -int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) +int32_t GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) { mRec->PushNonPersistentMemory(qStr2Tag("TPCMERGE")); bool doGPU = GetRecoStepsGPU() & RecoStep::TPCMerging; bool doGPUall = doGPU && GetProcessingSettings().fullMergerOnGPU; GPUReconstruction::krnlDeviceType deviceType = doGPUall ? GPUReconstruction::krnlDeviceType::Auto : GPUReconstruction::krnlDeviceType::CPU; - unsigned int numBlocks = (!mRec->IsGPU() || doGPUall) ? BlockCount() : 1; + uint32_t numBlocks = (!mRec->IsGPU() || doGPUall) ? BlockCount() : 1; GPUTPCGMMerger& Merger = processors()->tpcMerger; GPUTPCGMMerger& MergerShadow = doGPU ? processorsShadow()->tpcMerger : Merger; GPUTPCGMMerger& MergerShadowAll = doGPUall ? processorsShadow()->tpcMerger : Merger; - const int outputStream = OutputStream(); + const int32_t outputStream = OutputStream(); if (GetProcessingSettings().debugLevel >= 2) { GPUInfo("Running TPC Merger"); } @@ -119,7 +119,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) if (GetProcessingSettings().deterministicGPUReconstruction) { runKernel(GetGridAuto(0, deviceType), 1); } - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { runKernel({{1, -WarpSize(), 0, deviceType}}, i); runKernel(GetGridAuto(0, deviceType), i); runKernel(GetGridAuto(0, deviceType), i); @@ -128,7 +128,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) runKernel({{1, -WarpSize(), 0, deviceType}}, NSLICES); runKernel({{GPUCA_NSLICES, -WarpSize(), 0, deviceType}}, 0); } - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { runKernel({{1, -WarpSize(), 0, deviceType}}, NSLICES + i); runKernel(GetGridAuto(0, deviceType), i); } @@ -177,7 +177,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) runKernel(GetGridAuto(0, deviceType)); DoDebugAndDump(RecoStep::TPCMerging, 2048, doGPUall, Merger, &GPUTPCGMMerger::DumpMergeCE, *mDebugFile); } - int waitForTransfer = 0; + int32_t waitForTransfer = 0; if (doGPUall) { TransferMemoryResourceLinkToHost(RecoStep::TPCMerging, Merger.MemoryResMemory(), 0, &mEvents->single); waitForTransfer = 1; @@ -189,7 +189,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) runKernel(GetGridAuto(0, deviceType)); } - unsigned int maxId = param().rec.nonConsecutiveIDs ? Merger.Memory()->nOutputTrackClusters : Merger.NMaxClusters(); + uint32_t maxId = param().rec.nonConsecutiveIDs ? Merger.Memory()->nOutputTrackClusters : Merger.NMaxClusters(); if (maxId > Merger.NMaxClusters()) { throw std::runtime_error("mNMaxClusters too small"); } @@ -215,7 +215,7 @@ int GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) } if (GetProcessingSettings().delayedOutput) { - for (unsigned int i = 0; i < mOutputQueue.size(); i++) { + for (uint32_t i = 0; i < mOutputQueue.size(); i++) { GPUMemCpy(mOutputQueue[i].step, mOutputQueue[i].dst, mOutputQueue[i].src, mOutputQueue[i].size, outputStream, false); } mOutputQueue.clear(); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingRefit.cxx b/GPU/GPUTracking/Global/GPUChainTrackingRefit.cxx index 4d1b7e821479e..50ed3f115c02b 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingRefit.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingRefit.cxx @@ -18,7 +18,7 @@ using namespace GPUCA_NAMESPACE::gpu; -int GPUChainTracking::RunRefit() +int32_t GPUChainTracking::RunRefit() { #ifdef GPUCA_HAVE_O2HEADERS bool doGPU = GetRecoStepsGPU() & RecoStep::Refit; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx index 221d722878d1d..da4629928789c 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx @@ -24,7 +24,7 @@ using namespace GPUCA_NAMESPACE::gpu; -int GPUChainTracking::GlobalTracking(unsigned int iSlice, int threadId, bool synchronizeOutput) +int32_t GPUChainTracking::GlobalTracking(uint32_t iSlice, int32_t threadId, bool synchronizeOutput) { if (GetProcessingSettings().debugLevel >= 5) { GPUInfo("GPU Tracker running Global Tracking for slice %u on thread %d\n", iSlice, threadId); @@ -45,7 +45,7 @@ int GPUChainTracking::GlobalTracking(unsigned int iSlice, int threadId, bool syn return (0); } -int GPUChainTracking::RunTPCTrackingSlices() +int32_t GPUChainTracking::RunTPCTrackingSlices() { if (mRec->GPUStuck()) { GPUWarning("This GPU is stuck, processing of tracking for this event is skipped!"); @@ -54,7 +54,7 @@ int GPUChainTracking::RunTPCTrackingSlices() const auto& threadContext = GetThreadContext(); - int retVal = RunTPCTrackingSlices_internal(); + int32_t retVal = RunTPCTrackingSlices_internal(); if (retVal) { SynchronizeGPU(); } @@ -64,7 +64,7 @@ int GPUChainTracking::RunTPCTrackingSlices() return (retVal != 0); } -int GPUChainTracking::RunTPCTrackingSlices_internal() +int32_t GPUChainTracking::RunTPCTrackingSlices_internal() { if (GetProcessingSettings().debugLevel >= 2) { GPUInfo("Running TPC Slice Tracker"); @@ -72,7 +72,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() bool doGPU = GetRecoStepsGPU() & RecoStep::TPCSliceTracking; bool doSliceDataOnGPU = processors()->tpcTrackers[0].SliceDataOnGPU(); if (!param().par.earlyTpcTransform) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { processors()->tpcTrackers[i].Data().SetClusterData(nullptr, mIOPtrs.clustersNative->nClustersSector[i], mIOPtrs.clustersNative->clusterOffset[i][0]); if (doGPU) { processorsShadow()->tpcTrackers[i].Data().SetClusterData(nullptr, mIOPtrs.clustersNative->nClustersSector[i], mIOPtrs.clustersNative->clusterOffset[i][0]); // TODO: not needed I think, anyway copied in SetupGPUProcessor @@ -80,8 +80,8 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } mRec->MemoryScalers()->nTPCHits = mIOPtrs.clustersNative->nClustersTotal; } else { - int offset = 0; - for (unsigned int i = 0; i < NSLICES; i++) { + int32_t offset = 0; + for (uint32_t i = 0; i < NSLICES; i++) { processors()->tpcTrackers[i].Data().SetClusterData(mIOPtrs.clusterData[i], mIOPtrs.nClusterData[i], offset); #ifdef GPUCA_HAVE_O2HEADERS if (doGPU && GetRecoSteps().isSet(RecoStep::TPCConversion)) { @@ -92,19 +92,19 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } mRec->MemoryScalers()->nTPCHits = offset; } - GPUInfo("Event has %u TPC Clusters, %d TRD Tracklets", (unsigned int)mRec->MemoryScalers()->nTPCHits, mIOPtrs.nTRDTracklets); + GPUInfo("Event has %u TPC Clusters, %d TRD Tracklets", (uint32_t)mRec->MemoryScalers()->nTPCHits, mIOPtrs.nTRDTracklets); - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { processors()->tpcTrackers[iSlice].SetMaxData(mIOPtrs); // First iteration to set data sizes } mRec->ComputeReuseMax(nullptr); // Resolve maximums for shared buffers - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { SetupGPUProcessor(&processors()->tpcTrackers[iSlice], false); // Prepare custom allocation for 1st stack level mRec->AllocateRegisteredMemory(processors()->tpcTrackers[iSlice].MemoryResSliceScratch()); mRec->AllocateRegisteredMemory(processors()->tpcTrackers[iSlice].MemoryResSliceInput()); } mRec->PushNonPersistentMemory(qStr2Tag("TPCSLTRK")); - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { SetupGPUProcessor(&processors()->tpcTrackers[iSlice], true); // Now we allocate mRec->ResetRegisteredMemoryPointers(&processors()->tpcTrackers[iSlice]); // TODO: The above call breaks the GPU ptrs to already allocated memory. This fixes them. Should actually be cleaned up at the source. processors()->tpcTrackers[iSlice].SetupCommonMemory(); @@ -112,7 +112,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() bool streamInit[GPUCA_MAX_STREAMS] = {false}; if (doGPU) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { processorsShadow()->tpcTrackers[iSlice].GPUParametersConst()->gpumem = (char*)mRec->DeviceMemoryBase(); // Initialize Startup Constants processors()->tpcTrackers[iSlice].GPUParameters()->nextStartHit = (((getKernelProperties().minBlocks * BlockCount()) + NSLICES - 1 - iSlice) / NSLICES) * getKernelProperties().nThreads; @@ -136,7 +136,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() WriteToConstantMemory(RecoStep::TPCSliceTracking, (char*)processors()->tpcTrackers - (char*)processors(), processorsShadow()->tpcTrackers, sizeof(GPUTPCTracker) * NSLICES, mRec->NStreams() - 1, &mEvents->init); - for (int i = 0; i < mRec->NStreams() - 1; i++) { + for (int32_t i = 0; i < mRec->NStreams() - 1; i++) { streamInit[i] = false; } streamInit[mRec->NStreams() - 1] = true; @@ -145,13 +145,13 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() return (2); } - int streamOccMap = mRec->NStreams() - 1; + int32_t streamOccMap = mRec->NStreams() - 1; if (param().rec.tpc.occupancyMapTimeBins || param().rec.tpc.sysClusErrorC12Norm) { AllocateRegisteredMemory(mInputsHost->mResourceOccupancyMap, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::tpcOccupancyMap)]); } if (param().rec.tpc.occupancyMapTimeBins) { ReleaseEvent(mEvents->init); - unsigned int* ptr = doGPU ? mInputsShadow->mTPCClusterOccupancyMap : mInputsHost->mTPCClusterOccupancyMap; + uint32_t* ptr = doGPU ? mInputsShadow->mTPCClusterOccupancyMap : mInputsHost->mTPCClusterOccupancyMap; auto* ptrTmp = (GPUTPCClusterOccupancyMapBin*)mRec->AllocateVolatileMemory(GPUTPCClusterOccupancyMapBin::getTotalSize(param()), doGPU); runKernel(GetGridAutoStep(streamOccMap, RecoStep::TPCSliceTracking), ptrTmp, GPUTPCClusterOccupancyMapBin::getTotalSize(param())); runKernel(GetGridBlk(GPUCA_NSLICES * GPUCA_ROW_COUNT, streamOccMap), ptrTmp); @@ -164,18 +164,18 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() TransferMemoryResourceLinkToGPU(RecoStep::TPCSliceTracking, mInputsHost->mResourceOccupancyMap, streamOccMap, &mEvents->init); } } - unsigned int& occupancyTotal = *mInputsHost->mTPCClusterOccupancyMap; + uint32_t& occupancyTotal = *mInputsHost->mTPCClusterOccupancyMap; occupancyTotal = CAMath::Float2UIntRn(mRec->MemoryScalers()->nTPCHits / (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasNHBFPerTF ? mIOPtrs.settingsTF->nHBFPerTF : 128)); mRec->UpdateParamOccupancyMap(param().rec.tpc.occupancyMapTimeBins ? mInputsHost->mTPCClusterOccupancyMap + 2 : nullptr, param().rec.tpc.occupancyMapTimeBins ? mInputsShadow->mTPCClusterOccupancyMap + 2 : nullptr, occupancyTotal, streamOccMap); - int streamMap[NSLICES]; + int32_t streamMap[NSLICES]; bool error = false; GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, NSLICES))) - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { GPUTPCTracker& trk = processors()->tpcTrackers[iSlice]; GPUTPCTracker& trkShadow = doGPU ? processorsShadow()->tpcTrackers[iSlice] : trk; - int useStream = (iSlice % mRec->NStreams()); + int32_t useStream = (iSlice % mRec->NStreams()); if (GetProcessingSettings().debugLevel >= 3) { GPUInfo("Creating Slice Data (Slice %d)", iSlice); @@ -194,7 +194,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() if (GetProcessingSettings().debugLevel >= 3) { GPUInfo("Waiting for helper thread %d", iSlice % (GetProcessingSettings().nDeviceHelperThreads + 1) - 1); } - while (HelperDone(iSlice % (GetProcessingSettings().nDeviceHelperThreads + 1) - 1) < (int)iSlice) { + while (HelperDone(iSlice % (GetProcessingSettings().nDeviceHelperThreads + 1) - 1) < (int32_t)iSlice) { } if (HelperError(iSlice % (GetProcessingSettings().nDeviceHelperThreads + 1) - 1)) { error = 1; @@ -304,30 +304,30 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() if (GetProcessingSettings().trackletConstructorInPipeline) { SynchronizeGPU(); } else { - for (int i = 0; i < mRec->NStreams(); i++) { + for (int32_t i = 0; i < mRec->NStreams(); i++) { RecordMarker(mEvents->stream[i], i); } runKernel({GetGridAuto(0), krnlRunRangeNone, {&mEvents->single, mEvents->stream, mRec->NStreams()}}); - for (int i = 0; i < mRec->NStreams(); i++) { + for (int32_t i = 0; i < mRec->NStreams(); i++) { ReleaseEvent(mEvents->stream[i]); } SynchronizeEventAndRelease(mEvents->single); } if (GetProcessingSettings().debugLevel >= 4) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { DoDebugAndDump(RecoStep::TPCSliceTracking, 128, processors()->tpcTrackers[iSlice], &GPUTPCTracker::DumpTrackletHits, *mDebugFile); } } - int runSlices = 0; - int useStream = 0; - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice += runSlices) { + int32_t runSlices = 0; + int32_t useStream = 0; + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice += runSlices) { if (runSlices < GetProcessingSettings().trackletSelectorSlices) { runSlices++; } - runSlices = CAMath::Min(runSlices, NSLICES - iSlice); - if (getKernelProperties().minBlocks * BlockCount() < (unsigned int)runSlices) { + runSlices = CAMath::Min(runSlices, NSLICES - iSlice); + if (getKernelProperties().minBlocks * BlockCount() < (uint32_t)runSlices) { runSlices = getKernelProperties().minBlocks * BlockCount(); } @@ -336,7 +336,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } runKernel({GetGridAuto(useStream), {iSlice, runSlices}}); runKernel({{1, -ThreadCount(), useStream}, {iSlice}}, runSlices); - for (unsigned int k = iSlice; k < iSlice + runSlices; k++) { + for (uint32_t k = iSlice; k < iSlice + runSlices; k++) { if (GetProcessingSettings().deterministicGPUReconstruction) { runKernel({GetGrid(1, 1, useStream), {k}}); } @@ -360,8 +360,8 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } RunHelperThreads(&GPUChainTracking::HelperOutput, this, NSLICES); - unsigned int tmpSlice = 0; - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t tmpSlice = 0; + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { if (GetProcessingSettings().debugLevel >= 3) { GPUInfo("Transfering Tracks from GPU to Host"); } @@ -406,9 +406,9 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() mSliceSelectorReady = iSlice; if (param().rec.tpc.globalTracking) { - for (unsigned int tmpSlice2a = 0; tmpSlice2a <= iSlice; tmpSlice2a += GetProcessingSettings().nDeviceHelperThreads + 1) { - unsigned int tmpSlice2 = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(tmpSlice2a); - unsigned int sliceLeft, sliceRight; + for (uint32_t tmpSlice2a = 0; tmpSlice2a <= iSlice; tmpSlice2a += GetProcessingSettings().nDeviceHelperThreads + 1) { + uint32_t tmpSlice2 = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(tmpSlice2a); + uint32_t sliceLeft, sliceRight; GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(tmpSlice2, sliceLeft, sliceRight); if (tmpSlice2 <= iSlice && sliceLeft <= iSlice && sliceRight <= iSlice && mWriteOutputDone[tmpSlice2] == 0) { @@ -427,15 +427,15 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } if (!(GetRecoStepsOutputs() & GPUDataTypes::InOutType::TPCSectorTracks) && param().rec.tpc.globalTracking) { std::vector blocking(NSLICES * mRec->NStreams()); - for (int i = 0; i < NSLICES; i++) { - for (int j = 0; j < mRec->NStreams(); j++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (int32_t j = 0; j < mRec->NStreams(); j++) { blocking[i * mRec->NStreams() + j] = i % mRec->NStreams() == j; } } - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { - unsigned int tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); if (!((GetRecoStepsOutputs() & GPUDataTypes::InOutType::TPCSectorTracks) || (doGPU && !(GetRecoStepsGPU() & RecoStep::TPCMerging)))) { - unsigned int sliceLeft, sliceRight; + uint32_t sliceLeft, sliceRight; GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(tmpSlice, sliceLeft, sliceRight); if (!blocking[tmpSlice * mRec->NStreams() + sliceLeft % mRec->NStreams()]) { StreamWaitForEvents(tmpSlice % mRec->NStreams(), &mEvents->slice[sliceLeft]); @@ -449,7 +449,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() GlobalTracking(tmpSlice, 0, !GetProcessingSettings().fullMergerOnGPU); } } - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { if (transferRunning[iSlice]) { ReleaseEvent(mEvents->slice[iSlice]); } @@ -457,7 +457,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } else { mSliceSelectorReady = NSLICES; GPUCA_OPENMP(parallel for if(!doGPU && GetProcessingSettings().ompKernels != 1) num_threads(mRec->SetAndGetNestedLoopOmpFactor(!doGPU, NSLICES))) - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { if (param().rec.tpc.globalTracking) { GlobalTracking(iSlice, 0); } @@ -469,14 +469,14 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() } if (param().rec.tpc.globalTracking && GetProcessingSettings().debugLevel >= 3) { - for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { GPUInfo("Slice %d - Tracks: Local %d Global %d - Hits: Local %d Global %d", iSlice, processors()->tpcTrackers[iSlice].CommonMemory()->nLocalTracks, processors()->tpcTrackers[iSlice].CommonMemory()->nTracks, processors()->tpcTrackers[iSlice].CommonMemory()->nLocalTrackHits, processors()->tpcTrackers[iSlice].CommonMemory()->nTrackHits); } } if (GetProcessingSettings().debugMask & 1024 && !GetProcessingSettings().deterministicGPUReconstruction) { - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { processors()->tpcTrackers[i].DumpOutput(*mDebugFile); } } @@ -484,7 +484,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() if (DoProfile()) { return (1); } - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mIOPtrs.nSliceTracks[i] = *processors()->tpcTrackers[i].NTracks(); mIOPtrs.sliceTracks[i] = processors()->tpcTrackers[i].Tracks(); mIOPtrs.nSliceClusters[i] = *processors()->tpcTrackers[i].NTrackHits(); @@ -500,7 +500,7 @@ int GPUChainTracking::RunTPCTrackingSlices_internal() return 0; } -int GPUChainTracking::ReadEvent(unsigned int iSlice, int threadId) +int32_t GPUChainTracking::ReadEvent(uint32_t iSlice, int32_t threadId) { if (GetProcessingSettings().debugLevel >= 5) { GPUInfo("Running ReadEvent for slice %d on thread %d\n", iSlice, threadId); @@ -512,7 +512,7 @@ int GPUChainTracking::ReadEvent(unsigned int iSlice, int threadId) return (0); } -void GPUChainTracking::WriteOutput(int iSlice, int threadId) +void GPUChainTracking::WriteOutput(int32_t iSlice, int32_t threadId) { if (GetProcessingSettings().debugLevel >= 5) { GPUInfo("Running WriteOutput for slice %d on thread %d\n", iSlice, threadId); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx index 3d16b6693cade..760f64833514e 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingTRD.cxx @@ -26,8 +26,8 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::trd; -template -int GPUChainTracking::RunTRDTracking() +template +int32_t GPUChainTracking::RunTRDTracking() { #ifndef GPUCA_ALIROOT_LIB auto& Tracker = processors()->getTRDTracker(); @@ -52,7 +52,7 @@ int GPUChainTracking::RunTRDTracking() SetupGPUProcessor(&Tracker, true); if constexpr (I == GPUTRDTrackerKernels::gpuVersion) { - for (unsigned int i = 0; i < mIOPtrs.nMergedTracks; i++) { + for (uint32_t i = 0; i < mIOPtrs.nMergedTracks; i++) { const GPUTPCGMMergedTrack& trk = mIOPtrs.mergedTracks[i]; if (!Tracker.PreCheckTrackTRDCandidate(trk)) { continue; @@ -84,7 +84,7 @@ int GPUChainTracking::RunTRDTracking() } } else { #ifdef GPUCA_HAVE_O2HEADERS - for (unsigned int i = 0; i < mIOPtrs.nOutputTracksTPCO2; i++) { + for (uint32_t i = 0; i < mIOPtrs.nOutputTracksTPCO2; i++) { const auto& trk = mIOPtrs.outputTracksTPCO2[i]; if (!Tracker.PreCheckTrackTRDCandidate(trk)) { @@ -133,8 +133,8 @@ int GPUChainTracking::RunTRDTracking() return 0; } -template -int GPUChainTracking::DoTRDGPUTracking(T* externalInstance) +template +int32_t GPUChainTracking::DoTRDGPUTracking(T* externalInstance) { #ifdef GPUCA_HAVE_O2HEADERS bool doGPU = GetRecoStepsGPU() & RecoStep::TRDTracking; @@ -149,7 +149,7 @@ int GPUChainTracking::DoTRDGPUTracking(T* externalInstance) } Tracker->PrepareTracking(this); - int useStream = 0; + int32_t useStream = 0; const auto& threadContext = GetThreadContext(); SetupGPUProcessor(Tracker, false); @@ -197,9 +197,9 @@ int GPUChainTracking::DoTRDGPUTracking(T* externalInstance) return (0); } -template int GPUChainTracking::RunTRDTracking(); -template int GPUChainTracking::DoTRDGPUTracking(GPUTRDTrackerGPU*); -template int GPUChainTracking::DoTRDGPUTracking(GPUTRDTracker*); -template int GPUChainTracking::RunTRDTracking(); -template int GPUChainTracking::DoTRDGPUTracking(GPUTRDTracker*); -template int GPUChainTracking::DoTRDGPUTracking(GPUTRDTrackerGPU*); +template int32_t GPUChainTracking::RunTRDTracking(); +template int32_t GPUChainTracking::DoTRDGPUTracking(GPUTRDTrackerGPU*); +template int32_t GPUChainTracking::DoTRDGPUTracking(GPUTRDTracker*); +template int32_t GPUChainTracking::RunTRDTracking(); +template int32_t GPUChainTracking::DoTRDGPUTracking(GPUTRDTracker*); +template int32_t GPUChainTracking::DoTRDGPUTracking(GPUTRDTrackerGPU*); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx b/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx index 84aef65146ca3..67f1ff63e9cb3 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingTransformation.cxx @@ -32,7 +32,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -int GPUChainTracking::ConvertNativeToClusterData() +int32_t GPUChainTracking::ConvertNativeToClusterData() { #ifdef GPUCA_HAVE_O2HEADERS mRec->PushNonPersistentMemory(qStr2Tag("TPCTRANS")); @@ -66,7 +66,7 @@ int GPUChainTracking::ConvertNativeToClusterData() return 0; } SetupGPUProcessor(&convert, true); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { convert.mMemory->clusters[i] = convertShadow.mClusters + mIOPtrs.clustersNative->clusterOffset[i][0]; } @@ -76,7 +76,7 @@ int GPUChainTracking::ConvertNativeToClusterData() TransferMemoryResourcesToHost(RecoStep::TPCConversion, &convert, 0); SynchronizeStream(0); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mIOPtrs.nClusterData[i] = (i == NSLICES - 1 ? mIOPtrs.clustersNative->nClustersTotal : mIOPtrs.clustersNative->clusterOffset[i + 1][0]) - mIOPtrs.clustersNative->clusterOffset[i][0]; mIOPtrs.clusterData[i] = convert.mClusters + mIOPtrs.clustersNative->clusterOffset[i][0]; } @@ -92,7 +92,7 @@ void GPUChainTracking::ConvertNativeToClusterDataLegacy() *tmp = *mIOPtrs.clustersNative; } GPUReconstructionConvert::ConvertNativeToClusterData(mIOMem.clusterNativeAccess.get(), mIOMem.clusterData, mIOPtrs.nClusterData, processors()->calibObjects.fastTransform, param().continuousMaxTimeBin); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mIOPtrs.clusterData[i] = mIOMem.clusterData[i].get(); if (GetProcessingSettings().registerStandaloneInputMemory) { if (mRec->registerMemoryForGPU(mIOMem.clusterData[i].get(), mIOPtrs.nClusterData[i] * sizeof(*mIOPtrs.clusterData[i]))) { @@ -107,7 +107,7 @@ void GPUChainTracking::ConvertNativeToClusterDataLegacy() void GPUChainTracking::ConvertRun2RawToNative() { GPUReconstructionConvert::ConvertRun2RawToNative(*mIOMem.clusterNativeAccess, mIOMem.clustersNative, mIOPtrs.rawClusters, mIOPtrs.nRawClusters); - for (unsigned int i = 0; i < NSLICES; i++) { + for (uint32_t i = 0; i < NSLICES; i++) { mIOPtrs.rawClusters[i] = nullptr; mIOPtrs.nRawClusters[i] = 0; mIOMem.rawClusters[i].reset(nullptr); @@ -123,7 +123,7 @@ void GPUChainTracking::ConvertRun2RawToNative() } } -void GPUChainTracking::ConvertZSEncoder(int version) +void GPUChainTracking::ConvertZSEncoder(int32_t version) { #ifdef GPUCA_HAVE_O2HEADERS mIOMem.tpcZSmeta2.reset(new GPUTrackingInOutZS::GPUTrackingInOutZSMeta); @@ -133,9 +133,9 @@ void GPUChainTracking::ConvertZSEncoder(int version) GPUReconstructionConvert::RunZSEncoderCreateMeta(mIOMem.tpcZSpages.get(), &mIOMem.tpcZSmeta2->n[0][0], &mIOMem.tpcZSmeta2->ptr[0][0], mIOMem.tpcZSmeta.get()); mIOPtrs.tpcZS = mIOMem.tpcZSmeta.get(); if (GetProcessingSettings().registerStandaloneInputMemory) { - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { - for (unsigned int k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t k = 0; k < mIOPtrs.tpcZS->slice[i].count[j]; k++) { if (mRec->registerMemoryForGPU(mIOPtrs.tpcZS->slice[i].zsPtr[j][k], mIOPtrs.tpcZS->slice[i].nZSPtr[j][k] * TPCZSHDR::TPC_ZS_PAGE_SIZE)) { throw std::runtime_error("Error registering memory for GPU"); } @@ -151,17 +151,17 @@ void GPUChainTracking::ConvertZSFilter(bool zs12bit) GPUReconstructionConvert::RunZSFilter(mIOMem.tpcDigits, mIOPtrs.tpcPackedDigits->tpcDigits, mIOMem.digitMap->nTPCDigits, mIOPtrs.tpcPackedDigits->nTPCDigits, param(), zs12bit, param().rec.tpc.zsThreshold); } -int GPUChainTracking::ForwardTPCDigits() +int32_t GPUChainTracking::ForwardTPCDigits() { #ifdef GPUCA_HAVE_O2HEADERS if (GetRecoStepsGPU() & RecoStep::TPCClusterFinding) { throw std::runtime_error("Cannot forward TPC digits with Clusterizer on GPU"); } std::vector tmp[NSLICES][GPUCA_ROW_COUNT]; - unsigned int nTotal = 0; + uint32_t nTotal = 0; const float zsThreshold = param().rec.tpc.zsThreshold; - for (int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < mIOPtrs.tpcPackedDigits->nTPCDigits[i]; j++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < mIOPtrs.tpcPackedDigits->nTPCDigits[i]; j++) { const auto& d = mIOPtrs.tpcPackedDigits->tpcDigits[i][j]; if (d.getChargeFloat() >= zsThreshold) { ClusterNative c; @@ -178,8 +178,8 @@ int GPUChainTracking::ForwardTPCDigits() mIOMem.clustersNative.reset(new ClusterNative[nTotal]); nTotal = 0; mClusterNativeAccess->clustersLinear = mIOMem.clustersNative.get(); - for (int i = 0; i < NSLICES; i++) { - for (int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (int32_t i = 0; i < NSLICES; i++) { + for (int32_t j = 0; j < GPUCA_ROW_COUNT; j++) { mClusterNativeAccess->nClusters[i][j] = tmp[i][j].size(); memcpy(&mIOMem.clustersNative[nTotal], tmp[i][j].data(), tmp[i][j].size() * sizeof(*mClusterNativeAccess->clustersLinear)); nTotal += tmp[i][j].size(); diff --git a/GPU/GPUTracking/Global/GPUErrors.cxx b/GPU/GPUTracking/Global/GPUErrors.cxx index 5e50d7751466c..d9835c25abbfe 100644 --- a/GPU/GPUTracking/Global/GPUErrors.cxx +++ b/GPU/GPUTracking/Global/GPUErrors.cxx @@ -22,9 +22,9 @@ using namespace GPUCA_NAMESPACE::gpu; #define GPUCA_MAX_ERRORS 255u -GPUd() void GPUErrors::raiseError(unsigned int code, unsigned int param1, unsigned int param2, unsigned int param3) const +GPUd() void GPUErrors::raiseError(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3) const { - unsigned int pos = CAMath::AtomicAdd(mErrors, 1u); + uint32_t pos = CAMath::AtomicAdd(mErrors, 1u); if (pos < GPUCA_MAX_ERRORS) { mErrors[4 * pos + 1] = code; mErrors[4 * pos + 2] = param1; @@ -38,7 +38,7 @@ GPUd() void GPUErrors::raiseError(unsigned int code, unsigned int param1, unsign #include #include -unsigned int GPUErrors::getMaxErrors() +uint32_t GPUErrors::getMaxErrors() { return GPUCA_MAX_ERRORS; } @@ -48,7 +48,7 @@ void GPUErrors::clear() memset(mErrors, 0, GPUCA_MAX_ERRORS * sizeof(*mErrors)); } -static std::unordered_map errorNames = { +static std::unordered_map errorNames = { #define GPUCA_ERROR_CODE(num, name, ...) {num, GPUCA_M_STR(name)}, #include "GPUErrorCodes.h" #undef GPUCA_ERROR_CODE @@ -56,8 +56,8 @@ static std::unordered_map errorNames = { void GPUErrors::printErrors(bool silent) { - for (unsigned int i = 0; i < std::min(*mErrors, GPUCA_MAX_ERRORS); i++) { - unsigned int errorCode = mErrors[4 * i + 1]; + for (uint32_t i = 0; i < std::min(*mErrors, GPUCA_MAX_ERRORS); i++) { + uint32_t errorCode = mErrors[4 * i + 1]; const auto& it = errorNames.find(errorCode); const char* errorName = it == errorNames.end() ? "INVALID ERROR CODE" : it->second; if (silent && i) { @@ -77,12 +77,12 @@ void GPUErrors::printErrors(bool silent) } } -unsigned int GPUErrors::getNErrors() const +uint32_t GPUErrors::getNErrors() const { return std::min(*mErrors, GPUCA_MAX_ERRORS); } -const unsigned int* GPUErrors::getErrorPtr() const +const uint32_t* GPUErrors::getErrorPtr() const { return mErrors + 1; } diff --git a/GPU/GPUTracking/Global/GPUErrors.h b/GPU/GPUTracking/Global/GPUErrors.h index 3351377f9f735..8da9b7de5b299 100644 --- a/GPU/GPUTracking/Global/GPUErrors.h +++ b/GPU/GPUTracking/Global/GPUErrors.h @@ -31,17 +31,17 @@ class GPUErrors #undef GPUCA_ERROR_CODE }; - GPUd() void raiseError(unsigned int code, unsigned int param1 = 0, unsigned int param2 = 0, unsigned int param3 = 0) const; + GPUd() void raiseError(uint32_t code, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0) const; GPUd() bool hasError() { return *mErrors > 0; } - void setMemory(GPUglobalref() unsigned int* m) { mErrors = m; } + void setMemory(GPUglobalref() uint32_t* m) { mErrors = m; } void clear(); void printErrors(bool silent = false); - unsigned int getNErrors() const; - const unsigned int* getErrorPtr() const; - static unsigned int getMaxErrors(); + uint32_t getNErrors() const; + const uint32_t* getErrorPtr() const; + static uint32_t getMaxErrors(); private: - GPUglobalref() unsigned int* mErrors; + GPUglobalref() uint32_t* mErrors; }; } // namespace gpu diff --git a/GPU/GPUTracking/Global/GPUTrackingInputProvider.h b/GPU/GPUTracking/Global/GPUTrackingInputProvider.h index 3c87aefc12505..4d9236de079fc 100644 --- a/GPU/GPUTracking/Global/GPUTrackingInputProvider.h +++ b/GPU/GPUTracking/Global/GPUTrackingInputProvider.h @@ -54,40 +54,40 @@ class GPUTrackingInputProvider : public GPUProcessor void* SetPointersErrorCodes(void* mem); #endif - unsigned short mResourceZS = -1; - unsigned short mResourceClusterNativeAccess = -1; - unsigned short mResourceClusterNativeBuffer = -1; - unsigned short mResourceClusterNativeOutput = -1; - unsigned short mResourceErrorCodes = -1; - unsigned short mResourceTRD = -1; - unsigned short mResourceOccupancyMap = -1; + uint16_t mResourceZS = -1; + uint16_t mResourceClusterNativeAccess = -1; + uint16_t mResourceClusterNativeBuffer = -1; + uint16_t mResourceClusterNativeOutput = -1; + uint16_t mResourceErrorCodes = -1; + uint16_t mResourceTRD = -1; + uint16_t mResourceOccupancyMap = -1; bool mHoldTPCZS = false; bool mHoldTPCClusterNative = false; bool mHoldTPCClusterNativeOutput = false; bool mHoldTPCOccupancyMap = false; - unsigned int mNClusterNative = 0; + uint32_t mNClusterNative = 0; GPUTrackingInOutZS* mPzsMeta = nullptr; - unsigned int* mPzsSizes = nullptr; + uint32_t* mPzsSizes = nullptr; void** mPzsPtrs = nullptr; - unsigned int mNTRDTracklets = 0; + uint32_t mNTRDTracklets = 0; bool mDoSpacepoints = false; - unsigned int mNTRDTriggerRecords = 0; + uint32_t mNTRDTriggerRecords = 0; GPUTRDTrackletWord* mTRDTracklets = nullptr; GPUTRDSpacePoint* mTRDSpacePoints = nullptr; float* mTRDTriggerTimes = nullptr; - int* mTRDTrackletIdxFirst = nullptr; - char* mTRDTrigRecMask = nullptr; + int32_t* mTRDTrackletIdxFirst = nullptr; + uint8_t* mTRDTrigRecMask = nullptr; o2::tpc::ClusterNativeAccess* mPclusterNativeAccess = nullptr; o2::tpc::ClusterNative* mPclusterNativeBuffer = nullptr; o2::tpc::ClusterNative* mPclusterNativeOutput = nullptr; - unsigned int* mTPCClusterOccupancyMap = nullptr; + uint32_t* mTPCClusterOccupancyMap = nullptr; - unsigned int* mErrorCodes = nullptr; + uint32_t* mErrorCodes = nullptr; }; } // namespace gpu diff --git a/GPU/GPUTracking/HLTHeaders/AliHLTTPCClusterMCData.h b/GPU/GPUTracking/HLTHeaders/AliHLTTPCClusterMCData.h index 70144139de1cb..3c793a9f4e366 100644 --- a/GPU/GPUTracking/HLTHeaders/AliHLTTPCClusterMCData.h +++ b/GPU/GPUTracking/HLTHeaders/AliHLTTPCClusterMCData.h @@ -24,7 +24,7 @@ struct AliHLTTPCClusterMCWeight { //* constructor **/ AliHLTTPCClusterMCWeight() : fMCID(-1), fWeight(0) {} - int fMCID; // MC track ID + int32_t fMCID; // MC track ID float fWeight; // weight of the track ID }; @@ -47,7 +47,7 @@ typedef struct AliHLTTPCClusterMCLabel AliHLTTPCClusterMCLabel; * @ingroup alihlt_tpc */ struct AliHLTTPCClusterMCData { - int fCount; + int32_t fCount; #if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC) AliHLTTPCClusterMCLabel fLabels[1]; #else diff --git a/GPU/GPUTracking/HLTHeaders/AliHLTTPCRawCluster.h b/GPU/GPUTracking/HLTHeaders/AliHLTTPCRawCluster.h index 4cd8c5cdc332a..943fbde4be834 100644 --- a/GPU/GPUTracking/HLTHeaders/AliHLTTPCRawCluster.h +++ b/GPU/GPUTracking/HLTHeaders/AliHLTTPCRawCluster.h @@ -24,7 +24,7 @@ struct AliHLTTPCRawCluster { AliHLTTPCRawCluster() : fPadRow(0), mFlags(0), fPad(0.), fTime(0.), fSigmaPad2(0.), fSigmaTime2(0.), fCharge(0), fQMax(0) {} - AliHLTTPCRawCluster(short PadRow, float Pad, float Time, float SigmaPad2, float SigmaTime2, unsigned short Charge, unsigned short QMax, unsigned short Flags) : fPadRow(PadRow), mFlags(Flags), fPad(Pad), fTime(Time), fSigmaPad2(SigmaPad2), fSigmaTime2(SigmaTime2), fCharge(Charge), fQMax(QMax) {} + AliHLTTPCRawCluster(int16_t PadRow, float Pad, float Time, float SigmaPad2, float SigmaTime2, uint16_t Charge, uint16_t QMax, uint16_t Flags) : fPadRow(PadRow), mFlags(Flags), fPad(Pad), fTime(Time), fSigmaPad2(SigmaPad2), fSigmaTime2(SigmaTime2), fCharge(Charge), fQMax(QMax) {} AliHLTTPCRawCluster(const AliHLTTPCRawCluster& other) : fPadRow(other.fPadRow), mFlags(other.mFlags), fPad(other.fPad), fTime(other.fTime), fSigmaPad2(other.fSigmaPad2), fSigmaTime2(other.fSigmaTime2), fCharge(other.fCharge), fQMax(other.fQMax) {} // NOLINT @@ -44,42 +44,42 @@ struct AliHLTTPCRawCluster { new (this) AliHLTTPCRawCluster; } - short fPadRow; - unsigned short mFlags; // Flags: (1 << 0): Split in pad direction - // (1 << 1): Split in time direction - // (1 << 2): Edge Cluster - // During cluster merging, flags are OR'd + int16_t fPadRow; + uint16_t mFlags; // Flags: (1 << 0): Split in pad direction + // (1 << 1): Split in time direction + // (1 << 2): Edge Cluster + // During cluster merging, flags are OR'd float fPad; float fTime; float fSigmaPad2; float fSigmaTime2; - unsigned short fCharge; - unsigned short fQMax; + uint16_t fCharge; + uint16_t fQMax; - int GetPadRow() const { return fPadRow; } + int32_t GetPadRow() const { return fPadRow; } float GetPad() const { return fPad; } float GetTime() const { return fTime; } float GetSigmaPad2() const { return fSigmaPad2; } float GetSigmaTime2() const { return fSigmaTime2; } - int GetCharge() const { return fCharge; } - int GetQMax() const { return fQMax; } + int32_t GetCharge() const { return fCharge; } + int32_t GetQMax() const { return fQMax; } bool GetFlagSplitPad() const { return (mFlags & (1 << 0)); } bool GetFlagSplitTime() const { return (mFlags & (1 << 1)); } bool GetFlagSplitAny() const { return (mFlags & 3); } bool GetFlagEdge() const { return (mFlags & (1 << 2)); } bool GetFlagSplitAnyOrEdge() const { return (mFlags & 7); } - unsigned short GetFlags() const { return (mFlags); } + uint16_t GetFlags() const { return (mFlags); } - void SetPadRow(short padrow) { fPadRow = padrow; } + void SetPadRow(int16_t padrow) { fPadRow = padrow; } void SetPad(float pad) { fPad = pad; } void SetTime(float time) { fTime = time; } void SetSigmaPad2(float sigmaPad2) { fSigmaPad2 = sigmaPad2; } void SetSigmaTime2(float sigmaTime2) { fSigmaTime2 = sigmaTime2; } - void SetCharge(unsigned short charge) { fCharge = charge; } - void SetQMax(unsigned short qmax) { fQMax = qmax; } + void SetCharge(uint16_t charge) { fCharge = charge; } + void SetQMax(uint16_t qmax) { fQMax = qmax; } void ClearFlags() { mFlags = 0; } - void SetFlags(unsigned short flags) { mFlags = flags; } + void SetFlags(uint16_t flags) { mFlags = flags; } void SetFlagSplitPad() { mFlags |= (1 << 0); } void SetFlagSplitTime() { mFlags |= (1 << 1); } void SetFlagEdge() { mFlags |= (1 << 2); } @@ -87,8 +87,8 @@ struct AliHLTTPCRawCluster { typedef struct AliHLTTPCRawCluster AliHLTTPCRawCluster; struct AliHLTTPCRawClusterData { - unsigned int fVersion; // version number - unsigned int fCount; // number of clusters + uint32_t fVersion; // version number + uint32_t fCount; // number of clusters #if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC) AliHLTTPCRawCluster fClusters[1]; // array of clusters #else diff --git a/GPU/GPUTracking/ITS/GPUITSFitter.cxx b/GPU/GPUTracking/ITS/GPUITSFitter.cxx index fa9482020cbda..f5a360145a9e9 100644 --- a/GPU/GPUTracking/ITS/GPUITSFitter.cxx +++ b/GPU/GPUTracking/ITS/GPUITSFitter.cxx @@ -29,7 +29,7 @@ void GPUITSFitter::InitializeProcessor() void* GPUITSFitter::SetPointersInput(void* mem) { computePointerWithAlignment(mem, mRoads, mNumberOfRoads); - for (int i = 0; i < 7; i++) { + for (int32_t i = 0; i < 7; i++) { computePointerWithAlignment(mem, mTF[i], mNTF[i]); } return mem; diff --git a/GPU/GPUTracking/ITS/GPUITSFitter.h b/GPU/GPUTracking/ITS/GPUITSFitter.h index 98bdce320096d..8a84a0df9da7f 100644 --- a/GPU/GPUTracking/ITS/GPUITSFitter.h +++ b/GPU/GPUTracking/ITS/GPUITSFitter.h @@ -20,7 +20,7 @@ namespace o2::its { -template +template class Road; struct TrackingFrameInfo; struct Cluster; @@ -48,19 +48,19 @@ class GPUITSFitter : public GPUProcessor { return mRoads; } - GPUd() void SetNumberOfRoads(int v) { mNumberOfRoads = v; } - GPUd() int NumberOfRoads() { return mNumberOfRoads; } + GPUd() void SetNumberOfRoads(int32_t v) { mNumberOfRoads = v; } + GPUd() int32_t NumberOfRoads() { return mNumberOfRoads; } GPUd() GPUITSTrack* tracks() { return mTracks; } - GPUd() GPUAtomic(unsigned int) & NumberOfTracks() + GPUd() GPUAtomic(uint32_t) & NumberOfTracks() { return mMemory->mNumberOfTracks; } - GPUd() void SetNumberOfLayers(int i) { mNumberOfLayers = i; } - GPUd() int NumberOfLayers() { return mNumberOfLayers; } - GPUd() void SetNumberTF(int i, int v) { mNTF[i] = v; } + GPUd() void SetNumberOfLayers(int32_t i) { mNumberOfLayers = i; } + GPUd() int32_t NumberOfLayers() { return mNumberOfLayers; } + GPUd() void SetNumberTF(int32_t i, int32_t v) { mNTF[i] = v; } GPUd() o2::its::TrackingFrameInfo** trackingFrame() { return mTF; @@ -77,14 +77,14 @@ class GPUITSFitter : public GPUProcessor void clearMemory(); struct Memory { - GPUAtomic(unsigned int) mNumberOfTracks = 0; + GPUAtomic(uint32_t) mNumberOfTracks = 0; }; protected: - int mNumberOfLayers; - int mNumberOfRoads = 0; - int mNMaxTracks = 0; - int* mNTF = nullptr; + int32_t mNumberOfLayers; + int32_t mNumberOfRoads = 0; + int32_t mNMaxTracks = 0; + int32_t* mNTF = nullptr; Memory* mMemory = nullptr; o2::its::Road<5>* mRoads = nullptr; o2::its::TrackingFrameInfo** mTF = {nullptr}; @@ -93,9 +93,9 @@ class GPUITSFitter : public GPUProcessor const o2::its::Cluster** mClusterPtrs; const o2::its::Cell** mCellPtrs; - short mMemoryResInput = -1; - short mMemoryResTracks = -1; - short mMemoryResMemory = -1; + int16_t mMemoryResInput = -1; + int16_t mMemoryResTracks = -1; + int16_t mMemoryResMemory = -1; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/ITS/GPUITSFitterKernels.cxx b/GPU/GPUTracking/ITS/GPUITSFitterKernels.cxx index d760ca52de6a3..5e6a70e1b8876 100644 --- a/GPU/GPUTracking/ITS/GPUITSFitterKernels.cxx +++ b/GPU/GPUTracking/ITS/GPUITSFitterKernels.cxx @@ -30,9 +30,9 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2; using namespace o2::its; -GPUdii() bool GPUITSFitterKernels::fitTrack(GPUITSFitter& GPUrestrict() Fitter, GPUTPCGMPropagator& GPUrestrict() prop, GPUITSTrack& GPUrestrict() track, int start, int end, int step) +GPUdii() bool GPUITSFitterKernels::fitTrack(GPUITSFitter& GPUrestrict() Fitter, GPUTPCGMPropagator& GPUrestrict() prop, GPUITSTrack& GPUrestrict() track, int32_t start, int32_t end, int32_t step) { - for (int iLayer{start}; iLayer != end; iLayer += step) { + for (int32_t iLayer{start}; iLayer != end; iLayer += step) { if (track.mClusters[iLayer] == o2::its::constants::its::UnusedIndex) { continue; } @@ -56,7 +56,7 @@ GPUdii() bool GPUITSFitterKernels::fitTrack(GPUITSFitter& GPUrestrict() Fitter, } template <> -GPUdii() void GPUITSFitterKernels::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUITSFitterKernels::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { GPUITSFitter& Fitter = processors.itsFitter; @@ -68,19 +68,19 @@ GPUdii() void GPUITSFitterKernels::Thread<0>(int nBlocks, int nThreads, int iBlo float bz = -5.f; // FIXME #ifdef CA_DEBUG - int roadCounters[4]{0, 0, 0, 0}; - int fitCounters[4]{0, 0, 0, 0}; - int backpropagatedCounters[4]{0, 0, 0, 0}; - int refitCounters[4]{0, 0, 0, 0}; + int32_t roadCounters[4]{0, 0, 0, 0}; + int32_t fitCounters[4]{0, 0, 0, 0}; + int32_t backpropagatedCounters[4]{0, 0, 0, 0}; + int32_t refitCounters[4]{0, 0, 0, 0}; #endif - for (int iRoad = get_global_id(0); iRoad < Fitter.NumberOfRoads(); iRoad += get_global_size(0)) { + for (int32_t iRoad = get_global_id(0); iRoad < Fitter.NumberOfRoads(); iRoad += get_global_size(0)) { Road<5>& road = Fitter.roads()[iRoad]; - int clusters[7] = {o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex}; - int lastCellLevel = o2::its::constants::its::UnusedIndex; - CA_DEBUGGER(int nClusters = 2); + int32_t clusters[7] = {o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex, o2::its::constants::its::UnusedIndex}; + int32_t lastCellLevel = o2::its::constants::its::UnusedIndex; + CA_DEBUGGER(int32_t nClusters = 2); - for (int iCell{0}; iCell < Fitter.NumberOfLayers() - 2; ++iCell) { - const int cellIndex = road[iCell]; + for (int32_t iCell{0}; iCell < Fitter.NumberOfLayers() - 2; ++iCell) { + const int32_t cellIndex = road[iCell]; if (cellIndex == o2::its::constants::its::UnusedIndex) { continue; } else { @@ -99,7 +99,7 @@ GPUdii() void GPUITSFitterKernels::Thread<0>(int nBlocks, int nThreads, int iBlo } /// From primary vertex context index to event index (== the one used as input of the tracking code) - for (int iC{0}; iC < 7; iC++) { + for (int32_t iC{0}; iC < 7; iC++) { if (clusters[iC] != o2::its::constants::its::UnusedIndex) { clusters[iC] = Fitter.clusters()[iC][clusters[iC]].clusterId; } @@ -176,10 +176,10 @@ GPUdii() void GPUITSFitterKernels::Thread<0>(int nBlocks, int nThreads, int iBlo continue; } CA_DEBUGGER(backpropagatedCounters[nClusters - 4]++); - for (int k = 0; k < 5; k++) { + for (int32_t k = 0; k < 5; k++) { temporaryTrack.mOuterParam.P[k] = temporaryTrack.Par()[k]; } - for (int k = 0; k < 15; k++) { + for (int32_t k = 0; k < 15; k++) { temporaryTrack.mOuterParam.C[k] = temporaryTrack.Cov()[k]; } temporaryTrack.mOuterParam.X = temporaryTrack.X(); @@ -190,7 +190,7 @@ GPUdii() void GPUITSFitterKernels::Thread<0>(int nBlocks, int nThreads, int iBlo continue; } CA_DEBUGGER(refitCounters[nClusters - 4]++); - int trackId = CAMath::AtomicAdd(&Fitter.NumberOfTracks(), 1u); + int32_t trackId = CAMath::AtomicAdd(&Fitter.NumberOfTracks(), 1u); Fitter.tracks()[trackId] = temporaryTrack; } #ifdef CA_DEBUG diff --git a/GPU/GPUTracking/ITS/GPUITSFitterKernels.h b/GPU/GPUTracking/ITS/GPUITSFitterKernels.h index 49735606486ee..f4b120564f179 100644 --- a/GPU/GPUTracking/ITS/GPUITSFitterKernels.h +++ b/GPU/GPUTracking/ITS/GPUITSFitterKernels.h @@ -31,11 +31,11 @@ class GPUITSFitterKernels : public GPUKernelTemplate { public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::ITSTracking; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors); protected: - GPUd() static bool fitTrack(GPUITSFitter& Fitter, GPUTPCGMPropagator& prop, GPUITSTrack& track, int start, int end, int step); + GPUd() static bool fitTrack(GPUITSFitter& Fitter, GPUTPCGMPropagator& prop, GPUITSTrack& track, int32_t start, int32_t end, int32_t step); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/ITS/GPUITSTrack.h b/GPU/GPUTracking/ITS/GPUITSTrack.h index ad4d2edc6d552..3ae48eeca97c5 100644 --- a/GPU/GPUTracking/ITS/GPUITSTrack.h +++ b/GPU/GPUTracking/ITS/GPUITSTrack.h @@ -25,7 +25,7 @@ class GPUITSTrack : public GPUTPCGMTrackParam public: gputpcgmmergertypes::GPUTPCOuterParam mOuterParam; float mAlpha; - int mClusters[7]; + int32_t mClusters[7]; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/Interface/GPUO2Interface.cxx b/GPU/GPUTracking/Interface/GPUO2Interface.cxx index 429a58ad65dd4..34cd5b7280dc3 100644 --- a/GPU/GPUTracking/Interface/GPUO2Interface.cxx +++ b/GPU/GPUTracking/Interface/GPUO2Interface.cxx @@ -50,7 +50,7 @@ GPUO2Interface::GPUO2Interface() : mInternals(new GPUO2Interface_Internals){}; GPUO2Interface::~GPUO2Interface() { Deinitialize(); } -int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) +int32_t GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) { if (mNContexts) { return (1); @@ -64,7 +64,7 @@ int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) if (mConfig->configWorkflow.inputs.isSet(GPUDataTypes::InOutType::TPCCompressedClusters)) { mConfig->configGRP.doCompClusterDecode = 1; } - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { if (i) { mConfig->configDeviceBackend.master = mCtx[0].mRec.get(); } @@ -77,7 +77,7 @@ int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) return 1; } } - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { mCtx[i].mChain = mCtx[i].mRec->AddChain(mConfig->configInterface.maxTPCHits, mConfig->configInterface.maxTRDTracklets); if (i) { mCtx[i].mChain->SetQAFromForeignChain(mCtx[0].mChain); @@ -93,7 +93,7 @@ int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) mCtx[i].mOutputRegions.reset(new GPUTrackingOutputs); if (mConfig->configInterface.outputToExternalBuffers) { - for (unsigned int j = 0; j < mCtx[i].mOutputRegions->count(); j++) { + for (uint32_t j = 0; j < mCtx[i].mOutputRegions->count(); j++) { mCtx[i].mChain->SetSubOutputControl(j, &mCtx[i].mOutputRegions->asArray()[j]); } GPUOutputControl dummy; @@ -101,7 +101,7 @@ int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) mCtx[i].mRec->SetOutputControl(dummy); } } - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { if (i == 0 && mCtx[i].mRec->Init()) { mNContexts = 0; mCtx.reset(nullptr); @@ -124,18 +124,18 @@ void GPUO2Interface::Deinitialize() mCtx[0].mRec->TerminatePipelineWorker(); mInternals->pipelineThread->join(); } - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { mCtx[i].mRec->Finalize(); } mCtx[0].mRec->Exit(); - for (int i = mNContexts - 1; i >= 0; i--) { + for (int32_t i = mNContexts - 1; i >= 0; i--) { mCtx[i].mRec.reset(); } } mNContexts = 0; } -void GPUO2Interface::DumpEvent(int nEvent, GPUTrackingInOutPointers* data) +void GPUO2Interface::DumpEvent(int32_t nEvent, GPUTrackingInOutPointers* data) { mCtx[0].mChain->ClearIOPointers(); mCtx[0].mChain->mIOPtrs = *data; @@ -160,7 +160,7 @@ void GPUO2Interface::DumpSettings() mCtx[0].mRec->DumpSettings(); } -int GPUO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutputs* outputs, unsigned int iThread, GPUInterfaceInputUpdate* inputUpdateCallback) +int32_t GPUO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutputs* outputs, uint32_t iThread, GPUInterfaceInputUpdate* inputUpdateCallback) { if (mNContexts <= iThread) { return (1); @@ -170,7 +170,7 @@ int GPUO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutp auto setOutputs = [this, iThread](GPUInterfaceOutputs* outputs) { if (mConfig->configInterface.outputToExternalBuffers) { - for (unsigned int i = 0; i < mCtx[iThread].mOutputRegions->count(); i++) { + for (uint32_t i = 0; i < mCtx[iThread].mOutputRegions->count(); i++) { if (outputs->asArray()[i].allocator) { mCtx[iThread].mOutputRegions->asArray()[i].set(outputs->asArray()[i].allocator); } else if (outputs->asArray()[i].ptrBase) { @@ -206,7 +206,7 @@ int GPUO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutp setOutputs(outputs); } - int retVal = mCtx[iThread].mRec->RunChains(); + int32_t retVal = mCtx[iThread].mRec->RunChains(); if (retVal == 2) { retVal = 0; // 2 signals end of event display, ignore } @@ -222,29 +222,29 @@ int GPUO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutp return retVal; } -void GPUO2Interface::Clear(bool clearOutputs, unsigned int iThread) { mCtx[iThread].mRec->ClearAllocatedMemory(clearOutputs); } +void GPUO2Interface::Clear(bool clearOutputs, uint32_t iThread) { mCtx[iThread].mRec->ClearAllocatedMemory(clearOutputs); } -int GPUO2Interface::registerMemoryForGPU(const void* ptr, size_t size) +int32_t GPUO2Interface::registerMemoryForGPU(const void* ptr, size_t size) { return mCtx[0].mRec->registerMemoryForGPU(ptr, size); } -int GPUO2Interface::unregisterMemoryForGPU(const void* ptr) +int32_t GPUO2Interface::unregisterMemoryForGPU(const void* ptr) { return mCtx[0].mRec->unregisterMemoryForGPU(ptr); } -int GPUO2Interface::UpdateCalibration(const GPUCalibObjectsConst& newCalib, const GPUNewCalibValues& newVals, unsigned int iThread) +int32_t GPUO2Interface::UpdateCalibration(const GPUCalibObjectsConst& newCalib, const GPUNewCalibValues& newVals, uint32_t iThread) { - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { mCtx[i].mChain->SetUpdateCalibObjects(newCalib, newVals); } return 0; } -void GPUO2Interface::setErrorCodeOutput(std::vector>* v) +void GPUO2Interface::setErrorCodeOutput(std::vector>* v) { - for (unsigned int i = 0; i < mNContexts; i++) { + for (uint32_t i = 0; i < mNContexts; i++) { mCtx[i].mRec->setErrorCodeOutput(v); } } @@ -256,7 +256,7 @@ void GPUO2Interface::GetITSTraits(o2::its::TrackerTraits*& trackerTraits, o2::it timeFrame = mChainITS->GetITSTimeframe(); } -const o2::base::Propagator* GPUO2Interface::GetDeviceO2Propagator(int iThread) const +const o2::base::Propagator* GPUO2Interface::GetDeviceO2Propagator(int32_t iThread) const { return mCtx[iThread].mChain->GetDeviceO2Propagator(); } diff --git a/GPU/GPUTracking/Interface/GPUO2Interface.h b/GPU/GPUTracking/Interface/GPUO2Interface.h index ae48775396fe4..aab3c1562c67d 100644 --- a/GPU/GPUTracking/Interface/GPUO2Interface.h +++ b/GPU/GPUTracking/Interface/GPUO2Interface.h @@ -72,24 +72,24 @@ class GPUO2Interface GPUO2Interface(); ~GPUO2Interface(); - int Initialize(const GPUO2InterfaceConfiguration& config); + int32_t Initialize(const GPUO2InterfaceConfiguration& config); void Deinitialize(); - int RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutputs* outputs = nullptr, unsigned int iThread = 0, GPUInterfaceInputUpdate* inputUpdateCallback = nullptr); - void Clear(bool clearOutputs, unsigned int iThread = 0); - void DumpEvent(int nEvent, GPUTrackingInOutPointers* data); + int32_t RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceOutputs* outputs = nullptr, uint32_t iThread = 0, GPUInterfaceInputUpdate* inputUpdateCallback = nullptr); + void Clear(bool clearOutputs, uint32_t iThread = 0); + void DumpEvent(int32_t nEvent, GPUTrackingInOutPointers* data); void DumpSettings(); void GetITSTraits(o2::its::TrackerTraits*& trackerTraits, o2::its::VertexerTraits*& vertexerTraits, o2::its::TimeFrame*& timeFrame); - const o2::base::Propagator* GetDeviceO2Propagator(int iThread = 0) const; + const o2::base::Propagator* GetDeviceO2Propagator(int32_t iThread = 0) const; void UseGPUPolynomialFieldInPropagator(o2::base::Propagator* prop) const; // Updates all calibration objects that are != nullptr in newCalib - int UpdateCalibration(const GPUCalibObjectsConst& newCalib, const GPUNewCalibValues& newVals, unsigned int iThread = 0); + int32_t UpdateCalibration(const GPUCalibObjectsConst& newCalib, const GPUNewCalibValues& newVals, uint32_t iThread = 0); - int registerMemoryForGPU(const void* ptr, size_t size); - int unregisterMemoryForGPU(const void* ptr); - void setErrorCodeOutput(std::vector>* v); + int32_t registerMemoryForGPU(const void* ptr, size_t size); + int32_t unregisterMemoryForGPU(const void* ptr); + void setErrorCodeOutput(std::vector>* v); const GPUO2InterfaceConfiguration& getConfig() const { return *mConfig; } @@ -99,7 +99,7 @@ class GPUO2Interface bool mContinuous = false; - unsigned int mNContexts = 0; + uint32_t mNContexts = 0; std::unique_ptr mCtx; std::unique_ptr mConfig; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx index 0cc65b2882c55..c3aaec8d9f9a6 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx @@ -65,7 +65,7 @@ GPUSettingsO2 GPUO2InterfaceConfiguration::ReadConfigurableParam(GPUO2InterfaceC #define AddOptionSet(name, type, value, optname, optnameshort, help, ...) #define AddOptionVec(name, type, optname, optnameshort, help, ...) #define AddOptionArray(name, type, count, default, optname, optnameshort, help, ...) \ - for (int i = 0; i < count; i++) { \ + for (int32_t i = 0; i < count; i++) { \ dst.name[i] = src.name[i]; \ } #define AddOptionArrayRTC(...) AddOptionArray(__VA_ARGS__) diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h index 0427d6d14c996..dd819f7ef7c05 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h @@ -81,10 +81,10 @@ struct GPUO2InterfaceConfiguration { struct GPUInterfaceSettings { bool outputToExternalBuffers = false; // These constants affect GPU memory allocation only and do not limit the CPU processing - unsigned long maxTPCZS = 8192ul * 1024 * 1024; - unsigned int maxTPCHits = 1024 * 1024 * 1024; - unsigned int maxTRDTracklets = 128 * 1024; - unsigned int maxITSTracks = 96 * 1024; + uint64_t maxTPCZS = 8192ul * 1024 * 1024; + uint32_t maxTPCHits = 1024 * 1024 * 1024; + uint32_t maxTRDTracklets = 128 * 1024; + uint32_t maxITSTracks = 96 * 1024; }; GPUSettingsDeviceBackend configDeviceBackend; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx index 6e51bcddb863a..f84f29d826f1d 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.cxx @@ -40,9 +40,9 @@ GPUO2InterfaceDisplay::GPUO2InterfaceDisplay(const GPUO2InterfaceConfiguration* GPUO2InterfaceDisplay::~GPUO2InterfaceDisplay() = default; -int GPUO2InterfaceDisplay::startDisplay() +int32_t GPUO2InterfaceDisplay::startDisplay() { - int retVal = mDisplay->StartDisplay(); + int32_t retVal = mDisplay->StartDisplay(); if (retVal) { return retVal; } @@ -50,7 +50,7 @@ int GPUO2InterfaceDisplay::startDisplay() return 0; } -int GPUO2InterfaceDisplay::show(const GPUTrackingInOutPointers* ptrs) +int32_t GPUO2InterfaceDisplay::show(const GPUTrackingInOutPointers* ptrs) { std::unique_ptr tmpPtr; if (mConfig->configProcessing.runMC) { @@ -70,7 +70,7 @@ int GPUO2InterfaceDisplay::show(const GPUTrackingInOutPointers* ptrs) return 0; } -int GPUO2InterfaceDisplay::endDisplay() +int32_t GPUO2InterfaceDisplay::endDisplay() { mFrontend->DisplayExit(); return 0; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.h b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.h index 275cddba23659..5b7a8672e746d 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceDisplay.h @@ -47,9 +47,9 @@ class GPUO2InterfaceDisplay void UpdateCalib(const GPUCalibObjectsConst* calib); void UpdateGRP(const GPUSettingsGRP* grp); - int startDisplay(); - int show(const GPUTrackingInOutPointers* ptrs); - int endDisplay(); + int32_t startDisplay(); + int32_t show(const GPUTrackingInOutPointers* ptrs); + int32_t endDisplay(); private: std::unique_ptr mDisplay; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx index e0ce9e01b549c..db6df3f9f1ede 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx @@ -30,7 +30,7 @@ GPUO2InterfaceQA::GPUO2InterfaceQA(const GPUO2InterfaceConfiguration* config) GPUO2InterfaceQA::~GPUO2InterfaceQA() = default; -int GPUO2InterfaceQA::initializeForProcessing(int tasks) +int32_t GPUO2InterfaceQA::initializeForProcessing(int32_t tasks) { return mQA->InitQA(tasks); } @@ -39,12 +39,12 @@ void GPUO2InterfaceQA::runQA(const std::vector* tracksExterna { mQA->RunQA(false, tracksExternal, tracksExtMC, clNative); } -int GPUO2InterfaceQA::postprocess(TObjArray& out) +int32_t GPUO2InterfaceQA::postprocess(TObjArray& out) { return mQA->DrawQAHistograms(&out); } -int GPUO2InterfaceQA::postprocessExternal(std::vector& in1, std::vector& in2, std::vector& in3, std::vector& in4, TObjArray& out, int tasks) +int32_t GPUO2InterfaceQA::postprocessExternal(std::vector& in1, std::vector& in2, std::vector& in3, std::vector& in4, TObjArray& out, int32_t tasks) { if (mQA->loadHistograms(in1, in2, in3, in4, tasks)) { return 1; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h index 05e55044415ea..e046183e646cd 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h @@ -57,14 +57,14 @@ class GPUO2InterfaceQA GPUO2InterfaceQA(const GPUO2InterfaceConfiguration* config = nullptr); ~GPUO2InterfaceQA(); - int initializeForProcessing(int tasks); // only needed for processing, not for postprocessing + int32_t initializeForProcessing(int32_t tasks); // only needed for processing, not for postprocessing void runQA(const std::vector* tracksExternal, const std::vector* tracksExtMC, const o2::tpc::ClusterNativeAccess* clNative); - int postprocess(TObjArray& out); + int32_t postprocess(TObjArray& out); void updateGRP(GPUSettingsGRP* grp); // Input might be modified, so we assume non-const. If it is const, a copy should be created before. - int postprocessExternal(std::vector& in1, std::vector& in2, std::vector& in3, std::vector& in4, TObjArray& out, int tasks); + int32_t postprocessExternal(std::vector& in1, std::vector& in2, std::vector& in3, std::vector& in4, TObjArray& out, int32_t tasks); void getHists(const std::vector*& h1, const std::vector*& h2, const std::vector*& h3, const std::vector*& h4); void resetHists(); diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx index 55122b7de4af6..10a1a75368c96 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx @@ -25,7 +25,7 @@ using namespace o2::gpu; using namespace o2::tpc; -void GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(const ClusterNativeAccess* cl, const gsl::span trks, const TPCClRefElem* trackRef, unsigned char* shmap, unsigned int* ocmap, unsigned int nHbfPerTf, const GPUParam* param) +void GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(const ClusterNativeAccess* cl, const gsl::span trks, const TPCClRefElem* trackRef, uint8_t* shmap, uint32_t* ocmap, uint32_t nHbfPerTf, const GPUParam* param) { if (!cl || (!shmap && cl->nClustersTotal > 0)) { throw std::runtime_error("Must provide clusters access and preallocated buffer for shared map"); @@ -39,14 +39,14 @@ void GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(const ClusterNativeA throw std::runtime_error("Must provide nHbfPerTf for occupancy map"); } memset(shmap, 0, sizeof(char) * cl->nClustersTotal); - for (unsigned int i = 0; i < trks.size(); i++) { - for (int j = 0; j < trks[i].getNClusterReferences(); j++) { + for (uint32_t i = 0; i < trks.size(); i++) { + for (int32_t j = 0; j < trks[i].getNClusterReferences(); j++) { size_t idx = &trks[i].getCluster(trackRef, j, *cl) - cl->clustersLinear; shmap[idx] = shmap[idx] ? 2 : 1; } } - std::vector tmp; - unsigned int* binmap = nullptr; + std::vector tmp; + uint32_t* binmap = nullptr; if (ocmap && nHbfPerTf) { tmp.resize(param->rec.tpc.occupancyMapTimeBinsAverage ? GPUTPCClusterOccupancyMapBin::getNBins(*param) : 0, 0); binmap = param->rec.tpc.occupancyMapTimeBinsAverage ? tmp.data() : (ocmap + 2); @@ -56,19 +56,19 @@ void GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(const ClusterNativeA } } - for (unsigned int i = 0; i < cl->nClustersTotal; i++) { + for (uint32_t i = 0; i < cl->nClustersTotal; i++) { shmap[i] = (shmap[i] > 1 ? GPUTPCGMMergedTrackHit::flagShared : 0) | cl->clustersLinear[i].getFlags(); if (binmap) { - binmap[(unsigned int)(cl->clustersLinear[i].getTime() / param->rec.tpc.occupancyMapTimeBins)]++; + binmap[(uint32_t)(cl->clustersLinear[i].getTime() / param->rec.tpc.occupancyMapTimeBins)]++; } } if (ocmap && nHbfPerTf && param->rec.tpc.occupancyMapTimeBinsAverage) { - for (unsigned int bin = 0; bin < GPUTPCClusterOccupancyMapBin::getNBins(*param); bin++) { - int binmin = CAMath::Max(0, bin - param->rec.tpc.occupancyMapTimeBinsAverage); - int binmax = CAMath::Min(GPUTPCClusterOccupancyMapBin::getNBins(*param), bin + param->rec.tpc.occupancyMapTimeBinsAverage + 1); - unsigned int sum = 0; - for (int i = binmin; i < binmax; i++) { + for (uint32_t bin = 0; bin < GPUTPCClusterOccupancyMapBin::getNBins(*param); bin++) { + int32_t binmin = CAMath::Max(0, bin - param->rec.tpc.occupancyMapTimeBinsAverage); + int32_t binmax = CAMath::Min(GPUTPCClusterOccupancyMapBin::getNBins(*param), bin + param->rec.tpc.occupancyMapTimeBinsAverage + 1); + uint32_t sum = 0; + for (int32_t i = binmin; i < binmax; i++) { sum += binmap[i]; } sum /= binmax - binmin; @@ -77,7 +77,7 @@ void GPUO2InterfaceRefit::fillSharedClustersAndOccupancyMap(const ClusterNativeA } } -size_t GPUO2InterfaceRefit::fillOccupancyMapGetSize(unsigned int nHbfPerTf, const GPUParam* param) +size_t GPUO2InterfaceRefit::fillOccupancyMapGetSize(uint32_t nHbfPerTf, const GPUParam* param) { std::unique_ptr tmpParam; if (param == nullptr) { @@ -88,15 +88,15 @@ size_t GPUO2InterfaceRefit::fillOccupancyMapGetSize(unsigned int nHbfPerTf, cons throw std::runtime_error("nHbfPerTf must not be zero for creation of the occupancy map"); } if (param->rec.tpc.occupancyMapTimeBins) { - return (GPUTPCClusterOccupancyMapBin::getNBins(*param) + 2) * sizeof(unsigned int); + return (GPUTPCClusterOccupancyMapBin::getNBins(*param) + 2) * sizeof(uint32_t); } else if (param->rec.tpc.sysClusErrorC12Norm) { - return sizeof(unsigned int); + return sizeof(uint32_t); } else { return 0; } } -GPUO2InterfaceRefit::GPUO2InterfaceRefit(const ClusterNativeAccess* cl, const CorrectionMapsHelper* trans, float bzNominalGPU, const TPCClRefElem* trackRef, unsigned int nHbfPerTf, const unsigned char* sharedmap, const unsigned int* occupancymap, int occupancyMapSize, const std::vector* trks, o2::base::Propagator* p) +GPUO2InterfaceRefit::GPUO2InterfaceRefit(const ClusterNativeAccess* cl, const CorrectionMapsHelper* trans, float bzNominalGPU, const TPCClRefElem* trackRef, uint32_t nHbfPerTf, const uint8_t* sharedmap, const uint32_t* occupancymap, int32_t occupancyMapSize, const std::vector* trks, o2::base::Propagator* p) { mParam = GPUO2InterfaceUtils::getFullParam(bzNominalGPU, nHbfPerTf); size_t expectedOccMapSize = nHbfPerTf ? fillOccupancyMapGetSize(nHbfPerTf, mParam.get()) : 0; @@ -133,10 +133,10 @@ void GPUO2InterfaceRefit::updateCalib(const CorrectionMapsHelper* trans, float b mRefit->SetFastTransformHelper(trans); } -int GPUO2InterfaceRefit::RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, outward, resetCov); } -int GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, outward, resetCov); } -int GPUO2InterfaceRefit::RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, clusRef, time0, chi2, outward, resetCov); } -int GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, clusRef, time0, chi2, outward, resetCov); } +int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, outward, resetCov); } +int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, outward, resetCov); } +int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, clusRef, time0, chi2, outward, resetCov); } +int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, clusRef, time0, chi2, outward, resetCov); } void GPUO2InterfaceRefit::setIgnoreErrorsAtTrackEnds(bool v) { mRefit->mIgnoreErrorsOnTrackEnds = v; } void GPUO2InterfaceRefit::setTrackReferenceX(float v) { mParam->rec.tpc.trackReferenceX = v; } diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.h b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.h index 4437e51121163..c3a253b647df3 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceRefit.h @@ -70,13 +70,13 @@ class GPUO2InterfaceRefit // - o2::base::Propagator (p) in case RefitTrackAsTrackParCov is to be used // - In case the --configKeyValues defining GPUParam settings require an occupancy map for TPC error estimation, the map must either be provided as occupancymap, or nHbfPerTf must be set non-zero - GPUO2InterfaceRefit(const o2::tpc::ClusterNativeAccess* cl, const o2::gpu::CorrectionMapsHelper* trans, float bzNominalGPU, const o2::tpc::TPCClRefElem* trackRef, unsigned int nHbfPerTf = 0, const unsigned char* sharedmap = nullptr, const unsigned int* occupancymap = nullptr, int occupancyMapSize = -1, const std::vector* trks = nullptr, o2::base::Propagator* p = nullptr); + GPUO2InterfaceRefit(const o2::tpc::ClusterNativeAccess* cl, const o2::gpu::CorrectionMapsHelper* trans, float bzNominalGPU, const o2::tpc::TPCClRefElem* trackRef, uint32_t nHbfPerTf = 0, const uint8_t* sharedmap = nullptr, const uint32_t* occupancymap = nullptr, int32_t occupancyMapSize = -1, const std::vector* trks = nullptr, o2::base::Propagator* p = nullptr); ~GPUO2InterfaceRefit(); - int RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false); - int RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false); - int RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false); - int RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false); + int32_t RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false); + int32_t RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false); + int32_t RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false); + int32_t RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false); void setTrackReferenceX(float v); void setIgnoreErrorsAtTrackEnds(bool v); void updateCalib(const o2::gpu::CorrectionMapsHelper* trans, float bzNominalGPU); @@ -87,14 +87,14 @@ class GPUO2InterfaceRefit // If the param object / default object requires an occupancy map, an occupancy map ptr and nHbfPerTf value must be provided. // You can use the function fillOccupancyMapGetSize(...) to get the required size of the occupancy map. If 0 is returned, no map is required. // Providing only the shmap ptr but no ocmap ptr will create only the shared map, but no occupancy map. - static void fillSharedClustersAndOccupancyMap(const o2::tpc::ClusterNativeAccess* cl, const gsl::span trks, const o2::tpc::TPCClRefElem* trackRef, unsigned char* shmap, unsigned int* ocmap = nullptr, unsigned int nHbfPerTf = 0, const GPUParam* param = nullptr); - static size_t fillOccupancyMapGetSize(unsigned int nHbfPerTf, const GPUParam* param = nullptr); + static void fillSharedClustersAndOccupancyMap(const o2::tpc::ClusterNativeAccess* cl, const gsl::span trks, const o2::tpc::TPCClRefElem* trackRef, uint8_t* shmap, uint32_t* ocmap = nullptr, uint32_t nHbfPerTf = 0, const GPUParam* param = nullptr); + static size_t fillOccupancyMapGetSize(uint32_t nHbfPerTf, const GPUParam* param = nullptr); private: std::unique_ptr mRefit; std::unique_ptr mParam; - std::vector mSharedMap; - std::vector mOccupancyMap; + std::vector mSharedMap; + std::vector mOccupancyMap; }; } // namespace o2::gpu diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index 70c0600c355c2..15a5980a47696 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -48,21 +48,21 @@ std::unique_ptr GPUO2InterfaceUtils::getCalibdEdxCo } template <> -void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) +void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int32_t version, bool verify, float threshold, bool padding, std::function&)> digitsFilter) { GPUParam param; param.SetDefaults(5.00668); o2::gpu::GPUReconstructionConvert::RunZSEncoder(in, outBuffer, outSizes, raw, ir, param, version, verify, threshold, padding, digitsFilter); } template <> -void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding, std::function&)> digitsFilter) +void GPUO2InterfaceUtils::RunZSEncoder(const DigitArray& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int32_t version, bool verify, bool padding, std::function&)> digitsFilter) { GPUParam param; param.SetDefaults(&config.configGRP, &config.configReconstruction, &config.configProcessing, nullptr); o2::gpu::GPUReconstructionConvert::RunZSEncoder(in, outBuffer, outSizes, raw, ir, param, version, verify, config.configReconstruction.tpc.zsThreshold, padding, digitsFilter); } -void GPUO2InterfaceUtils::GPUReconstructionZSDecoder::DecodePage(std::vector& outputBuffer, const void* page, unsigned int tfFirstOrbit, const GPUParam* param, unsigned int triggerBC) +void GPUO2InterfaceUtils::GPUReconstructionZSDecoder::DecodePage(std::vector& outputBuffer, const void* page, uint32_t tfFirstOrbit, const GPUParam* param, uint32_t triggerBC) { const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)page; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { @@ -79,7 +79,7 @@ void GPUO2InterfaceUtils::GPUReconstructionZSDecoder::DecodePage(std::vectorversion](outputBuffer, page, tfFirstOrbit, triggerBC); } -std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, unsigned int nHbfPerTf, std::unique_ptr* pConfiguration, std::unique_ptr* pO2Settings, bool* autoMaxTimeBin) +std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, uint32_t nHbfPerTf, std::unique_ptr* pConfiguration, std::unique_ptr* pO2Settings, bool* autoMaxTimeBin) { std::unique_ptr retVal = std::make_unique(); std::unique_ptr tmpConfig; @@ -112,12 +112,12 @@ std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, un return retVal; } -std::shared_ptr GPUO2InterfaceUtils::getFullParamShared(float solenoidBz, unsigned int nHbfPerTf, std::unique_ptr* pConfiguration, std::unique_ptr* pO2Settings, bool* autoMaxTimeBin) +std::shared_ptr GPUO2InterfaceUtils::getFullParamShared(float solenoidBz, uint32_t nHbfPerTf, std::unique_ptr* pConfiguration, std::unique_ptr* pO2Settings, bool* autoMaxTimeBin) { return std::move(getFullParam(solenoidBz, nHbfPerTf, pConfiguration, pO2Settings, autoMaxTimeBin)); } -void GPUO2InterfaceUtils::paramUseExternalOccupancyMap(GPUParam* param, unsigned int nHbfPerTf, const unsigned int* occupancymap, int occupancyMapSize) +void GPUO2InterfaceUtils::paramUseExternalOccupancyMap(GPUParam* param, uint32_t nHbfPerTf, const uint32_t* occupancymap, int32_t occupancyMapSize) { size_t expectedOccMapSize = nHbfPerTf ? GPUO2InterfaceRefit::fillOccupancyMapGetSize(nHbfPerTf, param) : 0; if (occupancyMapSize != -1 && nHbfPerTf && (size_t)occupancyMapSize != expectedOccMapSize) { diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h index aaa6bff20163d..7b96326387f59 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h @@ -47,25 +47,25 @@ class GPUO2InterfaceUtils static std::unique_ptr getPadGainCalib(const o2::tpc::CalDet& in); static std::unique_ptr getCalibdEdxContainerDefault(); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, int32_t version, bool verify, float threshold = 0.f, bool padding = false, std::function&)> digitsFilter = nullptr); template - static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, unsigned int* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int version, bool verify, bool padding = false, std::function&)> digitsFilter = nullptr); + static void RunZSEncoder(const S& in, std::unique_ptr* outBuffer, uint32_t* outSizes, o2::raw::RawFileWriter* raw, const o2::InteractionRecord* ir, GPUO2InterfaceConfiguration& config, int32_t version, bool verify, bool padding = false, std::function&)> digitsFilter = nullptr); template static float getNominalGPUBz(T& src) { return (5.00668f / 30000.f) * src.getL3Current(); } - static std::unique_ptr getFullParam(float solenoidBz, unsigned int nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); - static std::shared_ptr getFullParamShared(float solenoidBz, unsigned int nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); // Return owning pointer - static void paramUseExternalOccupancyMap(GPUParam* param, unsigned int nHbfPerTf, const unsigned int* occupancymap, int occupancyMapSize); + static std::unique_ptr getFullParam(float solenoidBz, uint32_t nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); + static std::shared_ptr getFullParamShared(float solenoidBz, uint32_t nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); // Return owning pointer + static void paramUseExternalOccupancyMap(GPUParam* param, uint32_t nHbfPerTf, const uint32_t* occupancymap, int32_t occupancyMapSize); class GPUReconstructionZSDecoder { public: - void DecodePage(std::vector& outputBuffer, const void* page, unsigned int tfFirstOrbit, const GPUParam* param, unsigned int triggerBC = 0); + void DecodePage(std::vector& outputBuffer, const void* page, uint32_t tfFirstOrbit, const GPUParam* param, uint32_t triggerBC = 0); private: - std::vector&, const void*, unsigned int, unsigned int)>> mDecoders; + std::vector&, const void*, uint32_t, uint32_t)>> mDecoders; }; }; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMBorderTrack.h b/GPU/GPUTracking/Merger/GPUTPCGMBorderTrack.h index 7c7ab6a17d421..5c1d1d11861bd 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMBorderTrack.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMBorderTrack.h @@ -32,21 +32,21 @@ namespace gpu class GPUTPCGMBorderTrack { public: - GPUd() int TrackID() const { return mTrackID; } - GPUd() short NClusters() const { return mNClusters; } - GPUd() short Row() const { return mRow; } + GPUd() int32_t TrackID() const { return mTrackID; } + GPUd() int16_t NClusters() const { return mNClusters; } + GPUd() int16_t Row() const { return mRow; } GPUd() const float* Par() const { return mP; } GPUd() float ZOffsetLinear() const { return mZOffsetLinear; } GPUd() const float* Cov() const { return mC; } GPUd() const float* CovD() const { return mD; } - GPUd() void SetTrackID(int v) { mTrackID = v; } - GPUd() void SetNClusters(short v) { mNClusters = v; } - GPUd() void SetRow(short v) { mRow = v; } - GPUd() void SetPar(int i, float x) { mP[i] = x; } + GPUd() void SetTrackID(int32_t v) { mTrackID = v; } + GPUd() void SetNClusters(int16_t v) { mNClusters = v; } + GPUd() void SetRow(int16_t v) { mRow = v; } + GPUd() void SetPar(int32_t i, float x) { mP[i] = x; } GPUd() void SetZOffsetLinear(float v) { mZOffsetLinear = v; } - GPUd() void SetCov(int i, float x) { mC[i] = x; } - GPUd() void SetCovD(int i, float x) { mD[i] = x; } + GPUd() void SetCov(int32_t i, float x) { mC[i] = x; } + GPUd() void SetCovD(int32_t i, float x) { mD[i] = x; } GPUd() static bool CheckChi2(float x1, float y1, float cx1, float cxy1, float cy1, float x2, float y2, float cx2, float cxy2, float cy2, float chi2cut) { @@ -89,12 +89,12 @@ class GPUTPCGMBorderTrack GPUd() void LimitCov() { // TODO: Why are Cov entries so large? - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { if (mC[i] > 5.f) { mC[i] = 5.f; } } - for (int i = 2; i < 4; i++) { + for (int32_t i = 2; i < 4; i++) { if (mC[i] > 0.5f) { mC[i] = 0.5f; } @@ -103,7 +103,7 @@ class GPUTPCGMBorderTrack if (mC[4] > maxCov4) { mC[4] = maxCov4; } - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { if (mD[i] > 0.5f) { mD[i] = 0.5f; } @@ -117,9 +117,9 @@ class GPUTPCGMBorderTrack } private: - int mTrackID; // track index - short mNClusters; // n clusters - short mRow; + int32_t mTrackID; // track index + int16_t mNClusters; // n clusters + int16_t mRow; float mP[5]; float mZOffsetLinear; // Z Offset, in case of T offset scaled linearly to Z with nominal vDrift. Used only for matching / merging float mC[5]; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergedTrack.h b/GPU/GPUTracking/Merger/GPUTPCGMMergedTrack.h index a1501c6634a9c..c61dcd220e0c6 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergedTrack.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergedTrack.h @@ -30,9 +30,9 @@ namespace gpu class GPUTPCGMMergedTrack { public: - GPUd() unsigned int NClusters() const { return mNClusters; } - GPUd() unsigned int NClustersFitted() const { return mNClustersFitted; } - GPUd() unsigned int FirstClusterRef() const { return mFirstClusterRef; } + GPUd() uint32_t NClusters() const { return mNClusters; } + GPUd() uint32_t NClustersFitted() const { return mNClustersFitted; } + GPUd() uint32_t FirstClusterRef() const { return mFirstClusterRef; } GPUd() const GPUTPCGMTrackParam& GetParam() const { return mParam; } GPUd() float GetAlpha() const { return mAlpha; } GPUd() GPUTPCGMTrackParam& Param() @@ -52,9 +52,9 @@ class GPUTPCGMMergedTrack GPUd() bool CCE() const { return mFlags & 0x08; } GPUd() bool MergedLooper() const { return mFlags & 0x10; } - GPUd() void SetNClusters(int v) { mNClusters = v; } - GPUd() void SetNClustersFitted(int v) { mNClustersFitted = v; } - GPUd() void SetFirstClusterRef(int v) { mFirstClusterRef = v; } + GPUd() void SetNClusters(int32_t v) { mNClusters = v; } + GPUd() void SetNClustersFitted(int32_t v) { mNClustersFitted = v; } + GPUd() void SetFirstClusterRef(int32_t v) { mFirstClusterRef = v; } GPUd() void SetParam(const GPUTPCGMTrackParam& v) { mParam = v; } GPUd() void SetAlpha(float v) { mAlpha = v; } GPUd() void SetLastX(float v) { mLastX = v; } @@ -100,9 +100,9 @@ class GPUTPCGMMergedTrack mFlags &= 0xEF; } } - GPUd() void SetFlags(unsigned char v) { mFlags = v; } - GPUd() void SetLegs(unsigned char v) { mLegs = v; } - GPUd() unsigned char Legs() const { return mLegs; } + GPUd() void SetFlags(uint8_t v) { mFlags = v; } + GPUd() void SetLegs(uint8_t v) { mLegs = v; } + GPUd() uint8_t Legs() const { return mLegs; } GPUd() const gputpcgmmergertypes::GPUTPCOuterParam& OuterParam() const { return mOuterParam; } GPUd() gputpcgmmergertypes::GPUTPCOuterParam& OuterParam() { return mOuterParam; } @@ -115,11 +115,11 @@ class GPUTPCGMMergedTrack float mLastX; //* outer X float mLastY; //* outer Y float mLastZ; //* outer Z - unsigned int mFirstClusterRef; //* index of the first track cluster in corresponding cluster arrays - unsigned int mNClusters; //* number of track clusters - unsigned int mNClustersFitted; //* number of clusters used in fit - unsigned char mFlags; - unsigned char mLegs; + uint32_t mFirstClusterRef; //* index of the first track cluster in corresponding cluster arrays + uint32_t mNClusters; //* number of track clusters + uint32_t mNClustersFitted; //* number of clusters used in fit + uint8_t mFlags; + uint8_t mLegs; #if !defined(GPUCA_STANDALONE) ClassDefNV(GPUTPCGMMergedTrack, 0); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx index a2d9a9ec400ee..6c90330efecc3 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx @@ -66,8 +66,8 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; using namespace gputpcgmmergertypes; -static constexpr int kMaxParts = 400; -static constexpr int kMaxClusters = GPUCA_MERGER_MAX_TRACK_CLUSTERS; +static constexpr int32_t kMaxParts = 400; +static constexpr int32_t kMaxClusters = GPUCA_MERGER_MAX_TRACK_CLUSTERS; //#define OFFLINE_FITTER @@ -81,7 +81,7 @@ struct MergeLooperParam { float refz; float x; float y; - unsigned int id; + uint32_t id; }; } // namespace GPUCA_NAMESPACE::gpu @@ -95,18 +95,18 @@ GPUTPCGMMerger::GPUTPCGMMerger() { //* constructor - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { mNextSliceInd[iSlice] = iSlice + 1; mPrevSliceInd[iSlice] = iSlice - 1; } - int mid = NSLICES / 2 - 1; - int last = NSLICES - 1; + int32_t mid = NSLICES / 2 - 1; + int32_t last = NSLICES - 1; mNextSliceInd[mid] = 0; mPrevSliceInd[0] = mid; mNextSliceInd[last] = NSLICES / 2; mPrevSliceInd[NSLICES / 2] = last; - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { mkSlices[i] = nullptr; } } @@ -118,11 +118,11 @@ GPUTPCGMMerger::GPUTPCGMMerger() void GPUTPCGMMerger::CheckMergedTracks() { std::vector trkUsed(SliceTrackInfoLocalTotal()); - for (int i = 0; i < SliceTrackInfoLocalTotal(); i++) { + for (int32_t i = 0; i < SliceTrackInfoLocalTotal(); i++) { trkUsed[i] = false; } - for (int itr = 0; itr < SliceTrackInfoLocalTotal(); itr++) { + for (int32_t itr = 0; itr < SliceTrackInfoLocalTotal(); itr++) { GPUTPCGMSliceTrack& track = mSliceTrackInfos[itr]; if (track.PrevSegmentNeighbour() >= 0) { continue; @@ -130,16 +130,16 @@ void GPUTPCGMMerger::CheckMergedTracks() if (track.PrevNeighbour() >= 0) { continue; } - int leg = 0; + int32_t leg = 0; GPUTPCGMSliceTrack *trbase = &track, *tr = &track; while (true) { - int iTrk = tr - mSliceTrackInfos; + int32_t iTrk = tr - mSliceTrackInfos; if (trkUsed[iTrk]) { GPUError("FAILURE: double use"); } trkUsed[iTrk] = true; - int jtr = tr->NextSegmentNeighbour(); + int32_t jtr = tr->NextSegmentNeighbour(); if (jtr >= 0) { tr = &(mSliceTrackInfos[jtr]); continue; @@ -157,7 +157,7 @@ void GPUTPCGMMerger::CheckMergedTracks() break; } } - for (int i = 0; i < SliceTrackInfoLocalTotal(); i++) { + for (int32_t i = 0; i < SliceTrackInfoLocalTotal(); i++) { if (trkUsed[i] == false) { GPUError("FAILURE: trk missed"); } @@ -176,10 +176,10 @@ inline const auto* resolveMCLabels(const o2::dataformat } template -long GPUTPCGMMerger::GetTrackLabelA(const S& trk) const +int64_t GPUTPCGMMerger::GetTrackLabelA(const S& trk) const { GPUTPCGMSliceTrack* sliceTrack = nullptr; - int nClusters = 0; + int32_t nClusters = 0; if constexpr (std::is_same::value) { sliceTrack = &mSliceTrackInfos[trk.TrackID()]; nClusters = sliceTrack->OrigTrack()->NHits(); @@ -187,8 +187,8 @@ long GPUTPCGMMerger::GetTrackLabelA(const S& trk) const nClusters = trk.NClusters(); } auto acc = GPUTPCTrkLbl(resolveMCLabels(GetConstantMem()->ioPtrs.clustersNative ? GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth : nullptr, GetConstantMem()->ioPtrs.mcLabelsTPC), 0.5f); - for (int i = 0; i < nClusters; i++) { - int id; + for (int32_t i = 0; i < nClusters; i++) { + int32_t id; if constexpr (std::is_same::value) { if (Param().rec.tpc.mergerReadFromTrackerDirectly) { const GPUTPCTracker& tracker = GetConstantMem()->tpcTrackers[sliceTrack->Slice()]; @@ -206,7 +206,7 @@ long GPUTPCGMMerger::GetTrackLabelA(const S& trk) const } template -long GPUTPCGMMerger::GetTrackLabel(const S& trk) const +int64_t GPUTPCGMMerger::GetTrackLabel(const S& trk) const { #ifdef GPUCA_TPC_GEOMETRY_O2 if (GetConstantMem()->ioPtrs.clustersNative->clustersMCTruth) { @@ -232,7 +232,7 @@ void GPUTPCGMMerger::PrintMergeGraph(const GPUTPCGMSliceTrack* trk, std::ostream trk = &mSliceTrackInfos[trk->PrevNeighbour()]; } - int nextId = trk - mSliceTrackInfos; + int32_t nextId = trk - mSliceTrackInfos; out << "Graph of track " << (orgTrack - mSliceTrackInfos) << "\n"; while (nextId >= 0) { trk = &mSliceTrackInfos[nextId]; @@ -271,9 +271,9 @@ void* GPUTPCGMMerger::SetPointersMerger(void* mem) void* memBase = mem; computePointerWithAlignment(mem, mBorderMemory, 2 * mNTotalSliceTracks); // MergeBorders & Resolve computePointerWithAlignment(mem, mBorderRangeMemory, 2 * mNTotalSliceTracks); - int nTracks = 0; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - const int n = mRec->GetParam().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[iSlice].NTracks() : mkSlices[iSlice]->NTracks(); + int32_t nTracks = 0; + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + const int32_t n = mRec->GetParam().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[iSlice].NTracks() : mkSlices[iSlice]->NTracks(); mBorder[iSlice] = mBorderMemory + 2 * nTracks; mBorder[NSLICES + iSlice] = mBorderMemory + 2 * nTracks + n; mBorderRange[iSlice] = mBorderRangeMemory + 2 * nTracks; @@ -397,8 +397,8 @@ void GPUTPCGMMerger::SetMaxData(const GPUTrackingInOutPointers& io) mNTotalSliceTracks = 0; mNClusters = 0; mNMaxSingleSliceTracks = 0; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - unsigned int ntrk = mRec->GetParam().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[iSlice].NTracks() : mkSlices[iSlice]->NTracks(); + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + uint32_t ntrk = mRec->GetParam().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[iSlice].NTracks() : mkSlices[iSlice]->NTracks(); mNTotalSliceTracks += ntrk; mNClusters += mRec->GetParam().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[iSlice].NTrackHits() : mkSlices[iSlice]->NTrackClusters(); if (mNMaxSingleSliceTracks < ntrk) { @@ -415,7 +415,7 @@ void GPUTPCGMMerger::SetMaxData(const GPUTrackingInOutPointers& io) mNMaxClusters = io.clustersNative->nClustersTotal; } else if (mRec->GetRecoSteps() & GPUDataTypes::RecoStep::TPCSliceTracking) { mNMaxClusters = 0; - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { mNMaxClusters += mRec->GetConstantMem().tpcTrackers[i].NHitsTotal(); } } else { @@ -424,9 +424,9 @@ void GPUTPCGMMerger::SetMaxData(const GPUTrackingInOutPointers& io) mNMaxLooperMatches = mNMaxClusters / 4; // We have that much scratch memory anyway } -int GPUTPCGMMerger::CheckSlices() +int32_t GPUTPCGMMerger::CheckSlices() { - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { if ((Param().rec.tpc.mergerReadFromTrackerDirectly ? mRec->GetConstantMem().tpcTrackers[i].CommonMemory()->nLocalTracks : mkSlices[i]->NLocalTracks()) > mNMaxSingleSliceTracks) { throw std::runtime_error("mNMaxSingleSliceTracks too small"); } @@ -439,15 +439,15 @@ int GPUTPCGMMerger::CheckSlices() #endif // GPUCA_GPUCODE -GPUd() void GPUTPCGMMerger::ClearTrackLinks(int nBlocks, int nThreads, int iBlock, int iThread, bool output) +GPUd() void GPUTPCGMMerger::ClearTrackLinks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, bool output) { - const int n = output ? mMemory->nOutputTracks : SliceTrackInfoLocalTotal(); - for (int i = iBlock * nThreads + iThread; i < n; i += nThreads * nBlocks) { + const int32_t n = output ? mMemory->nOutputTracks : SliceTrackInfoLocalTotal(); + for (int32_t i = iBlock * nThreads + iThread; i < n; i += nThreads * nBlocks) { mTrackLinks[i] = -1; } } -GPUd() int GPUTPCGMMerger::RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const GPUTPCTrack* inTrack, float alpha, int slice) +GPUd() int32_t GPUTPCGMMerger::RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const GPUTPCTrack* inTrack, float alpha, int32_t slice) { GPUTPCGMPropagator prop; prop.SetMaterialTPC(); @@ -466,23 +466,23 @@ GPUd() int GPUTPCGMMerger::RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const trk.TZOffset() = Param().par.earlyTpcTransform ? inTrack->Param().GetZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convZOffsetToVertexTime(slice, inTrack->Param().GetZOffset(), Param().continuousMaxTimeBin); trk.ShiftZ(this, slice, sliceTrack.ClusterZT0(), sliceTrack.ClusterZTN(), inTrack->Param().GetX(), inTrack->Param().GetX()); // We do not store the inner / outer cluster X, so we just use the track X instead sliceTrack.SetX2(0.f); - for (int way = 0; way < 2; way++) { + for (int32_t way = 0; way < 2; way++) { if (way) { prop.SetFitInProjections(true); prop.SetPropagateBzOnly(true); } trk.ResetCovariance(); prop.SetTrack(&trk, alpha); - int start = way ? inTrack->NHits() - 1 : 0; - int end = way ? 0 : (inTrack->NHits() - 1); - int incr = way ? -1 : 1; - for (int i = start; i != end; i += incr) { + int32_t start = way ? inTrack->NHits() - 1 : 0; + int32_t end = way ? 0 : (inTrack->NHits() - 1); + int32_t incr = way ? -1 : 1; + for (int32_t i = start; i != end; i += incr) { float x, y, z; - int row, flags; + int32_t row, flags; if (Param().rec.tpc.mergerReadFromTrackerDirectly) { const GPUTPCTracker& tracker = GetConstantMem()->tpcTrackers[slice]; const GPUTPCHitId& ic = tracker.TrackHits()[inTrack->FirstHitID() + i]; - int clusterIndex = tracker.Data().ClusterDataIndex(tracker.Data().Row(ic.RowIndex()), ic.HitIndex()); + int32_t clusterIndex = tracker.Data().ClusterDataIndex(tracker.Data().Row(ic.RowIndex()), ic.HitIndex()); row = ic.RowIndex(); const ClusterNative& cl = GetConstantMem()->ioPtrs.clustersNative->clustersLinear[GetConstantMem()->ioPtrs.clustersNative->clusterOffset[slice][0] + clusterIndex]; flags = cl.getFlags(); @@ -524,14 +524,14 @@ GPUd() int GPUTPCGMMerger::RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const return 0; } -GPUd() void GPUTPCGMMerger::SetTrackClusterZT(GPUTPCGMSliceTrack& track, int iSlice, const GPUTPCTrack* sliceTr) +GPUd() void GPUTPCGMMerger::SetTrackClusterZT(GPUTPCGMSliceTrack& track, int32_t iSlice, const GPUTPCTrack* sliceTr) { if (Param().rec.tpc.mergerReadFromTrackerDirectly) { const GPUTPCTracker& trk = GetConstantMem()->tpcTrackers[iSlice]; const GPUTPCHitId& ic1 = trk.TrackHits()[sliceTr->FirstHitID()]; const GPUTPCHitId& ic2 = trk.TrackHits()[sliceTr->FirstHitID() + sliceTr->NHits() - 1]; - int clusterIndex1 = trk.Data().ClusterDataIndex(trk.Data().Row(ic1.RowIndex()), ic1.HitIndex()); - int clusterIndex2 = trk.Data().ClusterDataIndex(trk.Data().Row(ic2.RowIndex()), ic2.HitIndex()); + int32_t clusterIndex1 = trk.Data().ClusterDataIndex(trk.Data().Row(ic1.RowIndex()), ic1.HitIndex()); + int32_t clusterIndex2 = trk.Data().ClusterDataIndex(trk.Data().Row(ic2.RowIndex()), ic2.HitIndex()); if (Param().par.earlyTpcTransform) { track.SetClusterZT(trk.Data().ClusterData()[clusterIndex1].z, trk.Data().ClusterData()[clusterIndex2].z); } else { @@ -548,29 +548,29 @@ GPUd() void GPUTPCGMMerger::SetTrackClusterZT(GPUTPCGMSliceTrack& track, int iSl } } -GPUd() void GPUTPCGMMerger::UnpackSaveNumber(int id) +GPUd() void GPUTPCGMMerger::UnpackSaveNumber(int32_t id) { mSliceTrackInfoIndex[id] = mMemory->nUnpackedTracks; } -GPUd() void GPUTPCGMMerger::UnpackSliceGlobal(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice) +GPUd() void GPUTPCGMMerger::UnpackSliceGlobal(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice) { const GPUTPCTracker& trk = GetConstantMem()->tpcTrackers[iSlice]; float alpha = Param().Alpha(iSlice); const GPUTPCTrack* sliceTr = mMemory->firstGlobalTracks[iSlice]; - unsigned int nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); - unsigned int nTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? *trk.NTracks() : mkSlices[iSlice]->NTracks(); - for (unsigned int itr = nLocalTracks + iBlock * nThreads + iThread; itr < nTracks; itr += nBlocks * nThreads) { + uint32_t nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); + uint32_t nTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? *trk.NTracks() : mkSlices[iSlice]->NTracks(); + for (uint32_t itr = nLocalTracks + iBlock * nThreads + iThread; itr < nTracks; itr += nBlocks * nThreads) { if (Param().rec.tpc.mergerReadFromTrackerDirectly) { sliceTr = &trk.Tracks()[itr]; } else if (itr > nLocalTracks) { sliceTr = sliceTr->GetNextTrack(); } - int localId = mTrackIDs[(sliceTr->LocalTrackId() >> 24) * mNMaxSingleSliceTracks + (sliceTr->LocalTrackId() & 0xFFFFFF)]; + int32_t localId = mTrackIDs[(sliceTr->LocalTrackId() >> 24) * mNMaxSingleSliceTracks + (sliceTr->LocalTrackId() & 0xFFFFFF)]; if (localId == -1) { continue; } - unsigned int myTrack = CAMath::AtomicAdd(&mMemory->nUnpackedTracks, 1u); + uint32_t myTrack = CAMath::AtomicAdd(&mMemory->nUnpackedTracks, 1u); GPUTPCGMSliceTrack& track = mSliceTrackInfos[myTrack]; SetTrackClusterZT(track, iSlice, sliceTr); track.Set(this, sliceTr, alpha, iSlice); @@ -583,24 +583,24 @@ GPUd() void GPUTPCGMMerger::UnpackSliceGlobal(int nBlocks, int nThreads, int iBl } } -GPUd() void GPUTPCGMMerger::UnpackResetIds(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice) +GPUd() void GPUTPCGMMerger::UnpackResetIds(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice) { const GPUTPCTracker& trk = GetConstantMem()->tpcTrackers[iSlice]; - unsigned int nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); - for (unsigned int i = iBlock * nThreads + iThread; i < nLocalTracks; i += nBlocks * nThreads) { + uint32_t nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); + for (uint32_t i = iBlock * nThreads + iThread; i < nLocalTracks; i += nBlocks * nThreads) { mTrackIDs[iSlice * mNMaxSingleSliceTracks + i] = -1; } } -GPUd() void GPUTPCGMMerger::RefitSliceTracks(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice) +GPUd() void GPUTPCGMMerger::RefitSliceTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice) { const GPUTPCTracker& trk = GetConstantMem()->tpcTrackers[iSlice]; - unsigned int nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); + uint32_t nLocalTracks = Param().rec.tpc.mergerReadFromTrackerDirectly ? trk.CommonMemory()->nLocalTracks : mkSlices[iSlice]->NLocalTracks(); float alpha = Param().Alpha(iSlice); const GPUTPCTrack* sliceTr = Param().rec.tpc.mergerReadFromTrackerDirectly ? nullptr : mkSlices[iSlice]->GetFirstTrack(); - for (unsigned int itr = iBlock * nThreads + iThread; itr < nLocalTracks; itr += nBlocks * nThreads) { + for (uint32_t itr = iBlock * nThreads + iThread; itr < nLocalTracks; itr += nBlocks * nThreads) { if (Param().rec.tpc.mergerReadFromTrackerDirectly) { sliceTr = &trk.Tracks()[itr]; } else if (itr) { @@ -632,7 +632,7 @@ GPUd() void GPUTPCGMMerger::RefitSliceTracks(int nBlocks, int nThreads, int iBlo track.SetPrevSegmentNeighbour(-1); track.SetGlobalTrackId(0, -1); track.SetGlobalTrackId(1, -1); - unsigned int myTrack = CAMath::AtomicAdd(&mMemory->nUnpackedTracks, 1u); + uint32_t myTrack = CAMath::AtomicAdd(&mMemory->nUnpackedTracks, 1u); mTrackIDs[iSlice * mNMaxSingleSliceTracks + sliceTr->LocalTrackId()] = myTrack; mSliceTrackInfos[myTrack] = track; } @@ -641,9 +641,9 @@ GPUd() void GPUTPCGMMerger::RefitSliceTracks(int nBlocks, int nThreads, int iBlo } } -GPUd() void GPUTPCGMMerger::LinkGlobalTracks(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::LinkGlobalTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (int itr = SliceTrackInfoGlobalFirst(0) + iBlock * nThreads + iThread; itr < SliceTrackInfoGlobalLast(NSLICES - 1); itr += nThreads * nBlocks) { + for (int32_t itr = SliceTrackInfoGlobalFirst(0) + iBlock * nThreads + iThread; itr < SliceTrackInfoGlobalLast(NSLICES - 1); itr += nThreads * nBlocks) { GPUTPCGMSliceTrack& globalTrack = mSliceTrackInfos[itr]; GPUTPCGMSliceTrack& localTrack = mSliceTrackInfos[globalTrack.LocalTrackId()]; if (localTrack.GlobalTrackId(0) != -1 || !CAMath::AtomicCAS(&localTrack.GlobalTrackIds()[0], -1, itr)) { @@ -652,7 +652,7 @@ GPUd() void GPUTPCGMMerger::LinkGlobalTracks(int nBlocks, int nThreads, int iBlo } } -GPUd() void GPUTPCGMMerger::MergeSlicesPrepareStep2(int nBlocks, int nThreads, int iBlock, int iThread, int iBorder, GPUTPCGMBorderTrack** B, GPUAtomic(unsigned int) * nB, bool useOrigTrackParam) +GPUd() void GPUTPCGMMerger::MergeSlicesPrepareStep2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iBorder, GPUTPCGMBorderTrack** B, GPUAtomic(uint32_t) * nB, bool useOrigTrackParam) { //* prepare slice tracks for merging with next/previous/same sector //* each track transported to the border line @@ -681,9 +681,9 @@ GPUd() void GPUTPCGMMerger::MergeSlicesPrepareStep2(int nBlocks, int nThreads, i float sinAlpha = CAMath::Sin(dAlpha); GPUTPCGMSliceTrack trackTmp; - for (int itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { + for (int32_t itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { const GPUTPCGMSliceTrack* track = &mSliceTrackInfos[itr]; - int iSlice = track->Slice(); + int32_t iSlice = track->Slice(); if (track->PrevSegmentNeighbour() >= 0 && track->Slice() == mSliceTrackInfos[track->PrevSegmentNeighbour()].Slice()) { continue; @@ -721,7 +721,7 @@ GPUd() void GPUTPCGMMerger::MergeSlicesPrepareStep2(int nBlocks, int nThreads, i if (track->TransportToXAlpha(this, x0, sinAlpha, cosAlpha, fieldBz, b, maxSin)) { b.SetTrackID(itr); b.SetNClusters(track->NClusters()); - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { if (CAMath::Abs(b.Cov()[i]) >= 5.0f) { b.SetCov(i, 5.0f); } @@ -729,20 +729,20 @@ GPUd() void GPUTPCGMMerger::MergeSlicesPrepareStep2(int nBlocks, int nThreads, i if (CAMath::Abs(b.Cov()[4]) >= 0.5f) { b.SetCov(4, 0.5f); } - unsigned int myTrack = CAMath::AtomicAdd(&nB[iSlice], 1u); + uint32_t myTrack = CAMath::AtomicAdd(&nB[iSlice], 1u); B[iSlice][myTrack] = b; } } } template <> -GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice1, GPUTPCGMBorderTrack* B1, int N1, int iSlice2, GPUTPCGMBorderTrack* B2, int N2, int mergeMode) +GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice1, GPUTPCGMBorderTrack* B1, int32_t N1, int32_t iSlice2, GPUTPCGMBorderTrack* B2, int32_t N2, int32_t mergeMode) { CADEBUG(GPUInfo("\nMERGING Slices %d %d NTracks %d %d CROSS %d", iSlice1, iSlice2, N1, N2, mergeMode)); GPUTPCGMBorderRange* range1 = mBorderRange[iSlice1]; GPUTPCGMBorderRange* range2 = mBorderRange[iSlice2] + (Param().rec.tpc.mergerReadFromTrackerDirectly ? *GetConstantMem()->tpcTrackers[iSlice2].NTracks() : mkSlices[iSlice2]->NTracks()); bool sameSlice = (iSlice1 == iSlice2); - for (int itr = iBlock * nThreads + iThread; itr < N1; itr += nThreads * nBlocks) { + for (int32_t itr = iBlock * nThreads + iThread; itr < N1; itr += nThreads * nBlocks) { GPUTPCGMBorderTrack& b = B1[itr]; float d = CAMath::Max(0.5f, 3.5f * CAMath::Sqrt(b.Cov()[1])); if (CAMath::Abs(b.Par()[4]) * Param().qptB5Scaler >= 20) { @@ -750,7 +750,7 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int } else if (d > 3) { d = 3; } - CADEBUG(printf(" Input Slice 1 %d Track %d: ", iSlice1, itr); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf(" - D %8.3f\n", d)); + CADEBUG(printf(" Input Slice 1 %d Track %d: ", iSlice1, itr); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf(" - D %8.3f\n", d)); GPUTPCGMBorderRange range; range.fId = itr; range.fMin = b.Par()[1] + b.ZOffsetLinear() - d; @@ -761,7 +761,7 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int } } if (!sameSlice) { - for (int itr = iBlock * nThreads + iThread; itr < N2; itr += nThreads * nBlocks) { + for (int32_t itr = iBlock * nThreads + iThread; itr < N2; itr += nThreads * nBlocks) { GPUTPCGMBorderTrack& b = B2[itr]; float d = CAMath::Max(0.5f, 3.5f * CAMath::Sqrt(b.Cov()[1])); if (CAMath::Abs(b.Par()[4]) * Param().qptB5Scaler >= 20) { @@ -769,7 +769,7 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int } else if (d > 3) { d = 3; } - CADEBUG(printf(" Input Slice 2 %d Track %d: ", iSlice2, itr); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf(" - D %8.3f\n", d)); + CADEBUG(printf(" Input Slice 2 %d Track %d: ", iSlice2, itr); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf(" - D %8.3f\n", d)); GPUTPCGMBorderRange range; range.fId = itr; range.fMin = b.Par()[1] + b.ZOffsetLinear() - d; @@ -780,7 +780,7 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int } template <> -GPUd() void GPUTPCGMMerger::MergeBorderTracks<1>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice1, GPUTPCGMBorderTrack* B1, int N1, int iSlice2, GPUTPCGMBorderTrack* B2, int N2, int mergeMode) +GPUd() void GPUTPCGMMerger::MergeBorderTracks<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice1, GPUTPCGMBorderTrack* B1, int32_t N1, int32_t iSlice2, GPUTPCGMBorderTrack* B2, int32_t N2, int32_t mergeMode) { #if !defined(GPUCA_GPUCODE_COMPILEKERNELS) GPUTPCGMBorderRange* range1 = mBorderRange[iSlice1]; @@ -829,7 +829,7 @@ struct MergeBorderTracks_compMin { }; template <> -inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal(const krnlSetupTime& _xyz, GPUTPCGMBorderRange* const& range, int const& N, int const& cmpMax) +inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal(const krnlSetupTime& _xyz, GPUTPCGMBorderRange* const& range, int32_t const& N, int32_t const& cmpMax) { thrust::device_ptr p(range); ThrustVolatileAsyncAllocator alloc(this); @@ -842,7 +842,7 @@ inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal template <> -GPUd() void GPUTPCGMMerger::MergeBorderTracks<3>(int nBlocks, int nThreads, int iBlock, int iThread, GPUTPCGMBorderRange* range, int N, int cmpMax) +GPUd() void GPUTPCGMMerger::MergeBorderTracks<3>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUTPCGMBorderRange* range, int32_t N, int32_t cmpMax) { #ifndef GPUCA_SPECIALIZE_THRUST_SORTS if (iThread == 0) { @@ -856,9 +856,9 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<3>(int nBlocks, int nThreads, int } template <> -GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice1, GPUTPCGMBorderTrack* B1, int N1, int iSlice2, GPUTPCGMBorderTrack* B2, int N2, int mergeMode) +GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice1, GPUTPCGMBorderTrack* B1, int32_t N1, int32_t iSlice2, GPUTPCGMBorderTrack* B2, int32_t N2, int32_t mergeMode) { - // int statAll = 0, statMerged = 0; + // int32_t statAll = 0, statMerged = 0; float factor2ys = Param().rec.tpc.trackMergerFactor2YS; float factor2zt = Param().rec.tpc.trackMergerFactor2ZT; float factor2k = Param().rec.tpc.trackMergerFactor2K; @@ -868,16 +868,16 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int factor2ys = factor2General * factor2ys; factor2zt = factor2General * factor2zt; - int minNPartHits = Param().rec.tpc.trackMergerMinPartHits; - int minNTotalHits = Param().rec.tpc.trackMergerMinTotalHits; + int32_t minNPartHits = Param().rec.tpc.trackMergerMinPartHits; + int32_t minNTotalHits = Param().rec.tpc.trackMergerMinTotalHits; bool sameSlice = (iSlice1 == iSlice2); GPUTPCGMBorderRange* range1 = mBorderRange[iSlice1]; GPUTPCGMBorderRange* range2 = mBorderRange[iSlice2] + (Param().rec.tpc.mergerReadFromTrackerDirectly ? *GetConstantMem()->tpcTrackers[iSlice2].NTracks() : mkSlices[iSlice2]->NTracks()); - int i2 = 0; - for (int i1 = iBlock * nThreads + iThread; i1 < N1; i1 += nThreads * nBlocks) { + int32_t i2 = 0; + for (int32_t i1 = iBlock * nThreads + iThread; i1 < N1; i1 += nThreads * nBlocks) { GPUTPCGMBorderRange r1 = range1[i1]; while (i2 < N2 && range2[i2].fMax < r1.fMin) { i2++; @@ -887,10 +887,10 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int if (b1.NClusters() < minNPartHits) { continue; } - int iBest2 = -1; - int lBest2 = 0; + int32_t iBest2 = -1; + int32_t lBest2 = 0; // statAll++; - for (int k2 = i2; k2 < N2; k2++) { + for (int32_t k2 = i2; k2 < N2; k2++) { GPUTPCGMBorderRange r2 = range2[k2]; if (r2.fMin > r1.fMax) { break; @@ -902,19 +902,19 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int GPUTPCGMBorderTrack& b2 = B2[r2.fId]; #if defined(GPUCA_MERGER_BY_MC_LABEL) && !defined(GPUCA_GPUCODE) - long label1 = GetTrackLabel(b1); - long label2 = GetTrackLabel(b2); + int64_t label1 = GetTrackLabel(b1); + int64_t label2 = GetTrackLabel(b2); if (label1 != label2 && label1 != -1) // DEBUG CODE, match by MC label #endif { - CADEBUG(if (GetConstantMem()->ioPtrs.mcLabelsTPC) {printf("Comparing track %3d to %3d: ", r1.fId, r2.fId); for (int i = 0; i < 5; i++) { printf("%8.3f ", b1.Par()[i]); } printf(" - "); for (int i = 0; i < 5; i++) { printf("%8.3f ", b1.Cov()[i]); } printf("\n%28s", ""); }); - CADEBUG(if (GetConstantMem()->ioPtrs.mcLabelsTPC) {for (int i = 0; i < 5; i++) { printf("%8.3f ", b2.Par()[i]); } printf(" - "); for (int i = 0; i < 5; i++) { printf("%8.3f ", b2.Cov()[i]); } printf(" - %5s - ", GetTrackLabel(b1) == GetTrackLabel(b2) ? "CLONE" : "FAKE"); }); + CADEBUG(if (GetConstantMem()->ioPtrs.mcLabelsTPC) {printf("Comparing track %3d to %3d: ", r1.fId, r2.fId); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b1.Par()[i]); } printf(" - "); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b1.Cov()[i]); } printf("\n%28s", ""); }); + CADEBUG(if (GetConstantMem()->ioPtrs.mcLabelsTPC) {for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b2.Par()[i]); } printf(" - "); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b2.Cov()[i]); } printf(" - %5s - ", GetTrackLabel(b1) == GetTrackLabel(b2) ? "CLONE" : "FAKE"); }); if (b2.NClusters() < lBest2) { CADEBUG2(continue, printf("!NCl1\n")); } if (mergeMode > 0) { // Merging CE tracks - int maxRowDiff = mergeMode == 2 ? 1 : 3; // TODO: check cut + int32_t maxRowDiff = mergeMode == 2 ? 1 : 3; // TODO: check cut if (CAMath::Abs(b1.Row() - b2.Row()) > maxRowDiff) { CADEBUG2(continue, printf("!ROW\n")); } @@ -975,7 +975,7 @@ GPUd() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int // GPUInfo("STAT: slices %d, %d: all %d merged %d", iSlice1, iSlice2, statAll, statMerged); } -GPUdii() void GPUTPCGMMerger::MergeBorderTracksSetup(int& n1, int& n2, GPUTPCGMBorderTrack*& b1, GPUTPCGMBorderTrack*& b2, int& jSlice, int iSlice, char withinSlice, char mergeMode) const +GPUdii() void GPUTPCGMMerger::MergeBorderTracksSetup(int32_t& n1, int32_t& n2, GPUTPCGMBorderTrack*& b1, GPUTPCGMBorderTrack*& b2, int32_t& jSlice, int32_t iSlice, int8_t withinSlice, int8_t mergeMode) const { if (withinSlice == 1) { // Merge tracks within the same slice jSlice = iSlice; @@ -983,7 +983,7 @@ GPUdii() void GPUTPCGMMerger::MergeBorderTracksSetup(int& n1, int& n2, GPUTPCGMB b1 = b2 = mBorder[iSlice]; } else if (withinSlice == -1) { // Merge tracks accross the central electrode jSlice = (iSlice + NSLICES / 2); - const int offset = mergeMode == 2 ? NSLICES : 0; + const int32_t offset = mergeMode == 2 ? NSLICES : 0; n1 = mMemory->tmpCounter[iSlice + offset]; n2 = mMemory->tmpCounter[jSlice + offset]; b1 = mBorder[iSlice + offset]; @@ -997,46 +997,46 @@ GPUdii() void GPUTPCGMMerger::MergeBorderTracksSetup(int& n1, int& n2, GPUTPCGMB } } -template -GPUd() void GPUTPCGMMerger::MergeBorderTracks(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode) +template +GPUd() void GPUTPCGMMerger::MergeBorderTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice, int8_t withinSlice, int8_t mergeMode) { - int n1, n2; + int32_t n1, n2; GPUTPCGMBorderTrack *b1, *b2; - int jSlice; + int32_t jSlice; MergeBorderTracksSetup(n1, n2, b1, b2, jSlice, iSlice, withinSlice, mergeMode); MergeBorderTracks(nBlocks, nThreads, iBlock, iThread, iSlice, b1, n1, jSlice, b2, n2, mergeMode); } #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. -template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<0>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); -template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<1>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); -template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<2>(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); +template GPUdni() void GPUTPCGMMerger::MergeBorderTracks<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); #endif -GPUd() void GPUTPCGMMerger::MergeWithinSlicesPrepare(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::MergeWithinSlicesPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { float x0 = Param().tpcGeometry.Row2X(63); const float maxSin = CAMath::Sin(60.f / 180.f * CAMath::Pi()); - for (int itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { + for (int32_t itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { GPUTPCGMSliceTrack& track = mSliceTrackInfos[itr]; - int iSlice = track.Slice(); + int32_t iSlice = track.Slice(); GPUTPCGMBorderTrack b; if (track.TransportToX(this, x0, Param().bzCLight, b, maxSin)) { b.SetTrackID(itr); - CADEBUG(printf("WITHIN SLICE %d Track %d - ", iSlice, itr); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf("\n")); + CADEBUG(printf("WITHIN SLICE %d Track %d - ", iSlice, itr); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Par()[i]); } printf(" - "); for (int32_t i = 0; i < 5; i++) { printf("%8.3f ", b.Cov()[i]); } printf("\n")); b.SetNClusters(track.NClusters()); - unsigned int myTrack = CAMath::AtomicAdd(&mMemory->tmpCounter[iSlice], 1u); + uint32_t myTrack = CAMath::AtomicAdd(&mMemory->tmpCounter[iSlice], 1u); mBorder[iSlice][myTrack] = b; } } } -GPUd() void GPUTPCGMMerger::MergeSlicesPrepare(int nBlocks, int nThreads, int iBlock, int iThread, int border0, int border1, char useOrigTrackParam) +GPUd() void GPUTPCGMMerger::MergeSlicesPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t border0, int32_t border1, int8_t useOrigTrackParam) { bool part2 = iBlock & 1; - int border = part2 ? border1 : border0; - GPUAtomic(unsigned int)* n = mMemory->tmpCounter; + int32_t border = part2 ? border1 : border0; + GPUAtomic(uint32_t)* n = mMemory->tmpCounter; GPUTPCGMBorderTrack** b = mBorder; if (part2) { n += NSLICES; @@ -1045,14 +1045,14 @@ GPUd() void GPUTPCGMMerger::MergeSlicesPrepare(int nBlocks, int nThreads, int iB MergeSlicesPrepareStep2((nBlocks + !part2) >> 1, nThreads, iBlock >> 1, iThread, border, b, n, useOrigTrackParam); } -GPUdi() void GPUTPCGMMerger::setBlockRange(int elems, int nBlocks, int iBlock, int& start, int& end) +GPUdi() void GPUTPCGMMerger::setBlockRange(int32_t elems, int32_t nBlocks, int32_t iBlock, int32_t& start, int32_t& end) { start = (elems + nBlocks - 1) / nBlocks * iBlock; end = (elems + nBlocks - 1) / nBlocks * (iBlock + 1); end = CAMath::Min(elems, end); } -GPUd() void GPUTPCGMMerger::hookEdge(int u, int v) +GPUd() void GPUTPCGMMerger::hookEdge(int32_t u, int32_t v) { if (v < 0) { return; @@ -1063,10 +1063,10 @@ GPUd() void GPUTPCGMMerger::hookEdge(int u, int v) if (u == v) { break; } - int h = CAMath::Max(u, v); - int l = CAMath::Min(u, v); + int32_t h = CAMath::Max(u, v); + int32_t l = CAMath::Min(u, v); - int old = CAMath::AtomicCAS(&mTrackCCRoots[h], h, l); + int32_t old = CAMath::AtomicCAS(&mTrackCCRoots[h], h, l); if (old == h) { break; } @@ -1076,27 +1076,27 @@ GPUd() void GPUTPCGMMerger::hookEdge(int u, int v) } } -GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsSetup(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsSetup(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - int start, end; + int32_t start, end; setBlockRange(SliceTrackInfoLocalTotal(), nBlocks, iBlock, start, end); - for (int i = start + iThread; i < end; i += nThreads) { + for (int32_t i = start + iThread; i < end; i += nThreads) { mTrackCCRoots[i] = i; } } -GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsHookLinks(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsHookLinks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { // Compute connected components in parallel, step 1. // Source: Adaptive Work-Efficient Connected Components on the GPU, Sutton et al, 2016 (https://arxiv.org/pdf/1612.01178.pdf) - int start, end; + int32_t start, end; setBlockRange(SliceTrackInfoLocalTotal(), nBlocks, iBlock, start, end); - for (int itr = start + iThread; itr < end; itr += nThreads) { + for (int32_t itr = start + iThread; itr < end; itr += nThreads) { hookEdge(itr, mTrackLinks[itr]); } } -GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsHookNeighbors(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsHookNeighbors(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { // Compute connected components in parallel, step 1 - Part 2. nBlocks = nBlocks / 4 * 4; @@ -1104,25 +1104,25 @@ GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsHookNeighbors(int nBlo return; } - int start, end; + int32_t start, end; setBlockRange(SliceTrackInfoLocalTotal(), nBlocks / 4, iBlock / 4, start, end); - int myNeighbor = iBlock % 4; + int32_t myNeighbor = iBlock % 4; - for (int itr = start + iThread; itr < end; itr += nThreads) { - int v = mSliceTrackInfos[itr].AnyNeighbour(myNeighbor); + for (int32_t itr = start + iThread; itr < end; itr += nThreads) { + int32_t v = mSliceTrackInfos[itr].AnyNeighbour(myNeighbor); hookEdge(itr, v); } } -GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsMultiJump(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsMultiJump(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { // Compute connected components in parallel, step 2. - int start, end; + int32_t start, end; setBlockRange(SliceTrackInfoLocalTotal(), nBlocks, iBlock, start, end); - for (int itr = start + iThread; itr < end; itr += nThreads) { - int root = itr; - int next = mTrackCCRoots[root]; + for (int32_t itr = start + iThread; itr < end; itr += nThreads) { + int32_t root = itr; + int32_t next = mTrackCCRoots[root]; if (root == next) { continue; } @@ -1134,12 +1134,12 @@ GPUd() void GPUTPCGMMerger::ResolveFindConnectedComponentsMultiJump(int nBlocks, } } -GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int nBlocks, int nThreads, int iBlock, int iThread, char useOrigTrackParam, char mergeAll) +GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int8_t useOrigTrackParam, int8_t mergeAll) { if (!mergeAll) { - /*int neighborType = useOrigTrackParam ? 1 : 0; - int old1 = newTrack2.PrevNeighbour(0); - int old2 = newTrack1.NextNeighbour(0); + /*int32_t neighborType = useOrigTrackParam ? 1 : 0; + int32_t old1 = newTrack2.PrevNeighbour(0); + int32_t old2 = newTrack1.NextNeighbour(0); if (old1 < 0 && old2 < 0) neighborType = 0; if (old1 == itr) continue; if (neighborType) old1 = newTrack2.PrevNeighbour(1); @@ -1166,25 +1166,25 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int newTrack2.SetPrevNeighbour( itr, neighborType );*/ } - int start, end; + int32_t start, end; setBlockRange(SliceTrackInfoLocalTotal(), nBlocks, iBlock, start, end); - for (int baseIdx = 0; baseIdx < SliceTrackInfoLocalTotal(); baseIdx += nThreads) { - int itr = baseIdx + iThread; + for (int32_t baseIdx = 0; baseIdx < SliceTrackInfoLocalTotal(); baseIdx += nThreads) { + int32_t itr = baseIdx + iThread; bool inRange = itr < SliceTrackInfoLocalTotal(); - int itr2 = -1; + int32_t itr2 = -1; if (inRange) { itr2 = mTrackLinks[itr]; } bool resolveSlice = (itr2 > -1); if (resolveSlice) { - int root = mTrackCCRoots[itr]; + int32_t root = mTrackCCRoots[itr]; resolveSlice &= (start <= root) && (root < end); } - short smemIdx = work_group_scan_inclusive_add(short(resolveSlice)); + int16_t smemIdx = work_group_scan_inclusive_add(int16_t(resolveSlice)); if (resolveSlice) { smem.iTrack1[smemIdx - 1] = itr; @@ -1196,9 +1196,9 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int continue; } - const int nSlices = smemIdx; + const int32_t nSlices = smemIdx; - for (int i = 0; i < nSlices; i++) { + for (int32_t i = 0; i < nSlices; i++) { itr = smem.iTrack1[i]; itr2 = smem.iTrack2[i]; @@ -1208,7 +1208,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int GPUTPCGMSliceTrack* track2Base = track2; bool sameSegment = CAMath::Abs(track1->NClusters() > track2->NClusters() ? track1->QPt() : track2->QPt()) * Param().qptB5Scaler < 2 || track1->QPt() * track2->QPt() > 0; - // GPUInfo("\nMerge %d with %d - same segment %d", itr, itr2, (int) sameSegment); + // GPUInfo("\nMerge %d with %d - same segment %d", itr, itr2, (int32_t) sameSegment); // PrintMergeGraph(track1, std::cout); // PrintMergeGraph(track2, std::cout); @@ -1226,7 +1226,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int } } GPUCommonAlgorithm::swap(track1, track1Base); - for (int k = 0; k < 2; k++) { + for (int32_t k = 0; k < 2; k++) { GPUTPCGMSliceTrack* tmp = track1Base; while (tmp->Neighbour(k) >= 0) { tmp = &mSliceTrackInfos[tmp->Neighbour(k)]; @@ -1250,7 +1250,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int if (track1 == track2) { continue; } - for (int k = 0; k < 2; k++) { + for (int32_t k = 0; k < 2; k++) { GPUTPCGMSliceTrack* tmp = track1; while (tmp->Neighbour(k) >= 0) { tmp = &mSliceTrackInfos[tmp->Neighbour(k)]; @@ -1302,7 +1302,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int track2->SetPrevSegmentNeighbour(track1 - mSliceTrackInfos); // k = 0: Merge right side // k = 1: Merge left side - for (int k = 0; k < 2; k++) { + for (int32_t k = 0; k < 2; k++) { track1 = track1Base; track2 = track2Base; while (track2->Neighbour(k) >= 0) { @@ -1334,7 +1334,7 @@ GPUd() void GPUTPCGMMerger::ResolveMergeSlices(GPUResolveSharedMemory& smem, int } } -GPUd() void GPUTPCGMMerger::MergeCEFill(const GPUTPCGMSliceTrack* track, const GPUTPCGMMergedTrackHit& cls, const GPUTPCGMMergedTrackHitXYZ* clsXYZ, int itr) +GPUd() void GPUTPCGMMerger::MergeCEFill(const GPUTPCGMSliceTrack* track, const GPUTPCGMMergedTrackHit& cls, const GPUTPCGMMergedTrackHitXYZ* clsXYZ, int32_t itr) { if (Param().rec.nonConsecutiveIDs) { return; @@ -1356,8 +1356,8 @@ GPUd() void GPUTPCGMMerger::MergeCEFill(const GPUTPCGMSliceTrack* track, const G if (!Param().par.continuousTracking && CAMath::Abs(z) > 10) { return; } - int slice = track->Slice(); - for (int attempt = 0; attempt < 2; attempt++) { + int32_t slice = track->Slice(); + for (int32_t attempt = 0; attempt < 2; attempt++) { GPUTPCGMBorderTrack b; const float x0 = Param().tpcGeometry.Row2X(attempt == 0 ? 63 : cls.row); if (track->TransportToX(this, x0, Param().bzCLight, b, GPUCA_MAX_SIN_PHI_LOW)) { @@ -1371,20 +1371,20 @@ GPUd() void GPUTPCGMMerger::MergeCEFill(const GPUTPCGMSliceTrack* track, const G b.SetZOffsetLinear(-b.ZOffsetLinear()); } b.SetRow(cls.row); - unsigned int id = slice + attempt * NSLICES; - unsigned int myTrack = CAMath::AtomicAdd(&mMemory->tmpCounter[id], 1u); + uint32_t id = slice + attempt * NSLICES; + uint32_t myTrack = CAMath::AtomicAdd(&mMemory->tmpCounter[id], 1u); mBorder[id][myTrack] = b; break; } } } -GPUd() void GPUTPCGMMerger::MergeCE(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::MergeCE(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { const ClusterNative* cls = Param().par.earlyTpcTransform ? nullptr : mConstantMem->ioPtrs.clustersNative->clustersLinear; - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { if (mOutputTracks[i].CSide() == 0 && mTrackLinks[i] >= 0) { - if (mTrackLinks[mTrackLinks[i]] != (int)i) { + if (mTrackLinks[mTrackLinks[i]] != (int32_t)i) { continue; } GPUTPCGMMergedTrack* trk[2] = {&mOutputTracks[i], &mOutputTracks[mTrackLinks[i]]}; @@ -1398,10 +1398,10 @@ GPUd() void GPUTPCGMMerger::MergeCE(int nBlocks, int nThreads, int iBlock, int i continue; } - unsigned int newRef = CAMath::AtomicAdd(&mMemory->nOutputTrackClusters, trk[0]->NClusters() + trk[1]->NClusters()); + uint32_t newRef = CAMath::AtomicAdd(&mMemory->nOutputTrackClusters, trk[0]->NClusters() + trk[1]->NClusters()); if (newRef + trk[0]->NClusters() + trk[1]->NClusters() >= mNMaxOutputTrackClusters) { raiseError(GPUErrors::ERROR_MERGER_CE_HIT_OVERFLOW, newRef + trk[0]->NClusters() + trk[1]->NClusters(), mNMaxOutputTrackClusters); - for (unsigned int k = newRef; k < mNMaxOutputTrackClusters; k++) { + for (uint32_t k = newRef; k < mNMaxOutputTrackClusters; k++) { mClusters[k].num = 0; mClusters[k].state = 0; } @@ -1461,15 +1461,15 @@ GPUd() void GPUTPCGMMerger::MergeCE(int nBlocks, int nThreads, int iBlock, int i } } - int pos = newRef; - int leg = -1; - int lastLeg = -1; + int32_t pos = newRef; + int32_t leg = -1; + int32_t lastLeg = -1; #pragma unroll - for (int k = 1; k >= 0; k--) { - int loopstart = reverse[k] ? (trk[k]->NClusters() - 1) : 0; - int loopend = reverse[k] ? -1 : (int)trk[k]->NClusters(); - int loopinc = reverse[k] ? -1 : 1; - for (int j = loopstart; j != loopend; j += loopinc) { + for (int32_t k = 1; k >= 0; k--) { + int32_t loopstart = reverse[k] ? (trk[k]->NClusters() - 1) : 0; + int32_t loopend = reverse[k] ? -1 : (int32_t)trk[k]->NClusters(); + int32_t loopinc = reverse[k] ? -1 : 1; + for (int32_t j = loopstart; j != loopend; j += loopinc) { if (Param().par.earlyTpcTransform) { mClustersXYZ[pos] = mClustersXYZ[trk[k]->FirstClusterRef() + j]; } @@ -1503,20 +1503,20 @@ GPUd() void GPUTPCGMMerger::MergeCE(int nBlocks, int nThreads, int iBlock, int i } } - // for (int i = 0;i < mMemory->nOutputTracks;i++) {if (mOutputTracks[i].CCE() == false) {mOutputTracks[i].SetNClusters(0);mOutputTracks[i].SetOK(false);}} //Remove all non-CE tracks + // for (int32_t i = 0;i < mMemory->nOutputTracks;i++) {if (mOutputTracks[i].CCE() == false) {mOutputTracks[i].SetNClusters(0);mOutputTracks[i].SetOK(false);}} //Remove all non-CE tracks } struct GPUTPCGMMerger_CompareClusterIdsLooper { struct clcomparestruct { - unsigned char leg; + uint8_t leg; }; - const unsigned char leg; + const uint8_t leg; const bool outwards; const GPUTPCGMMerger::trackCluster* const cmp1; const clcomparestruct* const cmp2; - GPUd() GPUTPCGMMerger_CompareClusterIdsLooper(unsigned char l, bool o, const GPUTPCGMMerger::trackCluster* c1, const clcomparestruct* c2) : leg(l), outwards(o), cmp1(c1), cmp2(c2) {} - GPUd() bool operator()(const short aa, const short bb) + GPUd() GPUTPCGMMerger_CompareClusterIdsLooper(uint8_t l, bool o, const GPUTPCGMMerger::trackCluster* c1, const clcomparestruct* c2) : leg(l), outwards(o), cmp1(c1), cmp2(c2) {} + GPUd() bool operator()(const int16_t aa, const int16_t bb) { const clcomparestruct& a = cmp2[aa]; const clcomparestruct& b = cmp2[bb]; @@ -1542,7 +1542,7 @@ struct GPUTPCGMMerger_CompareClusterIdsLooper { struct GPUTPCGMMerger_CompareClusterIds { const GPUTPCGMMerger::trackCluster* const mCmp; GPUd() GPUTPCGMMerger_CompareClusterIds(const GPUTPCGMMerger::trackCluster* cmp) : mCmp(cmp) {} - GPUd() bool operator()(const short aa, const short bb) + GPUd() bool operator()(const int16_t aa, const int16_t bb) { const GPUTPCGMMerger::trackCluster& a = mCmp[aa]; const GPUTPCGMMerger::trackCluster& b = mCmp[bb]; @@ -1560,11 +1560,11 @@ struct GPUTPCGMMerger_CompareClusterIds { } }; -GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { GPUTPCGMSliceTrack* trackParts[kMaxParts]; - for (int itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { + for (int32_t itr = iBlock * nThreads + iThread; itr < SliceTrackInfoLocalTotal(); itr += nThreads * nBlocks) { GPUTPCGMSliceTrack& track = mSliceTrackInfos[itr]; @@ -1574,9 +1574,9 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i if (track.PrevNeighbour() >= 0) { continue; } - int nParts = 0; - int nHits = 0; - int leg = 0; + int32_t nParts = 0; + int32_t nHits = 0; + int32_t leg = 0; GPUTPCGMSliceTrack *trbase = &track, *tr = &track; tr->SetPrevSegmentNeighbour(1000000000); while (true) { @@ -1590,7 +1590,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i tr->SetLeg(leg); trackParts[nParts++] = tr; - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { if (tr->GlobalTrackId(i) != -1) { if (nParts >= kMaxParts) { break; @@ -1603,7 +1603,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i nHits += mSliceTrackInfos[tr->GlobalTrackId(i)].NClusters(); } } - int jtr = tr->NextSegmentNeighbour(); + int32_t jtr = tr->NextSegmentNeighbour(); if (jtr >= 0) { tr = &(mSliceTrackInfos[jtr]); tr->SetPrevSegmentNeighbour(1000000002); @@ -1650,20 +1650,20 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i trackCluster trackClusters[kMaxClusters]; nHits = 0; - for (int ipart = 0; ipart < nParts; ipart++) { + for (int32_t ipart = 0; ipart < nParts; ipart++) { const GPUTPCGMSliceTrack* t = trackParts[ipart]; CADEBUG(printf("Collect Track %d Part %d QPt %f DzDs %f\n", mMemory->nOutputTracks, ipart, t->QPt(), t->DzDs())); - int nTrackHits = t->NClusters(); + int32_t nTrackHits = t->NClusters(); trackCluster* c2 = trackClusters + nHits + nTrackHits - 1; - for (int i = 0; i < nTrackHits; i++, c2--) { + for (int32_t i = 0; i < nTrackHits; i++, c2--) { if (Param().rec.tpc.mergerReadFromTrackerDirectly) { const GPUTPCTracker& trk = GetConstantMem()->tpcTrackers[t->Slice()]; const GPUTPCHitId& ic = trk.TrackHits()[t->OrigTrack()->FirstHitID() + i]; - unsigned int id = trk.Data().ClusterDataIndex(trk.Data().Row(ic.RowIndex()), ic.HitIndex()) + GetConstantMem()->ioPtrs.clustersNative->clusterOffset[t->Slice()][0]; - *c2 = trackCluster{id, (unsigned char)ic.RowIndex(), t->Slice(), t->Leg()}; + uint32_t id = trk.Data().ClusterDataIndex(trk.Data().Row(ic.RowIndex()), ic.HitIndex()) + GetConstantMem()->ioPtrs.clustersNative->clusterOffset[t->Slice()][0]; + *c2 = trackCluster{id, (uint8_t)ic.RowIndex(), t->Slice(), t->Leg()}; } else { const GPUTPCSliceOutCluster& c = t->OrigTrack()->OutTrackClusters()[i]; - unsigned int id = Param().rec.nonConsecutiveIDs ? ((unsigned int)((unsigned int*)&c - (unsigned int*)mkSlices[t->Slice()]->GetFirstTrack())) : c.GetId(); + uint32_t id = Param().rec.nonConsecutiveIDs ? ((uint32_t)((uint32_t*)&c - (uint32_t*)mkSlices[t->Slice()]->GetFirstTrack())) : c.GetId(); *c2 = trackCluster{id, c.GetRow(), t->Slice(), t->Leg()}; } } @@ -1673,22 +1673,22 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i continue; } - int ordered = leg == 0; + int32_t ordered = leg == 0; if (ordered) { - for (int i = 1; i < nHits; i++) { + for (int32_t i = 1; i < nHits; i++) { if (trackClusters[i].row > trackClusters[i - 1].row || trackClusters[i].id == trackClusters[i - 1].id) { ordered = 0; break; } } } - int firstTrackIndex = 0; - int lastTrackIndex = nParts - 1; + int32_t firstTrackIndex = 0; + int32_t lastTrackIndex = nParts - 1; if (ordered == 0) { - int nTmpHits = 0; + int32_t nTmpHits = 0; trackCluster trackClustersUnsorted[kMaxClusters]; - short clusterIndices[kMaxClusters]; - for (int i = 0; i < nHits; i++) { + int16_t clusterIndices[kMaxClusters]; + for (int32_t i = 0; i < nHits; i++) { trackClustersUnsorted[i] = trackClusters[i]; clusterIndices[i] = i; } @@ -1696,8 +1696,8 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i if (leg > 0) { // Find QPt and DzDs for the segment closest to the vertex, if low/mid Pt float baseZT = 1e9; - unsigned char baseLeg = 0; - for (int i = 0; i < nParts; i++) { + uint8_t baseLeg = 0; + for (int32_t i = 0; i < nParts; i++) { if (trackParts[i]->Leg() == 0 || trackParts[i]->Leg() == leg) { float zt; if (Param().par.earlyTpcTransform) { @@ -1711,9 +1711,9 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i } } } - int iLongest = 1e9; - int length = 0; - for (int i = (baseLeg ? (nParts - 1) : 0); baseLeg ? (i >= 0) : (i < nParts); baseLeg ? i-- : i++) { + int32_t iLongest = 1e9; + int32_t length = 0; + for (int32_t i = (baseLeg ? (nParts - 1) : 0); baseLeg ? (i >= 0) : (i < nParts); baseLeg ? i-- : i++) { if (trackParts[i]->Leg() != baseLeg) { break; } @@ -1729,11 +1729,11 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i outwards = trackParts[iLongest]->ClusterZT0() < trackParts[iLongest]->ClusterZTN(); } GPUTPCGMMerger_CompareClusterIdsLooper::clcomparestruct clusterSort[kMaxClusters]; - for (int iPart = 0; iPart < nParts; iPart++) { + for (int32_t iPart = 0; iPart < nParts; iPart++) { const GPUTPCGMSliceTrack* t = trackParts[iPart]; - int nTrackHits = t->NClusters(); - for (int j = 0; j < nTrackHits; j++) { - int i = nTmpHits + j; + int32_t nTrackHits = t->NClusters(); + for (int32_t j = 0; j < nTrackHits; j++) { + int32_t i = nTmpHits + j; clusterSort[i].leg = t->Leg(); } nTmpHits += nTrackHits; @@ -1745,7 +1745,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i } nTmpHits = 0; firstTrackIndex = lastTrackIndex = -1; - for (int i = 0; i < nParts; i++) { + for (int32_t i = 0; i < nParts; i++) { nTmpHits += trackParts[i]->NClusters(); if (nTmpHits > clusterIndices[0] && firstTrackIndex == -1) { firstTrackIndex = i; @@ -1755,10 +1755,10 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i } } - int nFilteredHits = 0; - int indPrev = -1; - for (int i = 0; i < nHits; i++) { - int ind = clusterIndices[i]; + int32_t nFilteredHits = 0; + int32_t indPrev = -1; + for (int32_t i = 0; i < nHits; i++) { + int32_t ind = clusterIndices[i]; if (indPrev >= 0 && trackClustersUnsorted[ind].id == trackClustersUnsorted[indPrev].id) { continue; } @@ -1769,7 +1769,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i nHits = nFilteredHits; } - unsigned int iOutTrackFirstCluster = CAMath::AtomicAdd(&mMemory->nOutputTrackClusters, (unsigned int)nHits); + uint32_t iOutTrackFirstCluster = CAMath::AtomicAdd(&mMemory->nOutputTrackClusters, (uint32_t)nHits); if (iOutTrackFirstCluster >= mNMaxOutputTrackClusters) { raiseError(GPUErrors::ERROR_MERGER_HIT_OVERFLOW, iOutTrackFirstCluster, mNMaxOutputTrackClusters); CAMath::AtomicExch(&mMemory->nOutputTrackClusters, mNMaxOutputTrackClusters); @@ -1779,10 +1779,10 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i GPUTPCGMMergedTrackHit* cl = mClusters + iOutTrackFirstCluster; GPUTPCGMMergedTrackHitXYZ* clXYZ = mClustersXYZ + iOutTrackFirstCluster; - for (int i = 0; i < nHits; i++) { - unsigned char state; + for (int32_t i = 0; i < nHits; i++) { + uint8_t state; if (Param().rec.nonConsecutiveIDs) { - const GPUTPCSliceOutCluster* c = (const GPUTPCSliceOutCluster*)((const int*)mkSlices[trackClusters[i].slice]->GetFirstTrack() + trackClusters[i].id); + const GPUTPCSliceOutCluster* c = (const GPUTPCSliceOutCluster*)((const int32_t*)mkSlices[trackClusters[i].slice]->GetFirstTrack() + trackClusters[i].id); clXYZ[i].x = c->GetX(); clXYZ[i].y = c->GetY(); clXYZ[i].z = c->GetZ(); @@ -1827,7 +1827,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i cl[i].leg = trackClusters[i].leg; } // nHits - unsigned int iOutputTrack = CAMath::AtomicAdd(&mMemory->nOutputTracks, 1u); + uint32_t iOutputTrack = CAMath::AtomicAdd(&mMemory->nOutputTracks, 1u); if (iOutputTrack >= mNMaxTracks) { raiseError(GPUErrors::ERROR_MERGER_TRACK_OVERFLOW, iOutputTrack, mNMaxTracks); CAMath::AtomicExch(&mMemory->nOutputTracks, mNMaxTracks); @@ -1888,16 +1888,16 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int nBlocks, int nThreads, int i } // itr } -GPUd() void GPUTPCGMMerger::SortTracksPrepare(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::SortTracksPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { mTrackOrderProcess[i] = i; } } -GPUd() void GPUTPCGMMerger::PrepareClustersForFit0(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::PrepareClustersForFit0(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nBlocks * nThreads) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nBlocks * nThreads) { mTrackSort[i] = i; } } @@ -1906,7 +1906,7 @@ GPUd() void GPUTPCGMMerger::PrepareClustersForFit0(int nBlocks, int nThreads, in struct GPUTPCGMMergerSortTracks_comp { const GPUTPCGMMergedTrack* const mCmp; GPUhd() GPUTPCGMMergerSortTracks_comp(GPUTPCGMMergedTrack* cmp) : mCmp(cmp) {} - GPUd() bool operator()(const int aa, const int bb) + GPUd() bool operator()(const int32_t aa, const int32_t bb) { const GPUTPCGMMergedTrack& GPUrestrict() a = mCmp[aa]; const GPUTPCGMMergedTrack& GPUrestrict() b = mCmp[bb]; @@ -1936,7 +1936,7 @@ struct GPUTPCGMMergerSortTracks_comp { template <> inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal(const krnlSetupTime& _xyz) { - thrust::device_ptr trackSort((unsigned int*)mProcessorsShadow->tpcMerger.TrackOrderProcess()); + thrust::device_ptr trackSort((uint32_t*)mProcessorsShadow->tpcMerger.TrackOrderProcess()); ThrustVolatileAsyncAllocator alloc(this); thrust::sort(GPUCA_THRUST_NAMESPACE::par(alloc).on(mInternals->Streams[_xyz.x.stream]), trackSort, trackSort + processors()->tpcMerger.NOutputTracks(), GPUTPCGMMergerSortTracks_comp(mProcessorsShadow->tpcMerger.OutputTracks())); } @@ -1944,7 +1944,7 @@ inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal(const krnlSetupTime& _xyz) { - thrust::device_ptr trackSort((unsigned int*)mProcessorsShadow->tpcMerger.TrackSort()); + thrust::device_ptr trackSort((uint32_t*)mProcessorsShadow->tpcMerger.TrackSort()); ThrustVolatileAsyncAllocator alloc(this); thrust::sort(GPUCA_THRUST_NAMESPACE::par(alloc).on(mInternals->Streams[_xyz.x.stream]), trackSort, trackSort + processors()->tpcMerger.NOutputTracks(), GPUTPCGMMergerSortTracksQPt_comp(mProcessorsShadow->tpcMerger.OutputTracks())); } #endif // GPUCA_SPECIALIZE_THRUST_SORTS - Specialize GPUTPCGMMergerSortTracks and GPUTPCGMMergerSortTracksQPt -GPUd() void GPUTPCGMMerger::SortTracks(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::SortTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { #ifndef GPUCA_SPECIALIZE_THRUST_SORTS if (iThread || iBlock) { return; } // TODO: Fix this: Have to duplicate sort comparison: Thrust cannot use the Lambda but OpenCL cannot use the object - auto comp = [cmp = mOutputTracks](const int aa, const int bb) { + auto comp = [cmp = mOutputTracks](const int32_t aa, const int32_t bb) { const GPUTPCGMMergedTrack& GPUrestrict() a = cmp[aa]; const GPUTPCGMMergedTrack& GPUrestrict() b = cmp[bb]; if (a.CCE() != b.CCE()) { @@ -2007,14 +2007,14 @@ GPUd() void GPUTPCGMMerger::SortTracks(int nBlocks, int nThreads, int iBlock, in #endif } -GPUd() void GPUTPCGMMerger::SortTracksQPt(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::SortTracksQPt(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { #ifndef GPUCA_SPECIALIZE_THRUST_SORTS if (iThread || iBlock) { return; } // TODO: Fix this: Have to duplicate sort comparison: Thrust cannot use the Lambda but OpenCL cannot use the object - auto comp = [cmp = mOutputTracks](const int aa, const int bb) { + auto comp = [cmp = mOutputTracks](const int32_t aa, const int32_t bb) { const GPUTPCGMMergedTrack& GPUrestrict() a = cmp[aa]; const GPUTPCGMMergedTrack& GPUrestrict() b = cmp[bb]; #ifdef GPUCA_NO_FAST_MATH // TODO: Use a better define as swith @@ -2034,13 +2034,13 @@ GPUd() void GPUTPCGMMerger::SortTracksQPt(int nBlocks, int nThreads, int iBlock, #endif } -GPUd() void GPUTPCGMMerger::PrepareClustersForFit1(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::PrepareClustersForFit1(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nBlocks * nThreads) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nBlocks * nThreads) { mTrackOrderAttach[mTrackSort[i]] = i; const GPUTPCGMMergedTrack& trk = mOutputTracks[i]; if (trk.OK()) { - for (unsigned int j = 0; j < trk.NClusters(); j++) { + for (uint32_t j = 0; j < trk.NClusters(); j++) { mClusterAttachment[mClusters[trk.FirstClusterRef() + j].num] = attachAttached | attachGood; CAMath::AtomicAdd(&mSharedCount[mClusters[trk.FirstClusterRef() + j].num], 1u); } @@ -2048,16 +2048,16 @@ GPUd() void GPUTPCGMMerger::PrepareClustersForFit1(int nBlocks, int nThreads, in } } -GPUd() void GPUTPCGMMerger::PrepareClustersForFit2(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::PrepareClustersForFit2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nBlocks * nThreads) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nBlocks * nThreads) { if (mSharedCount[mClusters[i].num] > 1) { mClusters[i].state |= GPUTPCGMMergedTrackHit::flagShared; } } if (mClusterStateExt) { - for (unsigned int i = iBlock * nThreads + iThread; i < mNMaxClusters; i += nBlocks * nThreads) { - unsigned char state = GetConstantMem()->ioPtrs.clustersNative->clustersLinear[i].getFlags(); + for (uint32_t i = iBlock * nThreads + iThread; i < mNMaxClusters; i += nBlocks * nThreads) { + uint8_t state = GetConstantMem()->ioPtrs.clustersNative->clustersLinear[i].getFlags(); if (mSharedCount[i] > 1) { state |= GPUTPCGMMergedTrackHit::flagShared; } @@ -2066,34 +2066,34 @@ GPUd() void GPUTPCGMMerger::PrepareClustersForFit2(int nBlocks, int nThreads, in } } -GPUd() void GPUTPCGMMerger::Finalize0(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::Finalize0(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { if (Param().rec.nonConsecutiveIDs) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nThreads * nBlocks) { mClusters[i].num = mGlobalClusterIDs[i]; } } else { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { mTrackSort[mTrackOrderAttach[i]] = i; } - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTrackClusters; i += nThreads * nBlocks) { mClusterAttachment[mClusters[i].num] = 0; // Reset adjacent attachment for attached clusters, set correctly below } } } -GPUd() void GPUTPCGMMerger::Finalize1(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::Finalize1(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mMemory->nOutputTracks; i += nThreads * nBlocks) { const GPUTPCGMMergedTrack& trk = mOutputTracks[i]; if (!trk.OK() || trk.NClusters() == 0) { continue; } - unsigned char goodLeg = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].leg; - for (unsigned int j = 0; j < trk.NClusters(); j++) { - int id = mClusters[trk.FirstClusterRef() + j].num; - unsigned int weight = mTrackOrderAttach[i] | attachAttached; - unsigned char clusterState = mClusters[trk.FirstClusterRef() + j].state; + uint8_t goodLeg = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].leg; + for (uint32_t j = 0; j < trk.NClusters(); j++) { + int32_t id = mClusters[trk.FirstClusterRef() + j].num; + uint32_t weight = mTrackOrderAttach[i] | attachAttached; + uint8_t clusterState = mClusters[trk.FirstClusterRef() + j].state; if (!(clusterState & GPUTPCGMMergedTrackHit::flagReject)) { weight |= attachGood; } else if (clusterState & GPUTPCGMMergedTrackHit::flagNotFit) { @@ -2107,24 +2107,24 @@ GPUd() void GPUTPCGMMerger::Finalize1(int nBlocks, int nThreads, int iBlock, int } } -GPUd() void GPUTPCGMMerger::Finalize2(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::Finalize2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { - for (unsigned int i = iBlock * nThreads + iThread; i < mNMaxClusters; i += nThreads * nBlocks) { + for (uint32_t i = iBlock * nThreads + iThread; i < mNMaxClusters; i += nThreads * nBlocks) { if (mClusterAttachment[i] != 0) { mClusterAttachment[i] = (mClusterAttachment[i] & attachFlagMask) | mTrackSort[mClusterAttachment[i] & attachTrackMask]; } } } -GPUd() void GPUTPCGMMerger::MergeLoopersInit(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::MergeLoopersInit(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { const float lowPtThresh = Param().rec.tpc.rejectQPtB5 * 1.1f; // Might need to merge tracks above the threshold with parts below the threshold - for (unsigned int i = get_global_id(0); i < mMemory->nOutputTracks; i += get_global_size(0)) { + for (uint32_t i = get_global_id(0); i < mMemory->nOutputTracks; i += get_global_size(0)) { const auto& trk = mOutputTracks[i]; const auto& p = trk.GetParam(); const float qptabs = CAMath::Abs(p.GetQPt()); if (trk.NClusters() && qptabs * Param().qptB5Scaler > 5.f && qptabs * Param().qptB5Scaler <= lowPtThresh) { - const int slice = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].slice; + const int32_t slice = mClusters[trk.FirstClusterRef() + trk.NClusters() - 1].slice; const float refz = p.GetZ() + (Param().par.earlyTpcTransform ? p.GetTZOffset() : GetConstantMem()->calibObjects.fastTransformHelper->getCorrMap()->convVertexTimeToZOffset(slice, p.GetTZOffset(), Param().continuousMaxTimeBin)) + (trk.CSide() ? -100 : 100); float sinA, cosA; CAMath::SinCos(trk.GetAlpha(), sinA, cosA); @@ -2137,7 +2137,7 @@ GPUd() void GPUTPCGMMerger::MergeLoopersInit(int nBlocks, int nThreads, int iBlo const float my = p.GetY() - r * CAMath::Sqrt(1 - p.GetSinPhi() * p.GetSinPhi()); const float gmx = cosA * mx - sinA * my; const float gmy = cosA * my + sinA * mx; - unsigned int myId = CAMath::AtomicAdd(&mMemory->nLooperMatchCandidates, 1u); + uint32_t myId = CAMath::AtomicAdd(&mMemory->nLooperMatchCandidates, 1u); if (myId >= mNMaxLooperMatches) { raiseError(GPUErrors::ERROR_LOOPER_MATCH_OVERFLOW, myId, mNMaxLooperMatches); CAMath::AtomicExch(&mMemory->nLooperMatchCandidates, mNMaxLooperMatches); @@ -2146,7 +2146,7 @@ GPUd() void GPUTPCGMMerger::MergeLoopersInit(int nBlocks, int nThreads, int iBlo mLooperCandidates[myId] = MergeLooperParam{refz, gmx, gmy, i}; /*printf("Track %u Sanity qpt %f snp %f bz %f\n", mMemory->nLooperMatchCandidates, p.GetQPt(), p.GetSinPhi(), bz); - for (unsigned int k = 0;k < trk.NClusters();k++) { + for (uint32_t k = 0;k < trk.NClusters();k++) { float xx, yy, zz; if (Param().par.earlyTpcTransform) { const float zOffset = (mClusters[trk.FirstClusterRef() + k].slice < 18) == (mClusters[trk.FirstClusterRef() + 0].slice < 18) ? p.GetTZOffset() : -p.GetTZOffset(); @@ -2162,13 +2162,13 @@ GPUd() void GPUTPCGMMerger::MergeLoopersInit(int nBlocks, int nThreads, int iBlo float cx = ca2 * xx - sa2 * yy; float cy = ca2 * yy + sa2 * xx; float dist = CAMath::Sqrt((cx - gmx) * (cx - gmx) + (cy - gmy) * (cy - gmy)); - printf("Hit %3d/%3d slice %d xy %f %f R %f\n", k, trk.NClusters(), (int)mClusters[trk.FirstClusterRef() + k].slice, cx, cy, dist); + printf("Hit %3d/%3d slice %d xy %f %f R %f\n", k, trk.NClusters(), (int32_t)mClusters[trk.FirstClusterRef() + k].slice, cx, cy, dist); }*/ } } } -GPUd() void GPUTPCGMMerger::MergeLoopersSort(int nBlocks, int nThreads, int iBlock, int iThread) +GPUd() void GPUTPCGMMerger::MergeLoopersSort(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread) { #ifndef GPUCA_SPECIALIZE_THRUST_SORTS if (iThread || iBlock) { @@ -2196,27 +2196,27 @@ inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal paramLabels(mMemory->nLooperMatchCandidates); - for (unsigned int i = 0; i < mMemory->nLooperMatchCandidates; i++) { + std::vector paramLabels(mMemory->nLooperMatchCandidates); + for (uint32_t i = 0; i < mMemory->nLooperMatchCandidates; i++) { paramLabels[i] = GetTrackLabel(mOutputTracks[params[i].id]); } /*std::vector dropped(mMemory->nLooperMatchCandidates); std::vector droppedMC(mMemory->nLooperMatchCandidates); - std::vector histMatch(101); - std::vector histFail(101);*/ + std::vector histMatch(101); + std::vector histFail(101);*/ if (!mRec->GetProcessingSettings().runQA) { throw std::runtime_error("Need QA enabled for the Merge Loopers MC QA"); } #endif - for (unsigned int i = get_global_id(0); i < mMemory->nLooperMatchCandidates; i += get_global_size(0)) { - for (unsigned int j = i + 1; j < mMemory->nLooperMatchCandidates; j++) { - //int bs = 0; + for (uint32_t i = get_global_id(0); i < mMemory->nLooperMatchCandidates; i += get_global_size(0)) { + for (uint32_t j = i + 1; j < mMemory->nLooperMatchCandidates; j++) { + // int32_t bs = 0; if (CAMath::Abs(params[j].refz) > CAMath::Abs(params[i].refz) + 100.f) { break; } @@ -2240,10 +2240,10 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo const float dzcorr = dznormalized + phasecorr * phasecorrdirection; const bool sameside = !(trk1.CSide() ^ trk2.CSide()); const float dzcorrlimit[4] = {sameside ? 0.018f : 0.012f, sameside ? 0.12f : 0.025f, 0.14f, 0.15f}; - const int dzcorrcount = sameside ? 4 : 2; + const int32_t dzcorrcount = sameside ? 4 : 2; bool dzcorrok = false; float dznorm = 0.f; - for (int k = 0; k < dzcorrcount; k++) { + for (int32_t k = 0; k < dzcorrcount; k++) { const float d = CAMath::Abs(dzcorr - 0.5f * k); if (d <= dzcorrlimit[k]) { dzcorrok = true; @@ -2261,11 +2261,11 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo float d = CAMath::Sum2(dtgl * (1.f / 0.03f), dqpt * (1.f / 0.04f)) + d2xy * (1.f / 4.f) + dznorm * (1.f / 0.3f); bool EQ = d < 6.f; #if GPUCA_MERGE_LOOPER_MC && !defined(GPUCA_GPUCODE) - const long label1 = paramLabels[i]; - const long label2 = paramLabels[j]; + const int64_t label1 = paramLabels[i]; + const int64_t label2 = paramLabels[j]; bool labelEQ = label1 != -1 && label1 == label2; if (1 || EQ || labelEQ) { - //printf("Matching track %d/%d %u-%u (%ld/%ld): dist %f side %d %d, tgl %f %f, qpt %f %f, x %f %f, y %f %f\n", (int)EQ, (int)labelEQ, i, j, label1, label2, d, (int)mOutputTracks[params[i].id].CSide(), (int)mOutputTracks[params[j].id].CSide(), params[i].tgl, params[j].tgl, params[i].qpt, params[j].qpt, params[i].x, params[j].x, params[i].y, params[j].y); + // printf("Matching track %d/%d %u-%u (%ld/%ld): dist %f side %d %d, tgl %f %f, qpt %f %f, x %f %f, y %f %f\n", (int32_t)EQ, (int32_t)labelEQ, i, j, label1, label2, d, (int32_t)mOutputTracks[params[i].id].CSide(), (int32_t)mOutputTracks[params[j].id].CSide(), params[i].tgl, params[j].tgl, params[i].qpt, params[j].qpt, params[i].x, params[j].x, params[i].y, params[j].y); static auto& tup = GPUROOTDump::get("mergeloopers", "labeleq:sides:d2xy:tgl1:tgl2:qpt1:qpt2:dz:dzcorr:dtgl:dqpt:dznorm:bs"); tup.Fill((float)labelEQ, (trk1.CSide() ? 1 : 0) | (trk2.CSide() ? 2 : 0), d2xy, param1.GetDzDs(), param2.GetDzDs(), param1.GetQPt(), param2.GetQPt(), CAMath::Abs(params[j].refz) - CAMath::Abs(params[i].refz), dzcorr, dtgl, dqpt, dznorm, bs); static auto tup2 = GPUROOTDump::getNew("mergeloopers2", "labeleq:refz1:refz2:tgl1:tgl2:qpt1:qpt2:snp1:snp2:a1:a2:dzn:phasecor:phasedir:dzcorr"); @@ -2276,10 +2276,10 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo } if (labelEQ) { droppedMC[j] = true; - histMatch[CAMath::Min(100, d * 10.f)]++; + histMatch[CAMath::Min(100, d * 10.f)]++; } if (d < 10.f && !labelEQ) { - histFail[CAMath::Min(100, d * 10.f)]++; + histFail[CAMath::Min(100, d * 10.f)]++; }*/ #endif if (EQ) { @@ -2291,8 +2291,8 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo } } /*#if GPUCA_MERGE_LOOPER_MC && !defined(GPUCA_GPUCODE) - int total = 0, totalmc = 0, good = 0, missed = 0, fake = 0; - for (unsigned int i = 0; i < mMemory->nLooperMatchCandidates; i++) { + int32_t total = 0, totalmc = 0, good = 0, missed = 0, fake = 0; + for (uint32_t i = 0; i < mMemory->nLooperMatchCandidates; i++) { total += dropped[i]; totalmc += droppedMC[i]; good += dropped[i] && droppedMC[i]; @@ -2307,11 +2307,11 @@ GPUd() void GPUTPCGMMerger::MergeLoopersMain(int nBlocks, int nThreads, int iBlo printf("%20s: %8d (%8.3f%%)\n", "Fake", fake, 100.f * fake / total); } printf("Match histo\n"); - for (unsigned int i = 0; i < histMatch.size(); i++) { + for (uint32_t i = 0; i < histMatch.size(); i++) { printf("%8.3f: %3d\n", i / 10.f + 0.05f, histMatch[i]); } printf("Fake histo\n"); - for (unsigned int i = 0; i < histFail.size(); i++) { + for (uint32_t i = 0; i < histFail.size(); i++) { printf("%8.3f: %3d\n", i / 10.f + 0.05f, histFail[i]); } #endif*/ diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h index 05b128ad522e2..b3b23270f566f 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h @@ -66,30 +66,30 @@ class GPUTPCGMMerger : public GPUProcessor ~GPUTPCGMMerger() CON_DEFAULT; GPUTPCGMMerger(const GPUTPCGMMerger&) CON_DELETE; const GPUTPCGMMerger& operator=(const GPUTPCGMMerger&) const CON_DELETE; - static CONSTEXPR const int NSLICES = GPUCA_NSLICES; //* N slices + static CONSTEXPR const int32_t NSLICES = GPUCA_NSLICES; //* N slices struct memory { - GPUAtomic(unsigned int) nRetryRefit; - GPUAtomic(unsigned int) nLoopData; - GPUAtomic(unsigned int) nUnpackedTracks; - GPUAtomic(unsigned int) nOutputTracks; - GPUAtomic(unsigned int) nOutputTrackClusters; - GPUAtomic(unsigned int) nO2Tracks; - GPUAtomic(unsigned int) nO2ClusRefs; + GPUAtomic(uint32_t) nRetryRefit; + GPUAtomic(uint32_t) nLoopData; + GPUAtomic(uint32_t) nUnpackedTracks; + GPUAtomic(uint32_t) nOutputTracks; + GPUAtomic(uint32_t) nOutputTrackClusters; + GPUAtomic(uint32_t) nO2Tracks; + GPUAtomic(uint32_t) nO2ClusRefs; const GPUTPCTrack* firstGlobalTracks[NSLICES]; - GPUAtomic(unsigned int) tmpCounter[2 * NSLICES]; - GPUAtomic(unsigned int) nLooperMatchCandidates; + GPUAtomic(uint32_t) tmpCounter[2 * NSLICES]; + GPUAtomic(uint32_t) nLooperMatchCandidates; }; struct trackCluster { - unsigned int id; - unsigned char row; - unsigned char slice; - unsigned char leg; + uint32_t id; + uint8_t row; + uint8_t slice; + uint8_t leg; }; struct tmpSort { - unsigned int x; + uint32_t x; float y; }; @@ -107,96 +107,96 @@ class GPUTPCGMMerger : public GPUProcessor void* SetPointersOutputState(void* mem); void* SetPointersMemory(void* mem); - void SetSliceData(int index, const GPUTPCSliceOutput* sliceData) { mkSlices[index] = sliceData; } + void SetSliceData(int32_t index, const GPUTPCSliceOutput* sliceData) { mkSlices[index] = sliceData; } - GPUhdi() int NOutputTracks() const { return mMemory->nOutputTracks; } + GPUhdi() int32_t NOutputTracks() const { return mMemory->nOutputTracks; } GPUhdi() const GPUTPCGMMergedTrack* OutputTracks() const { return mOutputTracks; } GPUhdi() GPUTPCGMMergedTrack* OutputTracks() { return mOutputTracks; } GPUhdi() const GPUdEdxInfo* OutputTracksdEdx() const { return mOutputTracksdEdx; } GPUhdi() GPUdEdxInfo* OutputTracksdEdx() { return mOutputTracksdEdx; } - GPUhdi() unsigned int NClusters() const { return mNClusters; } - GPUhdi() unsigned int NMaxClusters() const { return mNMaxClusters; } - GPUhdi() unsigned int NMaxTracks() const { return mNMaxTracks; } - GPUhdi() unsigned int NMaxOutputTrackClusters() const { return mNMaxOutputTrackClusters; } - GPUhdi() unsigned int NOutputTrackClusters() const { return mMemory->nOutputTrackClusters; } + GPUhdi() uint32_t NClusters() const { return mNClusters; } + GPUhdi() uint32_t NMaxClusters() const { return mNMaxClusters; } + GPUhdi() uint32_t NMaxTracks() const { return mNMaxTracks; } + GPUhdi() uint32_t NMaxOutputTrackClusters() const { return mNMaxOutputTrackClusters; } + GPUhdi() uint32_t NOutputTrackClusters() const { return mMemory->nOutputTrackClusters; } GPUhdi() const GPUTPCGMMergedTrackHit* Clusters() const { return mClusters; } GPUhdi() GPUTPCGMMergedTrackHit* Clusters() { return (mClusters); } GPUhdi() const GPUTPCGMMergedTrackHitXYZ* ClustersXYZ() const { return mClustersXYZ; } GPUhdi() GPUTPCGMMergedTrackHitXYZ* ClustersXYZ() { return (mClustersXYZ); } - GPUhdi() GPUAtomic(unsigned int) * ClusterAttachment() const { return mClusterAttachment; } - GPUhdi() unsigned int* TrackOrderAttach() const { return mTrackOrderAttach; } - GPUhdi() unsigned int* TrackOrderProcess() const { return mTrackOrderProcess; } - GPUhdi() unsigned int* RetryRefitIds() const { return mRetryRefitIds; } - GPUhdi() unsigned char* ClusterStateExt() const { return mClusterStateExt; } + GPUhdi() GPUAtomic(uint32_t) * ClusterAttachment() const { return mClusterAttachment; } + GPUhdi() uint32_t* TrackOrderAttach() const { return mTrackOrderAttach; } + GPUhdi() uint32_t* TrackOrderProcess() const { return mTrackOrderProcess; } + GPUhdi() uint32_t* RetryRefitIds() const { return mRetryRefitIds; } + GPUhdi() uint8_t* ClusterStateExt() const { return mClusterStateExt; } GPUhdi() GPUTPCGMLoopData* LoopData() const { return mLoopData; } GPUhdi() memory* Memory() const { return mMemory; } - GPUhdi() GPUAtomic(unsigned int) * TmpCounter() { return mMemory->tmpCounter; } + GPUhdi() GPUAtomic(uint32_t) * TmpCounter() { return mMemory->tmpCounter; } GPUhdi() uint2* ClusRefTmp() { return mClusRefTmp; } - GPUhdi() unsigned int* TrackSort() { return mTrackSort; } + GPUhdi() uint32_t* TrackSort() { return mTrackSort; } GPUhdi() tmpSort* TrackSortO2() { return mTrackSortO2; } GPUhdi() MergeLooperParam* LooperCandidates() { return mLooperCandidates; } - GPUhdi() GPUAtomic(unsigned int) * SharedCount() { return mSharedCount; } - GPUhdi() gputpcgmmergertypes::GPUTPCGMBorderRange* BorderRange(int i) { return mBorderRange[i]; } - GPUhdi() const gputpcgmmergertypes::GPUTPCGMBorderRange* BorderRange(int i) const { return mBorderRange[i]; } - GPUhdi() GPUTPCGMBorderTrack* BorderTracks(int i) { return mBorder[i]; } + GPUhdi() GPUAtomic(uint32_t) * SharedCount() { return mSharedCount; } + GPUhdi() gputpcgmmergertypes::GPUTPCGMBorderRange* BorderRange(int32_t i) { return mBorderRange[i]; } + GPUhdi() const gputpcgmmergertypes::GPUTPCGMBorderRange* BorderRange(int32_t i) const { return mBorderRange[i]; } + GPUhdi() GPUTPCGMBorderTrack* BorderTracks(int32_t i) { return mBorder[i]; } GPUhdi() o2::tpc::TrackTPC* OutputTracksTPCO2() { return mOutputTracksTPCO2; } - GPUhdi() unsigned int* OutputClusRefsTPCO2() { return mOutputClusRefsTPCO2; } + GPUhdi() uint32_t* OutputClusRefsTPCO2() { return mOutputClusRefsTPCO2; } GPUhdi() o2::MCCompLabel* OutputTracksTPCO2MC() { return mOutputTracksTPCO2MC; } - GPUhdi() unsigned int NOutputTracksTPCO2() const { return mMemory->nO2Tracks; } - GPUhdi() unsigned int NOutputClusRefsTPCO2() const { return mMemory->nO2ClusRefs; } + GPUhdi() uint32_t NOutputTracksTPCO2() const { return mMemory->nO2Tracks; } + GPUhdi() uint32_t NOutputClusRefsTPCO2() const { return mMemory->nO2ClusRefs; } GPUhdi() GPUTPCGMSliceTrack* SliceTrackInfos() { return mSliceTrackInfos; } - GPUhdi() int NMaxSingleSliceTracks() const { return mNMaxSingleSliceTracks; } - GPUhdi() int* TrackIDs() { return mTrackIDs; } - GPUhdi() int* TmpSortMemory() { return mTmpSortMemory; } - - GPUd() unsigned short MemoryResMemory() { return mMemoryResMemory; } - GPUd() unsigned short MemoryResOutput() const { return mMemoryResOutput; } - GPUd() unsigned short MemoryResOutputState() const { return mMemoryResOutputState; } - GPUd() unsigned short MemoryResOutputO2() const { return mMemoryResOutputO2; } - GPUd() unsigned short MemoryResOutputO2Clus() const { return mMemoryResOutputO2Clus; } - GPUd() unsigned short MemoryResOutputO2MC() const { return mMemoryResOutputO2MC; } - GPUd() unsigned short MemoryResOutputO2Scratch() const { return mMemoryResOutputO2Scratch; } - - GPUd() int RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const GPUTPCTrack* inTrack, float alpha, int slice); - GPUd() void SetTrackClusterZT(GPUTPCGMSliceTrack& track, int iSlice, const GPUTPCTrack* sliceTr); - - int CheckSlices(); - GPUd() void RefitSliceTracks(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice); - GPUd() void UnpackSliceGlobal(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice); - GPUd() void UnpackSaveNumber(int id); - GPUd() void UnpackResetIds(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice); - GPUd() void MergeCE(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ClearTrackLinks(int nBlocks, int nThreads, int iBlock, int iThread, bool output); - GPUd() void MergeWithinSlicesPrepare(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void MergeSlicesPrepare(int nBlocks, int nThreads, int iBlock, int iThread, int border0, int border1, char useOrigTrackParam); - template - GPUd() void MergeBorderTracks(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice, char withinSlice, char mergeMode); - GPUd() void MergeBorderTracksSetup(int& n1, int& n2, GPUTPCGMBorderTrack*& b1, GPUTPCGMBorderTrack*& b2, int& jSlice, int iSlice, char withinSlice, char mergeMode) const; - template - GPUd() void MergeBorderTracks(int nBlocks, int nThreads, int iBlock, int iThread, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int N, int cmpMax); - GPUd() void SortTracks(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void SortTracksQPt(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void SortTracksPrepare(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void PrepareClustersForFit0(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void PrepareClustersForFit1(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void PrepareClustersForFit2(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void LinkGlobalTracks(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void CollectMergedTracks(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void Finalize0(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void Finalize1(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void Finalize2(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ResolveFindConnectedComponentsSetup(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ResolveFindConnectedComponentsHookNeighbors(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ResolveFindConnectedComponentsHookLinks(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ResolveFindConnectedComponentsMultiJump(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void ResolveMergeSlices(gputpcgmmergertypes::GPUResolveSharedMemory& smem, int nBlocks, int nThreads, int iBlock, int iThread, char useOrigTrackParam, char mergeAll); - GPUd() void MergeLoopersInit(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void MergeLoopersSort(int nBlocks, int nThreads, int iBlock, int iThread); - GPUd() void MergeLoopersMain(int nBlocks, int nThreads, int iBlock, int iThread); + GPUhdi() int32_t NMaxSingleSliceTracks() const { return mNMaxSingleSliceTracks; } + GPUhdi() int32_t* TrackIDs() { return mTrackIDs; } + GPUhdi() int32_t* TmpSortMemory() { return mTmpSortMemory; } + + GPUd() uint16_t MemoryResMemory() { return mMemoryResMemory; } + GPUd() uint16_t MemoryResOutput() const { return mMemoryResOutput; } + GPUd() uint16_t MemoryResOutputState() const { return mMemoryResOutputState; } + GPUd() uint16_t MemoryResOutputO2() const { return mMemoryResOutputO2; } + GPUd() uint16_t MemoryResOutputO2Clus() const { return mMemoryResOutputO2Clus; } + GPUd() uint16_t MemoryResOutputO2MC() const { return mMemoryResOutputO2MC; } + GPUd() uint16_t MemoryResOutputO2Scratch() const { return mMemoryResOutputO2Scratch; } + + GPUd() int32_t RefitSliceTrack(GPUTPCGMSliceTrack& sliceTrack, const GPUTPCTrack* inTrack, float alpha, int32_t slice); + GPUd() void SetTrackClusterZT(GPUTPCGMSliceTrack& track, int32_t iSlice, const GPUTPCTrack* sliceTr); + + int32_t CheckSlices(); + GPUd() void RefitSliceTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice); + GPUd() void UnpackSliceGlobal(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice); + GPUd() void UnpackSaveNumber(int32_t id); + GPUd() void UnpackResetIds(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice); + GPUd() void MergeCE(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ClearTrackLinks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, bool output); + GPUd() void MergeWithinSlicesPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void MergeSlicesPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t border0, int32_t border1, int8_t useOrigTrackParam); + template + GPUd() void MergeBorderTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); + GPUd() void MergeBorderTracksSetup(int32_t& n1, int32_t& n2, GPUTPCGMBorderTrack*& b1, GPUTPCGMBorderTrack*& b2, int32_t& jSlice, int32_t iSlice, int8_t withinSlice, int8_t mergeMode) const; + template + GPUd() void MergeBorderTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int32_t N, int32_t cmpMax); + GPUd() void SortTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void SortTracksQPt(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void SortTracksPrepare(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void PrepareClustersForFit0(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void PrepareClustersForFit1(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void PrepareClustersForFit2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void LinkGlobalTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void CollectMergedTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void Finalize0(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void Finalize1(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void Finalize2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ResolveFindConnectedComponentsSetup(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ResolveFindConnectedComponentsHookNeighbors(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ResolveFindConnectedComponentsHookLinks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ResolveFindConnectedComponentsMultiJump(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void ResolveMergeSlices(gputpcgmmergertypes::GPUResolveSharedMemory& smem, int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int8_t useOrigTrackParam, int8_t mergeAll); + GPUd() void MergeLoopersInit(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void MergeLoopersSort(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); + GPUd() void MergeLoopersMain(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread); #ifndef GPUCA_GPUCODE void DumpSliceTracks(std::ostream& out) const; - void DumpMergeRanges(std::ostream& out, int withinSlice, int mergeMode) const; + void DumpMergeRanges(std::ostream& out, int32_t withinSlice, int32_t mergeMode) const; void DumpTrackLinks(std::ostream& out, bool output, const char* type) const; void DumpMergedWithinSlices(std::ostream& out) const; void DumpMergedBetweenSlices(std::ostream& out) const; @@ -206,95 +206,95 @@ class GPUTPCGMMerger : public GPUProcessor void DumpRefit(std::ostream& out) const; void DumpFinal(std::ostream& out) const; - template - void MergedTrackStreamerInternal(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int slice1, int slice2, int mergeMode, float weight, float frac) const; - void MergedTrackStreamer(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int slice1, int slice2, int mergeMode, float weight, float frac) const; - const GPUTPCGMBorderTrack& MergedTrackStreamerFindBorderTrack(const GPUTPCGMBorderTrack* tracks, int N, int trackId) const; + template + void MergedTrackStreamerInternal(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int32_t slice1, int32_t slice2, int32_t mergeMode, float weight, float frac) const; + void MergedTrackStreamer(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int32_t slice1, int32_t slice2, int32_t mergeMode, float weight, float frac) const; + const GPUTPCGMBorderTrack& MergedTrackStreamerFindBorderTrack(const GPUTPCGMBorderTrack* tracks, int32_t N, int32_t trackId) const; void DebugRefitMergedTrack(const GPUTPCGMMergedTrack& track) const; - std::vector StreamerOccupancyBin(int iSlice, int iRow, float time) const; - std::vector StreamerUncorrectedZY(int iSlice, int iRow, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop) const; + std::vector StreamerOccupancyBin(int32_t iSlice, int32_t iRow, float time) const; + std::vector StreamerUncorrectedZY(int32_t iSlice, int32_t iRow, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop) const; - void DebugStreamerUpdate(int iTrk, int ihit, float xx, float yy, float zz, const GPUTPCGMMergedTrackHit& cluster, const o2::tpc::ClusterNative& clusterNative, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop, const gputpcgmmergertypes::InterpolationErrorHit& interpolation, char rejectChi2, bool refit, int retVal, float avgInvCharge, float posY, float posZ, short clusterState, int retValReject, float err2Y, float err2Z) const; + void DebugStreamerUpdate(int32_t iTrk, int32_t ihit, float xx, float yy, float zz, const GPUTPCGMMergedTrackHit& cluster, const o2::tpc::ClusterNative& clusterNative, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop, const gputpcgmmergertypes::InterpolationErrorHit& interpolation, int8_t rejectChi2, bool refit, int32_t retVal, float avgInvCharge, float posY, float posZ, int16_t clusterState, int32_t retValReject, float err2Y, float err2Z) const; #endif - GPUdi() int SliceTrackInfoFirst(int iSlice) const { return mSliceTrackInfoIndex[iSlice]; } - GPUdi() int SliceTrackInfoLast(int iSlice) const { return mSliceTrackInfoIndex[iSlice + 1]; } - GPUdi() int SliceTrackInfoGlobalFirst(int iSlice) const { return mSliceTrackInfoIndex[NSLICES + iSlice]; } - GPUdi() int SliceTrackInfoGlobalLast(int iSlice) const { return mSliceTrackInfoIndex[NSLICES + iSlice + 1]; } - GPUdi() int SliceTrackInfoLocalTotal() const { return mSliceTrackInfoIndex[NSLICES]; } - GPUdi() int SliceTrackInfoTotal() const { return mSliceTrackInfoIndex[2 * NSLICES]; } + GPUdi() int32_t SliceTrackInfoFirst(int32_t iSlice) const { return mSliceTrackInfoIndex[iSlice]; } + GPUdi() int32_t SliceTrackInfoLast(int32_t iSlice) const { return mSliceTrackInfoIndex[iSlice + 1]; } + GPUdi() int32_t SliceTrackInfoGlobalFirst(int32_t iSlice) const { return mSliceTrackInfoIndex[NSLICES + iSlice]; } + GPUdi() int32_t SliceTrackInfoGlobalLast(int32_t iSlice) const { return mSliceTrackInfoIndex[NSLICES + iSlice + 1]; } + GPUdi() int32_t SliceTrackInfoLocalTotal() const { return mSliceTrackInfoIndex[NSLICES]; } + GPUdi() int32_t SliceTrackInfoTotal() const { return mSliceTrackInfoIndex[2 * NSLICES]; } private: - GPUd() void MergeSlicesPrepareStep2(int nBlocks, int nThreads, int iBlock, int iThread, int iBorder, GPUTPCGMBorderTrack** B, GPUAtomic(unsigned int) * nB, bool useOrigTrackParam = false); - template - GPUd() void MergeBorderTracks(int nBlocks, int nThreads, int iBlock, int iThread, int iSlice1, GPUTPCGMBorderTrack* B1, int N1, int iSlice2, GPUTPCGMBorderTrack* B2, int N2, int mergeMode = 0); + GPUd() void MergeSlicesPrepareStep2(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iBorder, GPUTPCGMBorderTrack** B, GPUAtomic(uint32_t) * nB, bool useOrigTrackParam = false); + template + GPUd() void MergeBorderTracks(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t iSlice1, GPUTPCGMBorderTrack* B1, int32_t N1, int32_t iSlice2, GPUTPCGMBorderTrack* B2, int32_t N2, int32_t mergeMode = 0); - GPUd() void MergeCEFill(const GPUTPCGMSliceTrack* track, const GPUTPCGMMergedTrackHit& cls, const GPUTPCGMMergedTrackHitXYZ* clsXYZ, int itr); + GPUd() void MergeCEFill(const GPUTPCGMSliceTrack* track, const GPUTPCGMMergedTrackHit& cls, const GPUTPCGMMergedTrackHitXYZ* clsXYZ, int32_t itr); void CheckMergedTracks(); #ifndef GPUCA_GPUCODE void PrintMergeGraph(const GPUTPCGMSliceTrack* trk, std::ostream& out) const; template - long GetTrackLabelA(const S& trk) const; + int64_t GetTrackLabelA(const S& trk) const; template - long GetTrackLabel(const S& trk) const; + int64_t GetTrackLabel(const S& trk) const; #endif - GPUdi() void setBlockRange(int elems, int nBlocks, int iBlock, int& start, int& end); - GPUdi() void hookEdge(int u, int v); + GPUdi() void setBlockRange(int32_t elems, int32_t nBlocks, int32_t iBlock, int32_t& start, int32_t& end); + GPUdi() void hookEdge(int32_t u, int32_t v); - int mNextSliceInd[NSLICES]; - int mPrevSliceInd[NSLICES]; + int32_t mNextSliceInd[NSLICES]; + int32_t mPrevSliceInd[NSLICES]; const GPUTPCSliceOutput* mkSlices[NSLICES]; //* array of input slice tracks - int* mTrackLinks; - int* mTrackCCRoots; // root of the connected component of this track - - unsigned int mNTotalSliceTracks; // maximum number of incoming slice tracks - unsigned int mNMaxTracks; // maximum number of output tracks - unsigned int mNMaxSingleSliceTracks; // max N tracks in one slice - unsigned int mNMaxOutputTrackClusters; // max number of clusters in output tracks (double-counting shared clusters) - unsigned int mNMaxClusters; // max total unique clusters (in event) - unsigned int mNMaxLooperMatches; // Maximum number of candidate pairs for looper matching - - unsigned short mMemoryResMemory; - unsigned short mMemoryResOutput; - unsigned short mMemoryResOutputState; - unsigned short mMemoryResOutputO2; - unsigned short mMemoryResOutputO2Clus; - unsigned short mMemoryResOutputO2MC; - unsigned short mMemoryResOutputO2Scratch; - - int mNClusters; // Total number of incoming clusters (from slice tracks) + int32_t* mTrackLinks; + int32_t* mTrackCCRoots; // root of the connected component of this track + + uint32_t mNTotalSliceTracks; // maximum number of incoming slice tracks + uint32_t mNMaxTracks; // maximum number of output tracks + uint32_t mNMaxSingleSliceTracks; // max N tracks in one slice + uint32_t mNMaxOutputTrackClusters; // max number of clusters in output tracks (double-counting shared clusters) + uint32_t mNMaxClusters; // max total unique clusters (in event) + uint32_t mNMaxLooperMatches; // Maximum number of candidate pairs for looper matching + + uint16_t mMemoryResMemory; + uint16_t mMemoryResOutput; + uint16_t mMemoryResOutputState; + uint16_t mMemoryResOutputO2; + uint16_t mMemoryResOutputO2Clus; + uint16_t mMemoryResOutputO2MC; + uint16_t mMemoryResOutputO2Scratch; + + int32_t mNClusters; // Total number of incoming clusters (from slice tracks) GPUTPCGMMergedTrack* mOutputTracks; //* array of output merged tracks GPUdEdxInfo* mOutputTracksdEdx; //* dEdx information GPUTPCGMSliceTrack* mSliceTrackInfos; //* additional information for slice tracks - int* mSliceTrackInfoIndex; + int32_t* mSliceTrackInfoIndex; GPUTPCGMMergedTrackHit* mClusters; GPUTPCGMMergedTrackHitXYZ* mClustersXYZ; - int* mGlobalClusterIDs; - GPUAtomic(unsigned int) * mClusterAttachment; + int32_t* mGlobalClusterIDs; + GPUAtomic(uint32_t) * mClusterAttachment; o2::tpc::TrackTPC* mOutputTracksTPCO2; - unsigned int* mOutputClusRefsTPCO2; + uint32_t* mOutputClusRefsTPCO2; o2::MCCompLabel* mOutputTracksTPCO2MC; MergeLooperParam* mLooperCandidates; - unsigned int* mTrackOrderAttach; - unsigned int* mTrackOrderProcess; - unsigned char* mClusterStateExt; + uint32_t* mTrackOrderAttach; + uint32_t* mTrackOrderProcess; + uint8_t* mClusterStateExt; uint2* mClusRefTmp; - int* mTrackIDs; - int* mTmpSortMemory; - unsigned int* mTrackSort; + int32_t* mTrackIDs; + int32_t* mTmpSortMemory; + uint32_t* mTrackSort; tmpSort* mTrackSortO2; - GPUAtomic(unsigned int) * mSharedCount; // Must be unsigned int unfortunately for atomic support + GPUAtomic(uint32_t) * mSharedCount; // Must be uint32_t unfortunately for atomic support GPUTPCGMBorderTrack* mBorderMemory; // memory for border tracks GPUTPCGMBorderTrack* mBorder[2 * NSLICES]; gputpcgmmergertypes::GPUTPCGMBorderRange* mBorderRangeMemory; // memory for border tracks gputpcgmmergertypes::GPUTPCGMBorderRange* mBorderRange[NSLICES]; // memory for border tracks memory* mMemory; - unsigned int* mRetryRefitIds; + uint32_t* mRetryRefitIds; GPUTPCGMLoopData* mLoopData; }; } // namespace gpu diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergerDump.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMergerDump.cxx index 19d56b62ba490..e1de4030d672c 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergerDump.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergerDump.cxx @@ -48,11 +48,11 @@ void GPUTPCGMMerger::DumpSliceTracks(std::ostream& out) const std::streamsize ss = out.precision(); out << std::setprecision(2); out << "\nTPC Merger Slice Tracks\n"; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { out << "Slice Track Info Index " << (mSliceTrackInfoIndex[iSlice + 1] - mSliceTrackInfoIndex[iSlice]) << " / " << (mSliceTrackInfoIndex[NSLICES + iSlice + 1] - mSliceTrackInfoIndex[NSLICES + iSlice]) << "\n"; - for (int iGlobal = 0; iGlobal < 2; iGlobal++) { + for (int32_t iGlobal = 0; iGlobal < 2; iGlobal++) { out << " Track type " << iGlobal << "\n"; - for (int j = mSliceTrackInfoIndex[iSlice + NSLICES * iGlobal]; j < mSliceTrackInfoIndex[iSlice + NSLICES * iGlobal + 1]; j++) { + for (int32_t j = mSliceTrackInfoIndex[iSlice + NSLICES * iGlobal]; j < mSliceTrackInfoIndex[iSlice + NSLICES * iGlobal + 1]; j++) { const auto& trk = mSliceTrackInfos[j]; out << " Track " << j << ": LocalId " << (iGlobal ? (trk.LocalTrackId() >> 24) : -1) << "/" << (iGlobal ? (trk.LocalTrackId() & 0xFFFFFF) : -1) << " X " << trk.X() << " offsetz " << trk.TZOffset() << " A " << trk.Alpha() << " Y " << trk.Y() << " Z " << trk.Z() << " SinPhi " << trk.SinPhi() << " CosPhi " << trk.CosPhi() << " SecPhi " << trk.SecPhi() << " Tgl " << trk.DzDs() << " QPt " << trk.QPt() << "\n"; } @@ -61,33 +61,33 @@ void GPUTPCGMMerger::DumpSliceTracks(std::ostream& out) const out << std::setprecision(ss); } -void GPUTPCGMMerger::DumpMergeRanges(std::ostream& out, int withinSlice, int mergeMode) const +void GPUTPCGMMerger::DumpMergeRanges(std::ostream& out, int32_t withinSlice, int32_t mergeMode) const { - int n = withinSlice == -1 ? NSLICES / 2 : NSLICES; - for (int i = 0; i < n; i++) { - int n1, n2; + int32_t n = withinSlice == -1 ? NSLICES / 2 : NSLICES; + for (int32_t i = 0; i < n; i++) { + int32_t n1, n2; GPUTPCGMBorderTrack *b1, *b2; - int jSlice; + int32_t jSlice; MergeBorderTracksSetup(n1, n2, b1, b2, jSlice, i, withinSlice, mergeMode); - const int nTrk = Param().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[jSlice].NTracks() : mkSlices[jSlice]->NTracks(); + const int32_t nTrk = Param().rec.tpc.mergerReadFromTrackerDirectly ? *mRec->GetConstantMem().tpcTrackers[jSlice].NTracks() : mkSlices[jSlice]->NTracks(); const gputpcgmmergertypes::GPUTPCGMBorderRange* range1 = BorderRange(i); const gputpcgmmergertypes::GPUTPCGMBorderRange* range2 = BorderRange(jSlice) + nTrk; out << "\nBorder Tracks : i " << i << " withinSlice " << withinSlice << " mergeMode " << mergeMode << "\n"; - for (int k = 0; k < n1; k++) { + for (int32_t k = 0; k < n1; k++) { out << " " << k << ": t " << b1[k].TrackID() << " ncl " << b1[k].NClusters() << " row " << (mergeMode > 0 ? b1[k].Row() : -1) << " par " << b1[k].Par()[0] << " " << b1[k].Par()[1] << " " << b1[k].Par()[2] << " " << b1[k].Par()[3] << " " << b1[k].Par()[4] << " offset " << b1[k].ZOffsetLinear() << " cov " << b1[k].Cov()[0] << " " << b1[k].Cov()[1] << " " << b1[k].Cov()[2] << " " << b1[k].Cov()[3] << " " << b1[k].Cov()[4] << " covd " << b1[k].CovD()[0] << " " << b1[k].CovD()[1] << "\n"; } if (i != jSlice) { - for (int k = 0; k < n2; k++) { + for (int32_t k = 0; k < n2; k++) { out << " " << k << ": t " << b2[k].TrackID() << " ncl " << b2[k].NClusters() << " row " << (mergeMode > 0 ? b2[k].Row() : -1) << " par " << b2[k].Par()[0] << " " << b2[k].Par()[1] << " " << b2[k].Par()[2] << " " << b2[k].Par()[3] << " " << b2[k].Par()[4] << " offset " << b2[k].ZOffsetLinear() << " cov " << b2[k].Cov()[0] << " " << b2[k].Cov()[1] << " " << b2[k].Cov()[2] << " " << b2[k].Cov()[3] << " " << b2[k].Cov()[4] << " covd " << b2[k].CovD()[0] << " " << b2[k].CovD()[1] << "\n"; } } out << "\nBorder Range : i " << i << " withinSlice " << withinSlice << " mergeMode " << mergeMode << "\n"; - for (int k = 0; k < n1; k++) { + for (int32_t k = 0; k < n1; k++) { out << " " << k << ": " << range1[k].fId << " " << range1[k].fMin << " " << range1[k].fMax << "\n"; } - for (int k = 0; k < n2; k++) { + for (int32_t k = 0; k < n2; k++) { out << " " << k << ": " << range2[k].fId << " " << range2[k].fMin << " " << range2[k].fMax << "\n"; } } @@ -96,8 +96,8 @@ void GPUTPCGMMerger::DumpMergeRanges(std::ostream& out, int withinSlice, int mer void GPUTPCGMMerger::DumpTrackLinks(std::ostream& out, bool output, const char* type) const { out << "\nTPC Merger Links " << type << "\n"; - const int n = output ? mMemory->nOutputTracks : SliceTrackInfoLocalTotal(); - for (int i = 0; i < n; i++) { + const int32_t n = output ? mMemory->nOutputTracks : SliceTrackInfoLocalTotal(); + for (int32_t i = 0; i < n; i++) { if (mTrackLinks[i] != -1) { out << " " << i << ": " << mTrackLinks[i] << "\n"; } @@ -108,8 +108,8 @@ void GPUTPCGMMerger::DumpMergedWithinSlices(std::ostream& out) const { DumpTrackLinks(out, false, "within Slices"); out << "\nTPC Merger Merge Within Slices\n"; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int j = mSliceTrackInfoIndex[iSlice]; j < mSliceTrackInfoIndex[iSlice + 1]; j++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t j = mSliceTrackInfoIndex[iSlice]; j < mSliceTrackInfoIndex[iSlice + 1]; j++) { const auto& trk = mSliceTrackInfos[j]; if (trk.NextSegmentNeighbour() >= 0 || trk.PrevSegmentNeighbour() >= 0) { out << " Track " << j << ": Neighbour " << trk.PrevSegmentNeighbour() << " / " << trk.NextSegmentNeighbour() << "\n"; @@ -122,8 +122,8 @@ void GPUTPCGMMerger::DumpMergedBetweenSlices(std::ostream& out) const { DumpTrackLinks(out, false, "between Slices"); out << "\nTPC Merger Merge Between Slices\n"; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int j = mSliceTrackInfoIndex[iSlice]; j < mSliceTrackInfoIndex[iSlice + 1]; j++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t j = mSliceTrackInfoIndex[iSlice]; j < mSliceTrackInfoIndex[iSlice + 1]; j++) { const auto& trk = mSliceTrackInfos[j]; if (trk.NextNeighbour() >= 0 || trk.PrevNeighbour() >= 0) { out << " Track " << j << ": Neighbour " << trk.PrevNeighbour() << " / " << trk.NextNeighbour() << "\n"; @@ -140,7 +140,7 @@ void GPUTPCGMMerger::DumpCollected(std::ostream& out) const std::streamsize ss = out.precision(); out << std::setprecision(2); out << "\nTPC Merger Collected Tracks\n"; - for (unsigned int i = 0; i < mMemory->nOutputTracks; i++) { + for (uint32_t i = 0; i < mMemory->nOutputTracks; i++) { const auto& trk = mOutputTracks[i]; const auto& p = trk.GetParam(); out << " Track " << i << ": Loop " << trk.Looper() << " Alpha " << trk.GetAlpha() << " X " << p.GetX() << " offset " << p.GetTZOffset() << " Y " << p.GetY() << " Z " << p.GetZ() << " SPhi " << p.GetSinPhi() << " Tgl " << p.GetDzDs() << " QPt " << p.GetQPt() << " NCl " << trk.NClusters() << "\n"; @@ -152,7 +152,7 @@ void GPUTPCGMMerger::DumpMergeCE(std::ostream& out) const { DumpTrackLinks(out, true, " for CE merging"); out << "\nTPC Merger Merge CE\n"; - for (unsigned int i = 0; i < mMemory->nOutputTracks; i++) { + for (uint32_t i = 0; i < mMemory->nOutputTracks; i++) { const auto& trk = mOutputTracks[i]; if (trk.CCE()) { out << " Track " << i << ": CCE\n"; @@ -164,21 +164,21 @@ void GPUTPCGMMerger::DumpFitPrepare(std::ostream& out) const { out << "\nTPC Merger Refit Prepare\n"; out << " Sort\n"; - for (unsigned int i = 0; i < mMemory->nOutputTracks; i++) { + for (uint32_t i = 0; i < mMemory->nOutputTracks; i++) { out << " " << i << ": " << mTrackOrderAttach[i] << "\n"; } out << " Clusters\n"; - for (unsigned int j = 0; j < mMemory->nOutputTracks; j++) { + for (uint32_t j = 0; j < mMemory->nOutputTracks; j++) { const auto& trk = mOutputTracks[j]; out << " Track " << j << ": "; - for (unsigned int i = trk.FirstClusterRef(); i < trk.FirstClusterRef() + trk.NClusters(); i++) { - out << j << "/" << (i - trk.FirstClusterRef()) << ": " << mClusters[i].num << "/" << (int)mClusters[i].state << ", "; + for (uint32_t i = trk.FirstClusterRef(); i < trk.FirstClusterRef() + trk.NClusters(); i++) { + out << j << "/" << (i - trk.FirstClusterRef()) << ": " << mClusters[i].num << "/" << (int32_t)mClusters[i].state << ", "; } out << "\n"; } - unsigned int maxId = Param().rec.nonConsecutiveIDs ? mMemory->nOutputTrackClusters : mNMaxClusters; - unsigned int j = 0; - for (unsigned int i = 0; i < maxId; i++) { + uint32_t maxId = Param().rec.nonConsecutiveIDs ? mMemory->nOutputTrackClusters : mNMaxClusters; + uint32_t j = 0; + for (uint32_t i = 0; i < maxId; i++) { if ((mClusterAttachment[i] & attachFlagMask) != 0) { if (++j % 10 == 0) { out << " Cluster attachment "; @@ -197,7 +197,7 @@ void GPUTPCGMMerger::DumpRefit(std::ostream& out) const std::streamsize ss = out.precision(); out << std::setprecision(2); out << "\nTPC Merger Refit\n"; - for (unsigned int i = 0; i < mMemory->nOutputTracks; i++) { + for (uint32_t i = 0; i < mMemory->nOutputTracks; i++) { const auto& trk = mOutputTracks[i]; if (trk.NClusters() == 0) { continue; @@ -216,22 +216,22 @@ void GPUTPCGMMerger::DumpRefit(std::ostream& out) const void GPUTPCGMMerger::DumpFinal(std::ostream& out) const { out << "\nTPC Merger Finalized\n"; - for (unsigned int j = 0; j < mMemory->nOutputTracks; j++) { + for (uint32_t j = 0; j < mMemory->nOutputTracks; j++) { const auto& trk = mOutputTracks[j]; if (trk.NClusters() == 0) { continue; } out << " Track " << j << ": "; - for (unsigned int i = trk.FirstClusterRef(); i < trk.FirstClusterRef() + trk.NClusters(); i++) { + for (uint32_t i = trk.FirstClusterRef(); i < trk.FirstClusterRef() + trk.NClusters(); i++) { if (mClusters[i].state != 0) { - out << j << "/" << (i - trk.FirstClusterRef()) << ": " << mClusters[i].num << "/" << (int)mClusters[i].state << ", "; + out << j << "/" << (i - trk.FirstClusterRef()) << ": " << mClusters[i].num << "/" << (int32_t)mClusters[i].state << ", "; } } out << "\n"; } - unsigned int maxId = Param().rec.nonConsecutiveIDs ? mMemory->nOutputTrackClusters : mNMaxClusters; - unsigned int j = 0; - for (unsigned int i = 0; i < maxId; i++) { + uint32_t maxId = Param().rec.nonConsecutiveIDs ? mMemory->nOutputTrackClusters : mNMaxClusters; + uint32_t j = 0; + for (uint32_t i = 0; i < maxId; i++) { if ((mClusterAttachment[i] & attachFlagMask) != 0) { if (++j % 10 == 0) { out << " Cluster attachment "; @@ -245,28 +245,28 @@ void GPUTPCGMMerger::DumpFinal(std::ostream& out) const out << "\n"; } -template -inline void GPUTPCGMMerger::MergedTrackStreamerInternal(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int slice1, int slice2, int mergeMode, float weight, float frac) const +template +inline void GPUTPCGMMerger::MergedTrackStreamerInternal(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int32_t slice1, int32_t slice2, int32_t mergeMode, float weight, float frac) const { #ifdef DEBUG_STREAMER - std::vector hits1(152), hits2(152); - for (int i = 0; i < 152; i++) { + std::vector hits1(152), hits2(152); + for (int32_t i = 0; i < 152; i++) { hits1[i] = hits2[i] = -1; } const GPUTPCTracker& tracker1 = GetConstantMem()->tpcTrackers[slice1]; const GPUTPCGMSliceTrack& sliceTrack1 = mSliceTrackInfos[b1.TrackID()]; const GPUTPCTrack& inTrack1 = *sliceTrack1.OrigTrack(); - for (int i = 0; i < inTrack1.NHits(); i++) { + for (int32_t i = 0; i < inTrack1.NHits(); i++) { const GPUTPCHitId& ic1 = tracker1.TrackHits()[inTrack1.FirstHitID() + i]; - int clusterIndex = tracker1.Data().ClusterDataIndex(tracker1.Data().Row(ic1.RowIndex()), ic1.HitIndex()); + int32_t clusterIndex = tracker1.Data().ClusterDataIndex(tracker1.Data().Row(ic1.RowIndex()), ic1.HitIndex()); hits1[ic1.RowIndex()] = clusterIndex; } const GPUTPCTracker& tracker2 = GetConstantMem()->tpcTrackers[slice2]; const GPUTPCGMSliceTrack& sliceTrack2 = mSliceTrackInfos[b2.TrackID()]; const GPUTPCTrack& inTrack2 = *sliceTrack2.OrigTrack(); - for (int i = 0; i < inTrack2.NHits(); i++) { + for (int32_t i = 0; i < inTrack2.NHits(); i++) { const GPUTPCHitId& ic2 = tracker2.TrackHits()[inTrack2.FirstHitID() + i]; - int clusterIndex = tracker2.Data().ClusterDataIndex(tracker2.Data().Row(ic2.RowIndex()), ic2.HitIndex()); + int32_t clusterIndex = tracker2.Data().ClusterDataIndex(tracker2.Data().Row(ic2.RowIndex()), ic2.HitIndex()); hits2[ic2.RowIndex()] = clusterIndex; } @@ -276,7 +276,7 @@ inline void GPUTPCGMMerger::MergedTrackStreamerInternal(const GPUTPCGMBorderTrac #endif } -void GPUTPCGMMerger::MergedTrackStreamer(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int slice1, int slice2, int mergeMode, float weight, float frac) const +void GPUTPCGMMerger::MergedTrackStreamer(const GPUTPCGMBorderTrack& b1, const GPUTPCGMBorderTrack& b2, const char* name, int32_t slice1, int32_t slice2, int32_t mergeMode, float weight, float frac) const { #ifdef DEBUG_STREAMER if (mergeMode == 0) { @@ -287,9 +287,9 @@ void GPUTPCGMMerger::MergedTrackStreamer(const GPUTPCGMBorderTrack& b1, const GP #endif } -const GPUTPCGMBorderTrack& GPUTPCGMMerger::MergedTrackStreamerFindBorderTrack(const GPUTPCGMBorderTrack* tracks, int N, int trackId) const +const GPUTPCGMBorderTrack& GPUTPCGMMerger::MergedTrackStreamerFindBorderTrack(const GPUTPCGMBorderTrack* tracks, int32_t N, int32_t trackId) const { - for (int i = 0; i < N; i++) { + for (int32_t i = 0; i < N; i++) { if (tracks[i].TrackID() == trackId) { return tracks[i]; } @@ -305,7 +305,7 @@ void GPUTPCGMMerger::DebugRefitMergedTrack(const GPUTPCGMMergedTrack& track) con ((GPUConstantMem*)GetConstantMem())->ioPtrs.mergedTrackHitStates = ClusterStateExt(); ((GPUConstantMem*)GetConstantMem())->ioPtrs.mergedTrackHits = Clusters(); refit.SetPtrsFromGPUConstantMem(GetConstantMem()); - int retval = refit.RefitTrackAsGPU(trk, false, true); + int32_t retval = refit.RefitTrackAsGPU(trk, false, true); if (retval > 0) { GPUTPCGMPropagator prop; prop.SetMaterialTPC(); @@ -314,7 +314,7 @@ void GPUTPCGMMerger::DebugRefitMergedTrack(const GPUTPCGMMergedTrack& track) con prop.SetPropagateBzOnly(false); prop.SetMatLUT(Param().rec.useMatLUT ? GetConstantMem()->calibObjects.matLUT : nullptr); prop.SetTrack(&trk.Param(), trk.GetAlpha()); - int err = prop.PropagateToXAlpha(track.GetParam().GetX(), track.GetAlpha(), false); + int32_t err = prop.PropagateToXAlpha(track.GetParam().GetX(), track.GetAlpha(), false); if (err == 0) { printf("REFIT RESULT %d, SnpDiff %f\n", retval, trk.GetParam().GetSinPhi() - track.GetParam().GetSinPhi()); if (retval > 20 && fabsf(trk.GetParam().GetSinPhi() - track.GetParam().GetSinPhi()) > 0.01f) { @@ -329,21 +329,21 @@ void GPUTPCGMMerger::DebugRefitMergedTrack(const GPUTPCGMMergedTrack& track) con #endif } -std::vector GPUTPCGMMerger::StreamerOccupancyBin(int iSlice, int iRow, float time) const +std::vector GPUTPCGMMerger::StreamerOccupancyBin(int32_t iSlice, int32_t iRow, float time) const { - static int size = getenv("O2_DEBUG_STREAMER_OCCUPANCY_NBINS") ? atoi(getenv("O2_DEBUG_STREAMER_OCCUPANCY_NBINS")) : Param().rec.tpc.occupancyMapTimeBinsAverage; - std::vector retVal(1 + 2 * size); + static int32_t size = getenv("O2_DEBUG_STREAMER_OCCUPANCY_NBINS") ? atoi(getenv("O2_DEBUG_STREAMER_OCCUPANCY_NBINS")) : Param().rec.tpc.occupancyMapTimeBinsAverage; + std::vector retVal(1 + 2 * size); #ifdef DEBUG_STREAMER - const int bin = CAMath::Max(0.f, time / Param().rec.tpc.occupancyMapTimeBins); - for (int i = 0; i < 1 + 2 * size; i++) { - const int mybin = bin + i - size; - retVal[i] = (mybin >= 0 && mybin < (int)GPUTPCClusterOccupancyMapBin::getNBins(Param())) ? Param().occupancyMap[mybin] : 0; + const int32_t bin = CAMath::Max(0.f, time / Param().rec.tpc.occupancyMapTimeBins); + for (int32_t i = 0; i < 1 + 2 * size; i++) { + const int32_t mybin = bin + i - size; + retVal[i] = (mybin >= 0 && mybin < (int32_t)GPUTPCClusterOccupancyMapBin::getNBins(Param())) ? Param().occupancyMap[mybin] : 0; } #endif return retVal; } -std::vector GPUTPCGMMerger::StreamerUncorrectedZY(int iSlice, int iRow, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop) const +std::vector GPUTPCGMMerger::StreamerUncorrectedZY(int32_t iSlice, int32_t iRow, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop) const { std::vector retVal(2); #ifdef DEBUG_STREAMER @@ -352,17 +352,17 @@ std::vector GPUTPCGMMerger::StreamerUncorrectedZY(int iSlice, int iRow, c return retVal; } -void GPUTPCGMMerger::DebugStreamerUpdate(int iTrk, int ihit, float xx, float yy, float zz, const GPUTPCGMMergedTrackHit& cluster, const o2::tpc::ClusterNative& clusterNative, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop, const gputpcgmmergertypes::InterpolationErrorHit& interpolation, char rejectChi2, bool refit, int retVal, float avgInvCharge, float posY, float posZ, short clusterState, int retValReject, float err2Y, float err2Z) const +void GPUTPCGMMerger::DebugStreamerUpdate(int32_t iTrk, int32_t ihit, float xx, float yy, float zz, const GPUTPCGMMergedTrackHit& cluster, const o2::tpc::ClusterNative& clusterNative, const GPUTPCGMTrackParam& track, const GPUTPCGMPropagator& prop, const gputpcgmmergertypes::InterpolationErrorHit& interpolation, int8_t rejectChi2, bool refit, int32_t retVal, float avgInvCharge, float posY, float posZ, int16_t clusterState, int32_t retValReject, float err2Y, float err2Z) const { #ifdef DEBUG_STREAMER float time = clusterNative.getTime(); auto occupancyBins = StreamerOccupancyBin(cluster.slice, cluster.row, time); auto uncorrectedYZ = StreamerUncorrectedZY(cluster.slice, cluster.row, track, prop); float invCharge = 1.f / clusterNative.qMax; - int iRow = cluster.row; + int32_t iRow = cluster.row; float unscaledMult = (time >= 0.f ? Param().GetUnscaledMult(time) / Param().tpcGeometry.Row2X(iRow) : 0.f); const float clAlpha = Param().Alpha(cluster.slice); - unsigned int occupancyTotal = Param().occupancyTotal; + uint32_t occupancyTotal = Param().occupancyTotal; o2::utils::DebugStreamer::instance()->getStreamer("debug_update_track", "UPDATE") << o2::utils::DebugStreamer::instance()->getUniqueTreeName("tree_update_track").data() << "iTrk=" << iTrk << "ihit=" << ihit diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx index e7f9e7dbf3385..103fc0a4a08cc 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.cxx @@ -22,45 +22,45 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCGMMergerTrackFit::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int mode) +GPUdii() void GPUTPCGMMergerTrackFit::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t mode) { - const int iEnd = mode == -1 ? merger.Memory()->nRetryRefit : merger.NOutputTracks(); + const int32_t iEnd = mode == -1 ? merger.Memory()->nRetryRefit : merger.NOutputTracks(); GPUCA_OPENMP(parallel for if(!merger.GetRec().GetProcessingSettings().ompKernels) num_threads(merger.GetRec().GetProcessingSettings().ompThreads)) - for (int ii = get_global_id(0); ii < iEnd; ii += get_global_size(0)) { - const int i = mode == -1 ? merger.RetryRefitIds()[ii] : mode ? merger.TrackOrderProcess()[ii] : ii; + for (int32_t ii = get_global_id(0); ii < iEnd; ii += get_global_size(0)) { + const int32_t i = mode == -1 ? merger.RetryRefitIds()[ii] : mode ? merger.TrackOrderProcess()[ii] : ii; GPUTPCGMTrackParam::RefitTrack(merger.OutputTracks()[i], i, &merger, mode == -1); } } template <> -GPUdii() void GPUTPCGMMergerFollowLoopers::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerFollowLoopers::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { GPUCA_OPENMP(parallel for if(!merger.GetRec().GetProcessingSettings().ompKernels) num_threads(merger.GetRec().GetProcessingSettings().ompThreads)) - for (unsigned int i = get_global_id(0); i < merger.Memory()->nLoopData; i += get_global_size(0)) { + for (uint32_t i = get_global_id(0); i < merger.Memory()->nLoopData; i += get_global_size(0)) { GPUTPCGMTrackParam::RefitLoop(&merger, i); } } template <> -GPUdii() void GPUTPCGMMergerUnpackResetIds::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice) +GPUdii() void GPUTPCGMMergerUnpackResetIds::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice) { merger.UnpackResetIds(nBlocks, nThreads, iBlock, iThread, iSlice); } template <> -GPUdii() void GPUTPCGMMergerSliceRefit::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice) +GPUdii() void GPUTPCGMMergerSliceRefit::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice) { merger.RefitSliceTracks(nBlocks, nThreads, iBlock, iThread, iSlice); } template <> -GPUdii() void GPUTPCGMMergerUnpackGlobal::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice) +GPUdii() void GPUTPCGMMergerUnpackGlobal::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice) { merger.UnpackSliceGlobal(nBlocks, nThreads, iBlock, iThread, iSlice); } template <> -GPUdii() void GPUTPCGMMergerUnpackSaveNumber::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int id) +GPUdii() void GPUTPCGMMergerUnpackSaveNumber::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t id) { if (iThread == 0 && iBlock == 0) { merger.UnpackSaveNumber(id); @@ -68,155 +68,155 @@ GPUdii() void GPUTPCGMMergerUnpackSaveNumber::Thread<0>(int nBlocks, int nThread } template <> -GPUdii() void GPUTPCGMMergerResolve::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerResolve::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.ResolveFindConnectedComponentsSetup(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerResolve::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerResolve::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.ResolveFindConnectedComponentsHookLinks(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerResolve::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerResolve::Thread<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.ResolveFindConnectedComponentsHookNeighbors(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerResolve::Thread<3>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerResolve::Thread<3>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.ResolveFindConnectedComponentsMultiJump(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerResolve::Thread<4>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char useOrigTrackParam, char mergeAll) +GPUdii() void GPUTPCGMMergerResolve::Thread<4>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t useOrigTrackParam, int8_t mergeAll) { merger.ResolveMergeSlices(smem, nBlocks, nThreads, iBlock, iThread, useOrigTrackParam, mergeAll); } template <> -GPUdii() void GPUTPCGMMergerClearLinks::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char output) +GPUdii() void GPUTPCGMMergerClearLinks::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t output) { merger.ClearTrackLinks(nBlocks, nThreads, iBlock, iThread, output); } template <> -GPUdii() void GPUTPCGMMergerMergeWithinPrepare::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerMergeWithinPrepare::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.MergeWithinSlicesPrepare(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerMergeSlicesPrepare::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int border0, int border1, char useOrigTrackParam) +GPUdii() void GPUTPCGMMergerMergeSlicesPrepare::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t border0, int32_t border1, int8_t useOrigTrackParam) { merger.MergeSlicesPrepare(nBlocks, nThreads, iBlock, iThread, border0, border1, useOrigTrackParam); } -template -GPUdii() void GPUTPCGMMergerMergeBorders::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, Args... args) +template +GPUdii() void GPUTPCGMMergerMergeBorders::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, Args... args) { merger.MergeBorderTracks(nBlocks, nThreads, iBlock, iThread, args...); } #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. -template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); -template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode); -template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<3>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int N, int cmpMax); +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice, int8_t withinSlice, int8_t mergeMode); +template GPUdni() void GPUTPCGMMergerMergeBorders::Thread<3>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, gputpcgmmergertypes::GPUTPCGMBorderRange* range, int32_t N, int32_t cmpMax); #endif template <> -GPUdii() void GPUTPCGMMergerMergeBorders::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int iSlice, char withinSlice, char mergeMode) +GPUdii() void GPUTPCGMMergerMergeBorders::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int32_t iSlice, int8_t withinSlice, int8_t mergeMode) { merger.MergeBorderTracks<1>(2, nThreads, iBlock & 1, iThread, iBlock / 2, withinSlice, mergeMode); } template <> -GPUdii() void GPUTPCGMMergerMergeCE::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerMergeCE::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.MergeCE(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerLinkGlobalTracks::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerLinkGlobalTracks::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.LinkGlobalTracks(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerCollect::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerCollect::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.CollectMergedTracks(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerSortTracks::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerSortTracks::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.SortTracks(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerSortTracksQPt::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerSortTracksQPt::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.SortTracksQPt(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerSortTracksPrepare::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerSortTracksPrepare::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.SortTracksPrepare(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.PrepareClustersForFit0(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.PrepareClustersForFit1(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerPrepareClusters::Thread<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.PrepareClustersForFit2(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerFinalize::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerFinalize::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.Finalize0(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerFinalize::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerFinalize::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.Finalize1(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerFinalize::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerFinalize::Thread<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.Finalize2(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.MergeLoopersInit(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.MergeLoopersSort(nBlocks, nThreads, iBlock, iThread); } template <> -GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<2>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMMergerMergeLoopers::Thread<2>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { merger.MergeLoopersMain(nBlocks, nThreads, iBlock, iThread); } diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.h b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.h index d1865144e4ecc..1d5d445a7de67 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergerGPU.h @@ -40,8 +40,8 @@ class GPUTPCGMMergerTrackFit : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int mode); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t mode); #endif }; @@ -49,8 +49,8 @@ class GPUTPCGMMergerFollowLoopers : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -58,8 +58,8 @@ class GPUTPCGMMergerSliceRefit : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int iSlice); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t iSlice); #endif }; @@ -67,8 +67,8 @@ class GPUTPCGMMergerUnpackGlobal : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int iSlice); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t iSlice); #endif }; @@ -76,8 +76,8 @@ class GPUTPCGMMergerUnpackSaveNumber : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int id); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t id); #endif }; @@ -85,8 +85,8 @@ class GPUTPCGMMergerUnpackResetIds : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int id); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t id); #endif }; @@ -97,8 +97,8 @@ class GPUTPCGMMergerResolve : public GPUTPCGMMergerGeneral }; #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); #endif }; @@ -106,8 +106,8 @@ class GPUTPCGMMergerClearLinks : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, char nOutput); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int8_t nOutput); #endif }; @@ -115,8 +115,8 @@ class GPUTPCGMMergerMergeWithinPrepare : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -124,8 +124,8 @@ class GPUTPCGMMergerMergeSlicesPrepare : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int border0, int border1, char useOrigTrackParam); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, int32_t border0, int32_t border1, int8_t useOrigTrackParam); #endif }; @@ -138,8 +138,8 @@ class GPUTPCGMMergerMergeBorders : public GPUTPCGMMergerGeneral step2 = 2, variant = 3 }; #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger, Args... args); #endif }; @@ -147,8 +147,8 @@ class GPUTPCGMMergerMergeCE : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -156,8 +156,8 @@ class GPUTPCGMMergerLinkGlobalTracks : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -165,8 +165,8 @@ class GPUTPCGMMergerCollect : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -174,8 +174,8 @@ class GPUTPCGMMergerPrepareClusters : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -183,8 +183,8 @@ class GPUTPCGMMergerSortTracks : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -192,8 +192,8 @@ class GPUTPCGMMergerSortTracksQPt : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -201,8 +201,8 @@ class GPUTPCGMMergerSortTracksPrepare : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -210,8 +210,8 @@ class GPUTPCGMMergerFinalize : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; @@ -219,8 +219,8 @@ class GPUTPCGMMergerMergeLoopers : public GPUTPCGMMergerGeneral { public: #if !defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE) - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); #endif }; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMergerTypes.h b/GPU/GPUTracking/Merger/GPUTPCGMMergerTypes.h index c9b8e15d43925..3cd6870524060 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMMergerTypes.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMMergerTypes.h @@ -43,13 +43,13 @@ struct InterpolationErrors { InterpolationErrorHit hit[GPUCA_MERGER_MAX_TRACK_CLUSTERS]; }; -struct GPUResolveSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { - int iTrack1[GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCGMMergerResolve_step3)]; - int iTrack2[GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCGMMergerResolve_step3)]; +struct GPUResolveSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + int32_t iTrack1[GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCGMMergerResolve_step3)]; + int32_t iTrack2[GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCGMMergerResolve_step3)]; }; struct GPUTPCGMBorderRange { - int fId; + int32_t fId; float fMin, fMax; }; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx index de9b0aa0a2038..203968e091014 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx @@ -31,29 +31,29 @@ using namespace o2::gpu; using namespace o2::tpc; using namespace o2::tpc::constants; -GPUdi() static constexpr unsigned char getFlagsReject() { return GPUTPCGMMergedTrackHit::flagReject | GPUTPCGMMergedTrackHit::flagNotFit; } -GPUdi() static unsigned int getFlagsRequired(const GPUSettingsRec& rec) { return rec.tpc.dropSecondaryLegsInOutput ? gputpcgmmergertypes::attachGoodLeg : gputpcgmmergertypes::attachZero; } +GPUdi() static constexpr uint8_t getFlagsReject() { return GPUTPCGMMergedTrackHit::flagReject | GPUTPCGMMergedTrackHit::flagNotFit; } +GPUdi() static uint32_t getFlagsRequired(const GPUSettingsRec& rec) { return rec.tpc.dropSecondaryLegsInOutput ? gputpcgmmergertypes::attachGoodLeg : gputpcgmmergertypes::attachZero; } template <> -GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMO2Output::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { const GPUTPCGMMergedTrack* tracks = merger.OutputTracks(); - const unsigned int nTracks = merger.NOutputTracks(); + const uint32_t nTracks = merger.NOutputTracks(); const GPUTPCGMMergedTrackHit* trackClusters = merger.Clusters(); const GPUdEdxInfo* tracksdEdx = merger.OutputTracksdEdx(); - constexpr unsigned char flagsReject = getFlagsReject(); - const unsigned int flagsRequired = getFlagsRequired(merger.Param().rec); + constexpr uint8_t flagsReject = getFlagsReject(); + const uint32_t flagsRequired = getFlagsRequired(merger.Param().rec); bool cutOnTrackdEdx = merger.Param().par.dodEdx && merger.Param().dodEdxDownscaled && merger.Param().rec.tpc.minTrackdEdxMax2Tot > 0.f; GPUTPCGMMerger::tmpSort* GPUrestrict() trackSort = merger.TrackSortO2(); uint2* GPUrestrict() tmpData = merger.ClusRefTmp(); - for (unsigned int i = get_global_id(0); i < nTracks; i += get_global_size(0)) { + for (uint32_t i = get_global_id(0); i < nTracks; i += get_global_size(0)) { if (!tracks[i].OK()) { continue; } - unsigned int nCl = 0; - for (unsigned int j = 0; j < tracks[i].NClusters(); j++) { + uint32_t nCl = 0; + for (uint32_t j = 0; j < tracks[i].NClusters(); j++) { if ((trackClusters[tracks[i].FirstClusterRef() + j].state & flagsReject) || (merger.ClusterAttachment()[trackClusters[tracks[i].FirstClusterRef() + j].num] & flagsRequired) != flagsRequired) { continue; } @@ -68,20 +68,20 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, i if (merger.Param().rec.tpc.dropSecondaryLegsInOutput && nCl + 2 < GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tracks[i].GetParam().GetQPt() * merger.Param().qptB5Scaler)) { // Give 2 hits tolerance in the primary leg, compared to the full fit of the looper continue; } - if (merger.Param().rec.tpc.minNClustersFinalTrack != -1 && nCl < (unsigned int)merger.Param().rec.tpc.minNClustersFinalTrack) { + if (merger.Param().rec.tpc.minNClustersFinalTrack != -1 && nCl < (uint32_t)merger.Param().rec.tpc.minNClustersFinalTrack) { continue; } if (cutOnTrackdEdx && (tracksdEdx[i].dEdxMaxTPC < merger.Param().rec.tpc.minTrackdEdxMax || tracksdEdx[i].dEdxMaxTPC < tracksdEdx[i].dEdxTotTPC * merger.Param().rec.tpc.minTrackdEdxMax2Tot) && !(tracksdEdx[i].dEdxMaxTPC == 0 && CAMath::Abs(tracks[i].GetParam().GetDzDs()) > 0.03f)) { continue; } - unsigned int myId = CAMath::AtomicAdd(&merger.Memory()->nO2Tracks, 1u); + uint32_t myId = CAMath::AtomicAdd(&merger.Memory()->nO2Tracks, 1u); tmpData[i] = {nCl, CAMath::AtomicAdd(&merger.Memory()->nO2ClusRefs, nCl + (nCl + 1) / 2)}; trackSort[myId] = {i, (merger.Param().par.earlyTpcTransform || tracks[i].CSide()) ? tracks[i].GetParam().GetTZOffset() : -tracks[i].GetParam().GetTZOffset()}; } } template <> -GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMO2Output::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { #ifndef GPUCA_SPECIALIZE_THRUST_SORTS if (iThread || iBlock) { @@ -111,25 +111,25 @@ inline void GPUCA_KRNL_BACKEND_CLASS::runKernelBackendInternal template <> -GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMO2Output::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { constexpr float MinDelta = 0.1f; const GPUTPCGMMergedTrack* tracks = merger.OutputTracks(); GPUdEdxInfo* tracksdEdx = merger.OutputTracksdEdx(); - const int nTracks = merger.NOutputTracksTPCO2(); + const int32_t nTracks = merger.NOutputTracksTPCO2(); const GPUTPCGMMergedTrackHit* trackClusters = merger.Clusters(); - constexpr unsigned char flagsReject = getFlagsReject(); - const unsigned int flagsRequired = getFlagsRequired(merger.Param().rec); + constexpr uint8_t flagsReject = getFlagsReject(); + const uint32_t flagsRequired = getFlagsRequired(merger.Param().rec); TrackTPC* outputTracks = merger.OutputTracksTPCO2(); - unsigned int* clusRefs = merger.OutputClusRefsTPCO2(); + uint32_t* clusRefs = merger.OutputClusRefsTPCO2(); GPUTPCGMMerger::tmpSort* GPUrestrict() trackSort = merger.TrackSortO2(); uint2* GPUrestrict() tmpData = merger.ClusRefTmp(); float const SNPThresh = 0.999990f; - for (int iTmp = get_global_id(0); iTmp < nTracks; iTmp += get_global_size(0)) { + for (int32_t iTmp = get_global_id(0); iTmp < nTracks; iTmp += get_global_size(0)) { TrackTPC oTrack; - const int i = trackSort[iTmp].x; + const int32_t i = trackSort[iTmp].x; auto snpIn = tracks[i].GetParam().GetSinPhi(); if (snpIn > SNPThresh) { snpIn = SNPThresh; @@ -174,28 +174,28 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in oTrack.getParamOut().setPID(pid, true); } - unsigned int nOutCl = tmpData[i].x; - unsigned int clBuff = tmpData[i].y; + uint32_t nOutCl = tmpData[i].x; + uint32_t clBuff = tmpData[i].y; oTrack.setClusterRef(clBuff, nOutCl); - unsigned int* clIndArr = &clusRefs[clBuff]; - unsigned char* sectorIndexArr = reinterpret_cast(clIndArr + nOutCl); - unsigned char* rowIndexArr = sectorIndexArr + nOutCl; + uint32_t* clIndArr = &clusRefs[clBuff]; + uint8_t* sectorIndexArr = reinterpret_cast(clIndArr + nOutCl); + uint8_t* rowIndexArr = sectorIndexArr + nOutCl; - unsigned int nOutCl2 = 0; + uint32_t nOutCl2 = 0; float t1 = 0, t2 = 0; - int sector1 = 0, sector2 = 0; + int32_t sector1 = 0, sector2 = 0; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem()->ioPtrs.clustersNative; - for (unsigned int j = 0; j < tracks[i].NClusters(); j++) { + for (uint32_t j = 0; j < tracks[i].NClusters(); j++) { if ((trackClusters[tracks[i].FirstClusterRef() + j].state & flagsReject) || (merger.ClusterAttachment()[trackClusters[tracks[i].FirstClusterRef() + j].num] & flagsRequired) != flagsRequired) { continue; } if (merger.Param().rec.tpc.dropSecondaryLegsInOutput && trackClusters[tracks[i].FirstClusterRef() + j].leg != trackClusters[tracks[i].FirstClusterRef() + tracks[i].NClusters() - 1].leg) { continue; } - int clusterIdGlobal = trackClusters[tracks[i].FirstClusterRef() + j].num; - int sector = trackClusters[tracks[i].FirstClusterRef() + j].slice; - int globalRow = trackClusters[tracks[i].FirstClusterRef() + j].row; - int clusterIdInRow = clusterIdGlobal - clusters->clusterOffset[sector][globalRow]; + int32_t clusterIdGlobal = trackClusters[tracks[i].FirstClusterRef() + j].num; + int32_t sector = trackClusters[tracks[i].FirstClusterRef() + j].slice; + int32_t globalRow = trackClusters[tracks[i].FirstClusterRef() + j].row; + int32_t clusterIdInRow = clusterIdGlobal - clusters->clusterOffset[sector][globalRow]; clIndArr[nOutCl2] = clusterIdInRow; sectorIndexArr[nOutCl2] = sector; rowIndexArr[nOutCl2] = globalRow; @@ -216,7 +216,7 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in if (cce) { bool lastSide = trackClusters[tracks[i].FirstClusterRef()].slice < MAXSECTOR / 2; float delta = 0.f; - for (unsigned int iCl = 1; iCl < tracks[i].NClusters(); iCl++) { + for (uint32_t iCl = 1; iCl < tracks[i].NClusters(); iCl++) { auto& cacl1 = trackClusters[tracks[i].FirstClusterRef() + iCl]; if (lastSide ^ (cacl1.slice < MAXSECTOR / 2)) { auto& cl1 = clusters->clustersLinear[cacl1.num]; @@ -270,7 +270,7 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, in } template <> -GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) +GPUdii() void GPUTPCGMO2Output::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger) { #ifndef GPUCA_GPUCODE const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem()->ioPtrs.clustersNative; @@ -282,15 +282,15 @@ GPUdii() void GPUTPCGMO2Output::Thread(int nBlocks, int nT } auto labelAssigner = GPUTPCTrkLbl(clusters->clustersMCTruth, 0.1f); - unsigned int* clusRefs = merger.OutputClusRefsTPCO2(); - for (unsigned int i = get_global_id(0); i < merger.NOutputTracksTPCO2(); i += get_global_size(0)) { + uint32_t* clusRefs = merger.OutputClusRefsTPCO2(); + for (uint32_t i = get_global_id(0); i < merger.NOutputTracksTPCO2(); i += get_global_size(0)) { labelAssigner.reset(); const auto& trk = merger.OutputTracksTPCO2()[i]; - for (int j = 0; j < trk.getNClusters(); j++) { + for (int32_t j = 0; j < trk.getNClusters(); j++) { uint8_t sectorIndex, rowIndex; uint32_t clusterIndex; trk.getClusterReference(clusRefs, j, sectorIndex, rowIndex, clusterIndex); - unsigned int clusterIdGlobal = clusters->clusterOffset[sectorIndex][rowIndex] + clusterIndex; + uint32_t clusterIdGlobal = clusters->clusterOffset[sectorIndex][rowIndex] + clusterIndex; labelAssigner.addLabel(clusterIdGlobal); } merger.OutputTracksTPCO2MC()[i] = labelAssigner.computeLabel(); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.h b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.h index 42a7f2197f0cd..a5a9869c2061a 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMO2Output.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMO2Output.h @@ -30,8 +30,8 @@ class GPUTPCGMO2Output : public GPUTPCGMMergerGeneral sort = 1, output = 2, mc = 3 }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& merger); }; } // namespace gpu diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.cxx b/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.cxx index f9580bd6fe352..b33392cd27db1 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.cxx @@ -17,13 +17,13 @@ using namespace GPUCA_NAMESPACE::gpu; -GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBzLight(float x, float Bz, float& GPUrestrict() dLp) +GPUd() int32_t GPUTPCGMPhysicalTrackModel::PropagateToXBzLight(float x, float Bz, float& GPUrestrict() dLp) { GPUTPCGMPhysicalTrackModel t = *this; if (CAMath::Abs(x - t.X()) < 1.e-8f) { return 0; } - int err = t.PropagateToXBzLightNoUpdate(x, Bz, dLp); + int32_t err = t.PropagateToXBzLightNoUpdate(x, Bz, dLp); if (err) { return (err); } @@ -32,7 +32,7 @@ GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBzLight(float x, float Bz, fl return 0; } -GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBzLightNoUpdate(float x, float Bz, float& GPUrestrict() dLp) +GPUd() int32_t GPUTPCGMPhysicalTrackModel::PropagateToXBzLightNoUpdate(float x, float Bz, float& GPUrestrict() dLp) { // // transport the track to X=x in magnetic field B = ( 0, 0, Bz[kG*0.000299792458f] ) @@ -86,7 +86,7 @@ GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBzLightNoUpdate(float x, floa return 0; } -GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBxByBz(float x, float Bx, float By, float Bz, float& GPUrestrict() dLp) +GPUd() int32_t GPUTPCGMPhysicalTrackModel::PropagateToXBxByBz(float x, float Bx, float By, float Bz, float& GPUrestrict() dLp) { // // transport the track to X=x in magnetic field B = ( Bx, By, Bz )[kG*0.000299792458f] @@ -185,7 +185,7 @@ GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToXBxByBz(float x, float Bx, flo return 0; } -GPUd() int GPUTPCGMPhysicalTrackModel::PropagateToLpBz(float Lp, float Bz) +GPUd() int32_t GPUTPCGMPhysicalTrackModel::PropagateToLpBz(float Lp, float Bz) { // Lp is path length L over track momentum p in [cm/GeV], Bz in kG*clight // diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.h b/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.h index 410ec095f3aba..c77ef99e3790c 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMPhysicalTrackModel.h @@ -122,12 +122,12 @@ class GPUTPCGMPhysicalTrackModel GPUd() float GetP() const { return mP; } GPUd() float GetPt() const { return mPt; } - GPUd() int PropagateToXBzLightNoUpdate(float x, float Bz, float& dLp); - GPUd() int PropagateToXBzLight(float x, float Bz, float& dLp); + GPUd() int32_t PropagateToXBzLightNoUpdate(float x, float Bz, float& dLp); + GPUd() int32_t PropagateToXBzLight(float x, float Bz, float& dLp); - GPUd() int PropagateToXBxByBz(float x, float Bx, float By, float Bz, float& dLp); + GPUd() int32_t PropagateToXBxByBz(float x, float Bx, float By, float Bz, float& dLp); - GPUd() int PropagateToLpBz(float Lp, float Bz); + GPUd() int32_t PropagateToLpBz(float Lp, float Bz); GPUd() bool SetDirectionAlongX(); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.cxx b/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.cxx index bead89aa39d82..c444f3a399aae 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.cxx @@ -19,7 +19,7 @@ using namespace GPUCA_NAMESPACE::gpu; -int GPUTPCGMPolynomialFieldManager::GetPolynomialField(StoredField_t fieldType, float nominalFieldkG, GPUTPCGMPolynomialField& field) +int32_t GPUTPCGMPolynomialFieldManager::GetPolynomialField(StoredField_t fieldType, float nominalFieldkG, GPUTPCGMPolynomialField& field) { // // get pre-calculated polynomial field approximation of the TPC region @@ -27,15 +27,15 @@ int GPUTPCGMPolynomialFieldManager::GetPolynomialField(StoredField_t fieldType, // returns -2 if number of coefficients in GPUTPCGMPolynomialField is not 10 // - const int kTpcM = GPUTPCGMPolynomialField::NTPCM; - const int kTrdM = GPUTPCGMPolynomialField::NTRDM; - const int kItsM = GPUTPCGMPolynomialField::NITSM; + const int32_t kTpcM = GPUTPCGMPolynomialField::NTPCM; + const int32_t kTrdM = GPUTPCGMPolynomialField::NTRDM; + const int32_t kItsM = GPUTPCGMPolynomialField::NITSM; // // polynomial coefficients for the Uniform Bz field // float kSolUBx[100], kSolUBy[100], kSolUBz[100]; - for (int i = 0; i < 100; i++) { + for (int32_t i = 0; i < 100; i++) { kSolUBx[i] = 0; kSolUBy[i] = 0; kSolUBz[i] = 0; @@ -155,21 +155,21 @@ int GPUTPCGMPolynomialFieldManager::GetPolynomialField(StoredField_t fieldType, } float TpcBx[kTpcM], TpcBy[kTpcM], TpcBz[kTpcM]; - for (int i = 0; i < kTpcM; i++) { + for (int32_t i = 0; i < kTpcM; i++) { TpcBx[i] = nominalBz * cTpcBx[i]; TpcBy[i] = nominalBz * cTpcBy[i]; TpcBz[i] = nominalBz * cTpcBz[i]; } float TrdBx[kTrdM], TrdBy[kTrdM], TrdBz[kTrdM]; - for (int i = 0; i < kTrdM; i++) { + for (int32_t i = 0; i < kTrdM; i++) { TrdBx[i] = nominalBz * cTrdBx[i]; TrdBy[i] = nominalBz * cTrdBy[i]; TrdBz[i] = nominalBz * cTrdBz[i]; } float ItsBx[kItsM], ItsBy[kItsM], ItsBz[kItsM]; - for (int i = 0; i < kItsM; i++) { + for (int32_t i = 0; i < kItsM; i++) { ItsBx[i] = nominalBz * cItsBx[i]; ItsBy[i] = nominalBz * cItsBy[i]; ItsBz[i] = nominalBz * cItsBz[i]; @@ -183,7 +183,7 @@ int GPUTPCGMPolynomialFieldManager::GetPolynomialField(StoredField_t fieldType, return 0; } -int GPUTPCGMPolynomialFieldManager::GetPolynomialField(float nominalFieldkG, GPUTPCGMPolynomialField& field) +int32_t GPUTPCGMPolynomialFieldManager::GetPolynomialField(float nominalFieldkG, GPUTPCGMPolynomialField& field) { // // get closest pre-calculated polynomial field approximation of the TPC region for the given field value nominalFieldkG @@ -234,7 +234,7 @@ int GPUTPCGMPolynomialFieldManager::GetPolynomialField(float nominalFieldkG, GPU #include "TH1F.h" #include "TStyle.h" -int GPUTPCGMPolynomialFieldManager::GetPolynomialField(GPUTPCGMPolynomialField& field) +int32_t GPUTPCGMPolynomialFieldManager::GetPolynomialField(GPUTPCGMPolynomialField& field) { // // get pre-calculated polynomial field approximation of the TPC region appropriate for the current AliTracker field map (if exists) @@ -266,7 +266,7 @@ int GPUTPCGMPolynomialFieldManager::GetPolynomialField(GPUTPCGMPolynomialField& return GetPolynomialField(type, AliTracker::GetBz(), field); } -int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) +int32_t GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) { // // Fit magnetic field with polynoms @@ -286,7 +286,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn const double sectorAngleShift = 10. / 180. * TMath::Pi(); const double sectorAngle = 20. / 180. * TMath::Pi(); - const int nRows = AliHLTTPCGeometry::GetNRows(); + const int32_t nRows = AliHLTTPCGeometry::GetNRows(); double xMin = AliHLTTPCGeometry::Row2X(0); double xMax = AliHLTTPCGeometry::Row2X(nRows - 1); @@ -295,7 +295,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn double dA = 1. / rMax; // angular step == 1 cm at outer radius dA *= step; - int nSectorParticles = (int)(sectorAngle / dA); + int32_t nSectorParticles = (int32_t)(sectorAngle / dA); if (nSectorParticles < 1) { nSectorParticles = 1; } @@ -314,12 +314,12 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn std::cout << "solenoidBz = " << solenoidBzkG << " kG" << std::endl; - const int M = GPUTPCGMPolynomialField::NTPCM; + const int32_t M = GPUTPCGMPolynomialField::NTPCM; AliHLTTPCPolynomFit fitBx(M); AliHLTTPCPolynomFit fitBy(M); AliHLTTPCPolynomFit fitBz(M); - for (int sector = 0; sector < 18; sector++) { + for (int32_t sector = 0; sector < 18; sector++) { std::cout << "sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); @@ -327,7 +327,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn for (double al = alMin; al < alMax; al += dA) { std::cout << "angle " << al / TMath::Pi() * 180. << " grad " << std::endl; double tg = TMath::Tan(al); - for (int row = 0; row < AliHLTTPCGeometry::GetNRows(); row++) { + for (int32_t row = 0; row < AliHLTTPCGeometry::GetNRows(); row++) { double xl = AliHLTTPCGeometry::Row2X(row); double yl = xl * tg; double x = xl * cs - yl * ss; @@ -362,9 +362,9 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn float cY[M]; float cZ[M]; - int errX = fitBx.Fit(cX); - int errY = fitBy.Fit(cY); - int errZ = fitBz.Fit(cZ); + int32_t errX = fitBx.Fit(cX); + int32_t errY = fitBy.Fit(cY); + int32_t errZ = fitBz.Fit(cZ); if (errX != 0 || errY != 0 || errZ != 0) { std::cout << "Fit of polynamial field failed!!!: errX " << errX << " errY " << errY << " errZ " << errZ << std::endl; @@ -380,7 +380,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn // scale result double nominalBz = solenoidBzkG * gpu_common_constants::kCLight; - for (int i = 0; i < M; i++) { + for (int32_t i = 0; i < M; i++) { cX[i] = nominalBz * cX[i]; cY[i] = nominalBz * cY[i]; cZ[i] = nominalBz * cZ[i]; @@ -394,7 +394,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn TH1F histBy("Performance B_y", "Error B_y", 1000, -0.005, 0.005); TH1F histBz("Performance B_z", "Error B_z", 1000, -0.005, 0.005); - for (int sector = 0; sector < 18; sector++) { + for (int32_t sector = 0; sector < 18; sector++) { std::cout << "check quality: sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); @@ -402,7 +402,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn for (double al = alMin; al < alMax; al += dA) { std::cout << "check quality: angle " << al / TMath::Pi() * 180. << " grad " << std::endl; double tg = TMath::Tan(al); - for (int row = 0; row < AliHLTTPCGeometry::GetNRows(); row++) { + for (int32_t row = 0; row < AliHLTTPCGeometry::GetNRows(); row++) { double xl = AliHLTTPCGeometry::Row2X(row); double yl = xl * tg; double x = xl * cs - yl * ss; @@ -446,7 +446,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTpc(AliMagF* inputFld, GPUTPCGMPolyn return 0; } -int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) +int32_t GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) { // // Fit magnetic field with polynoms @@ -476,7 +476,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn double dA = 1. / rMax; // angular step == 1 cm at outer radius dA *= step; - int nSectorParticles = (int)(sectorAngle / dA); + int32_t nSectorParticles = (int32_t)(sectorAngle / dA); if (nSectorParticles < 1) { nSectorParticles = 1; } @@ -492,12 +492,12 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn std::cout << "solenoidBz = " << solenoidBzkG << " kG" << std::endl; - const int M = GPUTPCGMPolynomialField::NTRDM; + const int32_t M = GPUTPCGMPolynomialField::NTRDM; AliHLTTPCPolynomFit fitBx(M); AliHLTTPCPolynomFit fitBy(M); AliHLTTPCPolynomFit fitBz(M); - for (int sector = 0; sector < AliTRDgeometry::Nsector(); sector++) { + for (int32_t sector = 0; sector < AliTRDgeometry::Nsector(); sector++) { std::cout << "sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); @@ -538,9 +538,9 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn float cY[M]; float cZ[M]; - int errX = fitBx.Fit(cX); - int errY = fitBy.Fit(cY); - int errZ = fitBz.Fit(cZ); + int32_t errX = fitBx.Fit(cX); + int32_t errY = fitBy.Fit(cY); + int32_t errZ = fitBz.Fit(cZ); if (errX != 0 || errY != 0 || errZ != 0) { std::cout << "Fit of polynamial field failed!!!" << std::endl; @@ -556,7 +556,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn // scale result double nominalBz = solenoidBzkG * gpu_common_constants::kCLight; - for (int i = 0; i < M; i++) { + for (int32_t i = 0; i < M; i++) { cX[i] = nominalBz * cX[i]; cY[i] = nominalBz * cY[i]; cZ[i] = nominalBz * cZ[i]; @@ -570,7 +570,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn TH1F histBy("Performance B_y", "Error B_y", 1000, -0.005, 0.005); TH1F histBz("Performance B_z", "Error B_z", 1000, -0.005, 0.005); - for (int sector = 0; sector < AliTRDgeometry::Nsector(); sector++) { + for (int32_t sector = 0; sector < AliTRDgeometry::Nsector(); sector++) { std::cout << "check quality: sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); @@ -621,7 +621,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldTrd(AliMagF* inputFld, GPUTPCGMPolyn return 0; } -int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) +int32_t GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolynomialField& polyField, double step) { // // Fit magnetic field with polynoms @@ -652,7 +652,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolyn double dA = .1 / rMax; // angular step == 0.1 cm at the outer radius dA *= step; - int nSectorParticles = (int)(sectorAngle / dA); + int32_t nSectorParticles = (int32_t)(sectorAngle / dA); if (nSectorParticles < 1) { nSectorParticles = 1; } @@ -672,14 +672,14 @@ int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolyn std::cout << "solenoidBz = " << solenoidBzkG << " kG" << std::endl; - const int M = GPUTPCGMPolynomialField::NITSM; + const int32_t M = GPUTPCGMPolynomialField::NITSM; AliHLTTPCPolynomFit fitBx(M); AliHLTTPCPolynomFit fitBy(M); AliHLTTPCPolynomFit fitBz(M); double coneSlope = (zMax - zITS) / (xMax - xITS); - for (int sector = 0; sector < 18; sector++) { + for (int32_t sector = 0; sector < 18; sector++) { std::cout << "sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); @@ -723,9 +723,9 @@ int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolyn float cY[M]; float cZ[M]; - int errX = fitBx.Fit(cX); - int errY = fitBy.Fit(cY); - int errZ = fitBz.Fit(cZ); + int32_t errX = fitBx.Fit(cX); + int32_t errY = fitBy.Fit(cY); + int32_t errZ = fitBz.Fit(cZ); if (errX != 0 || errY != 0 || errZ != 0) { std::cout << "Fit of polynamial field failed!!!: errX " << errX << " errY " << errY << " errZ " << errZ << std::endl; @@ -741,7 +741,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolyn // scale result double nominalBz = solenoidBzkG * gpu_common_constants::kCLight; - for (int i = 0; i < M; i++) { + for (int32_t i = 0; i < M; i++) { cX[i] = nominalBz * cX[i]; cY[i] = nominalBz * cY[i]; cZ[i] = nominalBz * cZ[i]; @@ -755,7 +755,7 @@ int GPUTPCGMPolynomialFieldManager::FitFieldIts(AliMagF* inputFld, GPUTPCGMPolyn TH1F histBy("Performance B_y", "Error B_y", 1000, -0.005, 0.005); TH1F histBz("Performance B_z", "Error B_z", 1000, -0.005, 0.005); - for (int sector = 0; sector < 18; sector++) { + for (int32_t sector = 0; sector < 18; sector++) { std::cout << "check quality: sector = " << sector << std::endl; double asec = sectorAngleShift + sector * sectorAngle; double cs = TMath::Cos(asec); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.h b/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.h index 38651d8dfdee3..59f9cfcacb3d6 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMPolynomialFieldManager.h @@ -43,31 +43,31 @@ class GPUTPCGMPolynomialFieldManager /* Get appropriate pre-calculated polynomial field for the given field value nominalFieldkG */ - static int GetPolynomialField(float nominalFieldkG, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); + static int32_t GetPolynomialField(float nominalFieldkG, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); #if defined(GPUCA_ALIROOT_LIB) & !defined(GPUCA_GPUCODE) /* Get pre-calculated polynomial field for the current ALICE field (if exists) */ - static int GetPolynomialField(GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); + static int32_t GetPolynomialField(GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); /* Fit given field for TPC */ - static int FitFieldTpc(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); + static int32_t FitFieldTpc(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); /* Fit given field for TRD */ - static int FitFieldTrd(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); + static int32_t FitFieldTrd(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); /* Fit given field for ITS */ - static int FitFieldIts(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); + static int32_t FitFieldIts(AliMagF* fld, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field, double step = 1.); #endif /* Get pre-calculated polynomial field of type "type", scaled with respect to nominalFieldkG */ - static int GetPolynomialField(StoredField_t type, float nominalFieldkG, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); + static int32_t GetPolynomialField(StoredField_t type, float nominalFieldkG, GPUCA_NAMESPACE::gpu::GPUTPCGMPolynomialField& field); }; #endif diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPropagator.cxx b/GPU/GPUTracking/Merger/GPUTPCGMPropagator.cxx index 2362213d52fb0..32941e032019c 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPropagator.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMPropagator.cxx @@ -113,7 +113,7 @@ GPUd() float GPUTPCGMPropagator::GetBzBase(float cosAlpha, float sinAlpha, float #endif } -GPUd() int GPUTPCGMPropagator::RotateToAlpha(float newAlpha) +GPUd() int32_t GPUTPCGMPropagator::RotateToAlpha(float newAlpha) { // // Rotate the track coordinate system in XY to the angle newAlpha @@ -289,7 +289,7 @@ GPUd() int GPUTPCGMPropagator::RotateToAlpha(float newAlpha) return 0; } -GPUd() int GPUTPCGMPropagator::PropagateToXAlpha(float posX, float posAlpha, bool inFlyDirection) +GPUd() int32_t GPUTPCGMPropagator::PropagateToXAlpha(float posX, float posAlpha, bool inFlyDirection) { if (mPropagateBzOnly) { return PropagateToXAlphaBz(posX, posAlpha, inFlyDirection); @@ -322,7 +322,7 @@ GPUd() int GPUTPCGMPropagator::PropagateToXAlpha(float posX, float posAlpha, boo return FollowLinearization(t0e, B[2], dLp, inFlyDirection); } -GPUd() int GPUTPCGMPropagator::PropagateToXAlphaBz(float posX, float posAlpha, bool inFlyDirection) +GPUd() int32_t GPUTPCGMPropagator::PropagateToXAlphaBz(float posX, float posAlpha, bool inFlyDirection) { if (CAMath::Abs(posAlpha - mAlpha) > 1.e-4f) { if (RotateToAlpha(posAlpha) != 0) { @@ -351,7 +351,7 @@ GPUd() int GPUTPCGMPropagator::PropagateToXAlphaBz(float posX, float posAlpha, b return FollowLinearization(t0e, Bz, dLp, inFlyDirection); } -GPUd() int GPUTPCGMPropagator::FollowLinearization(const GPUTPCGMPhysicalTrackModel& GPUrestrict() t0e, float Bz, float dLp, bool inFlyDirection) +GPUd() int32_t GPUTPCGMPropagator::FollowLinearization(const GPUTPCGMPhysicalTrackModel& GPUrestrict() t0e, float Bz, float dLp, bool inFlyDirection) { // t0e is alrerady extrapolated t0 @@ -563,7 +563,7 @@ GPUd() int GPUTPCGMPropagator::FollowLinearization(const GPUTPCGMPhysicalTrackMo return 0; } -GPUd() int GPUTPCGMPropagator::GetPropagatedYZ(float x, float& GPUrestrict() projY, float& GPUrestrict() projZ) +GPUd() int32_t GPUTPCGMPropagator::GetPropagatedYZ(float x, float& GPUrestrict() projY, float& GPUrestrict() projZ) { float bz = GetBz(mT->X(), mT->Y(), mT->Z()); float k = mT0.QPt() * bz; @@ -598,12 +598,12 @@ GPUd() int GPUTPCGMPropagator::GetPropagatedYZ(float x, float& GPUrestrict() pro return 0; } -GPUd() void GPUTPCGMPropagator::GetErr2(float& GPUrestrict() err2Y, float& GPUrestrict() err2Z, const GPUParam& GPUrestrict() param, float posZ, int iRow, short clusterState, char sector, float time, float avgCharge, float charge) const +GPUd() void GPUTPCGMPropagator::GetErr2(float& GPUrestrict() err2Y, float& GPUrestrict() err2Z, const GPUParam& GPUrestrict() param, float posZ, int32_t iRow, int16_t clusterState, int8_t sector, float time, float avgCharge, float charge) const { GetErr2(err2Y, err2Z, param, mT0.GetSinPhi(), mT0.DzDs(), posZ, mT->GetX(), mT->GetY(), iRow, clusterState, sector, time, avgCharge, charge, mSeedingErrors); } -GPUd() void GPUTPCGMPropagator::GetErr2(float& GPUrestrict() err2Y, float& GPUrestrict() err2Z, const GPUParam& GPUrestrict() param, float snp, float tgl, float posZ, float trackX, float trackY, int iRow, short clusterState, char sector, float time, float avgCharge, float charge, bool seedingErrors) +GPUd() void GPUTPCGMPropagator::GetErr2(float& GPUrestrict() err2Y, float& GPUrestrict() err2Z, const GPUParam& GPUrestrict() param, float snp, float tgl, float posZ, float trackX, float trackY, int32_t iRow, int16_t clusterState, int8_t sector, float time, float avgCharge, float charge, bool seedingErrors) { #ifndef GPUCA_TPC_GEOMETRY_O2 if (seedingErrors) { @@ -622,7 +622,7 @@ GPUd() void GPUTPCGMPropagator::GetErr2(float& GPUrestrict() err2Y, float& GPUre err2Z += statErr2; } -GPUd() float GPUTPCGMPropagator::PredictChi2(float posY, float posZ, int iRow, const GPUParam& GPUrestrict() param, short clusterState, char sector, float time, float avgCharge, float charge) const +GPUd() float GPUTPCGMPropagator::PredictChi2(float posY, float posZ, int32_t iRow, const GPUParam& GPUrestrict() param, int16_t clusterState, int8_t sector, float time, float avgCharge, float charge) const { float err2Y, err2Z; GetErr2(err2Y, err2Z, param, posZ, iRow, clusterState, sector, time, avgCharge, charge); @@ -656,7 +656,7 @@ GPUd() float GPUTPCGMPropagator::PredictChi2(float posY, float posZ, float err2Y } } -GPUd() int GPUTPCGMPropagator::Update(float posY, float posZ, int iRow, const GPUParam& GPUrestrict() param, short clusterState, char rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, bool refit, char sector, float time, float avgInvCharge, float invCharge GPUCA_DEBUG_STREAMER_CHECK(, DebugStreamerVals* debugVals)) +GPUd() int32_t GPUTPCGMPropagator::Update(float posY, float posZ, int32_t iRow, const GPUParam& GPUrestrict() param, int16_t clusterState, int8_t rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, bool refit, int8_t sector, float time, float avgInvCharge, float invCharge GPUCA_DEBUG_STREAMER_CHECK(, DebugStreamerVals* debugVals)) { float err2Y, err2Z; GetErr2(err2Y, err2Z, param, posZ, iRow, clusterState, sector, time, avgInvCharge, invCharge); @@ -666,7 +666,7 @@ GPUd() int GPUTPCGMPropagator::Update(float posY, float posZ, int iRow, const GP if (rejectChi2 == rejectInterReject && inter->errorY < (GPUCA_MERGER_INTERPOLATION_ERROR_TYPE)0) { rejectChi2 = rejectDirect; } else { - int retVal = InterpolateReject(param, posY, posZ, clusterState, rejectChi2, inter, err2Y, err2Z); + int32_t retVal = InterpolateReject(param, posY, posZ, clusterState, rejectChi2, inter, err2Y, err2Z); GPUCA_DEBUG_STREAMER_CHECK(if (debugVals) { debugVals->retVal = retVal; }); if (retVal) { return retVal; @@ -694,7 +694,7 @@ GPUd() int GPUTPCGMPropagator::Update(float posY, float posZ, int iRow, const GP return Update(posY, posZ, clusterState, rejectChi2 == rejectDirect, err2Y, err2Z, ¶m); } -GPUd() int GPUTPCGMPropagator::InterpolateReject(const GPUParam& GPUrestrict() param, float posY, float posZ, short clusterState, char rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, float err2Y, float err2Z) +GPUd() int32_t GPUTPCGMPropagator::InterpolateReject(const GPUParam& GPUrestrict() param, float posY, float posZ, int16_t clusterState, int8_t rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, float err2Y, float err2Z) { float* GPUrestrict() mC = mT->Cov(); float* GPUrestrict() mP = mT->Par(); @@ -761,7 +761,7 @@ GPUd() int GPUTPCGMPropagator::InterpolateReject(const GPUParam& GPUrestrict() p return 0; } -GPUd() int GPUTPCGMPropagator::Update(float posY, float posZ, short clusterState, bool rejectChi2, float err2Y, float err2Z, const GPUParam* GPUrestrict() param) +GPUd() int32_t GPUTPCGMPropagator::Update(float posY, float posZ, int16_t clusterState, bool rejectChi2, float err2Y, float err2Z, const GPUParam* GPUrestrict() param) { float* GPUrestrict() mC = mT->Cov(); float* GPUrestrict() mP = mT->Par(); diff --git a/GPU/GPUTracking/Merger/GPUTPCGMPropagator.h b/GPU/GPUTracking/Merger/GPUTPCGMPropagator.h index f84e6fa413e31..c6a188ced5435 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMPropagator.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMPropagator.h @@ -75,7 +75,7 @@ class GPUTPCGMPropagator }; struct DebugStreamerVals { - int retVal = -100; + int32_t retVal = -100; float err2Y = -1e6f, err2Z = -1e6f; }; @@ -106,18 +106,18 @@ class GPUTPCGMPropagator mT0.Set(*mT); } - GPUd() int RotateToAlpha(float newAlpha); + GPUd() int32_t RotateToAlpha(float newAlpha); - GPUd() int PropagateToXAlpha(float posX, float posAlpha, bool inFlyDirection); + GPUd() int32_t PropagateToXAlpha(float posX, float posAlpha, bool inFlyDirection); - GPUd() int PropagateToXAlphaBz(float posX, float posAlpha, bool inFlyDirection); + GPUd() int32_t PropagateToXAlphaBz(float posX, float posAlpha, bool inFlyDirection); - GPUd() int Update(float posY, float posZ, int iRow, const GPUParam& param, short clusterState, char rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, bool refit, char sideC, float time, float avgInvCharge, float invCharge GPUCA_DEBUG_STREAMER_CHECK(, DebugStreamerVals* debugVals = nullptr)); - GPUd() int Update(float posY, float posZ, short clusterState, bool rejectChi2, float err2Y, float err2Z, const GPUParam* param = nullptr); - GPUd() int InterpolateReject(const GPUParam& param, float posY, float posZ, short clusterState, char rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, float err2Y, float err2Z); - GPUd() float PredictChi2(float posY, float posZ, int iRow, const GPUParam& param, short clusterState, char sideC, float time, float avgCharge, float charge) const; + GPUd() int32_t Update(float posY, float posZ, int32_t iRow, const GPUParam& param, int16_t clusterState, int8_t rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, bool refit, int8_t sideC, float time, float avgInvCharge, float invCharge GPUCA_DEBUG_STREAMER_CHECK(, DebugStreamerVals* debugVals = nullptr)); + GPUd() int32_t Update(float posY, float posZ, int16_t clusterState, bool rejectChi2, float err2Y, float err2Z, const GPUParam* param = nullptr); + GPUd() int32_t InterpolateReject(const GPUParam& param, float posY, float posZ, int16_t clusterState, int8_t rejectChi2, gputpcgmmergertypes::InterpolationErrorHit* inter, float err2Y, float err2Z); + GPUd() float PredictChi2(float posY, float posZ, int32_t iRow, const GPUParam& param, int16_t clusterState, int8_t sideC, float time, float avgCharge, float charge) const; GPUd() float PredictChi2(float posY, float posZ, float err2Y, float err2Z) const; - GPUd() int RejectCluster(float chiY, float chiZ, unsigned char clusterState) + GPUd() int32_t RejectCluster(float chiY, float chiZ, uint8_t clusterState) { if (chiY > 9.f || chiZ > 9.f) { return 2; @@ -141,8 +141,8 @@ class GPUTPCGMPropagator /// Bx,By,Bz in local coordinates rotated to Alpha GPUd() void GetBxByBz(float Alpha, float X, float Y, float Z, float B[3]) const; - GPUd() void GetErr2(float& err2Y, float& err2Z, const GPUParam& param, float posZ, int iRow, short clusterState, char sector, float time, float avgCharge, float charge) const; - GPUd() static void GetErr2(float& err2Y, float& err2Z, const GPUParam& param, float snp, float tgl, float posZ, float trackX, float trackY, int iRow, short clusterState, char sector, float time, float avgCharge, float charge, bool seedingErrors); + GPUd() void GetErr2(float& err2Y, float& err2Z, const GPUParam& param, float posZ, int32_t iRow, int16_t clusterState, int8_t sector, float time, float avgCharge, float charge) const; + GPUd() static void GetErr2(float& err2Y, float& err2Z, const GPUParam& param, float snp, float tgl, float posZ, float trackX, float trackY, int32_t iRow, int16_t clusterState, int8_t sector, float time, float avgCharge, float charge, bool seedingErrors); GPUd() float GetAlpha() const { return mAlpha; } GPUd() void SetAlpha(float v) { mAlpha = v; } @@ -154,7 +154,7 @@ class GPUTPCGMPropagator GPUd() void ChangeDirection(); GPUd() float GetMirroredYModel() const; GPUd() float GetMirroredYTrack() const; - GPUd() int GetPropagatedYZ(float x, float& projY, float& projZ); + GPUd() int32_t GetPropagatedYZ(float x, float& projY, float& projZ); GPUd() bool GetFitInProjections() const { return mFitInProjections; } GPUd() GPUTPCGMPhysicalTrackModel& Model() @@ -165,7 +165,7 @@ class GPUTPCGMPropagator private: GPUd() static float ApproximateBetheBloch(float beta2); - GPUd() int FollowLinearization(const GPUTPCGMPhysicalTrackModel& t0e, float Bz, float dLp, bool inFlyDirection); + GPUd() int32_t FollowLinearization(const GPUTPCGMPhysicalTrackModel& t0e, float Bz, float dLp, bool inFlyDirection); /// Bz in local coordinates rotated to cosAlpha, sinAlpha GPUd() float GetBzBase(float cosAlpha, float sinAlpha, float X, float Y, float Z) const; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx index c452d2f961979..f7f753d8302d9 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.cxx @@ -23,7 +23,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMMerger* merger, const GPUTPCTrack* sliceTr, float alpha, int slice) +GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMMerger* merger, const GPUTPCTrack* sliceTr, float alpha, int32_t slice) { const GPUTPCBaseTrackParam& t = sliceTr->Param(); mOrigTrack = sliceTr; @@ -45,7 +45,7 @@ GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMMerger* merger, const GPUTPCTr mNClusters = sliceTr->NHits(); } -GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMTrackParam& trk, const GPUTPCTrack* sliceTr, float alpha, int slice) +GPUd() void GPUTPCGMSliceTrack::Set(const GPUTPCGMTrackParam& trk, const GPUTPCTrack* sliceTr, float alpha, int32_t slice) { mOrigTrack = sliceTr; mParam.mX = trk.GetX(); @@ -92,7 +92,7 @@ GPUd() void GPUTPCGMSliceTrack::SetParam2(const GPUTPCGMTrackParam& trk) mParam2.mC14 = trk.GetCov(14); } -GPUd() bool GPUTPCGMSliceTrack::FilterErrors(const GPUTPCGMMerger* merger, int iSlice, float maxSinPhi, float sinPhiMargin) +GPUd() bool GPUTPCGMSliceTrack::FilterErrors(const GPUTPCGMMerger* merger, int32_t iSlice, float maxSinPhi, float sinPhiMargin) { float lastX; if (merger->Param().par.earlyTpcTransform && !merger->Param().rec.tpc.mergerReadFromTrackerDirectly) { @@ -101,7 +101,7 @@ GPUd() bool GPUTPCGMSliceTrack::FilterErrors(const GPUTPCGMMerger* merger, int i //float lastX = merger->Param().tpcGeometry.Row2X(mOrigTrack->Cluster(mOrigTrack->NClusters() - 1).GetRow()); // TODO: again, why does this reduce efficiency? float y, z; const GPUTPCSliceOutCluster* clo; - int row, index; + int32_t row, index; if (merger->Param().rec.tpc.mergerReadFromTrackerDirectly) { const GPUTPCTracker& trk = merger->GetConstantMem()->tpcTrackers[iSlice]; const GPUTPCHitId& ic = trk.TrackHits()[mOrigTrack->FirstHitID() + mOrigTrack->NHits() - 1]; @@ -116,7 +116,7 @@ GPUd() bool GPUTPCGMSliceTrack::FilterErrors(const GPUTPCGMMerger* merger, int i GPUTPCConvertImpl::convert(*merger->GetConstantMem(), iSlice, row, cl.getPad(), cl.getTime(), lastX, y, z); } - const int N = 3; + const int32_t N = 3; float bz = -merger->Param().bzCLight; @@ -148,7 +148,7 @@ GPUd() bool GPUTPCGMSliceTrack::FilterErrors(const GPUTPCGMMerger* merger, int i mParam.mC14 = 10; } - for (int iStep = 0; iStep < N; iStep++) { + for (int32_t iStep = 0; iStep < N; iStep++) { float err2Y, err2Z; { // transport block diff --git a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.h b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.h index e8f361338962c..627fc5c73c21c 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMSliceTrack.h @@ -34,16 +34,16 @@ class GPUTPCGMSliceTrack { public: GPUd() float Alpha() const { return mAlpha; } - GPUd() unsigned char Slice() const { return mSlice; } - GPUd() char CSide() const { return mSlice >= 18; } - GPUd() int NClusters() const { return mNClusters; } - GPUd() int PrevNeighbour() const { return mNeighbour[0]; } - GPUd() int NextNeighbour() const { return mNeighbour[1]; } - GPUd() int Neighbour(int i) const { return mNeighbour[i]; } - GPUd() int PrevSegmentNeighbour() const { return mSegmentNeighbour[0]; } - GPUd() int NextSegmentNeighbour() const { return mSegmentNeighbour[1]; } - GPUd() int SegmentNeighbour(int i) const { return mSegmentNeighbour[i]; } - GPUd() int AnyNeighbour(int i) const + GPUd() uint8_t Slice() const { return mSlice; } + GPUd() bool CSide() const { return mSlice >= 18; } + GPUd() int32_t NClusters() const { return mNClusters; } + GPUd() int32_t PrevNeighbour() const { return mNeighbour[0]; } + GPUd() int32_t NextNeighbour() const { return mNeighbour[1]; } + GPUd() int32_t Neighbour(int32_t i) const { return mNeighbour[i]; } + GPUd() int32_t PrevSegmentNeighbour() const { return mSegmentNeighbour[0]; } + GPUd() int32_t NextSegmentNeighbour() const { return mSegmentNeighbour[1]; } + GPUd() int32_t SegmentNeighbour(int32_t i) const { return mSegmentNeighbour[i]; } + GPUd() int32_t AnyNeighbour(int32_t i) const { return (i < 2) ? mSegmentNeighbour[i] : mNeighbour[i - 2]; } @@ -57,13 +57,13 @@ class GPUTPCGMSliceTrack GPUd() float DzDs() const { return mParam.mDzDs; } GPUd() float QPt() const { return mParam.mQPt; } GPUd() float TZOffset() const { return mTZOffset; } - GPUd() unsigned char Leg() const { return mLeg; } + GPUd() uint8_t Leg() const { return mLeg; } - GPUd() int LocalTrackId() const { return mLocalTrackId; } - GPUd() void SetLocalTrackId(int v) { mLocalTrackId = v; } - GPUd() int GlobalTrackId(int n) const { return mGlobalTrackIds[n]; } - GPUd() void SetGlobalTrackId(int n, int v) { mGlobalTrackIds[n] = v; } - GPUd() int* GlobalTrackIds() { return mGlobalTrackIds; } + GPUd() int32_t LocalTrackId() const { return mLocalTrackId; } + GPUd() void SetLocalTrackId(int32_t v) { mLocalTrackId = v; } + GPUd() int32_t GlobalTrackId(int32_t n) const { return mGlobalTrackIds[n]; } + GPUd() void SetGlobalTrackId(int32_t n, int32_t v) { mGlobalTrackIds[n] = v; } + GPUd() int32_t* GlobalTrackIds() { return mGlobalTrackIds; } GPUd() float MaxClusterZT() const { return CAMath::Max(mClusterZT[0], mClusterZT[1]); } GPUd() float MinClusterZT() const { return CAMath::Min(mClusterZT[0], mClusterZT[1]); } @@ -75,9 +75,9 @@ class GPUTPCGMSliceTrack mClusterZT[1] = v2; } - GPUd() void Set(const GPUTPCGMTrackParam& trk, const GPUTPCTrack* sliceTr, float alpha, int slice); + GPUd() void Set(const GPUTPCGMTrackParam& trk, const GPUTPCTrack* sliceTr, float alpha, int32_t slice); GPUd() void SetParam2(const GPUTPCGMTrackParam& trk); - GPUd() void Set(const GPUTPCGMMerger* merger, const GPUTPCTrack* sliceTr, float alpha, int slice); + GPUd() void Set(const GPUTPCGMMerger* merger, const GPUTPCTrack* sliceTr, float alpha, int32_t slice); GPUd() void UseParam2() { mParam = mParam2; } GPUd() void SetX2(float v) { mParam2.mX = v; } GPUd() float X2() const { return mParam2.mX; } @@ -95,13 +95,13 @@ class GPUTPCGMSliceTrack mParam.mC14 = 10; } - GPUd() void SetNClusters(int v) { mNClusters = v; } - GPUd() void SetPrevNeighbour(int v) { mNeighbour[0] = v; } - GPUd() void SetNextNeighbour(int v) { mNeighbour[1] = v; } - GPUd() void SetNeighbor(int v, int i) { mNeighbour[i] = v; } - GPUd() void SetPrevSegmentNeighbour(int v) { mSegmentNeighbour[0] = v; } - GPUd() void SetNextSegmentNeighbour(int v) { mSegmentNeighbour[1] = v; } - GPUd() void SetLeg(unsigned char v) { mLeg = v; } + GPUd() void SetNClusters(int32_t v) { mNClusters = v; } + GPUd() void SetPrevNeighbour(int32_t v) { mNeighbour[0] = v; } + GPUd() void SetNextNeighbour(int32_t v) { mNeighbour[1] = v; } + GPUd() void SetNeighbor(int32_t v, int32_t i) { mNeighbour[i] = v; } + GPUd() void SetPrevSegmentNeighbour(int32_t v) { mSegmentNeighbour[0] = v; } + GPUd() void SetNextSegmentNeighbour(int32_t v) { mSegmentNeighbour[1] = v; } + GPUd() void SetLeg(uint8_t v) { mLeg = v; } GPUd() void CopyParamFrom(const GPUTPCGMSliceTrack& t) { @@ -116,7 +116,7 @@ class GPUTPCGMSliceTrack mAlpha = t.mAlpha; } - GPUd() bool FilterErrors(const GPUTPCGMMerger* merger, int iSlice, float maxSinPhi = GPUCA_MAX_SIN_PHI, float sinPhiMargin = 0.f); + GPUd() bool FilterErrors(const GPUTPCGMMerger* merger, int32_t iSlice, float maxSinPhi = GPUCA_MAX_SIN_PHI, float sinPhiMargin = 0.f); GPUd() bool TransportToX(GPUTPCGMMerger* merger, float x, float Bz, GPUTPCGMBorderTrack& b, float maxSinPhi, bool doCov = true) const; GPUd() bool TransportToXAlpha(GPUTPCGMMerger* merger, float x, float sinAlpha, float cosAlpha, float Bz, GPUTPCGMBorderTrack& b, float maxSinPhi) const; GPUd() void CopyBaseTrackCov(); @@ -132,13 +132,13 @@ class GPUTPCGMSliceTrack float mTZOffset; // Z offset with early transform, T offset otherwise float mAlpha; // alpha angle float mClusterZT[2]; // Minimum maximum cluster Z / T - int mNClusters; // N clusters - int mNeighbour[2]; // - int mSegmentNeighbour[2]; // - int mLocalTrackId; // Corrected local track id in terms of GMSliceTracks array for global tracks, UNDEFINED for local tracks! - int mGlobalTrackIds[2]; // IDs of associated global tracks - unsigned char mSlice; // slice of this track segment - unsigned char mLeg; // Leg of this track segment + int32_t mNClusters; // N clusters + int32_t mNeighbour[2]; // + int32_t mSegmentNeighbour[2]; // + int32_t mLocalTrackId; // Corrected local track id in terms of GMSliceTracks array for global tracks, UNDEFINED for local tracks! + int32_t mGlobalTrackIds[2]; // IDs of associated global tracks + uint8_t mSlice; // slice of this track segment + uint8_t mLeg; // Leg of this track segment ClassDefNV(GPUTPCGMSliceTrack, 1); }; diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx index 5e1a6a37cb13a..13244dcb4b621 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx @@ -57,7 +57,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; -GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iTrk, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMMergedTrackHitXYZ* GPUrestrict() clustersXYZ, int& GPUrestrict() N, int& GPUrestrict() NTolerated, float& GPUrestrict() Alpha, int attempt, float maxSinPhi, gputpcgmmergertypes::GPUTPCOuterParam* GPUrestrict() outerParam) +GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_t iTrk, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMMergedTrackHitXYZ* GPUrestrict() clustersXYZ, int32_t& GPUrestrict() N, int32_t& GPUrestrict() NTolerated, float& GPUrestrict() Alpha, int32_t attempt, float maxSinPhi, gputpcgmmergertypes::GPUTPCOuterParam* GPUrestrict() outerParam) { static constexpr float kDeg2Rad = M_PI / 180.f; CADEBUG(static constexpr float kSectAngle = 2 * M_PI / 18.f); @@ -75,24 +75,24 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT ShiftZ2(clusters, clustersXYZ, merger, N); } if (param.rec.tpc.mergerInterpolateErrors) { - for (int i = 0; i < N; i++) { + for (int32_t i = 0; i < N; i++) { interpolation.hit[i].errorY = -1; } } - const int nWays = param.rec.tpc.nWays; - const int maxN = N; - int ihitStart = 0; + const int32_t nWays = param.rec.tpc.nWays; + const int32_t maxN = N; + int32_t ihitStart = 0; float covYYUpd = 0.f; float lastUpdateX = -1.f; - unsigned char lastRow = 255; - unsigned char lastSlice = 255; - unsigned char storeOuter = 0; + uint8_t lastRow = 255; + uint8_t lastSlice = 255; + uint8_t storeOuter = 0; - for (int iWay = 0; iWay < nWays; iWay++) { - int nMissed = 0, nMissed2 = 0; + for (int32_t iWay = 0; iWay < nWays; iWay++) { + int32_t nMissed = 0, nMissed2 = 0; float sumInvSqrtCharge = 0.f; - int nAvgCharge = 0; + int32_t nAvgCharge = 0; if (iWay && storeOuter != 255 && param.rec.tpc.nWaysOuter && outerParam) { storeOuter = 0; @@ -106,7 +106,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT } } - int resetT0 = initResetT0(); + int32_t resetT0 = initResetT0(); const bool refit = (nWays == 1 || iWay >= 1); const float maxSinForUpdate = CAMath::Sin(70.f * kDeg2Rad); @@ -122,12 +122,12 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT N = 0; lastUpdateX = -1; const bool inFlyDirection = iWay & 1; - unsigned char lastLeg = clusters[ihitStart].leg; - const int wayDirection = (iWay & 1) ? -1 : 1; + uint8_t lastLeg = clusters[ihitStart].leg; + const int32_t wayDirection = (iWay & 1) ? -1 : 1; bool noFollowCircle = false, noFollowCircle2 = false; - int goodRows = 0; - for (int ihit = ihitStart; ihit >= 0 && ihit < maxN; ihit += wayDirection) { + int32_t goodRows = 0; + for (int32_t ihit = ihitStart; ihit >= 0 && ihit < maxN; ihit += wayDirection) { const bool crossCE = lastSlice != 255 && ((lastSlice < 18) ^ (clusters[ihit].slice < 18)); if (crossCE) { lastSlice = clusters[ihit].slice; @@ -144,7 +144,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT } if ((param.rec.tpc.trackFitRejectMode > 0 && nMissed >= param.rec.tpc.trackFitRejectMode) || nMissed2 >= param.rec.tpc.trackFitMaxRowMissedHard || clusters[ihit].state & GPUTPCGMMergedTrackHit::flagReject) { - CADEBUG(printf("\tSkipping hit, %d hits rejected, flag %X\n", nMissed, (int)clusters[ihit].state)); + CADEBUG(printf("\tSkipping hit, %d hits rejected, flag %X\n", nMissed, (int32_t)clusters[ihit].state)); if (iWay + 2 >= nWays && !(clusters[ihit].state & GPUTPCGMMergedTrackHit::flagReject)) { clusters[ihit].state |= GPUTPCGMMergedTrackHit::flagRejectErr; } @@ -153,8 +153,8 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT const bool allowModification = refit && (iWay == 0 || (((nWays - iWay) & 1) ? (ihit >= CAMath::Min(maxN / 2, 30)) : (ihit <= CAMath::Max(maxN / 2, maxN - 30)))); - int ihitMergeFirst = ihit; - unsigned char clusterState = clusters[ihit].state; + int32_t ihitMergeFirst = ihit; + uint8_t clusterState = clusters[ihit].state; const float clAlpha = param.Alpha(clusters[ihit].slice); float xx, yy, zz; if (merger->Param().par.earlyTpcTransform) { @@ -167,9 +167,9 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT merger->GetConstantMem()->calibObjects.fastTransformHelper->Transform(clusters[ihit].slice, clusters[ihit].row, cl.getPad(), cl.getTime(), xx, yy, zz, mTZOffset); } // clang-format off - CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f (Missed %d)\n", ihit, maxN, (int)clusters[ihit].row, clAlpha, (int)clusters[ihit].slice, xx, yy, zz, nMissed)); - // CADEBUG(if ((unsigned int)merger->GetTrackingChain()->mIOPtrs.nMCLabelsTPC > clusters[ihit].num)) - // CADEBUG({printf(" MC:"); for (int i = 0; i < 3; i++) {int mcId = merger->GetTrackingChain()->mIOPtrs.mcLabelsTPC[clusters[ihit].num].fClusterID[i].fMCID; if (mcId >= 0) printf(" %d", mcId); } } printf("\n")); + CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f (Missed %d)\n", ihit, maxN, (int32_t)clusters[ihit].row, clAlpha, (int32_t)clusters[ihit].slice, xx, yy, zz, nMissed)); + // CADEBUG(if ((uint32_t)merger->GetTrackingChain()->mIOPtrs.nMCLabelsTPC > clusters[ihit].num)) + // CADEBUG({printf(" MC:"); for (int32_t i = 0; i < 3; i++) {int32_t mcId = merger->GetTrackingChain()->mIOPtrs.mcLabelsTPC[clusters[ihit].num].fClusterID[i].fMCID; if (mcId >= 0) printf(" %d", mcId); } } printf("\n")); // clang-format on if (MergeDoubleRowClusters(ihit, wayDirection, clusters, clustersXYZ, merger, prop, xx, yy, zz, maxN, clAlpha, clusterState, allowModification) == -1) { nMissed++; @@ -182,7 +182,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT bool changeDirection = (cluster.leg - lastLeg) & 1; // clang-format off CADEBUG(if (changeDirection) printf("\t\tChange direction\n")); - CADEBUG(printf("\tLeg %3d Slice %2d %4sTrack Alpha %8.3f %s, X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) %28s --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f - YPt %8.3f\n", (int)cluster.leg, (int)cluster.slice, "", prop.GetAlpha(), (CAMath::Abs(prop.GetAlpha() - clAlpha) < 0.01 ? " " : " R!"), mX, mP[0], mP[1], mP[4], prop.GetQPt0(), mP[2], prop.GetSinPhi0(), "", sqrtf(mC[0]), sqrtf(mC[2]), sqrtf(mC[5]), sqrtf(mC[14]), mC[10])); + CADEBUG(printf("\tLeg %3d Slice %2d %4sTrack Alpha %8.3f %s, X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) %28s --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f - YPt %8.3f\n", (int32_t)cluster.leg, (int32_t)cluster.slice, "", prop.GetAlpha(), (CAMath::Abs(prop.GetAlpha() - clAlpha) < 0.01 ? " " : " R!"), mX, mP[0], mP[1], mP[4], prop.GetQPt0(), mP[2], prop.GetSinPhi0(), "", sqrtf(mC[0]), sqrtf(mC[2]), sqrtf(mC[5]), sqrtf(mC[14]), mC[10])); // clang-format on if (allowModification && changeDirection && !noFollowCircle && !noFollowCircle2) { bool tryFollow = lastRow != 255; @@ -219,7 +219,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT } } - int err = prop.PropagateToXAlpha(xx, clAlpha, inFlyDirection); + int32_t err = prop.PropagateToXAlpha(xx, clAlpha, inFlyDirection); // clang-format off CADEBUG(if (!CheckCov()){printf("INVALID COV AFTER PROPAGATE!!!\n");}); // clang-format on @@ -230,7 +230,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT err = prop.PropagateToXAlpha(xx, clAlpha, inFlyDirection); } } - if (lastRow == 255 || CAMath::Abs((int)lastRow - (int)cluster.row) > 5 || lastSlice != cluster.slice || (param.rec.tpc.trackFitRejectMode < 0 && -nMissed <= param.rec.tpc.trackFitRejectMode)) { + if (lastRow == 255 || CAMath::Abs((int32_t)lastRow - (int32_t)cluster.row) > 5 || lastSlice != cluster.slice || (param.rec.tpc.trackFitRejectMode < 0 && -nMissed <= param.rec.tpc.trackFitRejectMode)) { goodRows = 0; } else { goodRows++; @@ -284,7 +284,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT uncorrectedY = AttachClusters(merger, cluster.slice, cluster.row, iTrk, cluster.leg == clusters[maxN - 1].leg, prop); } - const int err2 = mNDF > 0 && CAMath::Abs(prop.GetSinPhi0()) >= maxSinForUpdate; + const int32_t err2 = mNDF > 0 && CAMath::Abs(prop.GetSinPhi0()) >= maxSinForUpdate; if (err || err2) { if (mC[0] > param.rec.tpc.trackFitCovLimit || mC[2] > param.rec.tpc.trackFitCovLimit) { break; @@ -297,12 +297,12 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT } CADEBUG(printf("\n")); - int retVal; + int32_t retVal; float threshold = 3.f + (lastUpdateX >= 0 ? (CAMath::Abs(mX - lastUpdateX) / 2) : 0.f); if (mNDF > 5 && (CAMath::Abs(yy - mP[0]) > threshold || CAMath::Abs(zz - mP[1]) > threshold)) { retVal = GPUTPCGMPropagator::updateErrorClusterRejected; } else { - char rejectChi2 = attempt ? 0 : ((param.rec.tpc.mergerInterpolateErrors && CAMath::Abs(ihit - ihitMergeFirst) <= 1) ? (refit ? (GPUTPCGMPropagator::rejectInterFill + ((nWays - iWay) & 1)) : 0) : (allowModification && goodRows > 5)); + int8_t rejectChi2 = attempt ? 0 : ((param.rec.tpc.mergerInterpolateErrors && CAMath::Abs(ihit - ihitMergeFirst) <= 1) ? (refit ? (GPUTPCGMPropagator::rejectInterFill + ((nWays - iWay) & 1)) : 0) : (allowModification && goodRows > 5)); #if EXTRACT_RESIDUALS == 1 if (iWay == nWays - 1 && interpolation.hit[ihit].errorY > (GPUCA_MERGER_INTERPOLATION_ERROR_TYPE)0) { const float Iz0 = interpolation.hit[ihit].posY - mP[0]; @@ -364,8 +364,8 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int iT } if (merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { float qtot = 0, qmax = 0, pad = 0, relTime = 0; - const int clusterCount = (ihit - ihitMergeFirst) * wayDirection + 1; - for (int iTmp = ihitMergeFirst; iTmp != ihit + wayDirection; iTmp += wayDirection) { + const int32_t clusterCount = (ihit - ihitMergeFirst) * wayDirection + 1; + for (int32_t iTmp = ihitMergeFirst; iTmp != ihit + wayDirection; iTmp += wayDirection) { if (merger->GetConstantMem()->ioPtrs.clustersNative == nullptr) { qtot += clustersXYZ[ihit].amp; } else { @@ -431,7 +431,7 @@ GPUdni() void GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, cons if (param.rec.tpc.trackReferenceX <= 500) { GPUTPCGMTrackParam save = *this; float saveAlpha = Alpha; - for (int attempt = 0; attempt < 3; attempt++) { + for (int32_t attempt = 0; attempt < 3; attempt++) { float dAngle = CAMath::Round(CAMath::ATan2(mP[0], mX) / kDeg2Rad / 20.f) * kSectAngle; Alpha += dAngle; if (prop.PropagateToXAlpha(param.rec.tpc.trackReferenceX, Alpha, 0)) { @@ -453,7 +453,7 @@ GPUdni() void GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, cons } } -GPUd() void GPUTPCGMTrackParam::MirrorTo(GPUTPCGMPropagator& GPUrestrict() prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, unsigned char row, unsigned char clusterState, bool mirrorParameters, char sector) +GPUd() void GPUTPCGMTrackParam::MirrorTo(GPUTPCGMPropagator& GPUrestrict() prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, uint8_t row, uint8_t clusterState, bool mirrorParameters, int8_t sector) { if (mirrorParameters) { prop.Mirror(inFlyDirection); @@ -480,14 +480,14 @@ GPUd() void GPUTPCGMTrackParam::MirrorTo(GPUTPCGMPropagator& GPUrestrict() prop, mChi2 = 0; } -GPUd() int GPUTPCGMTrackParam::MergeDoubleRowClusters(int& ihit, int wayDirection, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* GPUrestrict() merger, GPUTPCGMPropagator& GPUrestrict() prop, float& GPUrestrict() xx, float& GPUrestrict() yy, float& GPUrestrict() zz, int maxN, float clAlpha, unsigned char& GPUrestrict() clusterState, bool rejectChi2) +GPUd() int32_t GPUTPCGMTrackParam::MergeDoubleRowClusters(int32_t& ihit, int32_t wayDirection, GPUTPCGMMergedTrackHit* GPUrestrict() clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* GPUrestrict() merger, GPUTPCGMPropagator& GPUrestrict() prop, float& GPUrestrict() xx, float& GPUrestrict() yy, float& GPUrestrict() zz, int32_t maxN, float clAlpha, uint8_t& GPUrestrict() clusterState, bool rejectChi2) { if (ihit + wayDirection >= 0 && ihit + wayDirection < maxN && clusters[ihit].row == clusters[ihit + wayDirection].row && clusters[ihit].slice == clusters[ihit + wayDirection].slice && clusters[ihit].leg == clusters[ihit + wayDirection].leg) { float maxDistY, maxDistZ; prop.GetErr2(maxDistY, maxDistZ, merger->Param(), zz, clusters[ihit].row, 0, clusters[ihit].slice, -1.f, 0.f, 0.f); // TODO: Use correct time, avgCharge maxDistY = (maxDistY + mC[0]) * 20.f; maxDistZ = (maxDistZ + mC[2]) * 20.f; - int noReject = 0; // Cannot reject if simple estimation of y/z fails (extremely unlike case) + int32_t noReject = 0; // Cannot reject if simple estimation of y/z fails (extremely unlike case) if (CAMath::Abs(clAlpha - prop.GetAlpha()) > 1.e-4f) { noReject = prop.RotateToAlpha(clAlpha); } @@ -542,7 +542,7 @@ GPUd() int GPUTPCGMTrackParam::MergeDoubleRowClusters(int& ihit, int wayDirectio return 0; } -GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, bool goodLeg, GPUTPCGMPropagator& prop) +GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, bool goodLeg, GPUTPCGMPropagator& prop) { float Y, Z; if (Merger->Param().par.earlyTpcTransform) { @@ -559,7 +559,7 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric return AttachClusters(Merger, slice, iRow, iTrack, goodLeg, Y, Z); } -GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, bool goodLeg, float Y, float Z) +GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, bool goodLeg, float Y, float Z) { if (Merger->Param().rec.tpc.disableRefitAttachment & 1) { return -1e6f; @@ -579,7 +579,7 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric const float stepY = row.HstepY(); const float z0 = row.Grid().ZMin() - zOffset; // We can use our own ZOffset, since this is only used temporarily anyway const float stepZ = row.HstepZ(); - int bin, ny, nz; + int32_t bin, ny, nz; float err2Y, err2Z; Merger->Param().GetClusterErrors2(slice, iRow, Z, mP[2], mP[3], -1.f, 0.f, 0.f, err2Y, err2Z); // TODO: Use correct time/avgCharge @@ -602,21 +602,21 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric } row.Grid().GetBinArea(uncorrectedY, uncorrectedZ + zOffset, tubeY, tubeZ, bin, ny, nz); - const int nBinsY = row.Grid().Ny(); - const int idOffset = tracker.Data().ClusterIdOffset(); - const int* ids = &(tracker.Data().ClusterDataIndex()[row.HitNumberOffset()]); - unsigned int myWeight = Merger->TrackOrderAttach()[iTrack] | gputpcgmmergertypes::attachAttached | gputpcgmmergertypes::attachTube; - GPUAtomic(unsigned int)* const weights = Merger->ClusterAttachment(); + const int32_t nBinsY = row.Grid().Ny(); + const int32_t idOffset = tracker.Data().ClusterIdOffset(); + const int32_t* ids = &(tracker.Data().ClusterDataIndex()[row.HitNumberOffset()]); + uint32_t myWeight = Merger->TrackOrderAttach()[iTrack] | gputpcgmmergertypes::attachAttached | gputpcgmmergertypes::attachTube; + GPUAtomic(uint32_t)* const weights = Merger->ClusterAttachment(); if (goodLeg) { myWeight |= gputpcgmmergertypes::attachGoodLeg; } - for (int k = 0; k <= nz; k++) { - const int mybin = bin + k * nBinsY; - const unsigned int hitFst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin); - const unsigned int hitLst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin + ny + 1); - for (unsigned int ih = hitFst; ih < hitLst; ih++) { - int id = idOffset + ids[ih]; - GPUAtomic(unsigned int)* const weight = weights + id; + for (int32_t k = 0; k <= nz; k++) { + const int32_t mybin = bin + k * nBinsY; + const uint32_t hitFst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin); + const uint32_t hitLst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin + ny + 1); + for (uint32_t ih = hitFst; ih < hitLst; ih++) { + int32_t id = idOffset + ids[ih]; + GPUAtomic(uint32_t)* const weight = weights + id; #if !defined(GPUCA_NO_ATOMIC_PRECHECK) && GPUCA_NO_ATOMIC_PRECHECK < 1 if (myWeight <= *weight) { continue; @@ -636,7 +636,7 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric return uncorrectedY; } -GPUd() bool GPUTPCGMTrackParam::AttachClustersPropagate(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int lastRow, int toRow, int iTrack, bool goodLeg, GPUTPCGMPropagator& GPUrestrict() prop, bool inFlyDirection, float maxSinPhi, bool dodEdx) +GPUd() bool GPUTPCGMTrackParam::AttachClustersPropagate(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t lastRow, int32_t toRow, int32_t iTrack, bool goodLeg, GPUTPCGMPropagator& GPUrestrict() prop, bool inFlyDirection, float maxSinPhi, bool dodEdx) { static constexpr float kSectAngle = 2 * M_PI / 18.f; if (Merger->Param().rec.tpc.disableRefitAttachment & 2) { @@ -645,23 +645,23 @@ GPUd() bool GPUTPCGMTrackParam::AttachClustersPropagate(const GPUTPCGMMerger* GP if (CAMath::Abs(lastRow - toRow) < 2) { return dodEdx; } - int step = toRow > lastRow ? 1 : -1; + int32_t step = toRow > lastRow ? 1 : -1; float xx = mX - Merger->Param().tpcGeometry.Row2X(lastRow); - for (int iRow = lastRow + step; iRow != toRow; iRow += step) { + for (int32_t iRow = lastRow + step; iRow != toRow; iRow += step) { if (CAMath::Abs(mP[2]) > maxSinPhi) { return dodEdx; } if (CAMath::Abs(mP[0]) > CAMath::Abs(mX) * CAMath::Tan(kSectAngle / 2.f)) { return dodEdx; } - int err = prop.PropagateToXAlpha(xx + Merger->Param().tpcGeometry.Row2X(iRow), prop.GetAlpha(), inFlyDirection); + int32_t err = prop.PropagateToXAlpha(xx + Merger->Param().tpcGeometry.Row2X(iRow), prop.GetAlpha(), inFlyDirection); if (err) { return dodEdx; } if (dodEdx && iRow + step == toRow) { float yUncorrected, zUncorrected; Merger->GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoNominalYZ(slice, iRow, mP[0], mP[1], yUncorrected, zUncorrected); - unsigned int pad = CAMath::Float2UIntRn(Merger->Param().tpcGeometry.LinearY2Pad(slice, iRow, yUncorrected)); + uint32_t pad = CAMath::Float2UIntRn(Merger->Param().tpcGeometry.LinearY2Pad(slice, iRow, yUncorrected)); if (pad >= Merger->Param().tpcGeometry.NPads(iRow) || (Merger->GetConstantMem()->calibObjects.dEdxCalibContainer && Merger->GetConstantMem()->calibObjects.dEdxCalibContainer->isDead(slice, iRow, pad))) { dodEdx = false; } @@ -679,22 +679,22 @@ GPUd() bool GPUTPCGMTrackParam::FollowCircleChk(float lrFactor, float toY, float (up ? (-mP[0] * lrFactor > toX || (right ^ (mP[2] > 0))) : (-mP[0] * lrFactor < toX || (right ^ (mP[2] < 0)))); // don't overshoot in X } -GPUdii() void GPUTPCGMTrackParam::StoreOuter(gputpcgmmergertypes::GPUTPCOuterParam* outerParam, const GPUTPCGMPropagator& prop, int phase) +GPUdii() void GPUTPCGMTrackParam::StoreOuter(gputpcgmmergertypes::GPUTPCOuterParam* outerParam, const GPUTPCGMPropagator& prop, int32_t phase) { CADEBUG(printf("\t%21sStorO%d Alpha %8.3f , X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f\n", "", phase, prop.GetAlpha(), mX, mP[0], mP[1], mP[4], prop.GetQPt0(), mP[2], prop.GetSinPhi0(), sqrtf(mC[0]), sqrtf(mC[2]), sqrtf(mC[5]), sqrtf(mC[14]))); - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { outerParam->P[i] = mP[i]; } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { outerParam->C[i] = mC[i]; } outerParam->X = mX; outerParam->alpha = prop.GetAlpha(); } -GPUdic(0, 1) void GPUTPCGMTrackParam::StoreAttachMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, float toAlpha, float toY, float toX, int toSlice, int toRow, bool inFlyDirection, float alpha) +GPUdic(0, 1) void GPUTPCGMTrackParam::StoreAttachMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, float toAlpha, float toY, float toX, int32_t toSlice, int32_t toRow, bool inFlyDirection, float alpha) { - unsigned int nLoopData = CAMath::AtomicAdd(&Merger->Memory()->nLoopData, 1u); + uint32_t nLoopData = CAMath::AtomicAdd(&Merger->Memory()->nLoopData, 1u); if (nLoopData >= Merger->NMaxTracks()) { Merger->raiseError(GPUErrors::ERROR_MERGER_LOOPER_OVERFLOW, nLoopData, Merger->NMaxTracks()); CAMath::AtomicExch(&Merger->Memory()->nLoopData, Merger->NMaxTracks()); @@ -715,7 +715,7 @@ GPUdic(0, 1) void GPUTPCGMTrackParam::StoreAttachMirror(const GPUTPCGMMerger* GP Merger->LoopData()[nLoopData] = data; } -GPUdii() void GPUTPCGMTrackParam::RefitLoop(const GPUTPCGMMerger* GPUrestrict() Merger, int loopIdx) +GPUdii() void GPUTPCGMTrackParam::RefitLoop(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t loopIdx) { GPUTPCGMPropagator prop; prop.SetMaterialTPC(); @@ -736,8 +736,8 @@ GPUdii() void GPUTPCGMTrackParam::RefitLoop(const GPUTPCGMMerger* GPUrestrict() } } -template -GPUdic(0, 1) int GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestrict() Merger, GPUTPCGMPropagator& GPUrestrict() prop, int slice, int iRow, int iTrack, float toAlpha, float toX, float toY, int toSlice, int toRow, bool inFlyDirection, bool phase2) +template +GPUdic(0, 1) int32_t GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestrict() Merger, GPUTPCGMPropagator& GPUrestrict() prop, int32_t slice, int32_t iRow, int32_t iTrack, float toAlpha, float toX, float toY, int32_t toSlice, int32_t toRow, bool inFlyDirection, bool phase2) { static constexpr float kSectAngle = 2 * M_PI / 18.f; if (Merger->Param().rec.tpc.disableRefitAttachment & 4) { @@ -750,17 +750,17 @@ GPUdic(0, 1) int GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestr const GPUParam& GPUrestrict() param = Merger->Param(); bool right; float dAlpha = toAlpha - prop.GetAlpha(); - int sliceSide = slice >= (GPUCA_NSLICES / 2) ? (GPUCA_NSLICES / 2) : 0; + int32_t sliceSide = slice >= (GPUCA_NSLICES / 2) ? (GPUCA_NSLICES / 2) : 0; if (CAMath::Abs(dAlpha) > 0.001f) { right = CAMath::Abs(dAlpha) < CAMath::Pi() ? (dAlpha > 0) : (dAlpha < 0); } else { right = toY > mP[0]; } bool up = (mP[2] < 0) ^ right; - int targetRow = up ? (GPUCA_ROW_COUNT - 1) : 0; + int32_t targetRow = up ? (GPUCA_ROW_COUNT - 1) : 0; float lrFactor = mP[2] < 0 ? -1.f : 1.f; // !(right ^ down) // TODO: shouldn't it be "right ? 1.f : -1.f", but that gives worse results... // clang-format off - CADEBUG(printf("CIRCLE Track %d: Slice %d Alpha %f X %f Y %f Z %f SinPhi %f DzDs %f - Next hit: Slice %d Alpha %f X %f Y %f - Right %d Up %d dAlpha %f lrFactor %f\n", iTrack, slice, prop.GetAlpha(), mX, mP[0], mP[1], mP[2], mP[3], toSlice, toAlpha, toX, toY, (int)right, (int)up, dAlpha, lrFactor)); + CADEBUG(printf("CIRCLE Track %d: Slice %d Alpha %f X %f Y %f Z %f SinPhi %f DzDs %f - Next hit: Slice %d Alpha %f X %f Y %f - Right %d Up %d dAlpha %f lrFactor %f\n", iTrack, slice, prop.GetAlpha(), mX, mP[0], mP[1], mP[2], mP[3], toSlice, toAlpha, toX, toY, (int32_t)right, (int32_t)up, dAlpha, lrFactor)); // clang-format on AttachClustersPropagate(Merger, slice, iRow, targetRow, iTrack, false, prop, inFlyDirection, 0.7f); @@ -770,14 +770,14 @@ GPUdic(0, 1) int GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestr CADEBUG(printf("\tRotated: X %f Y %f Z %f SinPhi %f (Alpha %f / %f)\n", mP[0], mX, mP[1], mP[2], prop.GetAlpha(), prop.GetAlpha() + CAMath::Pi() / 2.f)); while (slice != toSlice || FollowCircleChk(lrFactor, toY, toX, up, right)) { while ((slice != toSlice) ? (CAMath::Abs(mX) <= CAMath::Abs(mP[0]) * CAMath::Tan(kSectAngle / 2.f)) : FollowCircleChk(lrFactor, toY, toX, up, right)) { - int err = prop.PropagateToXAlpha(mX + 1.f, prop.GetAlpha(), inFlyDirection); + int32_t err = prop.PropagateToXAlpha(mX + 1.f, prop.GetAlpha(), inFlyDirection); if (err) { CADEBUG(printf("\t\tpropagation error (%d)\n", err)); prop.RotateToAlpha(prop.GetAlpha() - (CAMath::Pi() / 2.f) * lrFactor); return 1; } CADEBUG(printf("\tPropagated to y = %f: X %f Z %f SinPhi %f\n", mX, mP[0], mP[1], mP[2])); - for (int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (int32_t j = 0; j < GPUCA_ROW_COUNT; j++) { float rowX = Merger->Param().tpcGeometry.Row2X(j); if (CAMath::Abs(rowX - (-mP[0] * lrFactor)) < 1.5f) { CADEBUG(printf("\t\tAttempt row %d (Y %f Z %f)\n", j, mX * lrFactor, mP[1])); @@ -805,7 +805,7 @@ GPUdic(0, 1) int GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestr } } CADEBUG(printf("\tRotating back\n")); - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { if (prop.RotateToAlpha(prop.GetAlpha() + (CAMath::Pi() / 2.f) * lrFactor) == 0) { break; } @@ -840,8 +840,8 @@ GPUdic(0, 1) int GPUTPCGMTrackParam::FollowCircle(const GPUTPCGMMerger* GPUrestr return (0); } -template -GPUdni() void GPUTPCGMTrackParam::AttachClustersMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, float toY, GPUTPCGMPropagator& GPUrestrict() prop, bool phase2) +template +GPUdni() void GPUTPCGMTrackParam::AttachClustersMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, float toY, GPUTPCGMPropagator& GPUrestrict() prop, bool phase2) { static constexpr float kSectAngle = 2 * M_PI / 18.f; @@ -866,7 +866,7 @@ GPUdni() void GPUTPCGMTrackParam::AttachClustersMirror(const GPUTPCGMMerger* GPU } float b = prop.GetBz(prop.GetAlpha(), mX, mP[0], mP[1]); - int count = CAMath::Float2IntRn(CAMath::Abs((toX - X) * 2.f)); + int32_t count = CAMath::Float2IntRn(CAMath::Abs((toX - X) * 2.f)); if (count == 0) { return; } @@ -898,9 +898,9 @@ GPUdni() void GPUTPCGMTrackParam::AttachClustersMirror(const GPUTPCGMMerger* GPU // printf("count %d: At X %f Y %f Z %f SinPhi %f\n", count, mP[2] > 0 ? -Y : Y, mP[2] > 0 ? X : -X, Z, SinPhi); float paramX = mP[2] > 0 ? -Y : Y; - int step = paramX >= mX ? 1 : -1; - int found = 0; - for (int j = iRow; j >= 0 && j < GPUCA_ROW_COUNT && found < 3; j += step) { + int32_t step = paramX >= mX ? 1 : -1; + int32_t found = 0; + for (int32_t j = iRow; j >= 0 && j < GPUCA_ROW_COUNT && found < 3; j += step) { float rowX = mX + Merger->Param().tpcGeometry.Row2X(j) - myRowX; if (CAMath::Abs(rowX - paramX) < 1.5f) { // printf("Attempt row %d\n", j); @@ -910,7 +910,7 @@ GPUdni() void GPUTPCGMTrackParam::AttachClustersMirror(const GPUTPCGMMerger* GPU } } -GPUd() void GPUTPCGMTrackParam::ShiftZ2(const GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, int N) +GPUd() void GPUTPCGMTrackParam::ShiftZ2(const GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, int32_t N) { float tzInner, tzOuter; float xInner, xOuter; @@ -932,7 +932,7 @@ GPUd() void GPUTPCGMTrackParam::ShiftZ2(const GPUTPCGMMergedTrackHit* clusters, ShiftZ(merger, clusters[0].slice, tzInner, tzOuter, xInner, xOuter); } -GPUd() void GPUTPCGMTrackParam::ShiftZ(const GPUTPCGMMerger* GPUrestrict() merger, int slice, float tz1, float tz2, float x1, float x2) +GPUd() void GPUTPCGMTrackParam::ShiftZ(const GPUTPCGMMerger* GPUrestrict() merger, int32_t slice, float tz1, float tz2, float x1, float x2) { if (!merger->Param().par.continuousTracking) { return; @@ -946,7 +946,7 @@ GPUd() void GPUTPCGMTrackParam::ShiftZ(const GPUTPCGMMerger* GPUrestrict() merge if (dist1r2 < 4) { const float alpha = CAMath::ACos(1 - 0.5f * dist1r2); // Angle of a circle, such that |(cosa, sina) - (1,0)| == dist const float beta = CAMath::ATan2(mP[0], mX); - const int comp = mP[2] > CAMath::Sin(beta); + const int32_t comp = mP[2] > CAMath::Sin(beta); const float sinab = CAMath::Sin((comp ? 0.5f : -0.5f) * alpha + beta); // Angle of circle through origin and track position, to be compared to Snp const float res = CAMath::Abs(sinab - mP[2]); @@ -1047,28 +1047,28 @@ GPUd() bool GPUTPCGMTrackParam::CheckNumericalQuality(float overrideCovYY) const { //* Check that the track parameters and covariance matrix are reasonable bool ok = CAMath::Finite(mX) && CAMath::Finite(mChi2); - CADEBUG(printf("OK %d - %f - ", (int)ok, mX); for (int i = 0; i < 5; i++) { printf("%f ", mP[i]); } printf(" - "); for (int i = 0; i < 15; i++) { printf("%f ", mC[i]); } printf("\n")); + CADEBUG(printf("OK %d - %f - ", (int32_t)ok, mX); for (int32_t i = 0; i < 5; i++) { printf("%f ", mP[i]); } printf(" - "); for (int32_t i = 0; i < 15; i++) { printf("%f ", mC[i]); } printf("\n")); const float* c = mC; - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { ok = ok && CAMath::Finite(c[i]); } - CADEBUG(printf("OK1 %d\n", (int)ok)); - for (int i = 0; i < 5; i++) { + CADEBUG(printf("OK1 %d\n", (int32_t)ok)); + for (int32_t i = 0; i < 5; i++) { ok = ok && CAMath::Finite(mP[i]); } - CADEBUG(printf("OK2 %d\n", (int)ok)); + CADEBUG(printf("OK2 %d\n", (int32_t)ok)); if ((overrideCovYY > 0 ? overrideCovYY : c[0]) > 4.f * 4.f || c[2] > 4.f * 4.f || c[5] > 2.f * 2.f || c[9] > 2.f * 2.f) { ok = 0; } - CADEBUG(printf("OK3 %d\n", (int)ok)); + CADEBUG(printf("OK3 %d\n", (int32_t)ok)); if (CAMath::Abs(mP[2]) > GPUCA_MAX_SIN_PHI) { ok = 0; } - CADEBUG(printf("OK4 %d\n", (int)ok)); + CADEBUG(printf("OK4 %d\n", (int32_t)ok)); if (!CheckCov()) { ok = false; } - CADEBUG(printf("OK5 %d\n", (int)ok)); + CADEBUG(printf("OK5 %d\n", (int32_t)ok)); return ok; } @@ -1081,10 +1081,10 @@ bool GPUTPCGMTrackParam::GetExtParam(AliExternalTrackParam& T, double alpha) con bool ok = CheckNumericalQuality(); double par[5], cov[15]; - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { par[i] = mP[i]; } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { cov[i] = mC[i]; } @@ -1109,10 +1109,10 @@ void GPUTPCGMTrackParam::SetExtParam(const AliExternalTrackParam& T) { //* Convert from AliExternalTrackParam parameterisation - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { mP[i] = T.GetParameter()[i]; } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { mC[i] = T.GetCovariance()[i]; } mX = T.GetX(); @@ -1125,7 +1125,7 @@ void GPUTPCGMTrackParam::SetExtParam(const AliExternalTrackParam& T) } #endif -GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() track, int iTrk, GPUTPCGMMerger* GPUrestrict() merger, int attempt) // TODO: Inline me, once __forceinline__ is fixed by HIP +GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() track, int32_t iTrk, GPUTPCGMMerger* GPUrestrict() merger, int32_t attempt) // TODO: Inline me, once __forceinline__ is fixed by HIP { if (!track.OK()) { return; @@ -1135,17 +1135,17 @@ GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() tr CADEBUG(if (DEBUG_SINGLE_TRACK >= 0 && iTrk != DEBUG_SINGLE_TRACK) { track.SetNClusters(0); track.SetOK(0); return; } ); // clang-format on - int nTrackHits = track.NClusters(); - int NTolerated = 0; // Clusters not fit but tollerated for track length cut + int32_t nTrackHits = track.NClusters(); + int32_t NTolerated = 0; // Clusters not fit but tollerated for track length cut GPUTPCGMTrackParam t = track.Param(); float Alpha = track.Alpha(); - CADEBUG(int nTrackHitsOld = nTrackHits; float ptOld = t.QPt()); + CADEBUG(int32_t nTrackHitsOld = nTrackHits; float ptOld = t.QPt()); bool ok = t.Fit(merger, iTrk, merger->Clusters() + track.FirstClusterRef(), merger->ClustersXYZ() + track.FirstClusterRef(), nTrackHits, NTolerated, Alpha, attempt, GPUCA_MAX_SIN_PHI, &track.OuterParam()); CADEBUG(printf("Finished Fit Track %d\n", iTrk)); - CADEBUG(printf("OUTPUT hits %d -> %d+%d = %d, QPt %f -> %f, SP %f, ok %d chi2 %f chi2ndf %f\n", nTrackHitsOld, nTrackHits, NTolerated, nTrackHits + NTolerated, ptOld, t.QPt(), t.SinPhi(), (int)ok, t.Chi2(), t.Chi2() / CAMath::Max(1, nTrackHits))); + CADEBUG(printf("OUTPUT hits %d -> %d+%d = %d, QPt %f -> %f, SP %f, ok %d chi2 %f chi2ndf %f\n", nTrackHitsOld, nTrackHits, NTolerated, nTrackHits + NTolerated, ptOld, t.QPt(), t.SinPhi(), (int32_t)ok, t.Chi2(), t.Chi2() / CAMath::Max(1, nTrackHits))); if (!ok && attempt == 0 && merger->Param().rec.tpc.retryRefit) { - for (unsigned int i = 0; i < track.NClusters(); i++) { + for (uint32_t i = 0; i < track.NClusters(); i++) { merger->Clusters()[track.FirstClusterRef() + i].state &= GPUTPCGMMergedTrackHit::clustererAndSharedFlags; } CADEBUG(printf("Track rejected, marking for retry\n")); @@ -1156,7 +1156,7 @@ GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() tr Alpha = track.Alpha(); ok = t.Fit(merger, iTrk, merger->Clusters() + track.FirstClusterRef(), merger->ClustersXYZ() + track.FirstClusterRef(), nTrackHits, NTolerated, Alpha, 1, GPUCA_MAX_SIN_PHI, &track.OuterParam()); } else { - unsigned int nRefit = CAMath::AtomicAdd(&merger->Memory()->nRetryRefit, 1u); + uint32_t nRefit = CAMath::AtomicAdd(&merger->Memory()->nRetryRefit, 1u); merger->RetryRefitIds()[nRefit] = iTrk; return; } @@ -1165,7 +1165,7 @@ GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() tr t.QPt() = 1.e-4f; } - CADEBUG(if (t.GetX() > 250) { printf("ERROR, Track %d at impossible X %f, Pt %f, Looper %d\n", iTrk, t.GetX(), CAMath::Abs(1.f / t.QPt()), (int)merger->OutputTracks()[iTrk].Looper()); }); + CADEBUG(if (t.GetX() > 250) { printf("ERROR, Track %d at impossible X %f, Pt %f, Looper %d\n", iTrk, t.GetX(), CAMath::Abs(1.f / t.QPt()), (int32_t)merger->OutputTracks()[iTrk].Looper()); }); track.SetOK(ok); track.SetNClustersFitted(nTrackHits); @@ -1173,7 +1173,7 @@ GPUd() void GPUTPCGMTrackParam::RefitTrack(GPUTPCGMMergedTrack& GPUrestrict() tr track.Alpha() = Alpha; if (track.OK()) { - int ind = track.FirstClusterRef(); + int32_t ind = track.FirstClusterRef(); const GPUParam& GPUrestrict() param = merger->Param(); float alphaa = param.Alpha(merger->Clusters()[ind].slice); float xx, yy, zz; @@ -1242,11 +1242,11 @@ GPUd() void GPUTPCGMTrackParam::AddCovDiagErrors(const float* GPUrestrict() erro GPUd() void GPUTPCGMTrackParam::AddCovDiagErrorsWithCorrelations(const float* GPUrestrict() errors2) { - const int diagMap[5] = {0, 2, 5, 9, 14}; + const int32_t diagMap[5] = {0, 2, 5, 9, 14}; const float oldDiag[5] = {mC[0], mC[2], mC[5], mC[9], mC[14]}; - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { mC[diagMap[i]] += errors2[i]; - for (int j = 0; j < i; j++) { + for (int32_t j = 0; j < i; j++) { mC[diagMap[i - 1] + j + 1] *= gpu::CAMath::Sqrt(mC[diagMap[i]] * mC[diagMap[j]] / (oldDiag[i] * oldDiag[j])); } } diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h index b8aa3ad935d1d..7ce6167b653d2 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h @@ -95,14 +95,14 @@ class GPUTPCGMTrackParam return mP; } GPUd() const float* GetPar() const { return mP; } - GPUd() float GetPar(int i) const { return (mP[i]); } - GPUd() void SetPar(int i, float v) { mP[i] = v; } + GPUd() float GetPar(int32_t i) const { return (mP[i]); } + GPUd() void SetPar(int32_t i, float v) { mP[i] = v; } GPUd() float& Chi2() { return mChi2; } - GPUd() int& NDF() + GPUd() int32_t& NDF() { return mNDF; } @@ -114,7 +114,7 @@ class GPUTPCGMTrackParam GPUd() float Err2QPt() const { return mC[14]; } GPUd() float GetChi2() const { return mChi2; } - GPUd() int GetNDF() const { return mNDF; } + GPUd() int32_t GetNDF() const { return mNDF; } GPUd() float GetCosPhi() const { return CAMath::Sqrt(float(1.f) - GetSinPhi() * GetSinPhi()); } @@ -130,11 +130,11 @@ class GPUTPCGMTrackParam } GPUd() const float* GetCov() const { return mC; } - GPUd() float GetCov(int i) const { return mC[i]; } + GPUd() float GetCov(int32_t i) const { return mC[i]; } - GPUd() void SetCov(int i, float v) { mC[i] = v; } + GPUd() void SetCov(int32_t i, float v) { mC[i] = v; } GPUd() void SetChi2(float v) { mChi2 = v; } - GPUd() void SetNDF(int v) { mNDF = v; } + GPUd() void SetNDF(int32_t v) { mNDF = v; } GPUd() float GetMirroredY(float Bz) const; @@ -143,34 +143,34 @@ class GPUTPCGMTrackParam GPUd() bool CheckNumericalQuality(float overrideCovYY = -1.f) const; GPUd() bool CheckCov() const; - GPUd() bool Fit(GPUTPCGMMerger* merger, int iTrk, GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, int& N, int& NTolerated, float& Alpha, int attempt = 0, float maxSinPhi = GPUCA_MAX_SIN_PHI, gputpcgmmergertypes::GPUTPCOuterParam* outerParam = nullptr); + GPUd() bool Fit(GPUTPCGMMerger* merger, int32_t iTrk, GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, int32_t& N, int32_t& NTolerated, float& Alpha, int32_t attempt = 0, float maxSinPhi = GPUCA_MAX_SIN_PHI, gputpcgmmergertypes::GPUTPCOuterParam* outerParam = nullptr); GPUd() void MoveToReference(GPUTPCGMPropagator& prop, const GPUParam& param, float& alpha); - GPUd() void MirrorTo(GPUTPCGMPropagator& prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, unsigned char row, unsigned char clusterState, bool mirrorParameters, char sector); - GPUd() int MergeDoubleRowClusters(int& ihit, int wayDirection, GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, GPUTPCGMPropagator& prop, float& xx, float& yy, float& zz, int maxN, float clAlpha, unsigned char& clusterState, bool rejectChi2); + GPUd() void MirrorTo(GPUTPCGMPropagator& prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, uint8_t row, uint8_t clusterState, bool mirrorParameters, int8_t sector); + GPUd() int32_t MergeDoubleRowClusters(int32_t& ihit, int32_t wayDirection, GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, GPUTPCGMPropagator& prop, float& xx, float& yy, float& zz, int32_t maxN, float clAlpha, uint8_t& clusterState, bool rejectChi2); - GPUd() bool AttachClustersPropagate(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int lastRow, int toRow, int iTrack, bool goodLeg, GPUTPCGMPropagator& prop, bool inFlyDirection, float maxSinPhi = GPUCA_MAX_SIN_PHI, bool checkdEdx = false); - GPUd() float AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, bool goodLeg, GPUTPCGMPropagator& prop); // Returns uncorrectedY for later use - GPUd() float AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, bool goodLeg, float Y, float Z); + GPUd() bool AttachClustersPropagate(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t lastRow, int32_t toRow, int32_t iTrack, bool goodLeg, GPUTPCGMPropagator& prop, bool inFlyDirection, float maxSinPhi = GPUCA_MAX_SIN_PHI, bool checkdEdx = false); + GPUd() float AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, bool goodLeg, GPUTPCGMPropagator& prop); // Returns uncorrectedY for later use + GPUd() float AttachClusters(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, bool goodLeg, float Y, float Z); // We force to compile these twice, for RefitLoop and for Fit, for better optimization - template - GPUd() void AttachClustersMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, float toY, GPUTPCGMPropagator& prop, bool phase2 = false); - template - GPUd() int FollowCircle(const GPUTPCGMMerger* GPUrestrict() Merger, GPUTPCGMPropagator& prop, int slice, int iRow, int iTrack, float toAlpha, float toX, float toY, int toSlice, int toRow, bool inFlyDirection, bool phase2 = false); - GPUd() void StoreAttachMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int slice, int iRow, int iTrack, float toAlpha, float toY, float toX, int toSlice, int toRow, bool inFlyDirection, float alpha); - GPUd() void StoreOuter(gputpcgmmergertypes::GPUTPCOuterParam* outerParam, const GPUTPCGMPropagator& prop, int phase); - GPUd() static void RefitLoop(const GPUTPCGMMerger* GPUrestrict() Merger, int loopIdx); + template + GPUd() void AttachClustersMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, float toY, GPUTPCGMPropagator& prop, bool phase2 = false); + template + GPUd() int32_t FollowCircle(const GPUTPCGMMerger* GPUrestrict() Merger, GPUTPCGMPropagator& prop, int32_t slice, int32_t iRow, int32_t iTrack, float toAlpha, float toX, float toY, int32_t toSlice, int32_t toRow, bool inFlyDirection, bool phase2 = false); + GPUd() void StoreAttachMirror(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t slice, int32_t iRow, int32_t iTrack, float toAlpha, float toY, float toX, int32_t toSlice, int32_t toRow, bool inFlyDirection, float alpha); + GPUd() void StoreOuter(gputpcgmmergertypes::GPUTPCOuterParam* outerParam, const GPUTPCGMPropagator& prop, int32_t phase); + GPUd() static void RefitLoop(const GPUTPCGMMerger* GPUrestrict() Merger, int32_t loopIdx); GPUd() void AddCovDiagErrors(const float* GPUrestrict() errors2); GPUd() void AddCovDiagErrorsWithCorrelations(const float* GPUrestrict() errors2); - GPUdi() void MarkClusters(GPUTPCGMMergedTrackHit* GPUrestrict() clusters, int ihitFirst, int ihitLast, int wayDirection, unsigned char state) + GPUdi() void MarkClusters(GPUTPCGMMergedTrackHit* GPUrestrict() clusters, int32_t ihitFirst, int32_t ihitLast, int32_t wayDirection, uint8_t state) { clusters[ihitFirst].state |= state; while (ihitFirst != ihitLast) { clusters[ihitFirst += wayDirection].state |= state; } } - GPUdi() void UnmarkClusters(GPUTPCGMMergedTrackHit* GPUrestrict() clusters, int ihitFirst, int ihitLast, int wayDirection, unsigned char state) + GPUdi() void UnmarkClusters(GPUTPCGMMergedTrackHit* GPUrestrict() clusters, int32_t ihitFirst, int32_t ihitLast, int32_t wayDirection, uint8_t state) { clusters[ihitFirst].state &= ~state; while (ihitFirst != ihitLast) { @@ -187,8 +187,8 @@ class GPUTPCGMTrackParam } GPUd() void Rotate(float alpha); - GPUd() void ShiftZ(const GPUTPCGMMerger* merger, int slice, float tzInner, float tzOuter, float x1, float x2); - GPUd() void ShiftZ2(const GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, int N); + GPUd() void ShiftZ(const GPUTPCGMMerger* merger, int32_t slice, float tzInner, float tzOuter, float x1, float x2); + GPUd() void ShiftZ2(const GPUTPCGMMergedTrackHit* clusters, GPUTPCGMMergedTrackHitXYZ* clustersXYZ, const GPUTPCGMMerger* merger, int32_t N); GPUd() static float Reciprocal(float x) { return 1.f / x; } GPUdi() static void Assign(float& x, bool mask, float v) @@ -198,14 +198,14 @@ class GPUTPCGMTrackParam } } - GPUdi() static void Assign(int& x, bool mask, int v) + GPUdi() static void Assign(int32_t& x, bool mask, int32_t v) { if (mask) { x = v; } } - GPUd() static void RefitTrack(GPUTPCGMMergedTrack& track, int iTrk, GPUTPCGMMerger* merger, int attempt); + GPUd() static void RefitTrack(GPUTPCGMMergedTrack& track, int32_t iTrk, GPUTPCGMMerger* merger, int32_t attempt); #if defined(GPUCA_ALIROOT_LIB) & !defined(GPUCA_GPUCODE) bool GetExtParam(AliExternalTrackParam& T, double alpha) const; @@ -223,31 +223,31 @@ class GPUTPCGMTrackParam private: GPUd() bool FollowCircleChk(float lrFactor, float toY, float toX, bool up, bool right); - GPUd() int initResetT0(); + GPUd() int32_t initResetT0(); float mX; // x position float mTZOffset; // Z offset with early transform, T offset otherwise float mP[5]; // 'active' track parameters: Y, Z, SinPhi, DzDs, q/Pt float mC[15]; // the covariance matrix for Y,Z,SinPhi,.. float mChi2; // the chi^2 value - int mNDF; // the Number of Degrees of Freedom + int32_t mNDF; // the Number of Degrees of Freedom }; struct GPUTPCGMLoopData { GPUTPCGMTrackParam param; - unsigned int track; + uint32_t track; float toY; float toX; float alpha; float toAlpha; - unsigned char slice; - unsigned char row; - char toSlice; - unsigned char toRow; - unsigned char inFlyDirection; + uint8_t slice; + uint8_t row; + int8_t toSlice; + uint8_t toRow; + uint8_t inFlyDirection; }; -GPUdi() int GPUTPCGMTrackParam::initResetT0() +GPUdi() int32_t GPUTPCGMTrackParam::initResetT0() { const float absQPt = CAMath::Abs(mP[4]); if (absQPt < (150.f / 40.f)) { diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTracksToTPCSeeds.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTracksToTPCSeeds.cxx index 692034c1414fd..1a00f2cc1abff 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTracksToTPCSeeds.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTracksToTPCSeeds.cxx @@ -33,8 +33,8 @@ void GPUTPCGMTracksToTPCSeeds::CreateSeedsFromHLTTracks(TObjArray* seeds, AliTPC return; } seeds->Clear(); - int index = 0; - for (int i = 0; i < merger->NOutputTracks(); i++) { + int32_t index = 0; + for (int32_t i = 0; i < merger->NOutputTracks(); i++) { const GPUTPCGMMergedTrack& track = merger->OutputTracks()[i]; if (!track.OK()) { continue; @@ -43,14 +43,14 @@ void GPUTPCGMTracksToTPCSeeds::CreateSeedsFromHLTTracks(TObjArray* seeds, AliTPC AliTPCtrack tr; tr.Set(track.GetParam().GetX(), track.GetAlpha(), track.GetParam().GetPar(), track.GetParam().GetCov()); AliTPCseed* seed = new (tpctracker->NextFreeSeed()) AliTPCseed(tr); - for (int j = 0; j < GPUCA_ROW_COUNT; j++) { + for (int32_t j = 0; j < GPUCA_ROW_COUNT; j++) { seed->SetClusterPointer(j, nullptr); seed->SetClusterIndex(j, -1); } - int ncls = 0; - int lastrow = -1; - int lastleg = -1; - for (int j = track.NClusters() - 1; j >= 0; j--) { + int32_t ncls = 0; + int32_t lastrow = -1; + int32_t lastleg = -1; + for (int32_t j = track.NClusters() - 1; j >= 0; j--) { const GPUTPCGMMergedTrackHit& cls = merger->Clusters()[track.FirstClusterRef() + j]; if (cls.state & GPUTPCGMMergedTrackHit::flagReject) { continue; @@ -63,7 +63,7 @@ void GPUTPCGMTracksToTPCSeeds::CreateSeedsFromHLTTracks(TObjArray* seeds, AliTPC } AliTPCtrackerRow& row = tpctracker->GetRow(cls.slice % 18, cls.row); - unsigned int clIndexOffline = 0; + uint32_t clIndexOffline = 0; AliTPCclusterMI* clOffline = row.FindNearest2(cls.y, cls.z, 0.01f, 0.01f, clIndexOffline); if (!clOffline) { continue; @@ -111,8 +111,8 @@ void GPUTPCGMTracksToTPCSeeds::UpdateParamsOuter(TObjArray* seeds) if (merger == nullptr) { return; } - int index = 0; - for (int i = 0; i < merger->NOutputTracks(); i++) { + int32_t index = 0; + for (int32_t i = 0; i < merger->NOutputTracks(); i++) { const GPUTPCGMMergedTrack& track = merger->OutputTracks()[i]; if (!track.OK()) { continue; @@ -133,8 +133,8 @@ void GPUTPCGMTracksToTPCSeeds::UpdateParamsInner(TObjArray* seeds) if (merger == nullptr) { return; } - int index = 0; - for (int i = 0; i < merger->NOutputTracks(); i++) { + int32_t index = 0; + for (int32_t i = 0; i < merger->NOutputTracks(); i++) { const GPUTPCGMMergedTrack& track = merger->OutputTracks()[i]; if (!track.OK()) { continue; diff --git a/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.cxx b/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.cxx index 45544baf99610..12253296b62fc 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.cxx @@ -24,42 +24,42 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char) +GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t) { - for (int i = iBlock * nThreads + iThread; i < GPUCA_NSLICES * merger.NMaxSingleSliceTracks(); i++) { + for (int32_t i = iBlock * nThreads + iThread; i < GPUCA_NSLICES * merger.NMaxSingleSliceTracks(); i++) { merger.TrackIDs()[i] = -1; } } template <> -GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char parameter) +GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t parameter) { if (iThread) { return; } - int iStart = parameter ? GPUCA_NSLICES : 0; - int iEnd = iStart + GPUCA_NSLICES; - for (int i = iStart + iBlock; i < iEnd; i += nBlocks) { - const int offset = merger.SliceTrackInfoFirst(i); - int* GPUrestrict() tmp = merger.TmpSortMemory() + offset; - const int n = merger.SliceTrackInfoLast(i) - merger.SliceTrackInfoFirst(i); + int32_t iStart = parameter ? GPUCA_NSLICES : 0; + int32_t iEnd = iStart + GPUCA_NSLICES; + for (int32_t i = iStart + iBlock; i < iEnd; i += nBlocks) { + const int32_t offset = merger.SliceTrackInfoFirst(i); + int32_t* GPUrestrict() tmp = merger.TmpSortMemory() + offset; + const int32_t n = merger.SliceTrackInfoLast(i) - merger.SliceTrackInfoFirst(i); if (n < 2) { continue; } - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { tmp[j] = j; } - GPUCommonAlgorithm::sort(tmp, tmp + n, [&merger, offset](const int& aa, const int& bb) { + GPUCommonAlgorithm::sort(tmp, tmp + n, [&merger, offset](const int32_t& aa, const int32_t& bb) { const auto& a = merger.SliceTrackInfos()[offset + aa]; const auto& b = merger.SliceTrackInfos()[offset + bb]; return (a.X() != b.X()) ? (a.X() < b.X()) : (a.Y() != b.Y()) ? (a.Y() < b.Y()) : (a.Z() < b.Z()); }); - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { if (tmp[j] >= 0 && tmp[j] != j) { - auto getTrackIDIndex = [&merger](const int iSlice, const int iTrack) { - const int kEnd = merger.NMaxSingleSliceTracks(); - for (int k = 0; k < kEnd; k++) { + auto getTrackIDIndex = [&merger](const int32_t iSlice, const int32_t iTrack) { + const int32_t kEnd = merger.NMaxSingleSliceTracks(); + for (int32_t k = 0; k < kEnd; k++) { if (merger.TrackIDs()[iSlice * merger.NMaxSingleSliceTracks() + k] == iTrack) { return k; } @@ -69,11 +69,11 @@ GPUdii() void GPUTPCGlobalDebugSortKernels::Thread -GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char parameter) +GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t parameter) { if (iThread || iBlock) { return; } - int* GPUrestrict() tmp = merger.TmpSortMemory(); - const int n = merger.NOutputTracks(); - for (int j = 0; j < n; j++) { + int32_t* GPUrestrict() tmp = merger.TmpSortMemory(); + const int32_t n = merger.NOutputTracks(); + for (int32_t j = 0; j < n; j++) { tmp[j] = j; } - GPUCommonAlgorithm::sortDeviceDynamic(tmp, tmp + n, [&merger](const int& aa, const int& bb) { + GPUCommonAlgorithm::sortDeviceDynamic(tmp, tmp + n, [&merger](const int32_t& aa, const int32_t& bb) { const GPUTPCGMMergedTrack& a = merger.OutputTracks()[aa]; const GPUTPCGMMergedTrack& b = merger.OutputTracks()[bb]; return (a.GetAlpha() != b.GetAlpha()) ? (a.GetAlpha() < b.GetAlpha()) : (a.GetParam().GetX() != b.GetParam().GetX()) ? (a.GetParam().GetX() < b.GetParam().GetX()) : (a.GetParam().GetY() != b.GetParam().GetY()) ? (a.GetParam().GetY() < b.GetParam().GetY()) : (a.GetParam().GetZ() < b.GetParam().GetZ()); @@ -112,23 +112,23 @@ GPUdii() void GPUTPCGlobalDebugSortKernels::Thread -GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char parameter) +GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t parameter) { if (iBlock) { return; } - const int n = merger.NOutputTracks(); - int* GPUrestrict() tmp = merger.TmpSortMemory(); - int* GPUrestrict() tmp2 = tmp + n; + const int32_t n = merger.NOutputTracks(); + int32_t* GPUrestrict() tmp = merger.TmpSortMemory(); + int32_t* GPUrestrict() tmp2 = tmp + n; if (iThread == 0) { - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { if (tmp[j] == j) { tmp2[j] = j; } else if (tmp[j] >= 0) { - int firstIdx = j; + int32_t firstIdx = j; auto firstItem = merger.OutputTracks()[firstIdx]; - int currIdx = firstIdx; - int sourceIdx = tmp[currIdx]; + int32_t currIdx = firstIdx; + int32_t sourceIdx = tmp[currIdx]; tmp2[sourceIdx] = currIdx; do { tmp[currIdx] = -1; @@ -143,21 +143,21 @@ GPUdii() void GPUTPCGlobalDebugSortKernels::Thread -GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, char parameter) +GPUdii() void GPUTPCGlobalDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger, int8_t parameter) { if (iThread) { return; } auto* borderTracks = merger.BorderTracks(iBlock); - const unsigned int n = merger.TmpCounter()[iBlock]; + const uint32_t n = merger.TmpCounter()[iBlock]; GPUCommonAlgorithm::sortDeviceDynamic(borderTracks, borderTracks + n, [](const GPUTPCGMBorderTrack& a, const GPUTPCGMBorderTrack& b) { return (a.TrackID() < b.TrackID()); }); diff --git a/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.h b/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.h index 54d39857dc46f..4abf4ecae9a7a 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.h +++ b/GPU/GPUTracking/Merger/GPUTPCGlobalDebugSortKernels.h @@ -36,8 +36,8 @@ class GPUTPCGlobalDebugSortKernels : public GPUKernelTemplate typedef GPUTPCGMMerger processorType; GPUhdi() static processorType* Processor(GPUConstantMem& processors) { return &processors.tpcMerger; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& tracker, char parameter); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& tracker, int8_t parameter); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.cxx b/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.cxx index cc6e7b5f81efc..b905c72915670 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.cxx @@ -90,7 +90,7 @@ AliHLTComponentDataType GPUTPCGlobalMergerComponent::GetOutputDataType() return kAliHLTMultipleDataType; } -int GPUTPCGlobalMergerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) +int32_t GPUTPCGlobalMergerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) { // see header file for class documentation @@ -100,7 +100,7 @@ int GPUTPCGlobalMergerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& return tgtList.size(); } -void GPUTPCGlobalMergerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) +void GPUTPCGlobalMergerComponent::GetOutputDataSize(uint64_t& constBase, double& inputMultiplier) { // see header file for class documentation // XXX TODO: Find more realistic values. @@ -130,24 +130,24 @@ void GPUTPCGlobalMergerComponent::SetDefaultConfiguration() fBenchmark.SetTimer(1, "reco"); } -int GPUTPCGlobalMergerComponent::ReadConfigurationString(const char* arguments) +int32_t GPUTPCGlobalMergerComponent::ReadConfigurationString(const char* arguments) { // Set configuration parameters for the CA merger component from the string - int iResult = 0; + int32_t iResult = 0; if (!arguments) { return iResult; } TString allArgs = arguments; TString argument; - int bMissingParam = 0; + int32_t bMissingParam = 0; TObjArray* pTokens = allArgs.Tokenize(" "); - int nArgs = pTokens ? pTokens->GetEntries() : 0; + int32_t nArgs = pTokens ? pTokens->GetEntries() : 0; - for (int i = 0; i < nArgs; i++) { + for (int32_t i = 0; i < nArgs; i++) { argument = ((TObjString*)pTokens->At(i))->GetString(); if (argument.IsNull()) { continue; @@ -213,7 +213,7 @@ int GPUTPCGlobalMergerComponent::ReadConfigurationString(const char* arguments) return iResult; } -int GPUTPCGlobalMergerComponent::ReadCDBEntry(const char* cdbEntry, const char* chainId) +int32_t GPUTPCGlobalMergerComponent::ReadCDBEntry(const char* cdbEntry, const char* chainId) { // see header file for class documentation @@ -245,7 +245,7 @@ int GPUTPCGlobalMergerComponent::ReadCDBEntry(const char* cdbEntry, const char* return ReadConfigurationString(pString->GetString().Data()); } -int GPUTPCGlobalMergerComponent::Configure(const char* cdbEntry, const char* chainId, const char* commandLine) +int32_t GPUTPCGlobalMergerComponent::Configure(const char* cdbEntry, const char* chainId, const char* commandLine) { // Configure the component // There are few levels of configuration, @@ -257,7 +257,7 @@ int GPUTPCGlobalMergerComponent::Configure(const char* cdbEntry, const char* cha //* read the default CDB entry - int iResult = ReadCDBEntry(nullptr, chainId); + int32_t iResult = ReadCDBEntry(nullptr, chainId); if (iResult) { return iResult; } @@ -323,31 +323,31 @@ int GPUTPCGlobalMergerComponent::Configure(const char* cdbEntry, const char* cha return 0; } -int GPUTPCGlobalMergerComponent::DoInit(int argc, const char** argv) +int32_t GPUTPCGlobalMergerComponent::DoInit(int argc, const char** argv) { // see header file for class documentation TString arguments = ""; - for (int i = 0; i < argc; i++) { + for (int32_t i = 0; i < argc; i++) { if (!arguments.IsNull()) { arguments += " "; } arguments += argv[i]; } - int retVal = Configure(nullptr, nullptr, arguments.Data()); + int32_t retVal = Configure(nullptr, nullptr, arguments.Data()); return retVal; } -int GPUTPCGlobalMergerComponent::Reconfigure(const char* cdbEntry, const char* chainId) +int32_t GPUTPCGlobalMergerComponent::Reconfigure(const char* cdbEntry, const char* chainId) { // Reconfigure the component from OCDB return Configure(cdbEntry, chainId, nullptr); } -int GPUTPCGlobalMergerComponent::DoDeinit() +int32_t GPUTPCGlobalMergerComponent::DoDeinit() { // see header file for class documentation if (fChain == fgCurrentMergerReconstruction) { @@ -359,11 +359,11 @@ int GPUTPCGlobalMergerComponent::DoDeinit() return 0; } -int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks) +int32_t GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks) { // see header file for class documentation - int iResult = 0; - unsigned int maxBufferSize = size; + int32_t iResult = 0; + uint32_t maxBufferSize = size; size = 0; @@ -378,7 +378,7 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData fChain->GetTPCMerger().Clear(); - int nSlicesSet = 0; + int32_t nSlicesSet = 0; const AliHLTComponentBlockData* const blocksEnd = blocks + evtData.fBlockCnt; for (const AliHLTComponentBlockData* block = blocks; block < blocksEnd; ++block) { if (block->fDataType != GPUTPCDefinitions::fgkTrackletsDataType) { @@ -387,7 +387,7 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData fBenchmark.AddInput(block->fSize); - int slice = AliHLTTPCDefinitions::GetMinSliceNr(*block); + int32_t slice = AliHLTTPCDefinitions::GetMinSliceNr(*block); if (slice < 0 || slice >= AliHLTTPCGeometry::GetNSlice()) { HLTError("invalid slice number %d extracted from specification 0x%08lx, skipping block of type %s", slice, block->fSpecification, DataType2Text(block->fDataType).c_str()); // just remember the error, if there are other valid blocks ignore the error, return code otherwise @@ -418,22 +418,22 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData fBenchmark.Stop(1); // Fill output - unsigned int mySize = 0; + uint32_t mySize = 0; { AliHLTTracksData* outPtr = (AliHLTTracksData*)(outputPtr); AliHLTExternalTrackParam* currOutTrack = outPtr->fTracklets; mySize = ((AliHLTUInt8_t*)currOutTrack) - ((AliHLTUInt8_t*)outputPtr); outPtr->fCount = 0; - int nTracks = fChain->GetTPCMerger().NOutputTracks(); + int32_t nTracks = fChain->GetTPCMerger().NOutputTracks(); - for (int itr = 0; itr < nTracks; itr++) { + for (int32_t itr = 0; itr < nTracks; itr++) { // convert GPUTPCGMMergedTrack to AliHLTTrack const GPUTPCGMMergedTrack& track = fChain->GetTPCMerger().OutputTracks()[itr]; if (!track.OK()) { continue; } - unsigned int dSize = sizeof(AliHLTExternalTrackParam) + track.NClusters() * sizeof(unsigned int); + uint32_t dSize = sizeof(AliHLTExternalTrackParam) + track.NClusters() * sizeof(uint32_t); if (mySize + dSize > maxBufferSize) { HLTWarning("Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, nTracks - itr + 1); @@ -459,19 +459,19 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData currOutTrack->fq1Pt = tp.GetSigned1Pt(); currOutTrack->fSinPhi = tp.GetSnp(); currOutTrack->fTgl = tp.GetTgl(); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { currOutTrack->fC[i] = tp.GetCovariance()[i]; } currOutTrack->fTrackID = itr; currOutTrack->fFlags = 0; currOutTrack->fNPoints = 0; - for (int i = 0; i < track.NClusters(); i++) { + for (int32_t i = 0; i < track.NClusters(); i++) { if (fChain->GetTPCMerger().Clusters()[track.FirstClusterRef() + i].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } currOutTrack->fPointIDs[currOutTrack->fNPoints++] = fChain->GetTPCMerger().Clusters()[track.FirstClusterRef() + i].num; } - dSize = sizeof(AliHLTExternalTrackParam) + currOutTrack->fNPoints * sizeof(unsigned int); + dSize = sizeof(AliHLTExternalTrackParam) + currOutTrack->fNPoints * sizeof(uint32_t); currOutTrack = (AliHLTExternalTrackParam*)(((Byte_t*)currOutTrack) + dSize); mySize += dSize; @@ -491,19 +491,19 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData } if (fNWays > 1 && fNWaysOuter) { - unsigned int newSize = 0; + uint32_t newSize = 0; AliHLTTracksData* outPtr = (AliHLTTracksData*)(outputPtr + size); AliHLTExternalTrackParam* currOutTrack = outPtr->fTracklets; newSize = ((AliHLTUInt8_t*)currOutTrack) - (outputPtr + size); outPtr->fCount = 0; - int nTracks = fChain->GetTPCMerger().NOutputTracks(); + int32_t nTracks = fChain->GetTPCMerger().NOutputTracks(); - for (int itr = 0; itr < nTracks; itr++) { + for (int32_t itr = 0; itr < nTracks; itr++) { const GPUTPCGMMergedTrack& track = fChain->GetTPCMerger().OutputTracks()[itr]; if (!track.OK()) { continue; } - unsigned int dSize = sizeof(AliHLTExternalTrackParam); + uint32_t dSize = sizeof(AliHLTExternalTrackParam); if (mySize + newSize + dSize > maxBufferSize) { HLTWarning("Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize + newSize + dSize, nTracks - itr + 1); @@ -529,7 +529,7 @@ int GPUTPCGlobalMergerComponent::DoEvent(const AliHLTComponentEventData& evtData currOutTrack->fq1Pt = track.OuterParam().P[4]; currOutTrack->fSinPhi = track.OuterParam().P[2]; currOutTrack->fTgl = track.OuterParam().P[3]; - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { currOutTrack->fC[i] = track.OuterParam().C[i]; } currOutTrack->fTrackID = itr; diff --git a/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.h b/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.h index 414a23fbc2c9a..b34c5d3d799b6 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.h +++ b/GPU/GPUTracking/Merger/GPUTPCGlobalMergerComponent.h @@ -70,7 +70,7 @@ class GPUTPCGlobalMergerComponent : public AliHLTProcessor * @copydoc AliHLTComponent::GetInputDataTypes */ void GetInputDataTypes(AliHLTComponentDataTypeList& list); - int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); + int32_t GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); /** * @copydoc AliHLTComponent::GetOutputDataType @@ -80,7 +80,7 @@ class GPUTPCGlobalMergerComponent : public AliHLTProcessor /** * @copydoc AliHLTComponent::GetOutputDataSize */ - virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + virtual void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); /** * @copydoc AliHLTComponent::Spawn @@ -97,20 +97,20 @@ class GPUTPCGlobalMergerComponent : public AliHLTProcessor /** * @copydoc AliHLTComponent::DoInit */ - int DoInit(int argc, const char** argv); + int32_t DoInit(int argc, const char** argv); /** * @copydoc AliHLTComponent::DoDeinit */ - int DoDeinit(); + int32_t DoDeinit(); /** reconfigure **/ - int Reconfigure(const char* cdbEntry, const char* chainId); + int32_t Reconfigure(const char* cdbEntry, const char* chainId); /** * @copydoc @ref AliHLTProcessor::DoEvent */ - int DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks); + int32_t DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks); using AliHLTProcessor::DoEvent; @@ -123,17 +123,17 @@ class GPUTPCGlobalMergerComponent : public AliHLTProcessor /** set configuration parameters **/ void SetDefaultConfiguration(); - int ReadConfigurationString(const char* arguments); - int ReadCDBEntry(const char* cdbEntry, const char* chainId); - int Configure(const char* cdbEntry, const char* chainId, const char* commandLine); + int32_t ReadConfigurationString(const char* arguments); + int32_t ReadCDBEntry(const char* cdbEntry, const char* chainId); + int32_t Configure(const char* cdbEntry, const char* chainId, const char* commandLine); /** the global merger object */ double fSolenoidBz; // magnetic field double fClusterErrorCorrectionY; // correction for the cluster error during pre-fit double fClusterErrorCorrectionZ; // correction for the cluster error during pre-fit - int fNWays; // Setting for merger - char fNWaysOuter; // Store outer param after n-way fit + int32_t fNWays; // Setting for merger + int8_t fNWaysOuter; // Store outer param after n-way fit bool fNoClear; // Do not clear memory after processing an event static const GPUCA_NAMESPACE::gpu::GPUChainTracking* fgCurrentMergerReconstruction; // Pointer to current merger in case memory is not cleared after processing the event AliHLTComponentBenchmark fBenchmark; // benchmark diff --git a/GPU/GPUTracking/Merger/macros/checkPropagation.C b/GPU/GPUTracking/Merger/macros/checkPropagation.C index bdceb8fde999f..5431a3983fca3 100644 --- a/GPU/GPUTracking/Merger/macros/checkPropagation.C +++ b/GPU/GPUTracking/Merger/macros/checkPropagation.C @@ -15,7 +15,7 @@ const double kTwoPi = TMath::TwoPi(); // 2.*kPi; const double kSliceDAngle = kTwoPi / 18.; const double kSliceAngleOffset = kSliceDAngle / 2; -int GetSlice(double GlobalPhi) +int32_t GetSlice(double GlobalPhi) { double phi = GlobalPhi; // std::cout<<" GetSlice: phi = "<Uniform(-60,60)*TMath::Pi()/180.; double pt = .1 * std::pow(10, gRandom->Uniform(0, 2.2)); double q = 1.; - int iSlice = GetSlice(phi); + int32_t iSlice = GetSlice(phi); phi = phi - GetSliceAngle(iSlice); // std::cout<<"phi = "<=50 ) break; //SG!!! float xRow = geo.Row2X(iRow); // transport to row - int err = 0; - for (int itry = 0; itry < 1; itry++) { + int32_t err = 0; + for (int32_t itry = 0; itry < 1; itry++) { double alpha = GetSliceAngle(iSlice); float B[3]; prop.GetBxByBz(alpha, t.GetX(), t.GetY(), t.GetZ(), B); @@ -158,7 +158,7 @@ int checkPropagation() break; } // rotate track coordinate system to current sector - int isNewSlice = RecalculateSlice(t, t0, iSlice); + int32_t isNewSlice = RecalculateSlice(t, t0, iSlice); if (!isNewSlice) { break; } else { @@ -181,15 +181,15 @@ int checkPropagation() hDiff[2]->Fill(dz); // cout<<" x "<Divide(3); - int ipad = 1; - for (int i = 0; i < 3; i++) { + int32_t ipad = 1; + for (int32_t i = 0; i < 3; i++) { c->cd(ipad++); if (tout) { diff --git a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldIts.C b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldIts.C index a61004ce6f828..937d5a58dfc2d 100644 --- a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldIts.C +++ b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldIts.C @@ -1,4 +1,4 @@ -int fitPolynomialFieldIts() +int32_t fitPolynomialFieldIts() { gSystem->Load("libAliHLTTPC"); GPUTPCGMPolynomialField polyField; diff --git a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTpc.C b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTpc.C index 7b1424163a6c6..6ffa2bbe4babe 100644 --- a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTpc.C +++ b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTpc.C @@ -1,4 +1,4 @@ -int fitPolynomialFieldTpc() +int32_t fitPolynomialFieldTpc() { gSystem->Load("libAliHLTTPC"); GPUTPCGMPolynomialField polyField; diff --git a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTrd.C b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTrd.C index debfba0c34cf0..bc515e1fa5849 100644 --- a/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTrd.C +++ b/GPU/GPUTracking/Merger/macros/fitPolynomialFieldTrd.C @@ -1,4 +1,4 @@ -int fitPolynomialFieldTrd() +int32_t fitPolynomialFieldTrd() { gSystem->Load("libAliHLTTPC"); GPUTPCGMPolynomialField polyField; diff --git a/GPU/GPUTracking/Refit/GPUTrackParamConvert.h b/GPU/GPUTracking/Refit/GPUTrackParamConvert.h index 846037ddf0039..376471595e6fd 100644 --- a/GPU/GPUTracking/Refit/GPUTrackParamConvert.h +++ b/GPU/GPUTracking/Refit/GPUTrackParamConvert.h @@ -28,20 +28,20 @@ namespace o2::gpu GPUdi() static void convertTrackParam(GPUTPCGMTrackParam& trk, const o2::track::TrackParCov& trkX) { - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { trk.Par()[i] = trkX.getParams()[i]; } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { trk.Cov()[i] = trkX.getCov()[i]; } trk.X() = trkX.getX(); } GPUdi() static void convertTrackParam(o2::track::TrackParCov& trk, const GPUTPCGMTrackParam& trkX) { - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { trk.setParam(trkX.GetPar()[i], i); } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { trk.setCov(trkX.GetCov()[i], i); } trk.setX(trkX.GetX()); diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx index a78565f020ab1..25be5b3647d57 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx @@ -35,7 +35,7 @@ using namespace o2::track; using namespace o2::base; using namespace o2::tpc; -static constexpr int kIGNORE_ENDS = 3; +static constexpr int32_t kIGNORE_ENDS = 3; #define IgnoreErrors(SNP) \ if (mIgnoreErrorsOnTrackEnds) { \ @@ -207,20 +207,20 @@ GPUd() static const float* getPar(const GPUTPCGMTrackParam& trk) { return trk.Ge GPUd() static const float* getPar(const TrackParCov& trk) { return trk.getParams(); } template -GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) +GPUd() int32_t GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) { - CADEBUG(int ii; printf("\nRefitting track\n")); + CADEBUG(int32_t ii; printf("\nRefitting track\n")); typename refitTrackTypes::propagator prop; S trk; float TrackParCovChi2 = 0.f; convertTrack::propagator>(trk, trkX, prop, &TrackParCovChi2); - int begin = 0, count; + int32_t begin = 0, count; float tOffset; if constexpr (std::is_same_v) { count = trkX.NClusters(); if (trkX.Looper()) { - int leg = mPtrackHits[trkX.FirstClusterRef() + trkX.NClusters() - 1].leg; - for (int i = trkX.NClusters() - 2; i > 0; i--) { + int32_t leg = mPtrackHits[trkX.FirstClusterRef() + trkX.NClusters() - 1].leg; + for (int32_t i = trkX.NClusters() - 2; i > 0; i--) { if (mPtrackHits[trkX.FirstClusterRef() + i].leg != leg) { begin = i + 1; break; @@ -241,21 +241,21 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) CADEBUG(printf("\t%21sInit Alpha %8.3f , X %8.3f - Y %8.3f, Z %8.3f - QPt %7.2f (%7.2f), SP %5.2f (%5.2f) --- Cov sY %8.3f sZ %8.3f sSP %8.3f sPt %8.3f\n", "", prop.GetAlpha(), trk.GetX(), trk.Par()[0], trk.Par()[1], trk.Par()[4], prop.GetQPt0(), trk.Par()[2], prop.GetSinPhi0(), sqrtf(trk.Cov()[0]), sqrtf(trk.Cov()[2]), sqrtf(trk.Cov()[5]), sqrtf(trk.Cov()[14]))); } - int direction = outward ? -1 : 1; - int start = outward ? count - 1 : begin; - int stop = outward ? begin - 1 : count; + int32_t direction = outward ? -1 : 1; + int32_t start = outward ? count - 1 : begin; + int32_t stop = outward ? begin - 1 : count; const ClusterNative* cl = nullptr; uint8_t sector = 255, row = 255; - int lastSector = -1, currentSector = -1, currentRow = -1; - short clusterState = 0, nextState = 0; - int nFitted = 0; + int32_t lastSector = -1, currentSector = -1, currentRow = -1; + int16_t clusterState = 0, nextState = 0; + int32_t nFitted = 0; float sumInvSqrtCharge = 0.f; - int nAvgCharge = 0; + int32_t nAvgCharge = 0; - for (int i = start; i != stop; i += cl ? 0 : direction) { + for (int32_t i = start; i != stop; i += cl ? 0 : direction) { float x = 0, y = 0, z = 0, charge = 0; // FIXME: initialization unneeded, but GCC incorrectly produces uninitialized warnings otherwise float time = 0.f, invCharge = 0.f, invSqrtCharge = 0.f; // Same here... - int clusters = 0; + int32_t clusters = 0; while (true) { if (!cl) { CADEBUG(ii = i); @@ -291,7 +291,7 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) } if (clusters == 0) { mPfastTransformHelper->Transform(sector, row, cl->getPad(), cl->getTime(), x, y, z, tOffset); - CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", ii, count, row, mPparam->Alpha(sector), (int)sector, x, y, z, (int)nextState)); + CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", ii, count, row, mPparam->Alpha(sector), (int32_t)sector, x, y, z, (int32_t)nextState)); currentRow = row; currentSector = sector; charge = cl->qTot; @@ -302,7 +302,7 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) } else { float xx, yy, zz; mPfastTransformHelper->Transform(sector, row, cl->getPad(), cl->getTime(), xx, yy, zz, tOffset); - CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", ii, count, row, mPparam->Alpha(sector), (int)sector, xx, yy, zz, (int)nextState)); + CADEBUG(printf("\tHit %3d/%3d Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", ii, count, row, mPparam->Alpha(sector), (int32_t)sector, xx, yy, zz, (int32_t)nextState)); x += xx * cl->qTot; y += yy * cl->qTot; z += zz * cl->qTot; @@ -324,7 +324,7 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) x /= charge; y /= charge; z /= charge; - CADEBUG(printf("\tMerged Hit Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", row, mPparam->Alpha(sector), (int)sector, x, y, z, (int)clusterState)); + CADEBUG(printf("\tMerged Hit Row %3d: Cluster Alpha %8.3f %3d, X %8.3f - Y %8.3f, Z %8.3f - State %d\n", row, mPparam->Alpha(sector), (int32_t)sector, x, y, z, (int32_t)clusterState)); } float invAvgCharge = (sumInvSqrtCharge += invSqrtCharge) / ++nAvgCharge; @@ -422,12 +422,12 @@ GPUd() int GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov) } #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. -template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); -template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); -template GPUdni() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); -template GPUdni() int GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); -template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); -template GPUdni() int GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(TrackTPC& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); +template GPUdni() int32_t GPUTrackingRefit::RefitTrack(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov); #endif #ifndef GPUCA_GPUCODE diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefit.h b/GPU/GPUTracking/Refit/GPUTrackingRefit.h index ece3444668c07..2cc414bbc2d81 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefit.h +++ b/GPU/GPUTracking/Refit/GPUTrackingRefit.h @@ -15,9 +15,6 @@ #ifndef GPUTRACKINGREFIT_H #define GPUTRACKINGREFIT_H -#ifndef GPUCA_GPUCODE_DEVICE -#include -#endif #include "GPUDef.h" #include "GPUProcessor.h" @@ -60,18 +57,18 @@ struct GPUTPCGMMergedTrackHit; class GPUTrackingRefit { public: - void SetClusterStateArray(const unsigned char* v) { mPclusterState = v; } + void SetClusterStateArray(const uint8_t* v) { mPclusterState = v; } void SetPtrsFromGPUConstantMem(const GPUConstantMem* v, MEM_CONSTANT(GPUParam) * p = nullptr); void SetPropagator(const o2::base::Propagator* v) { mPpropagator = v; } void SetClusterNative(const o2::tpc::ClusterNativeAccess* v) { mPclusterNative = v; } void SetTrackHits(const GPUTPCGMMergedTrackHit* v) { mPtrackHits = v; } - void SetTrackHitReferences(const unsigned int* v) { mPtrackHitReferences = v; } + void SetTrackHitReferences(const uint32_t* v) { mPtrackHitReferences = v; } void SetFastTransformHelper(const CorrectionMapsHelper* v) { mPfastTransformHelper = v; } void SetGPUParam(const MEM_CONSTANT(GPUParam) * v) { mPparam = v; } - GPUd() int RefitTrackAsGPU(GPUTPCGMMergedTrack& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } - GPUd() int RefitTrackAsTrackParCov(GPUTPCGMMergedTrack& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } - GPUd() int RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } - GPUd() int RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } + GPUd() int32_t RefitTrackAsGPU(GPUTPCGMMergedTrack& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } + GPUd() int32_t RefitTrackAsTrackParCov(GPUTPCGMMergedTrack& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } + GPUd() int32_t RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } + GPUd() int32_t RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false) { return RefitTrack(trk, outward, resetCov); } struct TrackParCovWithArgs { o2::track::TrackParCov& trk; @@ -79,30 +76,30 @@ class GPUTrackingRefit float time0; float* chi2; }; - GPUd() int RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false) + GPUd() int32_t RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false) { TrackParCovWithArgs x{trk, clusRef, time0, chi2}; return RefitTrack(x, outward, resetCov); } - GPUd() int RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false) + GPUd() int32_t RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false) { TrackParCovWithArgs x{trk, clusRef, time0, chi2}; return RefitTrack(x, outward, resetCov); } - bool mIgnoreErrorsOnTrackEnds = true; // Ignore errors during propagation / update at the beginning / end of tracks for short tracks / tracks with high incl. angle + bool mIgnoreErrorsOnTrackEnds = true; // Ignore errors during propagation / update at the beginning / end of tracks for int16_t tracks / tracks with high incl. angle private: - const unsigned char* mPclusterState = nullptr; // Ptr to shared cluster state + const uint8_t* mPclusterState = nullptr; // Ptr to shared cluster state const o2::base::Propagator* mPpropagator = nullptr; // Ptr to propagator for TrackParCov track model const o2::base::MatLayerCylSet* mPmatLUT = nullptr; // Ptr to material LUT const o2::tpc::ClusterNativeAccess* mPclusterNative = nullptr; // Ptr to cluster native access structure const GPUTPCGMMergedTrackHit* mPtrackHits = nullptr; // Ptr to hits for GPUTPCGMMergedTrack tracks - const unsigned int* mPtrackHitReferences = nullptr; // Ptr to hits for TrackTPC tracks + const uint32_t* mPtrackHitReferences = nullptr; // Ptr to hits for TrackTPC tracks const CorrectionMapsHelper* mPfastTransformHelper = nullptr; // Ptr to TPC fast transform object helper const MEM_CONSTANT(GPUParam) * mPparam = nullptr; // Ptr to GPUParam template - GPUd() int RefitTrack(T& trk, bool outward, bool resetCov); + GPUd() int32_t RefitTrack(T& trk, bool outward, bool resetCov); template GPUd() void convertTrack(T& trk, const S& trkX, U& prop, float* chi2); template diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx index 87005299b9484..6baea86f05d36 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx @@ -18,14 +18,14 @@ using namespace GPUCA_NAMESPACE::gpu; -template -GPUdii() void GPUTrackingRefitKernel::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +template +GPUdii() void GPUTrackingRefitKernel::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { auto& refit = processors.trackingRefit; - for (unsigned int i = get_global_id(0); i < processors.ioPtrs.nMergedTracks; i += get_global_size(0)) { + for (uint32_t i = get_global_id(0); i < processors.ioPtrs.nMergedTracks; i += get_global_size(0)) { if (refit.mPTracks[i].OK()) { GPUTPCGMMergedTrack trk = refit.mPTracks[i]; - int retval; + int32_t retval; if constexpr (I == mode0asGPU) { retval = refit.RefitTrackAsGPU(trk, false, true); } else if constexpr (I == mode1asTrackParCov) { @@ -45,6 +45,6 @@ GPUdii() void GPUTrackingRefitKernel::Thread(int nBlocks, int nThreads, int iBlo } } #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. -template GPUdni() void GPUTrackingRefitKernel::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); -template GPUdni() void GPUTrackingRefitKernel::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); +template GPUdni() void GPUTrackingRefitKernel::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); +template GPUdni() void GPUTrackingRefitKernel::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); #endif diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.h b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.h index e0d85ef85156c..d52a3f3fdedb5 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.h +++ b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.h @@ -26,13 +26,13 @@ class GPUTrackingRefitKernel : public GPUKernelTemplate public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::TPCCompression; } - enum K : int { + enum K : int32_t { mode0asGPU = 0, mode1asTrackParCov = 1, }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); }; } // namespace o2::gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCBaseTrackParam.h b/GPU/GPUTracking/SliceTracker/GPUTPCBaseTrackParam.h index 28390eb50e3d0..28fa54544e292 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCBaseTrackParam.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCBaseTrackParam.h @@ -47,8 +47,8 @@ struct GPUTPCBaseTrackParam { GPUd() float Err2DzDs() const { return mC[9]; } GPUd() float Err2QPt() const { return mC[14]; } GPUhd() const float* Cov() const { return mC; } - GPUd() float GetCov(int i) const { return mC[i]; } - GPUhd() void SetCov(int i, float v) { mC[i] = v; } + GPUd() float GetCov(int32_t i) const { return mC[i]; } + GPUhd() void SetCov(int32_t i, float v) { mC[i] = v; } GPUhd() float GetX() const { return mX; } GPUhd() float GetY() const { return mP[0]; } @@ -62,9 +62,9 @@ struct GPUTPCBaseTrackParam { GPUhd() MakeType(const float*) Par() const { return mP; } GPUd() const MakeType(float*) GetPar() const { return mP; } - GPUd() float GetPar(int i) const { return (mP[i]); } + GPUd() float GetPar(int32_t i) const { return (mP[i]); } - GPUhd() void SetPar(int i, float v) { mP[i] = v; } + GPUhd() void SetPar(int32_t i, float v) { mP[i] = v; } GPUd() void SetX(float v) { mX = v; } GPUd() void SetY(float v) { mP[0] = v; } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCClusterData.h b/GPU/GPUTracking/SliceTracker/GPUTPCClusterData.h index c84e3de708346..cf35efbd8af6c 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCClusterData.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCClusterData.h @@ -22,9 +22,9 @@ namespace GPUCA_NAMESPACE namespace gpu { struct GPUTPCClusterData { - int id; - short row; - short flags; + int32_t id; + int16_t row; + int16_t flags; float x; float y; float z; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.cxx index 84c6c65a8a7b9..18813d53932d8 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.cxx @@ -18,36 +18,36 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCCreateOccupancyMap::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, GPUTPCClusterOccupancyMapBin* GPUrestrict() map) +GPUdii() void GPUTPCCreateOccupancyMap::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, GPUTPCClusterOccupancyMapBin* GPUrestrict() map) { const GPUTrackingInOutPointers& GPUrestrict() ioPtrs = processors.ioPtrs; const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = ioPtrs.clustersNative; GPUParam& GPUrestrict() param = processors.param; - const int iSliceRow = iBlock * nThreads + iThread; + const int32_t iSliceRow = iBlock * nThreads + iThread; if (iSliceRow >= GPUCA_ROW_COUNT * GPUCA_NSLICES) { return; } - const unsigned int iSlice = iSliceRow / GPUCA_ROW_COUNT; - const unsigned int iRow = iSliceRow % GPUCA_ROW_COUNT; - for (unsigned int i = 0; i < clusters->nClusters[iSlice][iRow]; i++) { - const unsigned int bin = clusters->clusters[iSlice][iRow][i].getTime() / param.rec.tpc.occupancyMapTimeBins; + const uint32_t iSlice = iSliceRow / GPUCA_ROW_COUNT; + const uint32_t iRow = iSliceRow % GPUCA_ROW_COUNT; + for (uint32_t i = 0; i < clusters->nClusters[iSlice][iRow]; i++) { + const uint32_t bin = clusters->clusters[iSlice][iRow][i].getTime() / param.rec.tpc.occupancyMapTimeBins; map[bin].bin[iSlice][iRow]++; } } template <> -GPUdii() void GPUTPCCreateOccupancyMap::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, GPUTPCClusterOccupancyMapBin* GPUrestrict() map, unsigned int* GPUrestrict() output) +GPUdii() void GPUTPCCreateOccupancyMap::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, GPUTPCClusterOccupancyMapBin* GPUrestrict() map, uint32_t* GPUrestrict() output) { GPUParam& GPUrestrict() param = processors.param; - const unsigned int bin = iBlock * nThreads + iThread; + const uint32_t bin = iBlock * nThreads + iThread; if (bin >= GPUTPCClusterOccupancyMapBin::getNBins(param)) { return; } - int binmin = CAMath::Max(0, bin - param.rec.tpc.occupancyMapTimeBinsAverage); - int binmax = CAMath::Min(GPUTPCClusterOccupancyMapBin::getNBins(param), bin + param.rec.tpc.occupancyMapTimeBinsAverage + 1); - unsigned int sum = 0; - for (int i = binmin; i < binmax; i++) { - for (int iSliceRow = 0; iSliceRow < GPUCA_NSLICES * GPUCA_ROW_COUNT; iSliceRow++) { + int32_t binmin = CAMath::Max(0, bin - param.rec.tpc.occupancyMapTimeBinsAverage); + int32_t binmax = CAMath::Min(GPUTPCClusterOccupancyMapBin::getNBins(param), bin + param.rec.tpc.occupancyMapTimeBinsAverage + 1); + uint32_t sum = 0; + for (int32_t i = binmin; i < binmax; i++) { + for (int32_t iSliceRow = 0; iSliceRow < GPUCA_NSLICES * GPUCA_ROW_COUNT; iSliceRow++) { sum += (&map[i].bin[0][0])[iSliceRow]; } } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.h b/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.h index 0cfd5dd45d9b3..86a1a66eeef43 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCCreateOccupancyMap.h @@ -30,8 +30,8 @@ class GPUTPCCreateOccupancyMap : public GPUKernelTemplate fill = 0, fold = 1 }; GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::TPCSliceTracking; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, Args... args); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.cxx index 6990626fa0ecb..3ddedd702f784 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.cxx @@ -19,7 +19,7 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCCreateSliceData::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCCreateSliceData::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { tracker.Data().InitFromClusterData(nBlocks, nThreads, iBlock, iThread, tracker.GetConstantMem(), tracker.ISlice(), s.tmp); } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.h b/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.h index 2271296888d47..9a64d04e7ca6d 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCCreateSliceData.h @@ -40,8 +40,8 @@ class GPUTPCCreateSliceData : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCDef.h b/GPU/GPUTracking/SliceTracker/GPUTPCDef.h index 12548078dc5f5..a134954451e8c 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCDef.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCDef.h @@ -26,11 +26,11 @@ namespace GPUCA_NAMESPACE namespace gpu { #if defined(GPUCA_O2_LIB) || defined(GPUCA_O2_INTERFACE) -typedef unsigned int calink; -typedef unsigned int cahit; +typedef uint32_t calink; +typedef uint32_t cahit; #else -typedef unsigned int calink; -typedef unsigned int cahit; +typedef uint32_t calink; +typedef uint32_t cahit; #endif struct cahit2 { cahit x, y; }; } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.cxx index 9ce30210b975a..e8d7a405261f2 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.cxx @@ -24,9 +24,9 @@ using namespace GPUCA_NAMESPACE::gpu; #if !defined(__OPENCL__) || defined(__OPENCLCPP__) -GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, const GPUTPCTracker& GPUrestrict() sliceSource, int iTrack, int rowIndex, float angle, int direction) +GPUd() int32_t GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, const GPUTPCTracker& GPUrestrict() sliceSource, int32_t iTrack, int32_t rowIndex, float angle, int32_t direction) { - /*for (int j = 0;j < Tracks()[j].NHits();j++) + /*for (int32_t j = 0;j < Tracks()[j].NHits();j++) { GPUInfo("Hit %3d: Row %3d: X %3.7lf Y %3.7lf", j, mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex(), Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).X(), (float) Data().HitDataY(Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()), mTrackHits[Tracks()[iTrack].FirstHitID() + j].HitIndex()) * Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).HstepY() + Row(mTrackHits[Tracks()[iTrack].FirstHitID() + j].RowIndex()).Grid().YMin()); @@ -47,7 +47,7 @@ GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker } // GPUInfo("Rotated X %f Y %f Z %f SinPhi %f DzDs %f QPt %f SignCosPhi %f", tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt(), tParam.SignCosPhi()); - int maxRowGap = 10; + int32_t maxRowGap = 10; GPUTPCTrackLinearisation t0(tParam); do { rowIndex += direction; @@ -70,16 +70,16 @@ GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker } calink rowHits[GPUCA_ROW_COUNT]; - int nHits = GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(tracker, smem, tParam, rowIndex, direction, 0, rowHits); + int32_t nHits = GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(tracker, smem, tParam, rowIndex, direction, 0, rowHits); if (nHits >= tracker.Param().rec.tpc.globalTrackingMinHits) { // GPUInfo("%d hits found", nHits); - unsigned int hitId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTrackHits, (unsigned int)nHits); + uint32_t hitId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTrackHits, (uint32_t)nHits); if (hitId + nHits > tracker.NMaxTrackHits()) { tracker.raiseError(GPUErrors::ERROR_GLOBAL_TRACKING_TRACK_HIT_OVERFLOW, tracker.ISlice(), hitId + nHits, tracker.NMaxTrackHits()); CAMath::AtomicExch(&tracker.CommonMemory()->nTrackHits, tracker.NMaxTrackHits()); return 0; } - unsigned int trackId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTracks, 1u); + uint32_t trackId = CAMath::AtomicAdd(&tracker.CommonMemory()->nTracks, 1u); if (trackId >= tracker.NMaxTracks()) { // >= since will increase by 1 tracker.raiseError(GPUErrors::ERROR_GLOBAL_TRACKING_TRACK_OVERFLOW, tracker.ISlice(), trackId, tracker.NMaxTracks()); CAMath::AtomicExch(&tracker.CommonMemory()->nTracks, tracker.NMaxTracks()); @@ -87,7 +87,7 @@ GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker } if (direction == 1) { - int i = 0; + int32_t i = 0; while (i < nHits) { const calink rowHit = rowHits[rowIndex]; if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) { @@ -99,7 +99,7 @@ GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker rowIndex++; } } else { - int i = nHits - 1; + int32_t i = nHits - 1; while (i >= 0) { const calink rowHit = rowHits[rowIndex]; if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) { @@ -120,13 +120,13 @@ GPUd() int GPUTPCGlobalTracking::PerformGlobalTrackingRun(GPUTPCTracker& tracker return (nHits >= tracker.Param().rec.tpc.globalTrackingMinHits); } -GPUd() void GPUTPCGlobalTracking::PerformGlobalTracking(int nBlocks, int nThreads, int iBlock, int iThread, const GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, GPUTPCTracker& GPUrestrict() sliceTarget, bool right) +GPUd() void GPUTPCGlobalTracking::PerformGlobalTracking(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, GPUTPCTracker& GPUrestrict() sliceTarget, bool right) { - for (int i = iBlock * nThreads + iThread; i < tracker.CommonMemory()->nLocalTracks; i += nThreads * nBlocks) { + for (int32_t i = iBlock * nThreads + iThread; i < tracker.CommonMemory()->nLocalTracks; i += nThreads * nBlocks) { { - const int tmpHit = tracker.Tracks()[i].FirstHitID(); + const int32_t tmpHit = tracker.Tracks()[i].FirstHitID(); if (tracker.TrackHits()[tmpHit].RowIndex() >= tracker.Param().rec.tpc.globalTrackingMinRows && tracker.TrackHits()[tmpHit].RowIndex() < tracker.Param().rec.tpc.globalTrackingRowRange) { - int rowIndex = tracker.TrackHits()[tmpHit].RowIndex(); + int32_t rowIndex = tracker.TrackHits()[tmpHit].RowIndex(); const GPUTPCRow& GPUrestrict() row = tracker.Row(rowIndex); float Y = (float)tracker.Data().HitDataY(row, tracker.TrackHits()[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin(); if (!right && Y < -row.MaxY() * tracker.Param().rec.tpc.globalTrackingYRangeLower) { @@ -141,9 +141,9 @@ GPUd() void GPUTPCGlobalTracking::PerformGlobalTracking(int nBlocks, int nThread } { - const int tmpHit = tracker.Tracks()[i].FirstHitID() + tracker.Tracks()[i].NHits() - 1; + const int32_t tmpHit = tracker.Tracks()[i].FirstHitID() + tracker.Tracks()[i].NHits() - 1; if (tracker.TrackHits()[tmpHit].RowIndex() < GPUCA_ROW_COUNT - tracker.Param().rec.tpc.globalTrackingMinRows && tracker.TrackHits()[tmpHit].RowIndex() >= GPUCA_ROW_COUNT - tracker.Param().rec.tpc.globalTrackingRowRange) { - int rowIndex = tracker.TrackHits()[tmpHit].RowIndex(); + int32_t rowIndex = tracker.TrackHits()[tmpHit].RowIndex(); const GPUTPCRow& GPUrestrict() row = tracker.Row(rowIndex); float Y = (float)tracker.Data().HitDataY(row, tracker.TrackHits()[tmpHit].HitIndex()) * row.HstepY() + row.Grid().YMin(); if (!right && Y < -row.MaxY() * tracker.Param().rec.tpc.globalTrackingYRangeUpper) { @@ -160,7 +160,7 @@ GPUd() void GPUTPCGlobalTracking::PerformGlobalTracking(int nBlocks, int nThread } template <> -GPUdii() void GPUTPCGlobalTracking::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCGlobalTracking::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() tracker) { CA_SHARED_CACHE(&smem.mRows[0], tracker.SliceDataRows(), GPUCA_ROW_COUNT * sizeof(MEM_PLAIN(GPUTPCRow))); GPUbarrier(); @@ -168,10 +168,10 @@ GPUdii() void GPUTPCGlobalTracking::Thread<0>(int nBlocks, int nThreads, int iBl if (tracker.NHitsTotal() == 0) { return; } - const int iSlice = tracker.ISlice(); - int sliceLeft = (iSlice + (GPUDataTypes::NSLICES / 2 - 1)) % (GPUDataTypes::NSLICES / 2); - int sliceRight = (iSlice + 1) % (GPUDataTypes::NSLICES / 2); - if (iSlice >= (int)GPUDataTypes::NSLICES / 2) { + const int32_t iSlice = tracker.ISlice(); + int32_t sliceLeft = (iSlice + (GPUDataTypes::NSLICES / 2 - 1)) % (GPUDataTypes::NSLICES / 2); + int32_t sliceRight = (iSlice + 1) % (GPUDataTypes::NSLICES / 2); + if (iSlice >= (int32_t)GPUDataTypes::NSLICES / 2) { sliceLeft += GPUDataTypes::NSLICES / 2; sliceRight += GPUDataTypes::NSLICES / 2; } @@ -179,7 +179,7 @@ GPUdii() void GPUTPCGlobalTracking::Thread<0>(int nBlocks, int nThreads, int iBl PerformGlobalTracking(nBlocks, nThreads, iBlock, iThread, tracker.GetConstantMem()->tpcTrackers[sliceRight], smem, tracker, false); } -GPUd() int GPUTPCGlobalTracking::GlobalTrackingSliceOrder(int iSlice) +GPUd() int32_t GPUTPCGlobalTracking::GlobalTrackingSliceOrder(int32_t iSlice) { iSlice++; if (iSlice == GPUDataTypes::NSLICES / 2) { @@ -191,11 +191,11 @@ GPUd() int GPUTPCGlobalTracking::GlobalTrackingSliceOrder(int iSlice) return iSlice; } -GPUd() void GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(unsigned int iSlice, unsigned int& left, unsigned int& right) +GPUd() void GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(uint32_t iSlice, uint32_t& left, uint32_t& right) { left = (iSlice + (GPUDataTypes::NSLICES / 2 - 1)) % (GPUDataTypes::NSLICES / 2); right = (iSlice + 1) % (GPUDataTypes::NSLICES / 2); - if (iSlice >= (int)GPUDataTypes::NSLICES / 2) { + if (iSlice >= (int32_t)GPUDataTypes::NSLICES / 2) { left += GPUDataTypes::NSLICES / 2; right += GPUDataTypes::NSLICES / 2; } @@ -203,9 +203,9 @@ GPUd() void GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(unsigned int iSli #endif // !__OPENCL__ || __OPENCLCPP__ template <> -GPUdii() void GPUTPCGlobalTrackingCopyNumbers::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() tracker, int n) +GPUdii() void GPUTPCGlobalTrackingCopyNumbers::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() tracker, int32_t n) { - for (int i = get_global_id(0); i < n; i += get_global_size(0)) { + for (int32_t i = get_global_id(0); i < n; i += get_global_size(0)) { GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() trk = (&tracker)[i]; trk.CommonMemory()->nLocalTracks = trk.CommonMemory()->nTracks; trk.CommonMemory()->nLocalTrackHits = trk.CommonMemory()->nTrackHits; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h index 2a48ab239bcec..075957ff4c8c8 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h @@ -39,15 +39,15 @@ class GPUTPCGlobalTracking : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); - GPUd() static int GlobalTrackingSliceOrder(int iSlice); - GPUd() static void GlobalTrackingSliceLeftRight(unsigned int iSlice, unsigned int& left, unsigned int& right); + GPUd() static int32_t GlobalTrackingSliceOrder(int32_t iSlice); + GPUd() static void GlobalTrackingSliceLeftRight(uint32_t iSlice, uint32_t& left, uint32_t& right); private: - GPUd() static int PerformGlobalTrackingRun(GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, const GPUTPCTracker& sliceSource, int iTrack, int rowIndex, float angle, int direction); - GPUd() static void PerformGlobalTracking(int nBlocks, int nThreads, int iBlock, int iThread, const GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, GPUTPCTracker& sliceTarget, bool right); + GPUd() static int32_t PerformGlobalTrackingRun(GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, const GPUTPCTracker& sliceSource, int32_t iTrack, int32_t rowIndex, float angle, int32_t direction); + GPUd() static void PerformGlobalTracking(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const GPUTPCTracker& tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, GPUTPCTracker& sliceTarget, bool right); }; #endif @@ -61,8 +61,8 @@ class GPUTPCGlobalTrackingCopyNumbers : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker, int n); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker, int32_t n); }; } // namespace gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCGrid.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCGrid.cxx index 67055b85dec04..00fceaf8a5874 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCGrid.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCGrid.cxx @@ -38,7 +38,7 @@ GPUd() void MEM_LG(GPUTPCGrid)::CreateEmpty() } MEM_CLASS_PRE() -GPUd() void MEM_LG(GPUTPCGrid)::Create(float yMin, float yMax, float zMin, float zMax, int ny, int nz) +GPUd() void MEM_LG(GPUTPCGrid)::Create(float yMin, float yMax, float zMin, float zMax, int32_t ny, int32_t nz) { //* Create the grid mYMin = yMin; @@ -60,27 +60,27 @@ GPUd() void MEM_LG(GPUTPCGrid)::Create(float yMin, float yMax, float zMin, float } MEM_CLASS_PRE() -GPUd() int MEM_LG(GPUTPCGrid)::GetBin(float Y, float Z) const +GPUd() int32_t MEM_LG(GPUTPCGrid)::GetBin(float Y, float Z) const { //* get the bin pointer - const int yBin = static_cast((Y - mYMin) * mStepYInv); - const int zBin = static_cast((Z - mZMin) * mStepZInv); - const int bin = zBin * mNy + yBin; + const int32_t yBin = static_cast((Y - mYMin) * mStepYInv); + const int32_t zBin = static_cast((Z - mZMin) * mStepZInv); + const int32_t bin = zBin * mNy + yBin; #ifndef GPUCA_GPUCODE assert(bin >= 0); - assert(bin < static_cast(mN)); + assert(bin < static_cast(mN)); #endif return bin; } MEM_CLASS_PRE() -GPUd() int MEM_LG(GPUTPCGrid)::GetBinBounded(float Y, float Z) const +GPUd() int32_t MEM_LG(GPUTPCGrid)::GetBinBounded(float Y, float Z) const { //* get the bin pointer - const int yBin = static_cast((Y - mYMin) * mStepYInv); - const int zBin = static_cast((Z - mZMin) * mStepZInv); - int bin = zBin * mNy + yBin; - if (bin >= static_cast(mN)) { + const int32_t yBin = static_cast((Y - mYMin) * mStepYInv); + const int32_t zBin = static_cast((Z - mZMin) * mStepZInv); + int32_t bin = zBin * mNy + yBin; + if (bin >= static_cast(mN)) { bin = mN - 1; } if (bin < 0) { @@ -90,55 +90,55 @@ GPUd() int MEM_LG(GPUTPCGrid)::GetBinBounded(float Y, float Z) const } MEM_CLASS_PRE() -GPUd() void MEM_LG(GPUTPCGrid)::GetBin(float Y, float Z, int* const bY, int* const bZ) const +GPUd() void MEM_LG(GPUTPCGrid)::GetBin(float Y, float Z, int32_t* const bY, int32_t* const bZ) const { //* get the bin pointer - int bbY = (int)((Y - mYMin) * mStepYInv); - int bbZ = (int)((Z - mZMin) * mStepZInv); + int32_t bbY = (int32_t)((Y - mYMin) * mStepYInv); + int32_t bbZ = (int32_t)((Z - mZMin) * mStepZInv); - if (bbY >= (int)mNy) { + if (bbY >= (int32_t)mNy) { bbY = mNy - 1; } if (bbY < 0) { bbY = 0; } - if (bbZ >= (int)mNz) { + if (bbZ >= (int32_t)mNz) { bbZ = mNz - 1; } if (bbZ < 0) { bbZ = 0; } - *bY = (unsigned int)bbY; - *bZ = (unsigned int)bbZ; + *bY = (uint32_t)bbY; + *bZ = (uint32_t)bbZ; } MEM_CLASS_PRE() -GPUd() void MEM_LG(GPUTPCGrid)::GetBinArea(float Y, float Z, float dy, float dz, int& bin, int& ny, int& nz) const +GPUd() void MEM_LG(GPUTPCGrid)::GetBinArea(float Y, float Z, float dy, float dz, int32_t& bin, int32_t& ny, int32_t& nz) const { Y -= mYMin; - int by = (int)((Y - dy) * mStepYInv); - ny = (int)((Y + dy) * mStepYInv) - by; + int32_t by = (int32_t)((Y - dy) * mStepYInv); + ny = (int32_t)((Y + dy) * mStepYInv) - by; Z -= mZMin; - int bz = (int)((Z - dz) * mStepZInv); - nz = (int)((Z + dz) * mStepZInv) - bz; - if (by >= (int)mNy) { + int32_t bz = (int32_t)((Z - dz) * mStepZInv); + nz = (int32_t)((Z + dz) * mStepZInv) - bz; + if (by >= (int32_t)mNy) { by = mNy - 1; } if (by < 0) { by = 0; } - if (bz >= (int)mNz) { + if (bz >= (int32_t)mNz) { bz = mNz - 1; } if (bz < 0) { bz = 0; } - if (by + ny >= (int)mNy) { + if (by + ny >= (int32_t)mNy) { ny = mNy - 1 - by; } - if (bz + nz >= (int)mNz) { + if (bz + nz >= (int32_t)mNz) { nz = mNz - 1 - bz; } bin = bz * mNy + by; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCGrid.h b/GPU/GPUTracking/SliceTracker/GPUTPCGrid.h index 06b248c92cf06..a069282e2a0a9 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCGrid.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCGrid.h @@ -34,19 +34,19 @@ class GPUTPCGrid { public: GPUd() void CreateEmpty(); - GPUd() void Create(float yMin, float yMax, float zMin, float zMax, int ny, int nz); + GPUd() void Create(float yMin, float yMax, float zMin, float zMax, int32_t ny, int32_t nz); - GPUd() int GetBin(float Y, float Z) const; + GPUd() int32_t GetBin(float Y, float Z) const; /** * returns -1 if the row is empty == no hits */ - GPUd() int GetBinBounded(float Y, float Z) const; - GPUd() void GetBin(float Y, float Z, int* const bY, int* const bZ) const; - GPUd() void GetBinArea(float Y, float Z, float dy, float dz, int& bin, int& ny, int& nz) const; + GPUd() int32_t GetBinBounded(float Y, float Z) const; + GPUd() void GetBin(float Y, float Z, int32_t* const bY, int32_t* const bZ) const; + GPUd() void GetBinArea(float Y, float Z, float dy, float dz, int32_t& bin, int32_t& ny, int32_t& nz) const; - GPUd() unsigned int N() const { return mN; } - GPUd() unsigned int Ny() const { return mNy; } - GPUd() unsigned int Nz() const { return mNz; } + GPUd() uint32_t N() const { return mN; } + GPUd() uint32_t Ny() const { return mNy; } + GPUd() uint32_t Nz() const { return mNz; } GPUd() float YMin() const { return mYMin; } GPUd() float YMax() const { return mYMax; } GPUd() float ZMin() const { return mZMin; } @@ -57,9 +57,9 @@ class GPUTPCGrid private: friend class GPUTPCNeighboursFinder; - unsigned int mNy; //* N bins in Y - unsigned int mNz; //* N bins in Z - unsigned int mN; //* total N bins + uint32_t mNy; //* N bins in Y + uint32_t mNz; //* N bins in Z + uint32_t mN; //* total N bins float mYMin; //* minimal Y value float mYMax; //* maximal Y value float mZMin; //* minimal Z value diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCHitId.h b/GPU/GPUTracking/SliceTracker/GPUTPCHitId.h index 7d1c97650385b..9fb27d7a1a892 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCHitId.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCHitId.h @@ -22,12 +22,12 @@ namespace gpu class GPUTPCHitId { public: - GPUhd() void Set(int row, int hit) { mId = (hit << 8) | row; } - GPUhd() int RowIndex() const { return mId & 0xff; } - GPUhd() int HitIndex() const { return mId >> 8; } + GPUhd() void Set(int32_t row, int32_t hit) { mId = (hit << 8) | row; } + GPUhd() int32_t RowIndex() const { return mId & 0xff; } + GPUhd() int32_t HitIndex() const { return mId >> 8; } private: - int mId; + int32_t mId; }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCMCInfo.h b/GPU/GPUTracking/SliceTracker/GPUTPCMCInfo.h index 6b20f8a680940..25b423b965f07 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCMCInfo.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCMCInfo.h @@ -20,10 +20,10 @@ namespace GPUCA_NAMESPACE namespace gpu { struct GPUTPCMCInfo { - int charge; - char prim; - char primDaughters; - int pid; + int32_t charge; + int8_t prim; + int8_t primDaughters; + int32_t pid; float x; float y; float z; @@ -36,8 +36,8 @@ struct GPUTPCMCInfo { #endif }; struct GPUTPCMCInfoCol { - unsigned int first; - unsigned int num; + uint32_t first; + uint32_t num; }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.cxx index 3c03f894d6e12..7842a57f47794 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.cxx @@ -18,7 +18,7 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCNeighboursCleaner::Thread<0>(int /*nBlocks*/, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCNeighboursCleaner::Thread<0>(int32_t /*nBlocks*/, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { // * // * kill link to the neighbour if the neighbour is not pointed to the cluster @@ -36,8 +36,8 @@ GPUdii() void GPUTPCNeighboursCleaner::Thread<0>(int /*nBlocks*/, int nThreads, if (s.mIRow <= GPUCA_ROW_COUNT - 3) { #ifdef GPUCA_GPUCODE - int Up = s.mIRowUp; - int Dn = s.mIRowDn; + int32_t Up = s.mIRowUp; + int32_t Dn = s.mIRowDn; GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() row = tracker.Row(s.mIRow); GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() rowUp = tracker.Row(Up); GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() rowDn = tracker.Row(Dn); @@ -51,7 +51,7 @@ GPUdii() void GPUTPCNeighboursCleaner::Thread<0>(int /*nBlocks*/, int nThreads, // the link // - look at down link, if it's valid but the up link in the row below doesn't link to us remove // the link - for (int ih = iThread; ih < s.mNHits; ih += nThreads) { + for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) { calink up = tracker.HitLinkUpData(row, ih); if (up != CALINK_INVAL) { calink upDn = tracker.HitLinkDownData(rowUp, up); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.h b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.h index a46c39d99e083..26e85907bc6ab 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursCleaner.h @@ -35,10 +35,10 @@ class GPUTPCNeighboursCleaner : public GPUKernelTemplate public: MEM_CLASS_PRE() struct GPUSharedMemory { - int mIRow; // current row index - int mIRowUp; // current row index - int mIRowDn; // current row index - int mNHits; // number of hits + int32_t mIRow; // current row index + int32_t mIRowUp; // current row index + int32_t mIRowDn; // current row index + int32_t mNHits; // number of hits }; typedef GPUconstantref() MEM_GLOBAL(GPUTPCTracker) processorType; @@ -48,8 +48,8 @@ class GPUTPCNeighboursCleaner : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int /*nBlocks*/, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t /*nBlocks*/, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.cxx index 8f5cc2f1f7dd5..b7cfccfa15408 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.cxx @@ -20,16 +20,16 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int32_t /*nBlocks*/, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { //* find neighbours #ifdef GPUCA_GPUCODE - for (unsigned int i = iThread; i < sizeof(MEM_PLAIN(GPUTPCRow)) / sizeof(int); i += nThreads) { - reinterpret_cast(&s.mRow)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock])[i]; + for (uint32_t i = iThread; i < sizeof(MEM_PLAIN(GPUTPCRow)) / sizeof(int32_t); i += nThreads) { + reinterpret_cast(&s.mRow)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock])[i]; if (iBlock >= 2 && iBlock < GPUCA_ROW_COUNT - 2) { - reinterpret_cast(&s.mRowUp)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock + 2])[i]; - reinterpret_cast(&s.mRowDown)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock - 2])[i]; + reinterpret_cast(&s.mRowUp)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock + 2])[i]; + reinterpret_cast(&s.mRowDown)[i] = reinterpret_cast(&tracker.SliceDataRows()[iBlock - 2])[i]; } } GPUbarrier(); @@ -67,8 +67,8 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i // local copies if ((s.mIRow <= 1) || (s.mIRow >= GPUCA_ROW_COUNT - 2) || (rowUp.mNHits <= 0) || (rowDn.mNHits <= 0)) { - const int lHitNumberOffset = row.mHitNumberOffset; - for (int ih = iThread; ih < s.mNHits; ih += nThreads) { + const int32_t lHitNumberOffset = row.mHitNumberOffset; + for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) { tracker.mData.mLinkUpData[lHitNumberOffset + ih] = CALINK_INVAL; tracker.mData.mLinkDownData[lHitNumberOffset + ih] = CALINK_INVAL; } @@ -87,11 +87,11 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i const float chi2Cut = 3.f * 3.f * 4 * (s.mUpDx * s.mUpDx + s.mDnDx * s.mDnDx); // float chi2Cut = 3.f*3.f*(s.mUpDx*s.mUpDx + s.mDnDx*s.mDnDx ); //SG - const int lHitNumberOffset = row.mHitNumberOffset; - const int lHitNumberOffsetUp = rowUp.mHitNumberOffset; - const int lHitNumberOffsetDn = rowDn.mHitNumberOffset; - const unsigned int lFirstHitInBinOffsetUp = rowUp.mFirstHitInBinOffset; - const unsigned int lFirstHitInBinOffsetDn = rowDn.mFirstHitInBinOffset; + const int32_t lHitNumberOffset = row.mHitNumberOffset; + const int32_t lHitNumberOffsetUp = rowUp.mHitNumberOffset; + const int32_t lHitNumberOffsetDn = rowDn.mHitNumberOffset; + const uint32_t lFirstHitInBinOffsetUp = rowUp.mFirstHitInBinOffset; + const uint32_t lFirstHitInBinOffsetDn = rowDn.mFirstHitInBinOffset; const GPUglobalref() calink* GPUrestrict() lFirstHitInBin = tracker.mData.mFirstHitInBin; const GPUglobalref() cahit2* GPUrestrict() pHitData = tracker.mData.mHitData; @@ -122,16 +122,16 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i float yzUp[2 * MaxGlobal]; #endif - for (int ih = iThread; ih < s.mNHits; ih += nThreads) { + for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) { const GPUglobalref() cahit2& hitData = pHitData[lHitNumberOffset + ih]; const float y = y0 + hitData.x * stepY; const float z = z0 + hitData.y * stepZ; - int nNeighUp = 0; + int32_t nNeighUp = 0; float minZ, maxZ, minY, maxY; - int binYmin, binYmax, binZmin, binZmax; - int nY; + int32_t binYmin, binYmax, binZmin, binZmax; + int32_t nY; { // area in the upper row const float yy = y * s.mUpTx; @@ -145,11 +145,11 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i nY = rowUp.Grid().Ny(); } - for (int k1 = binZmin; k1 <= binZmax && (nNeighUp < MaxTotal); k1++) { - int iMin = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmin]; - int iMax = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmax + 1]; + for (int32_t k1 = binZmin; k1 <= binZmax && (nNeighUp < MaxTotal); k1++) { + int32_t iMin = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmin]; + int32_t iMax = lFirstHitInBin[lFirstHitInBinOffsetUp + k1 * nY + binYmax + 1]; GPUCA_UNROLL(U(4), U(2)) - for (int i = iMin; i < iMax && (nNeighUp < MaxTotal); i++) { + for (int32_t i = iMin; i < iMax && (nNeighUp < MaxTotal); i++) { const GPUglobalref() cahit2& hitDataUp = pHitData[lHitNumberOffsetUp + i]; GPUTPCHit h; h.mY = y0Up + (hitDataUp.x) * stepYUp; @@ -182,7 +182,7 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i } #if MaxShared > 0 // init a rest of the shared array - for (int iUp = nNeighUp; iUp < MaxShared; iUp++) { + for (int32_t iUp = nNeighUp; iUp < MaxShared; iUp++) { s.mA1[iUp][iThread] = -1.e10f; s.mA2[iUp][iThread] = -1.e10f; s.mB[iUp][iThread] = (calink)-1; @@ -190,12 +190,12 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i #endif #if MaxGlobal > 0 // init a rest of the UnrollGlobal chunk of the global array - int Nrest = nNeighUp - MaxShared; - int N4 = (Nrest / UnrollGlobal) * UnrollGlobal; + int32_t Nrest = nNeighUp - MaxShared; + int32_t N4 = (Nrest / UnrollGlobal) * UnrollGlobal; if (N4 < Nrest) { N4 += UnrollGlobal; GPUCA_UNROLL(U(UnrollGlobal - 1), U(UnrollGlobal - 1)) - for (int k = 0; k < UnrollGlobal - 1; k++) { + for (int32_t k = 0; k < UnrollGlobal - 1; k++) { if (Nrest + k < N4) { yzUp[2 * (Nrest + k)] = -1.e10f; yzUp[2 * (Nrest + k) + 1] = -1.e10f; @@ -217,14 +217,14 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i rowDn.Grid().GetBin(maxY, maxZ, &binYmax, &binZmax); nY = rowDn.Grid().Ny(); - int linkUp = -1; // CALINK_INVAL as integer - int linkDn = -1; // CALINK_INVAL as integer + int32_t linkUp = -1; // CALINK_INVAL as integer + int32_t linkDn = -1; // CALINK_INVAL as integer float bestD = chi2Cut; - for (int k1 = binZmin; k1 <= binZmax; k1++) { - int iMin = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmin]; - int iMax = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmax + 1]; - for (int i = iMin; i < iMax; i++) { + for (int32_t k1 = binZmin; k1 <= binZmax; k1++) { + int32_t iMin = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmin]; + int32_t iMax = lFirstHitInBin[lFirstHitInBinOffsetDn + k1 * nY + binYmax + 1]; + for (int32_t i = iMin; i < iMax; i++) { const GPUglobalref() cahit2& hitDataDn = pHitData[lHitNumberOffsetDn + i]; float yDn = y0Dn + (hitDataDn.x) * stepYDn; float zDn = z0Dn + (hitDataDn.y) * stepZDn; @@ -238,7 +238,7 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i #if MaxShared > 0 GPUCA_UNROLL(U(MaxShared), U(MaxShared)) - for (int iUp = 0; iUp < MaxShared; iUp++) { + for (int32_t iUp = 0; iUp < MaxShared; iUp++) { const float dy = yDnProjUp - s.mA1[iUp][iThread]; const float dz = zDnProjUp - s.mA2[iUp][iThread]; const float d = dy * dy + dz * dz; @@ -251,10 +251,10 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int /*nBlocks*/, int nThreads, i #endif #if MaxGlobal > 0 - for (int iUp = 0; iUp < N4; iUp += UnrollGlobal) { + for (int32_t iUp = 0; iUp < N4; iUp += UnrollGlobal) { GPUCA_UNROLL(U(UnrollGlobal), U(UnrollGlobal)) - for (int k = 0; k < UnrollGlobal; k++) { - int jUp = iUp + k; + for (int32_t k = 0; k < UnrollGlobal; k++) { + int32_t jUp = iUp + k; const float dy = yDnProjUp - yzUp[2 * jUp]; const float dz = zDnProjUp - yzUp[2 * jUp + 1]; const float d = dy * dy + dz * dz; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.h b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.h index 238346a3ef742..7174286fde948 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCNeighboursFinder.h @@ -36,14 +36,14 @@ class GPUTPCNeighboursFinder : public GPUKernelTemplate public: MEM_CLASS_PRE() struct GPUSharedMemory { - int mNHits; // n hits + int32_t mNHits; // n hits float mUpDx; // x distance to the next row float mDnDx; // x distance to the previous row float mUpTx; // normalized x distance to the next row float mDnTx; // normalized x distance to the previous row - int mIRow; // row number - int mIRowUp; // next row number - int mIRowDn; // previous row number + int32_t mIRow; // row number + int32_t mIRowUp; // next row number + int32_t mIRowDn; // previous row number #if GPUCA_NEIGHBOURS_FINDER_MAX_NNEIGHUP > 0 float mA1[GPUCA_NEIGHBOURS_FINDER_MAX_NNEIGHUP][GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCNeighboursFinder)]; float mA2[GPUCA_NEIGHBOURS_FINDER_MAX_NNEIGHUP][GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCNeighboursFinder)]; @@ -60,8 +60,8 @@ class GPUTPCNeighboursFinder : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCRow.h b/GPU/GPUTracking/SliceTracker/GPUTPCRow.h index 7a6f00cb800cd..ed25e18e90c46 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCRow.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCRow.h @@ -40,7 +40,7 @@ class GPUTPCRow GPUTPCRow(); #endif //! GPUCA_GPUCODE - GPUhd() int NHits() const + GPUhd() int32_t NHits() const { return mNHits; } @@ -54,8 +54,8 @@ class GPUTPCRow GPUhd() float HstepZ() const { return mHstepZ; } GPUhd() float HstepYi() const { return mHstepYi; } GPUhd() float HstepZi() const { return mHstepZi; } - GPUhd() int HitNumberOffset() const { return mHitNumberOffset; } - GPUhd() unsigned int FirstHitInBinOffset() const { return mFirstHitInBinOffset; } + GPUhd() int32_t HitNumberOffset() const { return mHitNumberOffset; } + GPUhd() uint32_t FirstHitInBinOffset() const { return mFirstHitInBinOffset; } GPUhd() static float getTPCMaxY1X() { return 0.1763269f; } // 0.1763269 = tan(2Pi / (2 * 18)) GPUhd() float getTPCMaxY() const { return getTPCMaxY1X() * mX; } @@ -63,7 +63,7 @@ class GPUTPCRow friend class GPUTPCNeighboursFinder; friend class GPUTPCStartHitsFinder; - int mNHits; // number of hits + int32_t mNHits; // number of hits float mX; // X coordinate of the row float mMaxY; // maximal Y coordinate of the row MEM_LG(GPUTPCGrid) @@ -77,9 +77,9 @@ class GPUTPCRow float mHstepYi; // inverse step size float mHstepZi; // inverse step size - int mHitNumberOffset; // index of the first hit in the hit array, used as + int32_t mHitNumberOffset; // index of the first hit in the hit array, used as // offset in GPUTPCSliceData::LinkUp/DownData/HitDataY/... - unsigned int mFirstHitInBinOffset; // offset in Tracker::mRowData to find the FirstHitInBin + uint32_t mFirstHitInBinOffset; // offset in Tracker::mRowData to find the FirstHitInBin }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.cxx index 701d4016f7e13..99088a1e99c53 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.cxx @@ -25,20 +25,20 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) { - const unsigned int iRow = iBlock; + const uint32_t iRow = iBlock; const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() row = tracker.Data().Row(iRow); const MEM_GLOBAL(GPUTPCGrid) & GPUrestrict() grid = row.Grid(); - for (unsigned int i = iThread; i < grid.N(); i += nThreads) { - unsigned int jMin = tracker.Data().FirstHitInBin(row, i); - unsigned int jMax = tracker.Data().FirstHitInBin(row, i + 1); - const unsigned int n = jMax - jMin; + for (uint32_t i = iThread; i < grid.N(); i += nThreads) { + uint32_t jMin = tracker.Data().FirstHitInBin(row, i); + uint32_t jMax = tracker.Data().FirstHitInBin(row, i + 1); + const uint32_t n = jMax - jMin; calink* GPUrestrict() tmp1 = tracker.Data().HitLinkUpData(row) + jMin; auto* GPUrestrict() tmp2 = tracker.Data().HitWeights() + row.HitNumberOffset() + jMin; cahit2* GPUrestrict() hitData = tracker.Data().HitData(row) + jMin; - int* GPUrestrict() clusterId = tracker.Data().ClusterDataIndex() + row.HitNumberOffset() + jMin; - for (unsigned int j = 0; j < n; j++) { + int32_t* GPUrestrict() clusterId = tracker.Data().ClusterDataIndex() + row.HitNumberOffset() + jMin; + for (uint32_t j = 0; j < n; j++) { tmp1[j] = j; } GPUCommonAlgorithm::sort(tmp1, tmp1 + n, [&hitData, &clusterId](const calink& a, const calink& b) { @@ -50,29 +50,29 @@ GPUdii() void GPUTPCSectorDebugSortKernels::Thread -GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) { if (iThread || iBlock) { return; @@ -86,7 +86,7 @@ GPUdii() void GPUTPCSectorDebugSortKernels::Thread -GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCSectorDebugSortKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() tracker) { if (iThread || iBlock) { return; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.h b/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.h index d779a4af2525e..50a3738501e2e 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSectorDebugSortKernels.h @@ -34,8 +34,8 @@ class GPUTPCSectorDebugSortKernels : public GPUKernelTemplate typedef GPUTPCTracker processorType; GPUhdi() static processorType* Processor(GPUConstantMem& processors) { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& tracker); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx index 7b5af5acede78..6908bc326a535 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx @@ -35,16 +35,16 @@ using namespace GPUCA_NAMESPACE::gpu; void GPUTPCSliceData::InitializeRows(const MEM_CONSTANT(GPUParam) & p) { // initialisation of rows - for (int i = 0; i < GPUCA_ROW_COUNT + 1; ++i) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT + 1; ++i) { new (&mRows[i]) GPUTPCRow; } - for (int i = 0; i < GPUCA_ROW_COUNT; ++i) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; ++i) { mRows[i].mX = p.tpcGeometry.Row2X(i); mRows[i].mMaxY = CAMath::Tan(p.par.dAlpha / 2.f) * mRows[i].mX; } } -void GPUTPCSliceData::SetClusterData(const GPUTPCClusterData* data, int nClusters, int clusterIdOffset) +void GPUTPCSliceData::SetClusterData(const GPUTPCClusterData* data, int32_t nClusters, int32_t clusterIdOffset) { mClusterData = data; mNumberOfHits = nClusters; @@ -53,9 +53,9 @@ void GPUTPCSliceData::SetClusterData(const GPUTPCClusterData* data, int nCluster void GPUTPCSliceData::SetMaxData() { - int hitMemCount = GPUCA_ROW_COUNT * GPUCA_ROWALIGNMENT + mNumberOfHits; - const unsigned int kVectorAlignment = 256; - mNumberOfHitsPlusAlign = GPUProcessor::nextMultipleOf<(kVectorAlignment > GPUCA_ROWALIGNMENT ? kVectorAlignment : GPUCA_ROWALIGNMENT) / sizeof(int)>(hitMemCount); + int32_t hitMemCount = GPUCA_ROW_COUNT * GPUCA_ROWALIGNMENT + mNumberOfHits; + const uint32_t kVectorAlignment = 256; + mNumberOfHitsPlusAlign = GPUProcessor::nextMultipleOf<(kVectorAlignment > GPUCA_ROWALIGNMENT ? kVectorAlignment : GPUCA_ROWALIGNMENT) / sizeof(int32_t)>(hitMemCount); } void* GPUTPCSliceData::SetPointersInput(void* mem, bool idsOnGPU, bool sliceDataOnGPU) @@ -63,7 +63,7 @@ void* GPUTPCSliceData::SetPointersInput(void* mem, bool idsOnGPU, bool sliceData if (sliceDataOnGPU) { return mem; } - const int firstHitInBinSize = GetGridSize(mNumberOfHits, GPUCA_ROW_COUNT) + GPUCA_ROW_COUNT * GPUCA_ROWALIGNMENT / sizeof(int); + const int32_t firstHitInBinSize = GetGridSize(mNumberOfHits, GPUCA_ROW_COUNT) + GPUCA_ROW_COUNT * GPUCA_ROWALIGNMENT / sizeof(int32_t); GPUProcessor::computePointerWithAlignment(mem, mHitData, mNumberOfHitsPlusAlign); GPUProcessor::computePointerWithAlignment(mem, mFirstHitInBin, firstHitInBinSize); if (idsOnGPU) { @@ -109,14 +109,14 @@ void* GPUTPCSliceData::SetPointersRows(void* mem) #endif -GPUd() void GPUTPCSliceData::GetMaxNBins(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, GPUTPCRow* GPUrestrict() row, int& maxY, int& maxZ) +GPUd() void GPUTPCSliceData::GetMaxNBins(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, GPUTPCRow* GPUrestrict() row, int32_t& maxY, int32_t& maxZ) { maxY = row->mMaxY * 2.f / GPUCA_MIN_BIN_SIZE + 1; maxZ = (mem->param.continuousMaxTimeBin > 0 ? (mem->calibObjects.fastTransformHelper->getCorrMap()->convTimeToZinTimeFrame(0, 0, mem->param.continuousMaxTimeBin)) : mem->param.tpcGeometry.TPCLength()) + 50; maxZ = maxZ / GPUCA_MIN_BIN_SIZE + 1; } -GPUd() unsigned int GPUTPCSliceData::GetGridSize(unsigned int nHits, unsigned int nRows) +GPUd() uint32_t GPUTPCSliceData::GetGridSize(uint32_t nHits, uint32_t nRows) { return 128 * nRows + 4 * nHits; } @@ -132,10 +132,10 @@ GPUdi() void GPUTPCSliceData::CreateGrid(GPUconstantref() const MEM_CONSTANT(GPU const float norm = CAMath::InvSqrt(row->mNHits / tfFactor); float sy = CAMath::Min(CAMath::Max((yMax - yMin) * norm, GPUCA_MIN_BIN_SIZE), GPUCA_MAX_BIN_SIZE); float sz = CAMath::Min(CAMath::Max(dz * norm, GPUCA_MIN_BIN_SIZE), GPUCA_MAX_BIN_SIZE); - int maxy, maxz; + int32_t maxy, maxz; GetMaxNBins(mem, row, maxy, maxz); - int ny = CAMath::Max(1, CAMath::Min(maxy, (yMax - yMin) / sy + 1)); - int nz = CAMath::Max(1, CAMath::Min(maxz, (zMax - zMin) / sz + 1)); + int32_t ny = CAMath::Max(1, CAMath::Min(maxy, (yMax - yMin) / sy + 1)); + int32_t nz = CAMath::Max(1, CAMath::Min(maxz, (zMax - zMin) / sz + 1)); row->mGrid.Create(yMin, yMax, zMin, zMax, ny, nz); } @@ -167,29 +167,29 @@ GPUdii() void GPUTPCSliceData::SetRowGridEmpty(GPUTPCRow& GPUrestrict() row) row.mHstepZ = 1.f; row.mHstepYi = 1.f; row.mHstepZi = 1.f; - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { c[i] = 0; } } -GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int iBlock, int iThread, GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * GPUrestrict() mem, int iSlice, float* tmpMinMax) +GPUdii() int32_t GPUTPCSliceData::InitFromClusterData(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * GPUrestrict() mem, int32_t iSlice, float* tmpMinMax) { #ifdef GPUCA_GPUCODE constexpr bool EarlyTransformWithoutClusterNative = false; #else bool EarlyTransformWithoutClusterNative = mem->param.par.earlyTpcTransform && mem->ioPtrs.clustersNative == nullptr; #endif - int* tmpHitIndex = nullptr; - const unsigned int* NumberOfClustersInRow = nullptr; - const unsigned int* RowOffsets = nullptr; + int32_t* tmpHitIndex = nullptr; + const uint32_t* NumberOfClustersInRow = nullptr; + const uint32_t* RowOffsets = nullptr; #ifndef GPUCA_GPUCODE vecpod YZData(mNumberOfHits); vecpod binMemory(mNumberOfHits); - unsigned int RowOffsetsA[GPUCA_ROW_COUNT]; - unsigned int NumberOfClustersInRowA[GPUCA_ROW_COUNT]; + uint32_t RowOffsetsA[GPUCA_ROW_COUNT]; + uint32_t NumberOfClustersInRowA[GPUCA_ROW_COUNT]; - vecpod tmpHitIndexA; + vecpod tmpHitIndexA; if (EarlyTransformWithoutClusterNative) { // Implies mem->param.par.earlyTpcTransform but no ClusterNative present NumberOfClustersInRow = NumberOfClustersInRowA; RowOffsets = RowOffsetsA; @@ -197,23 +197,23 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int tmpHitIndex = tmpHitIndexA.data(); memset(NumberOfClustersInRowA, 0, GPUCA_ROW_COUNT * sizeof(NumberOfClustersInRowA[0])); - for (int i = 0; i < mNumberOfHits; i++) { - const int tmpRow = mClusterData[i].row; + for (int32_t i = 0; i < mNumberOfHits; i++) { + const int32_t tmpRow = mClusterData[i].row; NumberOfClustersInRowA[tmpRow]++; } - int tmpOffset = 0; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + int32_t tmpOffset = 0; + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { RowOffsetsA[i] = tmpOffset; tmpOffset += NumberOfClustersInRow[i]; } - int RowsFilled[GPUCA_ROW_COUNT]; - memset(RowsFilled, 0, GPUCA_ROW_COUNT * sizeof(int)); - for (int i = 0; i < mNumberOfHits; i++) { + int32_t RowsFilled[GPUCA_ROW_COUNT]; + memset(RowsFilled, 0, GPUCA_ROW_COUNT * sizeof(int32_t)); + for (int32_t i = 0; i < mNumberOfHits; i++) { float2 tmp; tmp.x = mClusterData[i].y; tmp.y = mClusterData[i].z; - int tmpRow = mClusterData[i].row; - int newIndex = RowOffsetsA[tmpRow] + (RowsFilled[tmpRow])++; + int32_t tmpRow = mClusterData[i].row; + int32_t newIndex = RowOffsetsA[tmpRow] + (RowsFilled[tmpRow])++; YZData[newIndex] = tmp; tmpHitIndex[newIndex] = i; } @@ -225,18 +225,18 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int static_assert(sizeof(*binMemory) <= sizeof(*mHitWeights), "Cannot reuse memory"); #endif - for (int rowIndex = iBlock; rowIndex < GPUCA_ROW_COUNT; rowIndex += nBlocks) { + for (int32_t rowIndex = iBlock; rowIndex < GPUCA_ROW_COUNT; rowIndex += nBlocks) { float yMin = 1.e6f; float yMax = -1.e6f; float zMin = 1.e6f; float zMax = -1.e6f; - const unsigned int NumberOfClusters = EarlyTransformWithoutClusterNative ? NumberOfClustersInRow[rowIndex] : mem->ioPtrs.clustersNative->nClusters[iSlice][rowIndex]; - const unsigned int RowOffset = EarlyTransformWithoutClusterNative ? RowOffsets[rowIndex] : (mem->ioPtrs.clustersNative->clusterOffset[iSlice][rowIndex] - mem->ioPtrs.clustersNative->clusterOffset[iSlice][0]); - CONSTEXPR const unsigned int maxN = 1u << (sizeof(calink) < 3 ? (sizeof(calink) * 8) : 24); + const uint32_t NumberOfClusters = EarlyTransformWithoutClusterNative ? NumberOfClustersInRow[rowIndex] : mem->ioPtrs.clustersNative->nClusters[iSlice][rowIndex]; + const uint32_t RowOffset = EarlyTransformWithoutClusterNative ? RowOffsets[rowIndex] : (mem->ioPtrs.clustersNative->clusterOffset[iSlice][rowIndex] - mem->ioPtrs.clustersNative->clusterOffset[iSlice][0]); + CONSTEXPR const uint32_t maxN = 1u << (sizeof(calink) < 3 ? (sizeof(calink) * 8) : 24); GPUTPCRow& row = mRows[rowIndex]; if (iThread == 0) { - row.mFirstHitInBinOffset = CAMath::nextMultipleOf(GetGridSize(RowOffset, rowIndex) + rowIndex * GPUCA_ROWALIGNMENT / sizeof(int)); + row.mFirstHitInBinOffset = CAMath::nextMultipleOf(GetGridSize(RowOffset, rowIndex) + rowIndex * GPUCA_ROWALIGNMENT / sizeof(int32_t)); } if (NumberOfClusters >= maxN) { if (iThread == 0) { @@ -262,12 +262,12 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int } if (EarlyTransformWithoutClusterNative) { - for (unsigned int i = iThread; i < NumberOfClusters; i += nThreads) { + for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { UpdateMinMaxYZ(yMin, yMax, zMin, zMax, YZData[RowOffset + i].x, YZData[RowOffset + i].y); } } else { if (mem->param.par.earlyTpcTransform) { // Early transform case with ClusterNative present - for (unsigned int i = iThread; i < NumberOfClusters; i += nThreads) { + for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { float2 tmp; tmp.x = mClusterData[RowOffset + i].y; tmp.y = mClusterData[RowOffset + i].z; @@ -275,7 +275,7 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int YZData[RowOffset + i] = tmp; } } else { - for (unsigned int i = iThread; i < NumberOfClusters; i += nThreads) { + for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { float x, y, z; GPUTPCConvertImpl::convert(*mem, iSlice, rowIndex, mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getPad(), mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getTime(), x, y, z); UpdateMinMaxYZ(yMin, yMax, zMin, zMax, y, z); @@ -295,7 +295,7 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int CAMath::AtomicMinShared(&tmpMinMax[2], zMin); CAMath::AtomicMaxShared(&tmpMinMax[3], zMax); #else - for (int i = 0; i < nThreads; i++) { + for (int32_t i = 0; i < nThreads; i++) { GPUbarrier(); if (iThread == i) { if (tmpMinMax[0] > yMin) { @@ -319,8 +319,8 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int } GPUbarrier(); const GPUTPCGrid& grid = row.mGrid; - const int numberOfBins = grid.N(); - CONSTEXPR const int maxBins = sizeof(calink) < 4 ? (int)(1ul << (sizeof(calink) * 8)) : 0x7FFFFFFF; // NOLINT: false warning + const int32_t numberOfBins = grid.N(); + CONSTEXPR const int32_t maxBins = sizeof(calink) < 4 ? (int32_t)(1ul << (sizeof(calink) * 8)) : 0x7FFFFFFF; // NOLINT: false warning if (sizeof(calink) < 4 && numberOfBins >= maxBins) { if (iThread == 0) { mem->errorCodes.raiseError(GPUErrors::ERROR_SLICEDATA_BIN_OVERFLOW, iSlice * 1000 + rowIndex, numberOfBins, maxBins); @@ -328,8 +328,8 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int } continue; } - const unsigned int nn = numberOfBins + grid.Ny() + 3; - const unsigned int maxnn = GetGridSize(NumberOfClusters, 1); + const uint32_t nn = numberOfBins + grid.Ny() + 3; + const uint32_t maxnn = GetGridSize(NumberOfClusters, 1); if (nn >= maxnn) { if (iThread == 0) { mem->errorCodes.raiseError(GPUErrors::ERROR_SLICEDATA_FIRSTHITINBIN_OVERFLOW, iSlice, nn, maxnn); @@ -340,12 +340,12 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int calink* bins = &binMemory[RowOffset]; // Reuse mLinkUpData memory as temporary memory - for (int bin = iThread; bin < numberOfBins; bin += nThreads) { + for (int32_t bin = iThread; bin < numberOfBins; bin += nThreads) { c[bin] = 0; // initialize to 0 } GPUbarrier(); - for (int hitIndex = iThread; hitIndex < row.mNHits; hitIndex += nThreads) { - const int globalHitIndex = RowOffset + hitIndex; + for (int32_t hitIndex = iThread; hitIndex < row.mNHits; hitIndex += nThreads) { + const int32_t globalHitIndex = RowOffset + hitIndex; const calink bin = row.mGrid.GetBin(YZData[globalHitIndex].x, YZData[globalHitIndex].y); bins[hitIndex] = bin; @@ -355,17 +355,17 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int if (iThread == 0) { calink n = 0; - for (int bin = 0; bin < numberOfBins; ++bin) { // TODO: Parallelize + for (int32_t bin = 0; bin < numberOfBins; ++bin) { // TODO: Parallelize n += c[bin]; c[bin] = n; } - for (unsigned int bin = numberOfBins; bin < nn; bin++) { + for (uint32_t bin = numberOfBins; bin < nn; bin++) { c[bin] = n; } } GPUbarrier(); - constexpr float maxVal = (((long)1 << (sizeof(cahit) < 3 ? sizeof(cahit) * 8 : 24)) - 1); // Stay within float precision in any case! + constexpr float maxVal = (((int64_t)1 << (sizeof(cahit) < 3 ? sizeof(cahit) * 8 : 24)) - 1); // Stay within float precision in any case! constexpr float packingConstant = 1.f / (maxVal - 2.f); const float y0 = row.mGrid.YMin(); const float z0 = row.mGrid.ZMin(); @@ -385,11 +385,11 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int GPUbarrier(); - for (int hitIndex = iThread; hitIndex < row.mNHits; hitIndex += nThreads) { + for (int32_t hitIndex = iThread; hitIndex < row.mNHits; hitIndex += nThreads) { const calink bin = bins[hitIndex]; const calink ind = CAMath::AtomicAdd(&c[bin], (calink)-1) - 1; // generate an index for this hit that is >= c[bin] and < c[bin + 1] - const int globalBinsortedIndex = row.mHitNumberOffset + ind; - const int globalHitIndex = RowOffset + hitIndex; + const int32_t globalBinsortedIndex = row.mHitNumberOffset + ind; + const int32_t globalHitIndex = RowOffset + hitIndex; // allows to find the global hit index / coordinates from a global bin sorted hit index mClusterDataIndex[globalBinsortedIndex] = EarlyTransformWithoutClusterNative ? tmpHitIndex[globalHitIndex] : (RowOffset + hitIndex); @@ -412,7 +412,7 @@ GPUdii() int GPUTPCSliceData::InitFromClusterData(int nBlocks, int nThreads, int if (iThread == 0 && !mem->param.par.continuousTracking) { const float maxAbsZ = CAMath::Max(CAMath::Abs(tmpMinMax[2]), CAMath::Abs(tmpMinMax[3])); if (maxAbsZ > 300) { - mem->errorCodes.raiseError(GPUErrors::ERROR_SLICEDATA_Z_OVERFLOW, iSlice, (unsigned int)maxAbsZ); + mem->errorCodes.raiseError(GPUErrors::ERROR_SLICEDATA_Z_OVERFLOW, iSlice, (uint32_t)maxAbsZ); SetRowGridEmpty(row); continue; } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.h b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.h index 72d6c28b856d3..a75cba8dd861b 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.h @@ -38,7 +38,7 @@ class GPUTPCSliceData ~GPUTPCSliceData() CON_DEFAULT; void InitializeRows(const MEM_CONSTANT(GPUParam) & p); void SetMaxData(); - void SetClusterData(const GPUTPCClusterData* data, int nClusters, int clusterIdOffset); + void SetClusterData(const GPUTPCClusterData* data, int32_t nClusters, int32_t clusterIdOffset); void* SetPointersInput(void* mem, bool idsOnGPU, bool sliceDataOnGPU); void* SetPointersScratch(void* mem, bool idsOnGPU, bool sliceDataOnGPU); void* SetPointersLinks(void* mem); @@ -47,14 +47,14 @@ class GPUTPCSliceData void* SetPointersRows(void* mem); #endif - GPUd() int InitFromClusterData(int nBlocks, int nThreads, int iBlock, int iThread, GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, int iSlice, float* tmpMinMax); + GPUd() int32_t InitFromClusterData(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, int32_t iSlice, float* tmpMinMax); /** * Return the number of hits in this slice. */ - GPUhd() int NumberOfHits() const { return mNumberOfHits; } - GPUhd() int NumberOfHitsPlusAlign() const { return mNumberOfHitsPlusAlign; } - GPUhd() int ClusterIdOffset() const { return mClusterIdOffset; } + GPUhd() int32_t NumberOfHits() const { return mNumberOfHits; } + GPUhd() int32_t NumberOfHitsPlusAlign() const { return mNumberOfHitsPlusAlign; } + GPUhd() int32_t ClusterIdOffset() const { return mClusterIdOffset; } /** * Access to the hit links. @@ -89,11 +89,11 @@ class GPUTPCSliceData * Return the y and z coordinate(s) of the given hit(s). */ MEM_TEMPLATE() - GPUd() cahit HitDataY(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const; + GPUd() cahit HitDataY(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const; MEM_TEMPLATE() - GPUd() cahit HitDataZ(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const; + GPUd() cahit HitDataZ(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const; MEM_TEMPLATE() - GPUd() cahit2 HitData(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const; + GPUd() cahit2 HitData(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const; /** * For a given bin index, content tells how many hits there are in the preceding bins. This maps @@ -108,31 +108,31 @@ class GPUTPCSliceData * If the given weight is higher than what is currently stored replace with the new weight. */ MEM_TEMPLATE() - GPUd() void MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex, unsigned int weight); + GPUd() void MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex, uint32_t weight); MEM_TEMPLATE() - GPUd() void SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex, unsigned int weight); + GPUd() void SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex, uint32_t weight); /** * Return the maximal weight the given hit got from one tracklet */ MEM_TEMPLATE() - GPUd() int HitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex) const; + GPUd() int32_t HitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex) const; /** * Returns the index in the original GPUTPCClusterData object of the given hit */ MEM_TEMPLATE() - GPUhd() int ClusterDataIndex(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex) const; - GPUd() GPUglobalref() const int* ClusterDataIndex() const { return mClusterDataIndex; } - GPUd() GPUglobalref() int* ClusterDataIndex() { return mClusterDataIndex; } + GPUhd() int32_t ClusterDataIndex(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex) const; + GPUd() GPUglobalref() const int32_t* ClusterDataIndex() const { return mClusterDataIndex; } + GPUd() GPUglobalref() int32_t* ClusterDataIndex() { return mClusterDataIndex; } /** * Return the row object for the given row index. */ - GPUhdi() GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & Row(int rowIndex) const { return mRows[rowIndex]; } + GPUhdi() GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & Row(int32_t rowIndex) const { return mRows[rowIndex]; } GPUhdi() GPUglobalref() MEM_GLOBAL(GPUTPCRow) * Rows() const { return mRows; } - GPUhdi() GPUglobalref() GPUAtomic(unsigned int) * HitWeights() { return (mHitWeights); } + GPUhdi() GPUglobalref() GPUAtomic(uint32_t) * HitWeights() { return (mHitWeights); } GPUhdi() void SetGPUTextureBase(GPUglobalref() const void* val) { mGPUTextureBase = val; } GPUhdi() char* GPUTextureBase() const { return ((char*)mGPUTextureBase); } @@ -147,15 +147,15 @@ class GPUTPCSliceData #endif GPUd() void CreateGrid(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, MEM_GLOBAL(GPUTPCRow) * GPUrestrict() row, float yMin, float yMax, float zMin, float zMax); GPUd() void SetRowGridEmpty(MEM_GLOBAL(GPUTPCRow) & GPUrestrict() row); - GPUd() static void GetMaxNBins(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, MEM_GLOBAL(GPUTPCRow) * GPUrestrict() row, int& maxY, int& maxZ); - GPUd() unsigned int GetGridSize(unsigned int nHits, unsigned int nRows); + GPUd() static void GetMaxNBins(GPUconstantref() const MEM_CONSTANT(GPUConstantMem) * mem, MEM_GLOBAL(GPUTPCRow) * GPUrestrict() row, int32_t& maxY, int32_t& maxZ); + GPUd() uint32_t GetGridSize(uint32_t nHits, uint32_t nRows); friend class GPUTPCNeighboursFinder; friend class GPUTPCStartHitsFinder; - int mNumberOfHits; // the number of hits in this slice - int mNumberOfHitsPlusAlign; - int mClusterIdOffset; + int32_t mNumberOfHits; // the number of hits in this slice + int32_t mNumberOfHitsPlusAlign; + int32_t mClusterIdOffset; GPUglobalref() const void* mGPUTextureBase; // pointer to start of GPU texture @@ -164,14 +164,14 @@ class GPUTPCSliceData GPUglobalref() calink* mLinkUpData; // hit index in the row above which is linked to the given (global) hit index GPUglobalref() calink* mLinkDownData; // hit index in the row below which is linked to the given (global) hit index GPUglobalref() cahit2* mHitData; // packed y,z coordinate of the given (global) hit index - GPUglobalref() int* mClusterDataIndex; // see ClusterDataIndex() + GPUglobalref() int32_t* mClusterDataIndex; // see ClusterDataIndex() /* * The size of the array is row.Grid.N + row.Grid.Ny + 3. The row.Grid.Ny + 3 is an optimization * to remove the need for bounds checking. The last values are the same as the entry at [N - 1]. */ GPUglobalref() calink* mFirstHitInBin; // see FirstHitInBin - GPUglobalref() GPUAtomic(unsigned int) * mHitWeights; // the weight of the longest tracklet crossed the cluster + GPUglobalref() GPUAtomic(uint32_t) * mHitWeights; // the weight of the longest tracklet crossed the cluster GPUglobalref() const GPUTPCClusterData* mClusterData; }; @@ -199,15 +199,15 @@ GPUdi() void MEM_LG(GPUTPCSliceData)::SetHitLinkDownData(const MEM_TYPE(GPUTPCRo MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() cahit MEM_LG(GPUTPCSliceData)::HitDataY(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex].x; } +GPUdi() cahit MEM_LG(GPUTPCSliceData)::HitDataY(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex].x; } MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() cahit MEM_LG(GPUTPCSliceData)::HitDataZ(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex].y; } +GPUdi() cahit MEM_LG(GPUTPCSliceData)::HitDataZ(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex].y; } MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() cahit2 MEM_LG(GPUTPCSliceData)::HitData(const MEM_TYPE(GPUTPCRow) & row, const unsigned int& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex]; } +GPUdi() cahit2 MEM_LG(GPUTPCSliceData)::HitData(const MEM_TYPE(GPUTPCRow) & row, const uint32_t& hitIndex) const { return mHitData[row.mHitNumberOffset + hitIndex]; } MEM_CLASS_PRE() MEM_TEMPLATE() @@ -215,25 +215,25 @@ GPUdi() calink MEM_LG(GPUTPCSliceData)::FirstHitInBin(const MEM_TYPE(GPUTPCRow) MEM_CLASS_PRE() MEM_TEMPLATE() -GPUhdi() int MEM_LG(GPUTPCSliceData)::ClusterDataIndex(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex) const { return mClusterDataIndex[row.mHitNumberOffset + hitIndex]; } +GPUhdi() int32_t MEM_LG(GPUTPCSliceData)::ClusterDataIndex(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex) const { return mClusterDataIndex[row.mHitNumberOffset + hitIndex]; } MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() void MEM_LG(GPUTPCSliceData)::MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex, unsigned int weight) +GPUdi() void MEM_LG(GPUTPCSliceData)::MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex, uint32_t weight) { CAMath::AtomicMax(&mHitWeights[row.mHitNumberOffset + hitIndex], weight); } MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() void MEM_LG(GPUTPCSliceData)::SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex, unsigned int weight) +GPUdi() void MEM_LG(GPUTPCSliceData)::SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex, uint32_t weight) { mHitWeights[row.mHitNumberOffset + hitIndex] = weight; } MEM_CLASS_PRE() MEM_TEMPLATE() -GPUdi() int MEM_LG(GPUTPCSliceData)::HitWeight(const MEM_TYPE(GPUTPCRow) & row, unsigned int hitIndex) const { return mHitWeights[row.mHitNumberOffset + hitIndex]; } +GPUdi() int32_t MEM_LG(GPUTPCSliceData)::HitWeight(const MEM_TYPE(GPUTPCRow) & row, uint32_t hitIndex) const { return mHitWeights[row.mHitNumberOffset + hitIndex]; } } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutCluster.h b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutCluster.h index a1cda9e491c6e..59d079d7e6328 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutCluster.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutCluster.h @@ -29,7 +29,7 @@ namespace gpu class GPUTPCSliceOutCluster { public: - GPUhd() void Set(unsigned int id, unsigned char row, unsigned char flags, unsigned short amp, float x, float y, float z) + GPUhd() void Set(uint32_t id, uint8_t row, uint8_t flags, uint16_t amp, float x, float y, float z) { mRow = row; mFlags = flags; @@ -43,16 +43,16 @@ class GPUTPCSliceOutCluster GPUhd() float GetX() const { return mX; } GPUhd() float GetY() const { return mY; } GPUhd() float GetZ() const { return mZ; } - GPUhd() unsigned short GetAmp() const { return mAmp; } - GPUhd() unsigned int GetId() const { return mId; } - GPUhd() unsigned char GetRow() const { return mRow; } - GPUhd() unsigned char GetFlags() const { return mFlags; } + GPUhd() uint16_t GetAmp() const { return mAmp; } + GPUhd() uint32_t GetId() const { return mId; } + GPUhd() uint8_t GetRow() const { return mRow; } + GPUhd() uint8_t GetFlags() const { return mFlags; } private: - unsigned int mId; // Id - unsigned char mRow; // row - unsigned char mFlags; // flags - unsigned short mAmp; // amplitude + uint32_t mId; // Id + uint8_t mRow; // row + uint8_t mFlags; // flags + uint16_t mAmp; // amplitude float mX; // coordinates float mY; // coordinates float mZ; // coordinates diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.cxx index d54c3140083e5..b7f876dc87e2e 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.cxx @@ -19,14 +19,14 @@ using namespace GPUCA_NAMESPACE::gpu; -unsigned int GPUTPCSliceOutput::EstimateSize(unsigned int nOfTracks, unsigned int nOfTrackClusters) +uint32_t GPUTPCSliceOutput::EstimateSize(uint32_t nOfTracks, uint32_t nOfTrackClusters) { // calculate the amount of memory [bytes] needed for the event return sizeof(GPUTPCSliceOutput) + sizeof(GPUTPCTrack) * nOfTracks + sizeof(GPUTPCSliceOutCluster) * nOfTrackClusters; } #ifndef GPUCA_GPUCODE -void GPUTPCSliceOutput::Allocate(GPUTPCSliceOutput*& ptrOutput, int nTracks, int nTrackHits, GPUOutputControl* outputControl, void*& internalMemory) +void GPUTPCSliceOutput::Allocate(GPUTPCSliceOutput*& ptrOutput, int32_t nTracks, int32_t nTrackHits, GPUOutputControl* outputControl, void*& internalMemory) { // Allocate All memory needed for slice output const size_t memsize = EstimateSize(nTracks, nTrackHits); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h index 7ade263cf208f..8892225f119cd 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h @@ -38,12 +38,12 @@ struct GPUOutputControl; class GPUTPCSliceOutput { public: - GPUhd() unsigned int NTracks() const + GPUhd() uint32_t NTracks() const { return mNTracks; } - GPUhd() unsigned int NLocalTracks() const { return mNLocalTracks; } - GPUhd() unsigned int NTrackClusters() const { return mNTrackClusters; } + GPUhd() uint32_t NLocalTracks() const { return mNLocalTracks; } + GPUhd() uint32_t NTrackClusters() const { return mNTrackClusters; } #if !defined(__OPENCL__) || defined(__OPENCLCPP__) GPUhd() const GPUTPCTrack* GetFirstTrack() const { @@ -59,12 +59,12 @@ class GPUTPCSliceOutput return (mMemorySize); } - static unsigned int EstimateSize(unsigned int nOfTracks, unsigned int nOfTrackClusters); - static void Allocate(GPUTPCSliceOutput*& ptrOutput, int nTracks, int nTrackHits, GPUOutputControl* outputControl, void*& internalMemory); + static uint32_t EstimateSize(uint32_t nOfTracks, uint32_t nOfTrackClusters); + static void Allocate(GPUTPCSliceOutput*& ptrOutput, int32_t nTracks, int32_t nTrackHits, GPUOutputControl* outputControl, void*& internalMemory); - GPUhd() void SetNTracks(unsigned int v) { mNTracks = v; } - GPUhd() void SetNLocalTracks(unsigned int v) { mNLocalTracks = v; } - GPUhd() void SetNTrackClusters(unsigned int v) { mNTrackClusters = v; } + GPUhd() void SetNTracks(uint32_t v) { mNTracks = v; } + GPUhd() void SetNLocalTracks(uint32_t v) { mNLocalTracks = v; } + GPUhd() void SetNTrackClusters(uint32_t v) { mNTrackClusters = v; } private: GPUTPCSliceOutput() CON_DELETE; // NOLINT: Must be private or ROOT tries to use them! @@ -74,9 +74,9 @@ class GPUTPCSliceOutput GPUhd() void SetMemorySize(size_t val) { mMemorySize = val; } - unsigned int mNTracks; // number of reconstructed tracks - unsigned int mNLocalTracks; - unsigned int mNTrackClusters; // total number of track clusters + uint32_t mNTracks; // number of reconstructed tracks + uint32_t mNLocalTracks; + uint32_t mNTrackClusters; // total number of track clusters size_t mMemorySize; // Amount of memory really used }; } // namespace gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx index 3c90adb9b03e6..e9bbcdf91ca6c 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.cxx @@ -19,7 +19,7 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int /*nBlocks*/, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int32_t /*nBlocks*/, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { // find start hits for tracklets if (iThread == 0) { @@ -34,14 +34,14 @@ GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int /*nBlocks*/, int nThreads, in GPUbarrier(); GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() row = tracker.mData.mRows[s.mIRow]; GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & GPUrestrict() rowUp = tracker.mData.mRows[s.mIRow + 2]; - for (int ih = iThread; ih < s.mNHits; ih += nThreads) { - long lHitNumberOffset = row.mHitNumberOffset; - unsigned int linkUpData = tracker.mData.mLinkUpData[lHitNumberOffset + ih]; + for (int32_t ih = iThread; ih < s.mNHits; ih += nThreads) { + int64_t lHitNumberOffset = row.mHitNumberOffset; + uint32_t linkUpData = tracker.mData.mLinkUpData[lHitNumberOffset + ih]; if (tracker.mData.mLinkDownData[lHitNumberOffset + ih] == CALINK_INVAL && linkUpData != CALINK_INVAL && tracker.mData.mLinkUpData[rowUp.mHitNumberOffset + linkUpData] != CALINK_INVAL) { #ifdef GPUCA_SORT_STARTHITS GPUglobalref() GPUTPCHitId* const GPUrestrict() startHits = tracker.mTrackletTmpStartHits + s.mIRow * tracker.mNMaxRowStartHits; - unsigned int nextRowStartHits = CAMath::AtomicAddShared(&s.mNRowStartHits, 1u); + uint32_t nextRowStartHits = CAMath::AtomicAddShared(&s.mNRowStartHits, 1u); if (nextRowStartHits >= tracker.mNMaxRowStartHits) { tracker.raiseError(GPUErrors::ERROR_ROWSTARTHIT_OVERFLOW, tracker.ISlice() * 1000 + s.mIRow, nextRowStartHits, tracker.mNMaxRowStartHits); CAMath::AtomicExchShared(&s.mNRowStartHits, tracker.mNMaxRowStartHits); @@ -49,7 +49,7 @@ GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int /*nBlocks*/, int nThreads, in } #else GPUglobalref() GPUTPCHitId* const GPUrestrict() startHits = tracker.mTrackletStartHits; - unsigned int nextRowStartHits = CAMath::AtomicAdd(&tracker.mCommonMem->nStartHits, 1u); + uint32_t nextRowStartHits = CAMath::AtomicAdd(&tracker.mCommonMem->nStartHits, 1u); if (nextRowStartHits >= tracker.mNMaxStartHits) { tracker.raiseError(GPUErrors::ERROR_STARTHIT_OVERFLOW, tracker.ISlice() * 1000 + s.mIRow, nextRowStartHits, tracker.mNMaxStartHits); CAMath::AtomicExch(&tracker.mCommonMem->nStartHits, tracker.mNMaxStartHits); @@ -63,7 +63,7 @@ GPUdii() void GPUTPCStartHitsFinder::Thread<0>(int /*nBlocks*/, int nThreads, in #ifdef GPUCA_SORT_STARTHITS if (iThread == 0) { - unsigned int nOffset = CAMath::AtomicAdd(&tracker.mCommonMem->nStartHits, s.mNRowStartHits); + uint32_t nOffset = CAMath::AtomicAdd(&tracker.mCommonMem->nStartHits, s.mNRowStartHits); tracker.mRowStartHitCountOffset[s.mIRow] = s.mNRowStartHits; if (nOffset + s.mNRowStartHits > tracker.mNMaxStartHits) { tracker.raiseError(GPUErrors::ERROR_STARTHIT_OVERFLOW, tracker.ISlice() * 1000 + s.mIRow, nOffset + s.mNRowStartHits, tracker.mNMaxStartHits); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.h b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.h index 2407a5dafda7b..f0adf3985a613 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsFinder.h @@ -36,9 +36,9 @@ class GPUTPCStartHitsFinder : public GPUKernelTemplate public: MEM_CLASS_PRE() struct GPUSharedMemory { - int mIRow; // row index - int mNHits; // n hits in the row - GPUAtomic(unsigned int) mNRowStartHits; // start hits found in the row + int32_t mIRow; // row index + int32_t mNHits; // n hits in the row + GPUAtomic(uint32_t) mNRowStartHits; // start hits found in the row }; typedef GPUconstantref() MEM_GLOBAL(GPUTPCTracker) processorType; @@ -48,8 +48,8 @@ class GPUTPCStartHitsFinder : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.cxx index cfd3f66d536c4..4275306999531 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.cxx @@ -21,16 +21,16 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCStartHitsSorter::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCStartHitsSorter::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { // Sorts the Start Hits by Row Index if (iThread == 0) { - const int tmpNRows = GPUCA_ROW_COUNT - 6; - const int nRows = iBlock == (nBlocks - 1) ? (tmpNRows - (tmpNRows / nBlocks) * (nBlocks - 1)) : (tmpNRows / nBlocks); - const int nStartRow = (tmpNRows / nBlocks) * iBlock + 1; - int startOffset2 = 0; + const int32_t tmpNRows = GPUCA_ROW_COUNT - 6; + const int32_t nRows = iBlock == (nBlocks - 1) ? (tmpNRows - (tmpNRows / nBlocks) * (nBlocks - 1)) : (tmpNRows / nBlocks); + const int32_t nStartRow = (tmpNRows / nBlocks) * iBlock + 1; + int32_t startOffset2 = 0; GPUCA_UNROLL(, U()) - for (int ir = 1; ir < GPUCA_ROW_COUNT - 5; ir++) { + for (int32_t ir = 1; ir < GPUCA_ROW_COUNT - 5; ir++) { if (ir < nStartRow) { startOffset2 += tracker.mRowStartHitCountOffset[ir]; } @@ -41,17 +41,17 @@ GPUdii() void GPUTPCStartHitsSorter::Thread<0>(int nBlocks, int nThreads, int iB } GPUbarrier(); - int startOffset = s.mStartOffset; + int32_t startOffset = s.mStartOffset; #ifdef __HIPCC__ // TODO: Fixme - for (int ir = -1; ++ir < s.mNRows;) { + for (int32_t ir = -1; ++ir < s.mNRows;) { #else - for (int ir = 0; ir < s.mNRows; ir++) { + for (int32_t ir = 0; ir < s.mNRows; ir++) { #endif GPUglobalref() GPUTPCHitId* const GPUrestrict() startHits = tracker.mTrackletStartHits; GPUglobalref() GPUTPCHitId* const GPUrestrict() tmpStartHits = tracker.mTrackletTmpStartHits + (s.mStartRow + ir) * tracker.mNMaxRowStartHits; - const int tmpLen = tracker.mRowStartHitCountOffset[ir + s.mStartRow]; // Length of hits in row stored by StartHitsFinder - for (int j = iThread; j < tmpLen; j += nThreads) { + const int32_t tmpLen = tracker.mRowStartHitCountOffset[ir + s.mStartRow]; // Length of hits in row stored by StartHitsFinder + for (int32_t j = iThread; j < tmpLen; j += nThreads) { startHits[startOffset + j] = tmpStartHits[j]; } startOffset += tmpLen; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.h b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.h index f2f0a614be563..d5f9cc41e2a1a 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCStartHitsSorter.h @@ -36,9 +36,9 @@ class GPUTPCStartHitsSorter : public GPUKernelTemplate public: MEM_CLASS_PRE() struct GPUSharedMemory { - int mStartRow; // start row index - int mNRows; // number of rows to process - int mStartOffset; // start offset for hits sorted by this block + int32_t mStartRow; // start row index + int32_t mNRows; // number of rows to process + int32_t mStartOffset; // start offset for hits sorted by this block }; typedef GPUconstantref() MEM_GLOBAL(GPUTPCTracker) processorType; @@ -48,8 +48,8 @@ class GPUTPCStartHitsSorter : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrack.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrack.h index 0e13c46f3b19f..759f4e0f954bd 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrack.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrack.h @@ -41,30 +41,30 @@ class GPUTPCTrack ~GPUTPCTrack() CON_DEFAULT; #endif //! GPUCA_GPUCODE - GPUhd() int NHits() const { return mNHits; } - GPUhd() int LocalTrackId() const { return mLocalTrackId; } - GPUhd() int FirstHitID() const { return mFirstHitID; } + GPUhd() int32_t NHits() const { return mNHits; } + GPUhd() int32_t LocalTrackId() const { return mLocalTrackId; } + GPUhd() int32_t FirstHitID() const { return mFirstHitID; } GPUhd() MakeType(const MEM_LG(GPUTPCBaseTrackParam) &) Param() const { return mParam; } - GPUhd() void SetNHits(int v) { mNHits = v; } - GPUhd() void SetLocalTrackId(int v) { mLocalTrackId = v; } - GPUhd() void SetFirstHitID(int v) { mFirstHitID = v; } + GPUhd() void SetNHits(int32_t v) { mNHits = v; } + GPUhd() void SetLocalTrackId(int32_t v) { mLocalTrackId = v; } + GPUhd() void SetFirstHitID(int32_t v) { mFirstHitID = v; } MEM_TEMPLATE() GPUhd() void SetParam(const MEM_TYPE(GPUTPCBaseTrackParam) & v) { mParam = v; } // Only if used as replacement for SliceOutTrack - GPUhd() static int GetSize(int nClust) { return sizeof(GPUTPCTrack) + nClust * sizeof(GPUTPCSliceOutCluster); } + GPUhd() static int32_t GetSize(int32_t nClust) { return sizeof(GPUTPCTrack) + nClust * sizeof(GPUTPCSliceOutCluster); } GPUhd() const GPUTPCTrack* GetNextTrack() const { return (const GPUTPCTrack*)(((char*)this) + GetSize(mNHits)); } GPUhd() GPUTPCTrack* NextTrack() { return (GPUTPCTrack*)(((char*)this) + GetSize(mNHits)); } - GPUhd() void SetOutTrackCluster(int i, const GPUTPCSliceOutCluster& v) { ((GPUTPCSliceOutCluster*)((char*)this + sizeof(*this)))[i] = v; } + GPUhd() void SetOutTrackCluster(int32_t i, const GPUTPCSliceOutCluster& v) { ((GPUTPCSliceOutCluster*)((char*)this + sizeof(*this)))[i] = v; } GPUhd() const GPUTPCSliceOutCluster* OutTrackClusters() const { return (const GPUTPCSliceOutCluster*)((char*)this + sizeof(*this)); } - GPUhd() const GPUTPCSliceOutCluster& OutTrackCluster(int i) const { return OutTrackClusters()[i]; } + GPUhd() const GPUTPCSliceOutCluster& OutTrackCluster(int32_t i) const { return OutTrackClusters()[i]; } private: - int mFirstHitID; // index of the first track cell in the track->cell pointer array - int mNHits; // number of track cells - int mLocalTrackId; // Id of local track this global track belongs to, index of this track itself if it is a local track + int32_t mFirstHitID; // index of the first track cell in the track->cell pointer array + int32_t mNHits; // number of track cells + int32_t mLocalTrackId; // Id of local track this global track belongs to, index of this track itself if it is a local track MEM_LG(GPUTPCBaseTrackParam) mParam; // track parameters diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.cxx index 2179118ff1ccd..18245c48ab578 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.cxx @@ -698,10 +698,10 @@ GPUd() bool MEM_LG(GPUTPCTrackParam)::CheckNumericalQuality() const bool ok = CAMath::Finite(GetX()) && CAMath::Finite(mSignCosPhi) && CAMath::Finite(mChi2); const float* c = Cov(); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { ok = ok && CAMath::Finite(c[i]); } - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { ok = ok && CAMath::Finite(Par()[i]); } @@ -728,7 +728,7 @@ GPUd() bool MEM_LG(GPUTPCTrackParam)::CheckNumericalQuality() const } MEM_CLASS_PRE() -GPUd() void MEM_LG(GPUTPCTrackParam)::ConstrainZ(float& z, int sector, float& z0, float& lastZ) +GPUd() void MEM_LG(GPUTPCTrackParam)::ConstrainZ(float& z, int32_t sector, float& z0, float& lastZ) { if (sector < GPUCA_NSLICES / 2) { if (z < 0) { @@ -775,7 +775,7 @@ GPUd() void MEM_LG(GPUTPCTrackParam)::ShiftZ(float z1, float z2, float x1, float if (dist1r2 < 4) { const float alpha = CAMath::ACos(1 - 0.5f * dist1r2); // Angle of a circle, such that |(cosa, sina) - (1,0)| == dist const float beta = CAMath::ATan2(mParam.mP[0], mParam.mX); - const int comp = mParam.mP[2] > CAMath::Sin(beta); + const int32_t comp = mParam.mP[2] > CAMath::Sin(beta); const float sinab = CAMath::Sin((comp ? 0.5f : -0.5f) * alpha + beta); // Angle of circle through origin and track position, to be compared to Snp const float res = CAMath::Abs(sinab - mParam.mP[2]); @@ -838,7 +838,7 @@ GPUd() void MEM_LG(GPUTPCTrackParam)::Print() const } MEM_CLASS_PRE() -GPUd() int MEM_LG(GPUTPCTrackParam)::GetPropagatedYZ(float bz, float x, float& projY, float& projZ) const +GPUd() int32_t MEM_LG(GPUTPCTrackParam)::GetPropagatedYZ(float bz, float x, float& projY, float& projZ) const { float k = mParam.mP[4] * bz; float dx = x - mParam.mX; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h index 38d81c6e594b5..ffc28af6f4e32 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackParam.h @@ -53,7 +53,7 @@ class GPUTPCTrackParam GPUd() float ZOffset() const { return mParam.ZOffset(); } GPUd() float SignCosPhi() const { return mSignCosPhi; } GPUd() float Chi2() const { return mChi2; } - GPUd() int NDF() const { return mNDF; } + GPUd() int32_t NDF() const { return mNDF; } GPUd() float Err2Y() const { return mParam.Err2Y(); } GPUd() float Err2Z() const { return mParam.Err2Z(); } @@ -69,7 +69,7 @@ class GPUTPCTrackParam GPUd() float GetQPt() const { return mParam.GetQPt(); } GPUd() float GetSignCosPhi() const { return mSignCosPhi; } GPUd() float GetChi2() const { return mChi2; } - GPUd() int GetNDF() const { return mNDF; } + GPUd() int32_t GetNDF() const { return mNDF; } GPUd() float GetKappa(float Bz) const { return mParam.GetKappa(Bz); } GPUd() float GetCosPhi() const { return mSignCosPhi * CAMath::Sqrt(1 - SinPhi() * SinPhi()); } @@ -78,11 +78,11 @@ class GPUTPCTrackParam GPUhd() const float* Cov() const { return mParam.Cov(); } GPUd() const float* GetPar() const { return mParam.GetPar(); } - GPUd() float GetPar(int i) const { return (mParam.GetPar(i)); } - GPUd() float GetCov(int i) const { return mParam.GetCov(i); } + GPUd() float GetPar(int32_t i) const { return (mParam.GetPar(i)); } + GPUd() float GetCov(int32_t i) const { return mParam.GetCov(i); } - GPUhd() void SetPar(int i, float v) { mParam.SetPar(i, v); } - GPUhd() void SetCov(int i, float v) { mParam.SetCov(i, v); } + GPUhd() void SetPar(int32_t i, float v) { mParam.SetPar(i, v); } + GPUhd() void SetCov(int32_t i, float v) { mParam.SetCov(i, v); } GPUd() void SetX(float v) { mParam.SetX(v); } GPUd() void SetY(float v) { mParam.SetY(v); } @@ -93,7 +93,7 @@ class GPUTPCTrackParam GPUd() void SetZOffset(float v) { mParam.SetZOffset(v); } GPUd() void SetSignCosPhi(float v) { mSignCosPhi = v >= 0 ? 1 : -1; } GPUd() void SetChi2(float v) { mChi2 = v; } - GPUd() void SetNDF(int v) { mNDF = v; } + GPUd() void SetNDF(int32_t v) { mNDF = v; } GPUd() float GetDist2(const GPUTPCTrackParam& t) const; GPUd() float GetDistXZ2(const GPUTPCTrackParam& t) const; @@ -128,8 +128,8 @@ class GPUTPCTrackParam GPUd() bool CheckNumericalQuality() const; GPUd() void ShiftZ(float z1, float z2, float x1, float x2, float bz, float defaultZOffsetOverR); - GPUd() void ConstrainZ(float& z, int sector, float& z0, float& lastZ); - GPUd() int GetPropagatedYZ(float bz, float x, float& projY, float& projZ) const; + GPUd() void ConstrainZ(float& z, int32_t sector, float& z0, float& lastZ); + GPUd() int32_t GetPropagatedYZ(float bz, float x, float& projY, float& projZ) const; GPUdi() void ConstrainSinPhi(float limit = GPUCA_MAX_SIN_PHI) { @@ -154,7 +154,7 @@ class GPUTPCTrackParam // Changes to Elements of this class therefore must also be applied to TrackletConstructor!!! float mSignCosPhi; // sign of cosPhi float mChi2; // the chi^2 value - int mNDF; // the Number of Degrees of Freedom + int32_t mNDF; // the Number of Degrees of Freedom }; MEM_CLASS_PRE() diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx index c0927491d4367..552d61a88fc39 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx @@ -54,7 +54,7 @@ GPUTPCTracker::~GPUTPCTracker() } // ---------------------------------------------------------------------------------- -void GPUTPCTracker::SetSlice(int iSlice) { mISlice = iSlice; } +void GPUTPCTracker::SetSlice(int32_t iSlice) { mISlice = iSlice; } void GPUTPCTracker::InitializeProcessor() { if (mISlice < 0) { @@ -107,19 +107,19 @@ void GPUTPCTracker::RegisterMemoryAllocation() { AllocateAndInitializeLate(); bool reuseCondition = !mRec->GetProcessingSettings().keepDisplayMemory && mRec->GetProcessingSettings().trackletSelectorInPipeline && ((mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCSliceTracking) || mRec->GetProcessingSettings().ompKernels == 1 || mRec->GetProcessingSettings().ompThreads == 1); - GPUMemoryReuse reLinks{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerDataLinks, (unsigned short)(mISlice % mRec->GetProcessingSettings().nStreams)}; + GPUMemoryReuse reLinks{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerDataLinks, (uint16_t)(mISlice % mRec->GetProcessingSettings().nStreams)}; mMemoryResLinks = mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersDataLinks, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK, "TPCSliceLinks", reLinks); mMemoryResSliceScratch = mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersDataScratch, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK | GPUMemoryResource::MEMORY_CUSTOM, "TPCSliceScratch"); mMemoryResSliceInput = mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersDataInput, GPUMemoryResource::MEMORY_INPUT | GPUMemoryResource::MEMORY_STACK | GPUMemoryResource::MEMORY_CUSTOM, "TPCSliceInput"); - GPUMemoryReuse reWeights{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerDataWeights, (unsigned short)(mISlice % mRec->GetProcessingSettings().nStreams)}; + GPUMemoryReuse reWeights{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerDataWeights, (uint16_t)(mISlice % mRec->GetProcessingSettings().nStreams)}; mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersDataWeights, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK, "TPCSliceWeights", reWeights); - GPUMemoryReuse reScratch{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerScratch, (unsigned short)(mISlice % mRec->GetProcessingSettings().nStreams)}; + GPUMemoryReuse reScratch{reuseCondition, GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::TrackerScratch, (uint16_t)(mISlice % mRec->GetProcessingSettings().nStreams)}; mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersScratch, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK, "TPCTrackerScratch", reScratch); mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersScratchHost, GPUMemoryResource::MEMORY_SCRATCH_HOST, "TPCTrackerHost"); mMemoryResCommon = mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersCommon, GPUMemoryResource::MEMORY_PERMANENT, "TPCTrackerCommon"); mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersDataRows, GPUMemoryResource::MEMORY_PERMANENT, "TPCSliceRows"); - unsigned int type = mRec->GetProcessingSettings().fullMergerOnGPU ? GPUMemoryResource::MEMORY_SCRATCH : GPUMemoryResource::MEMORY_OUTPUT; + uint32_t type = mRec->GetProcessingSettings().fullMergerOnGPU ? GPUMemoryResource::MEMORY_SCRATCH : GPUMemoryResource::MEMORY_OUTPUT; if (mRec->GetProcessingSettings().memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_INDIVIDUAL) { // For individual scheme, we allocate tracklets separately, and change the type for the following allocations to custom type |= GPUMemoryResource::MEMORY_CUSTOM; mMemoryResTracklets = mRec->RegisterMemoryAllocation(this, &GPUTPCTracker::SetPointersTracklets, type, "TPCTrackerTracklets"); @@ -149,8 +149,8 @@ void GPUTPCTracker::SetMaxData(const GPUTrackingInOutPointers& io) mNMaxStartHits = mRec->MemoryScalers()->NTPCStartHits(mData.NumberOfHits()); } if (io.clustersNative) { - unsigned int maxRowHits = 0; - for (unsigned int i = 0; i < GPUCA_ROW_COUNT; i++) { + uint32_t maxRowHits = 0; + for (uint32_t i = 0; i < GPUCA_ROW_COUNT; i++) { if (io.clustersNative->nClusters[mISlice][i] > maxRowHits) { maxRowHits = io.clustersNative->nClusters[mISlice][i]; } @@ -182,7 +182,7 @@ void GPUTPCTracker::UpdateMaxData() void GPUTPCTracker::SetupCommonMemory() { new (mCommonMem) commonMemoryStruct; } -GPUh() int GPUTPCTracker::CheckEmptySlice() +GPUh() int32_t GPUTPCTracker::CheckEmptySlice() { // Check if the Slice is empty, if so set the output apropriate and tell the reconstuct procesdure to terminate if (NHitsTotal() < 1) { @@ -219,35 +219,35 @@ GPUh() void GPUTPCTracker::WriteOutput() return; } - int nStoredHits = 0; - int nStoredTracks = 0; - int nStoredLocalTracks = 0; + int32_t nStoredHits = 0; + int32_t nStoredTracks = 0; + int32_t nStoredLocalTracks = 0; GPUTPCTrack* out = mOutput->FirstTrack(); trackSortData* trackOrder = new trackSortData[mCommonMem->nTracks]; - for (unsigned int i = 0; i < mCommonMem->nTracks; i++) { + for (uint32_t i = 0; i < mCommonMem->nTracks; i++) { trackOrder[i].fTtrack = i; trackOrder[i].fSortVal = mTracks[trackOrder[i].fTtrack].NHits() / 1000.f + mTracks[trackOrder[i].fTtrack].Param().GetZ() * 100.f + mTracks[trackOrder[i].fTtrack].Param().GetY(); } std::sort(trackOrder, trackOrder + mCommonMem->nLocalTracks, SortComparison); // TODO: Check why this sorting affects the merging efficiency! std::sort(trackOrder + mCommonMem->nLocalTracks, trackOrder + mCommonMem->nTracks, SortComparison); - for (unsigned int iTrTmp = 0; iTrTmp < mCommonMem->nTracks; iTrTmp++) { - const int iTr = trackOrder[iTrTmp].fTtrack; + for (uint32_t iTrTmp = 0; iTrTmp < mCommonMem->nTracks; iTrTmp++) { + const int32_t iTr = trackOrder[iTrTmp].fTtrack; GPUTPCTrack& iTrack = mTracks[iTr]; *out = iTrack; - int nClu = 0; - int iID = iTrack.FirstHitID(); + int32_t nClu = 0; + int32_t iID = iTrack.FirstHitID(); - for (int ith = 0; ith < iTrack.NHits(); ith++) { + for (int32_t ith = 0; ith < iTrack.NHits(); ith++) { const GPUTPCHitId& ic = mTrackHits[iID + ith]; - int iRow = ic.RowIndex(); - int ih = ic.HitIndex(); + int32_t iRow = ic.RowIndex(); + int32_t ih = ic.HitIndex(); const GPUTPCRow& row = mData.Row(iRow); - int clusterIndex = mData.ClusterDataIndex(row, ih); + int32_t clusterIndex = mData.ClusterDataIndex(row, ih); #ifdef GPUCA_ARRAY_BOUNDS_CHECKS if (ih >= row.NHits() || ih < 0) { GPUError("Array out of bounds access (Sector Row) (Hit %d / %d - NumC %d): Sector %d Row %d Index %d", ith, iTrack.NHits(), NHitsTotal(), mISlice, iRow, ih); @@ -262,9 +262,9 @@ GPUh() void GPUTPCTracker::WriteOutput() #endif float origX, origY, origZ; - unsigned char flags; - unsigned short amp; - int id; + uint8_t flags; + uint16_t amp; + int32_t id; if (Param().par.earlyTpcTransform) { origX = mData.ClusterData()[clusterIndex].x; origY = mData.ClusterData()[clusterIndex].y; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h index 9e35800d13517..f19b4f0a6c0a7 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h @@ -53,19 +53,19 @@ class GPUTPCTracker : public GPUProcessor GPUTPCTracker& operator=(const GPUTPCTracker&) CON_DELETE; MEM_CLASS_PRE2() - void SetSlice(int iSlice); + void SetSlice(int32_t iSlice); MEM_CLASS_PRE2() void InitializeProcessor(); MEM_CLASS_PRE2() void InitializeRows(const MEM_CONSTANT(GPUParam) * param) { mData.InitializeRows(*param); } - int CheckEmptySlice(); + int32_t CheckEmptySlice(); void WriteOutputPrepare(); void WriteOutput(); // Debugging Stuff void DumpSliceData(std::ostream& out); // Dump Input Slice Data - void DumpLinks(std::ostream& out, int phase); // Dump all links to file (for comparison after NeighboursFinder/Cleaner) + void DumpLinks(std::ostream& out, int32_t phase); // Dump all links to file (for comparison after NeighboursFinder/Cleaner) void DumpStartHits(std::ostream& out); // Same for Start Hits void DumpHitWeights(std::ostream& out); //.... void DumpTrackHits(std::ostream& out); // Same for Track Hits @@ -74,7 +74,7 @@ class GPUTPCTracker : public GPUProcessor #endif struct StructGPUParameters { - GPUAtomic(unsigned int) nextStartHit; // Next Tracklet to process + GPUAtomic(uint32_t) nextStartHit; // Next Tracklet to process }; MEM_CLASS_PRE2() @@ -84,13 +84,13 @@ class GPUTPCTracker : public GPUProcessor struct commonMemoryStruct { commonMemoryStruct() : nStartHits(0), nTracklets(0), nRowHits(0), nTracks(0), nLocalTracks(0), nTrackHits(0), nLocalTrackHits(0), gpuParameters() {} - GPUAtomic(unsigned int) nStartHits; // number of start hits - GPUAtomic(unsigned int) nTracklets; // number of tracklets - GPUAtomic(unsigned int) nRowHits; // number of tracklet hits - GPUAtomic(unsigned int) nTracks; // number of reconstructed tracks - int nLocalTracks; // number of reconstructed tracks before global tracking - GPUAtomic(unsigned int) nTrackHits; // number of track hits - int nLocalTrackHits; // see above + GPUAtomic(uint32_t) nStartHits; // number of start hits + GPUAtomic(uint32_t) nTracklets; // number of tracklets + GPUAtomic(uint32_t) nRowHits; // number of tracklet hits + GPUAtomic(uint32_t) nTracks; // number of reconstructed tracks + int32_t nLocalTracks; // number of reconstructed tracks before global tracking + GPUAtomic(uint32_t) nTrackHits; // number of track hits + int32_t nLocalTrackHits; // see above StructGPUParameters gpuParameters; // GPU parameters }; @@ -108,19 +108,19 @@ class GPUTPCTracker : public GPUProcessor } MEM_CLASS_PRE2() - GPUdi() static void GetErrors2Seeding(const MEM_CONSTANT(GPUParam) & param, char sector, int iRow, const MEM_LG2(GPUTPCTrackParam) & t, float time, float& ErrY2, float& ErrZ2) + GPUdi() static void GetErrors2Seeding(const MEM_CONSTANT(GPUParam) & param, char sector, int32_t iRow, const MEM_LG2(GPUTPCTrackParam) & t, float time, float& ErrY2, float& ErrZ2) { // param.GetClusterErrors2(sector, iRow, param.GetContinuousTracking() != 0. ? 125.f : t.Z(), t.SinPhi(), t.DzDs(), time, 0.f, 0.f, ErrY2, ErrZ2); param.GetClusterErrorsSeeding2(sector, iRow, param.par.continuousTracking != 0.f ? 125.f : t.Z(), t.SinPhi(), t.DzDs(), time, ErrY2, ErrZ2); } MEM_CLASS_PRE2() - GPUdi() void GetErrors2Seeding(int iRow, const MEM_LG2(GPUTPCTrackParam) & t, float time, float& ErrY2, float& ErrZ2) const + GPUdi() void GetErrors2Seeding(int32_t iRow, const MEM_LG2(GPUTPCTrackParam) & t, float time, float& ErrY2, float& ErrZ2) const { // Param().GetClusterErrors2(mISlice, iRow, Param().GetContinuousTracking() != 0. ? 125.f : t.Z(), t.SinPhi(), t.DzDs(), time, 0.f, 0.f, ErrY2, ErrZ2); Param().GetClusterErrorsSeeding2(mISlice, iRow, Param().par.continuousTracking != 0.f ? 125.f : t.Z(), t.SinPhi(), t.DzDs(), time, ErrY2, ErrZ2); } - GPUdi() void GetErrors2Seeding(int iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const + GPUdi() void GetErrors2Seeding(int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const { // Param().GetClusterErrors2(mISlice, iRow, Param().GetContinuousTracking() != 0. ? 125.f : z, sinPhi, DzDs, time, 0.f, 0.f, ErrY2, ErrZ2); Param().GetClusterErrorsSeeding2(mISlice, iRow, Param().par.continuousTracking != 0.f ? 125.f : z, sinPhi, DzDs, time, ErrY2, ErrZ2); @@ -140,18 +140,18 @@ class GPUTPCTracker : public GPUProcessor void* SetPointersOutput(void* mem); void RegisterMemoryAllocation(); - short MemoryResLinks() const { return mMemoryResLinks; } - short MemoryResScratchHost() const { return mMemoryResScratchHost; } - short MemoryResCommon() const { return mMemoryResCommon; } - short MemoryResTracklets() const { return mMemoryResTracklets; } - short MemoryResOutput() const { return mMemoryResOutput; } - short MemoryResSliceScratch() const { return mMemoryResSliceScratch; } - short MemoryResSliceInput() const { return mMemoryResSliceInput; } + int16_t MemoryResLinks() const { return mMemoryResLinks; } + int16_t MemoryResScratchHost() const { return mMemoryResScratchHost; } + int16_t MemoryResCommon() const { return mMemoryResCommon; } + int16_t MemoryResTracklets() const { return mMemoryResTracklets; } + int16_t MemoryResOutput() const { return mMemoryResOutput; } + int16_t MemoryResSliceScratch() const { return mMemoryResSliceScratch; } + int16_t MemoryResSliceInput() const { return mMemoryResSliceInput; } void SetMaxData(const GPUTrackingInOutPointers& io); void UpdateMaxData(); - GPUhd() int ISlice() const { return mISlice; } + GPUhd() int32_t ISlice() const { return mISlice; } GPUhd() GPUconstantref() const MEM_LG(GPUTPCSliceData) & Data() const { return mData; } GPUhdi() GPUconstantref() MEM_LG(GPUTPCSliceData) & Data() @@ -159,24 +159,24 @@ class GPUTPCTracker : public GPUProcessor return mData; } - GPUhd() GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & Row(int rowIndex) const { return mData.Row(rowIndex); } + GPUhd() GPUglobalref() const MEM_GLOBAL(GPUTPCRow) & Row(int32_t rowIndex) const { return mData.Row(rowIndex); } - GPUhd() unsigned int NHitsTotal() const { return mData.NumberOfHits(); } - GPUhd() unsigned int NMaxTracklets() const { return mNMaxTracklets; } - GPUhd() unsigned int NMaxRowHits() const { return mNMaxRowHits; } - GPUhd() unsigned int NMaxTracks() const { return mNMaxTracks; } - GPUhd() unsigned int NMaxTrackHits() const { return mNMaxTrackHits; } - GPUhd() unsigned int NMaxStartHits() const { return mNMaxStartHits; } - GPUhd() unsigned int NMaxRowStartHits() const { return mNMaxRowStartHits; } + GPUhd() uint32_t NHitsTotal() const { return mData.NumberOfHits(); } + GPUhd() uint32_t NMaxTracklets() const { return mNMaxTracklets; } + GPUhd() uint32_t NMaxRowHits() const { return mNMaxRowHits; } + GPUhd() uint32_t NMaxTracks() const { return mNMaxTracks; } + GPUhd() uint32_t NMaxTrackHits() const { return mNMaxTrackHits; } + GPUhd() uint32_t NMaxStartHits() const { return mNMaxStartHits; } + GPUhd() uint32_t NMaxRowStartHits() const { return mNMaxRowStartHits; } MEM_TEMPLATE() - GPUd() void SetHitLinkUpData(const MEM_TYPE(GPUTPCRow) & row, int hitIndex, calink v) { mData.SetHitLinkUpData(row, hitIndex, v); } + GPUd() void SetHitLinkUpData(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex, calink v) { mData.SetHitLinkUpData(row, hitIndex, v); } MEM_TEMPLATE() - GPUd() void SetHitLinkDownData(const MEM_TYPE(GPUTPCRow) & row, int hitIndex, calink v) { mData.SetHitLinkDownData(row, hitIndex, v); } + GPUd() void SetHitLinkDownData(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex, calink v) { mData.SetHitLinkDownData(row, hitIndex, v); } MEM_TEMPLATE() - GPUd() calink HitLinkUpData(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitLinkUpData(row, hitIndex); } + GPUd() calink HitLinkUpData(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitLinkUpData(row, hitIndex); } MEM_TEMPLATE() - GPUd() calink HitLinkDownData(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitLinkDownData(row, hitIndex); } + GPUd() calink HitLinkDownData(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitLinkDownData(row, hitIndex); } MEM_TEMPLATE() GPUd() GPUglobalref() const cahit2* HitData(const MEM_TYPE(GPUTPCRow) & row) const { return mData.HitData(row); } @@ -188,17 +188,17 @@ class GPUTPCTracker : public GPUProcessor GPUd() GPUglobalref() const calink* FirstHitInBin(const MEM_TYPE(GPUTPCRow) & row) const { return mData.FirstHitInBin(row); } MEM_TEMPLATE() - GPUd() int FirstHitInBin(const MEM_TYPE(GPUTPCRow) & row, int binIndex) const { return mData.FirstHitInBin(row, binIndex); } + GPUd() int32_t FirstHitInBin(const MEM_TYPE(GPUTPCRow) & row, int32_t binIndex) const { return mData.FirstHitInBin(row, binIndex); } MEM_TEMPLATE() - GPUd() cahit HitDataY(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitDataY(row, hitIndex); } + GPUd() cahit HitDataY(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitDataY(row, hitIndex); } MEM_TEMPLATE() - GPUd() cahit HitDataZ(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitDataZ(row, hitIndex); } + GPUd() cahit HitDataZ(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitDataZ(row, hitIndex); } MEM_TEMPLATE() - GPUd() cahit2 HitData(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitData(row, hitIndex); } + GPUd() cahit2 HitData(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitData(row, hitIndex); } MEM_TEMPLATE() - GPUhd() int HitInputID(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.ClusterDataIndex(row, hitIndex); } + GPUhd() int32_t HitInputID(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.ClusterDataIndex(row, hitIndex); } /** * The hit weight is used to determine whether a hit belongs to a certain tracklet or another one @@ -208,43 +208,43 @@ class GPUTPCTracker : public GPUProcessor * only one. So a unique number (row index is good) is added in the least significant part of * the weight */ - GPUdi() static int CalculateHitWeight(int NHits, float chi2) + GPUdi() static int32_t CalculateHitWeight(int32_t NHits, float chi2) { const float chi2_suppress = 6.f; float weight = (((float)NHits * (chi2_suppress - chi2 / 500.f)) * (1e9f / chi2_suppress / 160.f)); if (weight < 0.f || weight > 2e9f) { return 0; } - return ((int)weight); + return ((int32_t)weight); // return( (NHits << 16) + num); } MEM_TEMPLATE() - GPUd() void MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, int hitIndex, int weight) { mData.MaximizeHitWeight(row, hitIndex, weight); } + GPUd() void MaximizeHitWeight(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex, int32_t weight) { mData.MaximizeHitWeight(row, hitIndex, weight); } MEM_TEMPLATE() - GPUd() void SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, int hitIndex, int weight) { mData.SetHitWeight(row, hitIndex, weight); } + GPUd() void SetHitWeight(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex, int32_t weight) { mData.SetHitWeight(row, hitIndex, weight); } MEM_TEMPLATE() - GPUd() int HitWeight(const MEM_TYPE(GPUTPCRow) & row, int hitIndex) const { return mData.HitWeight(row, hitIndex); } + GPUd() int32_t HitWeight(const MEM_TYPE(GPUTPCRow) & row, int32_t hitIndex) const { return mData.HitWeight(row, hitIndex); } - GPUhd() GPUglobalref() GPUAtomic(unsigned int) * NTracklets() const { return &mCommonMem->nTracklets; } - GPUhd() GPUglobalref() GPUAtomic(unsigned int) * NRowHits() const { return &mCommonMem->nRowHits; } - GPUhd() GPUglobalref() GPUAtomic(unsigned int) * NStartHits() const { return &mCommonMem->nStartHits; } + GPUhd() GPUglobalref() GPUAtomic(uint32_t) * NTracklets() const { return &mCommonMem->nTracklets; } + GPUhd() GPUglobalref() GPUAtomic(uint32_t) * NRowHits() const { return &mCommonMem->nRowHits; } + GPUhd() GPUglobalref() GPUAtomic(uint32_t) * NStartHits() const { return &mCommonMem->nStartHits; } - GPUhd() GPUglobalref() const GPUTPCHitId& TrackletStartHit(int i) const { return mTrackletStartHits[i]; } + GPUhd() GPUglobalref() const GPUTPCHitId& TrackletStartHit(int32_t i) const { return mTrackletStartHits[i]; } GPUhd() GPUglobalref() const GPUTPCHitId* TrackletStartHits() const { return mTrackletStartHits; } GPUhd() GPUglobalref() GPUTPCHitId* TrackletStartHits() { return mTrackletStartHits; } GPUhd() GPUglobalref() GPUTPCHitId* TrackletTmpStartHits() const { return mTrackletTmpStartHits; } MEM_CLASS_PRE2() - GPUhd() GPUglobalref() const MEM_LG2(GPUTPCTracklet) & Tracklet(int i) const { return mTracklets[i]; } + GPUhd() GPUglobalref() const MEM_LG2(GPUTPCTracklet) & Tracklet(int32_t i) const { return mTracklets[i]; } GPUhd() GPUglobalref() MEM_GLOBAL(GPUTPCTracklet) * Tracklets() const { return mTracklets; } GPUhd() GPUglobalref() calink* TrackletRowHits() const { return mTrackletRowHits; } - GPUhd() GPUglobalref() GPUAtomic(unsigned int) * NTracks() const { return &mCommonMem->nTracks; } + GPUhd() GPUglobalref() GPUAtomic(uint32_t) * NTracks() const { return &mCommonMem->nTracks; } GPUhd() GPUglobalref() MEM_GLOBAL(GPUTPCTrack) * Tracks() const { return mTracks; } - GPUhd() GPUglobalref() GPUAtomic(unsigned int) * NTrackHits() const { return &mCommonMem->nTrackHits; } + GPUhd() GPUglobalref() GPUAtomic(uint32_t) * NTrackHits() const { return &mCommonMem->nTrackHits; } GPUhd() GPUglobalref() GPUTPCHitId* TrackHits() const { return mTrackHits; } GPUhd() GPUglobalref() MEM_GLOBAL(GPUTPCRow) * SliceDataRows() const { return (mData.Rows()); } - GPUhd() GPUglobalref() int* RowStartHitCountOffset() const { return (mRowStartHitCountOffset); } + GPUhd() GPUglobalref() int32_t* RowStartHitCountOffset() const { return (mRowStartHitCountOffset); } GPUhd() GPUglobalref() StructGPUParameters* GPUParameters() const { return (&mCommonMem->gpuParameters); } GPUhd() MakeType(MEM_LG(StructGPUParametersConst) *) GPUParametersConst() { @@ -254,7 +254,7 @@ class GPUTPCTracker : public GPUProcessor GPUhd() void SetGPUTextureBase(GPUglobalref() const void* val) { mData.SetGPUTextureBase(val); } struct trackSortData { - int fTtrack; // Track ID + int32_t fTtrack; // Track ID float fSortVal; // Value to sort for }; @@ -270,30 +270,30 @@ class GPUTPCTracker : public GPUProcessor friend class GPUTPCStartHitsFinder; char* mLinkTmpMemory; // tmp memory for hits after neighbours finder - int mISlice; // Number of slice + int32_t mISlice; // Number of slice /** A pointer to the ClusterData object that the SliceData was created from. This can be used to * merge clusters from inside the SliceTracker code and recreate the SliceData. */ MEM_LG(GPUTPCSliceData) mData; // The SliceData object. It is used to encapsulate the storage in memory from the access - unsigned int mNMaxStartHits; - unsigned int mNMaxRowStartHits; - unsigned int mNMaxTracklets; - unsigned int mNMaxRowHits; - unsigned int mNMaxTracks; - unsigned int mNMaxTrackHits; - short mMemoryResLinks; - short mMemoryResScratch; - short mMemoryResScratchHost; - short mMemoryResCommon; - short mMemoryResTracklets; - short mMemoryResOutput; - short mMemoryResSliceScratch; - short mMemoryResSliceInput; + uint32_t mNMaxStartHits; + uint32_t mNMaxRowStartHits; + uint32_t mNMaxTracklets; + uint32_t mNMaxRowHits; + uint32_t mNMaxTracks; + uint32_t mNMaxTrackHits; + int16_t mMemoryResLinks; + int16_t mMemoryResScratch; + int16_t mMemoryResScratchHost; + int16_t mMemoryResCommon; + int16_t mMemoryResTracklets; + int16_t mMemoryResOutput; + int16_t mMemoryResSliceScratch; + int16_t mMemoryResSliceInput; // GPU Temp Arrays - GPUglobalref() int* mRowStartHitCountOffset; // Offset, length and new offset of start hits in row + GPUglobalref() int32_t* mRowStartHitCountOffset; // Offset, length and new offset of start hits in row GPUglobalref() GPUTPCHitId* mTrackletTmpStartHits; // Unsorted start hits GPUglobalref() char* mGPUTrackletTemp; // Temp Memory for GPU Tracklet Constructor @@ -312,7 +312,7 @@ class GPUTPCTracker : public GPUProcessor GPUglobalref() GPUTPCSliceOutput* mOutput; // address of pointer pointing to SliceOutput Object void* mOutputMemory; // Pointer to output memory if stored internally - static int StarthitSortComparison(const void* a, const void* b); + static int32_t StarthitSortComparison(const void* a, const void* b); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.cxx index 7b62a43a7c627..581e2926365f4 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.cxx @@ -101,7 +101,7 @@ AliHLTComponentDataType GPUTPCTrackerComponent::GetOutputDataType() return GPUTPCDefinitions::fgkTrackletsDataType; } -void GPUTPCTrackerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) +void GPUTPCTrackerComponent::GetOutputDataSize(uint64_t& constBase, double& inputMultiplier) { // define guess for the output data size constBase = 10000; // minimum size @@ -131,24 +131,24 @@ void GPUTPCTrackerComponent::SetDefaultConfiguration() fBenchmark.SetTimer(1, "reco"); } -int GPUTPCTrackerComponent::ReadConfigurationString(const char* arguments) +int32_t GPUTPCTrackerComponent::ReadConfigurationString(const char* arguments) { // Set configuration parameters for the CA tracker component from the string - int iResult = 0; + int32_t iResult = 0; if (!arguments) { return iResult; } TString allArgs = arguments; TString argument; - int bMissingParam = 0; + int32_t bMissingParam = 0; TObjArray* pTokens = allArgs.Tokenize(" "); - int nArgs = pTokens ? pTokens->GetEntries() : 0; + int32_t nArgs = pTokens ? pTokens->GetEntries() : 0; - for (int i = 0; i < nArgs; i++) { + for (int32_t i = 0; i < nArgs; i++) { argument = ((TObjString*)pTokens->At(i))->GetString(); if (argument.IsNull()) { continue; @@ -301,7 +301,7 @@ int GPUTPCTrackerComponent::ReadConfigurationString(const char* arguments) return iResult; } -int GPUTPCTrackerComponent::ReadCDBEntry(const char* cdbEntry, const char* chainId) +int32_t GPUTPCTrackerComponent::ReadCDBEntry(const char* cdbEntry, const char* chainId) { // see header file for class documentation @@ -333,7 +333,7 @@ int GPUTPCTrackerComponent::ReadCDBEntry(const char* cdbEntry, const char* chain return ReadConfigurationString(pString->GetString().Data()); } -int GPUTPCTrackerComponent::Configure(const char* cdbEntry, const char* chainId, const char* commandLine) +int32_t GPUTPCTrackerComponent::Configure(const char* cdbEntry, const char* chainId, const char* commandLine) { // Configure the component // There are few levels of configuration, @@ -343,16 +343,16 @@ int GPUTPCTrackerComponent::Configure(const char* cdbEntry, const char* chainId, SetDefaultConfiguration(); //* read the default CDB entry - int iResult1 = ReadCDBEntry(nullptr, chainId); + int32_t iResult1 = ReadCDBEntry(nullptr, chainId); //* read magnetic field fSolenoidBz = GetBz(); //* read the actual CDB entry if required - int iResult2 = (cdbEntry) ? ReadCDBEntry(cdbEntry, chainId) : 0; + int32_t iResult2 = (cdbEntry) ? ReadCDBEntry(cdbEntry, chainId) : 0; //* read extra parameters from input (if they are) - int iResult3 = 0; + int32_t iResult3 = 0; if (commandLine && commandLine[0] != '\0') { HLTInfo("received configuration string from HLT framework: \"%s\"", commandLine); @@ -366,7 +366,7 @@ int GPUTPCTrackerComponent::Configure(const char* cdbEntry, const char* chainId, return iResult1 ? iResult1 : (iResult2 ? iResult2 : iResult3); } -int GPUTPCTrackerComponent::ConfigureSlices() +int32_t GPUTPCTrackerComponent::ConfigureSlices() { // Initialize the tracker slices GPUSettingsRec rec; @@ -420,7 +420,7 @@ void* GPUTPCTrackerComponent::TrackerInit(void* par) return (nullptr); } -int GPUTPCTrackerComponent::DoInit(int argc, const char** argv) +int32_t GPUTPCTrackerComponent::DoInit(int argc, const char** argv) { if (fRec) { return EINPROGRESS; @@ -428,14 +428,14 @@ int GPUTPCTrackerComponent::DoInit(int argc, const char** argv) // Configure the CA tracker component TString arguments = ""; - for (int i = 0; i < argc; i++) { + for (int32_t i = 0; i < argc; i++) { if (!arguments.IsNull()) { arguments += " "; } arguments += argv[i]; } - int retVal = Configure(nullptr, nullptr, arguments.Data()); + int32_t retVal = Configure(nullptr, nullptr, arguments.Data()); if (retVal == 0) { if (fAsync) { if (fAsyncProcessor.Initialize(1)) { @@ -467,7 +467,7 @@ void* GPUTPCTrackerComponent::TrackerExit(void* par) return (nullptr); } -int GPUTPCTrackerComponent::DoDeinit() +int32_t GPUTPCTrackerComponent::DoDeinit() { // see header file for class documentation if (fAsync) { @@ -480,13 +480,13 @@ int GPUTPCTrackerComponent::DoDeinit() return 0; } -int GPUTPCTrackerComponent::Reconfigure(const char* cdbEntry, const char* chainId) +int32_t GPUTPCTrackerComponent::Reconfigure(const char* cdbEntry, const char* chainId) { // Reconfigure the component from OCDB . return Configure(cdbEntry, chainId, nullptr); } -int GPUTPCTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks) +int32_t GPUTPCTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks) { //* process event if (!fRec) { @@ -501,13 +501,13 @@ int GPUTPCTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con tmpPar.fSize = &size; tmpPar.mOutputBlocks = &outputBlocks; - static int trackerTimeout = 0; + static int32_t trackerTimeout = 0; if (trackerTimeout) { size = 0; return (0); } - int retVal; + int32_t retVal; if (fAsync) { void* asyncRetVal = nullptr; if (fAsyncProcessor.InitializeAsyncMemberTask(this, &GPUTPCTrackerComponent::TrackerDoEvent, &tmpPar, &asyncRetVal, fAsync) != 0) { @@ -516,10 +516,10 @@ int GPUTPCTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con size = 0; return (-ENODEV); } else { - retVal = (int)(size_t)asyncRetVal; + retVal = (int32_t)(size_t)asyncRetVal; } } else { - retVal = (int)(size_t)TrackerDoEvent(&tmpPar); + retVal = (int32_t)(size_t)TrackerDoEvent(&tmpPar); } return (retVal); } @@ -554,10 +554,10 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) const AliHLTTPCClusterXYZData* clustersXYZ[NSLICES][fgkNPatches] = {nullptr}; const AliHLTTPCRawClusterData* clustersRaw[NSLICES][fgkNPatches] = {nullptr}; - for (unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++) { + for (uint64_t ndx = 0; ndx < evtData.fBlockCnt; ndx++) { const AliHLTComponentBlockData& pBlock = blocks[ndx]; - int slice = AliHLTTPCDefinitions::GetMinSliceNr(pBlock); - int patch = AliHLTTPCDefinitions::GetMinPatchNr(pBlock); + int32_t slice = AliHLTTPCDefinitions::GetMinSliceNr(pBlock); + int32_t patch = AliHLTTPCDefinitions::GetMinPatchNr(pBlock); if (pBlock.fDataType == AliHLTTPCDefinitions::RawClustersDataType()) { clustersRaw[slice][patch] = (const AliHLTTPCRawClusterData*)pBlock.fPtr; } else if (pBlock.fDataType == AliHLTTPCDefinitions::ClustersXYZDataType()) { @@ -566,12 +566,12 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) } GPUTPCClusterData* clusterData[NSLICES] = {nullptr}; - int nClusters[NSLICES] = {0}; + int32_t nClusters[NSLICES] = {0}; - int nClustersTotal = 0; - for (int slice = 0; slice < NSLICES; slice++) { - int nClustersSliceTotal = 0; - for (int patch = 0; patch < 6; patch++) { + int32_t nClustersTotal = 0; + for (int32_t slice = 0; slice < NSLICES; slice++) { + int32_t nClustersSliceTotal = 0; + for (int32_t patch = 0; patch < 6; patch++) { if (clustersXYZ[slice][patch]) { nClustersSliceTotal += clustersXYZ[slice][patch]->fCount; } @@ -585,7 +585,7 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) clusterData[slice] = new GPUTPCClusterData[nClustersSliceTotal]; nClusters[slice] = nClustersSliceTotal; GPUTPCClusterData* pCluster = clusterData[slice]; - for (int patch = 0; patch < 6; patch++) { + for (int32_t patch = 0; patch < 6; patch++) { if (clustersXYZ[slice][patch] != nullptr && clustersRaw[slice][patch] != nullptr) { const AliHLTTPCClusterXYZData& clXYZ = *clustersXYZ[slice][patch]; const AliHLTTPCRawClusterData& clRaw = *clustersRaw[slice][patch]; @@ -595,8 +595,8 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) continue; } - const int firstRow = AliHLTTPCGeometry::GetFirstRow(patch); - for (int ic = 0; ic < clXYZ.fCount; ic++) { + const int32_t firstRow = AliHLTTPCGeometry::GetFirstRow(patch); + for (int32_t ic = 0; ic < clXYZ.fCount; ic++) { const AliHLTTPCClusterXYZ& c = clXYZ.fClusters[ic]; const AliHLTTPCRawCluster& cRaw = clRaw.fClusters[ic]; if (c.GetZ() > fClusterZCut || c.GetZ() < -fClusterZCut) { @@ -639,7 +639,7 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) } fChain->ClearIOPointers(); - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { fChain->mIOPtrs.clusterData[i] = clusterData[i]; fChain->mIOPtrs.nClusterData[i] = nClusters[i]; } @@ -664,24 +664,24 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) } fBenchmark.Stop(1); HLTInfo("Processed %d clusters", nClustersTotal); - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { fChain->GetTPCSliceTrackers()[i].Clear(); } - int ret = 0; + int32_t ret = 0; size = 0; if (fRec->OutputControl().size == 1) { HLTWarning("Output buffer size exceeded buffer size %d, tracks are not stored", maxBufferSize); ret = -ENOSPC; } else { - for (int slice = 0; slice < NSLICES; slice++) { + for (int32_t slice = 0; slice < NSLICES; slice++) { GPUTPCSliceOutput* pOut = fChain->GetTPCSliceTrackers()[slice].Output(); if (!pOut) { continue; } HLTDebug("%d tracks found for slice %d", pOut->NTracks(), slice); - unsigned int blockSize = pOut->Size(); + uint32_t blockSize = pOut->Size(); if (blockSize > 0) { AliHLTComponentBlockData bd; FillBlockData(bd); @@ -696,7 +696,7 @@ void* GPUTPCTrackerComponent::TrackerDoEvent(void* par) } } - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { if (clusterData[i]) { delete[] clusterData[i]; } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.h index b9dc408f3780d..5b09f50bf62bc 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerComponent.h @@ -66,7 +66,7 @@ class GPUTPCTrackerComponent : public AliHLTProcessor AliHLTComponentDataType GetOutputDataType(); /** @see component interface @ref AliHLTComponent::GetOutputDataSize */ - virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + virtual void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); /** @see component interface @ref AliHLTComponent::Spawn */ AliHLTComponent* Spawn(); @@ -77,16 +77,16 @@ class GPUTPCTrackerComponent : public AliHLTProcessor // capabilities of the component. /** @see component interface @ref AliHLTComponent::DoInit */ - int DoInit(int argc, const char** argv); + int32_t DoInit(int argc, const char** argv); /** @see component interface @ref AliHLTComponent::DoDeinit */ - int DoDeinit(); + int32_t DoDeinit(); /** reconfigure **/ - int Reconfigure(const char* cdbEntry, const char* chainId); + int32_t Reconfigure(const char* cdbEntry, const char* chainId); /** @see component interface @ref AliHLTProcessor::DoEvent */ - int DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); + int32_t DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); private: struct AliHLTTPCTrackerWrapperData { @@ -97,12 +97,12 @@ class GPUTPCTrackerComponent : public AliHLTProcessor vector* mOutputBlocks; }; - static const int NSLICES = 36; //* N slices - static const int fgkNPatches = 6; //* N slices + static const int32_t NSLICES = 36; //* N slices + static const int32_t fgkNPatches = 6; //* N slices /** magnetic field */ double fSolenoidBz; // see above - int fMinNTrackClusters; //* required min number of clusters on the track + int32_t fMinNTrackClusters; //* required min number of clusters on the track double fMinTrackPt; //* required min Pt of tracks double fClusterZCut; //* cut on cluster Z position (for noise rejection at the age of TPC) double mNeighboursSearchArea; //* area in cm for the neighbour search algorithm @@ -110,24 +110,24 @@ class GPUTPCTrackerComponent : public AliHLTProcessor double fClusterErrorCorrectionZ; // correction for the cluster errors AliHLTComponentBenchmark fBenchmark; // benchmarks - char fAllowGPU; //* Allow this tracker to run on GPU - int fGPUHelperThreads; // Number of helper threads for GPU tracker, set to -1 to use default number - int fCPUTrackers; // Number of CPU trackers to run in addition to GPU tracker - char fGlobalTracking; // Activate global tracking feature - int fGPUDeviceNum; // GPU Device to use, default -1 for auto detection + int8_t fAllowGPU; //* Allow this tracker to run on GPU + int32_t fGPUHelperThreads; // Number of helper threads for GPU tracker, set to -1 to use default number + int32_t fCPUTrackers; // Number of CPU trackers to run in addition to GPU tracker + int8_t fGlobalTracking; // Activate global tracking feature + int32_t fGPUDeviceNum; // GPU Device to use, default -1 for auto detection TString fGPUType; // GPU type to use "CUDA", "HIP", "OCL" - int fGPUStuckProtection; // Protect from stuck GPUs - int fAsync; // Run tracking in async thread to catch GPU hangs.... + int32_t fGPUStuckProtection; // Protect from stuck GPUs + int32_t fAsync; // Run tracking in async thread to catch GPU hangs.... float fSearchWindowDZDR; // See TPCCAParam GPUCA_NAMESPACE::gpu::GPUReconstruction* fRec; // GPUReconstruction GPUCA_NAMESPACE::gpu::GPUChainTracking* fChain; /** set configuration parameters **/ void SetDefaultConfiguration(); - int ReadConfigurationString(const char* arguments); - int ReadCDBEntry(const char* cdbEntry, const char* chainId); - int Configure(const char* cdbEntry, const char* chainId, const char* commandLine); - int ConfigureSlices(); + int32_t ReadConfigurationString(const char* arguments); + int32_t ReadCDBEntry(const char* cdbEntry, const char* chainId); + int32_t Configure(const char* cdbEntry, const char* chainId, const char* commandLine); + int32_t ConfigureSlices(); AliHLTAsyncMemberProcessor fAsyncProcessor; void* TrackerInit(void*); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerDump.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerDump.cxx index 751645822d57e..c1f731105dc5a 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackerDump.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackerDump.cxx @@ -31,9 +31,9 @@ void GPUTPCTracker::DumpOutput(std::ostream& out) if (Param().par.earlyTpcTransform) { out << "\nSlice " << mISlice << "\n"; const GPUTPCTrack* track = (Output())->GetFirstTrack(); - for (unsigned int j = 0; j < (Output())->NTracks(); j++) { + for (uint32_t j = 0; j < (Output())->NTracks(); j++) { out << "Track " << j << " (" << track->NHits() << "): "; - for (int k = 0; k < track->NHits(); k++) { + for (int32_t k = 0; k < track->NHits(); k++) { out << "(" << track->OutTrackCluster(k).GetX() << "," << track->OutTrackCluster(k).GetY() << "," << track->OutTrackCluster(k).GetZ() << ") "; } out << " - (" << track->Param().Y() << " " << track->Param().Z() << " " << track->Param().SinPhi() << " " << track->Param().DzDs() << " " << track->Param().QPt() << "\n"; @@ -46,12 +46,12 @@ void GPUTPCTracker::DumpSliceData(std::ostream& out) { // Dump Slice Input Data to File out << "\nSlice Data (Slice" << mISlice << "):" << std::endl; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { if (Row(i).NHits() == 0) { continue; } out << "Row: " << i << std::endl; - for (int j = 0; j < Row(i).NHits(); j++) { + for (int32_t j = 0; j < Row(i).NHits(); j++) { if (j && j % 16 == 0) { out << std::endl; } @@ -61,16 +61,16 @@ void GPUTPCTracker::DumpSliceData(std::ostream& out) } } -void GPUTPCTracker::DumpLinks(std::ostream& out, int phase) +void GPUTPCTracker::DumpLinks(std::ostream& out, int32_t phase) { // Dump Links (after Neighbours Finder / Cleaner) to file out << "\nHit Links (Phase " << phase << ", Slice" << mISlice << "):" << std::endl; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { if (Row(i).NHits() == 0) { continue; } out << "Row: " << i << std::endl; - for (int j = 0; j < Row(i).NHits(); j++) { + for (int32_t j = 0; j < Row(i).NHits(); j++) { if (j && j % 32 == 0) { out << std::endl; } @@ -84,12 +84,12 @@ void GPUTPCTracker::DumpHitWeights(std::ostream& out) { // dump hit weights to file out << "\nHit Weights(Slice" << mISlice << "):" << std::endl; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { if (Row(i).NHits() == 0) { continue; } out << "Row: " << i << ":" << std::endl; - for (int j = 0; j < Row(i).NHits(); j++) { + for (int32_t j = 0; j < Row(i).NHits(); j++) { if (j && j % 32 == 0) { out << std::endl; } @@ -103,7 +103,7 @@ void GPUTPCTracker::DumpStartHits(std::ostream& out) { // dump start hits to file out << "\nStart Hits: (Slice" << mISlice << ") (" << *NStartHits() << ")" << std::endl; - for (unsigned int i = 0; i < *NStartHits(); i++) { + for (uint32_t i = 0; i < *NStartHits(); i++) { out << TrackletStartHit(i).RowIndex() << "-" << TrackletStartHit(i).HitIndex() << std::endl; } out << std::endl; @@ -113,17 +113,17 @@ void GPUTPCTracker::DumpTrackHits(std::ostream& out) { // dump tracks to file out << "\nTracks: (Slice" << mISlice << ") (" << *NTracks() << ")" << std::endl; - for (unsigned int j = 0; j < *NTracks(); j++) { + for (uint32_t j = 0; j < *NTracks(); j++) { if (Tracks()[j].NHits() == 0) { continue; } const GPUTPCBaseTrackParam& p = Tracks()[j].Param(); out << " " << j << " x " << p.GetX() << " offset " << p.GetZOffset() << " y " << p.GetY() << " z " << p.GetZ() << " snp " << p.GetSinPhi() << " tgl " << p.GetDzDs() << " qpt " << p.GetQPt() << " - "; - for (int k = 0; k < 15; k++) { + for (int32_t k = 0; k < 15; k++) { out << p.GetCov(k) << " "; } out << "- "; - for (int i = 0; i < Tracks()[j].NHits(); i++) { + for (int32_t i = 0; i < Tracks()[j].NHits(); i++) { out << TrackHits()[Tracks()[j].FirstHitID() + i].RowIndex() << "-" << TrackHits()[Tracks()[j].FirstHitID() + i].HitIndex() << ", "; } if (!mRec->GetProcessingSettings().deterministicGPUReconstruction) { @@ -136,15 +136,15 @@ void GPUTPCTracker::DumpTrackHits(std::ostream& out) void GPUTPCTracker::DumpTrackletHits(std::ostream& out) { // dump tracklets to file - int nTracklets = *NTracklets(); + int32_t nTracklets = *NTracklets(); if (nTracklets < 0) { nTracklets = 0; } out << "\nTracklets: (Slice" << mISlice << ") (" << nTracklets << ")" << std::endl; - std::vector Ids(nTracklets); + std::vector Ids(nTracklets); std::iota(Ids.begin(), Ids.end(), 0); if (mRec->GetProcessingSettings().deterministicGPUReconstruction) { - std::sort(Ids.begin(), Ids.end(), [this](const int& a, const int& b) { + std::sort(Ids.begin(), Ids.end(), [this](const int32_t& a, const int32_t& b) { if (this->Tracklets()[a].FirstRow() != this->Tracklets()[b].FirstRow()) { return this->Tracklets()[a].FirstRow() > this->Tracklets()[b].FirstRow(); } @@ -157,19 +157,19 @@ void GPUTPCTracker::DumpTrackletHits(std::ostream& out) return this->Tracklets()[a].Param().Z() > this->Tracklets()[b].Param().Z(); }); } - for (int jj = 0; jj < nTracklets; jj++) { - const int j = Ids[jj]; + for (int32_t jj = 0; jj < nTracklets; jj++) { + const int32_t j = Ids[jj]; const auto& tracklet = Tracklets()[j]; out << "Tracklet " << std::setw(4) << jj << " (Rows: " << Tracklets()[j].FirstRow() << " - " << tracklet.LastRow() << ", Weight " << Tracklets()[j].HitWeight() << ") "; if (tracklet.LastRow() > tracklet.FirstRow() && (tracklet.FirstRow() >= GPUCA_ROW_COUNT || tracklet.LastRow() >= GPUCA_ROW_COUNT)) { GPUError("Error: Tracklet %d First %d Last %d", j, tracklet.FirstRow(), tracklet.LastRow()); out << " (Error: Tracklet " << j << " First " << tracklet.FirstRow() << " Last " << tracklet.LastRow() << ") "; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { // if (tracklet.RowHit(i) != CALINK_INVAL) out << i << "-" << mTrackletRowHits[tracklet.FirstHit() + (i - tracklet.FirstRow())] << ", "; } } else if (tracklet.LastRow() >= tracklet.FirstRow()) { - for (int i = tracklet.FirstRow(); i <= tracklet.LastRow(); i++) { + for (int32_t i = tracklet.FirstRow(); i <= tracklet.LastRow(); i++) { out << i << "-" << mTrackletRowHits[tracklet.FirstHit() + (i - tracklet.FirstRow())] << ", "; } } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracklet.h b/GPU/GPUTracking/SliceTracker/GPUTPCTracklet.h index 029f8bced764a..08ec8d8bf54e7 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracklet.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracklet.h @@ -36,26 +36,26 @@ class GPUTPCTracklet GPUTPCTracklet() : mFirstRow(0), mLastRow(0), mParam(), mHitWeight(0), mFirstHit(0){}; #endif //! GPUCA_GPUCODE - GPUhd() int FirstRow() const { return mFirstRow; } - GPUhd() int LastRow() const { return mLastRow; } - GPUhd() int HitWeight() const { return mHitWeight; } - GPUhd() unsigned int FirstHit() const { return mFirstHit; } + GPUhd() int32_t FirstRow() const { return mFirstRow; } + GPUhd() int32_t LastRow() const { return mLastRow; } + GPUhd() int32_t HitWeight() const { return mHitWeight; } + GPUhd() uint32_t FirstHit() const { return mFirstHit; } GPUhd() MakeType(const MEM_LG(GPUTPCBaseTrackParam) &) Param() const { return mParam; } - GPUhd() void SetFirstRow(int v) { mFirstRow = v; } - GPUhd() void SetLastRow(int v) { mLastRow = v; } - GPUhd() void SetFirstHit(unsigned int v) { mFirstHit = v; } + GPUhd() void SetFirstRow(int32_t v) { mFirstRow = v; } + GPUhd() void SetLastRow(int32_t v) { mLastRow = v; } + GPUhd() void SetFirstHit(uint32_t v) { mFirstHit = v; } MEM_CLASS_PRE2() GPUhd() void SetParam(const MEM_LG2(GPUTPCBaseTrackParam) & v) { mParam = reinterpret_cast(v); } - GPUhd() void SetHitWeight(const int w) { mHitWeight = w; } + GPUhd() void SetHitWeight(const int32_t w) { mHitWeight = w; } private: - int mFirstRow; // first TPC row // TODO: We can use smaller data format here! - int mLastRow; // last TPC row + int32_t mFirstRow; // first TPC row // TODO: We can use smaller data format here! + int32_t mLastRow; // last TPC row MEM_LG(GPUTPCBaseTrackParam) mParam; // tracklet parameters - int mHitWeight; // Hit Weight of Tracklet - unsigned int mFirstHit; // first hit in row hit array + int32_t mHitWeight; // Hit Weight of Tracklet + uint32_t mFirstHit; // first hit in row hit array }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx index 79623c6f66c32..9d6ed630dee8c 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx @@ -45,10 +45,10 @@ GPUd() bool GPUTPCTrackletConstructor::CheckCov(MEM_LG2(GPUTPCTrackParam) & GPUr { bool ok = 1; const float* c = tParam.Cov(); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { ok = ok && CAMath::Finite(c[i]); } - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { ok = ok && CAMath::Finite(tParam.Par()[i]); } ok = ok && (tParam.X() > 50); @@ -59,12 +59,12 @@ GPUd() bool GPUTPCTrackletConstructor::CheckCov(MEM_LG2(GPUTPCTrackParam) & GPUr } MEM_CLASS_PRE23() -GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int /*nBlocks*/, int /*nThreads*/, int /*iBlock*/, int /*iThread*/, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() MEM_LG2(GPUTPCTracker) & GPUrestrict() tracker, MEM_LG3(GPUTPCTrackParam) & GPUrestrict() tParam, calink* rowHits) +GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int32_t /*nBlocks*/, int32_t /*nThreads*/, int32_t /*iBlock*/, int32_t /*iThread*/, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() MEM_LG2(GPUTPCTracker) & GPUrestrict() tracker, MEM_LG3(GPUTPCTrackParam) & GPUrestrict() tParam, calink* rowHits) { // reconstruction of tracklets, tracklet store step - const unsigned int nHits = r.mLastRow + 1 - r.mFirstRow; + const uint32_t nHits = r.mLastRow + 1 - r.mFirstRow; if (nHits == 0 || r.mNHits == 0 || (r.mNHits < GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tParam.QPt() * tracker.Param().qptB5Scaler) || !CheckCov(tParam) || CAMath::Abs(tParam.GetQPt() * tracker.Param().qptB5Scaler) > tracker.Param().rec.maxTrackQPtB5)) { - CADEBUG(printf(" Rejected: nHits %d QPt %f MinHits %d MaxQPt %f CheckCov %d\n", r.mNHits, tParam.QPt(), GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tParam.QPt() * tracker.Param().qptB5Scaler), tracker.Param().rec.maxTrackQPtB5, (int)CheckCov(tParam))); + CADEBUG(printf(" Rejected: nHits %d QPt %f MinHits %d MaxQPt %f CheckCov %d\n", r.mNHits, tParam.QPt(), GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tParam.QPt() * tracker.Param().qptB5Scaler), tracker.Param().rec.maxTrackQPtB5, (int32_t)CheckCov(tParam))); return; } @@ -72,13 +72,13 @@ GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int /*nBlocks*/, int /*nThr tParam.Cov()[0], tParam.Cov()[1], tParam.Cov()[2], tParam.Cov()[3], tParam.Cov()[4], tParam.Cov()[5], tParam.Cov()[6], tParam.Cov()[7], tParam.Cov()[8], tParam.Cov()[9], tParam.Cov()[10], tParam.Cov()[11], tParam.Cov()[12], tParam.Cov()[13], tParam.Cov()[14]);*/ - unsigned int hitout = CAMath::AtomicAdd(tracker.NRowHits(), nHits); + uint32_t hitout = CAMath::AtomicAdd(tracker.NRowHits(), nHits); if (hitout + nHits > tracker.NMaxRowHits()) { tracker.raiseError(GPUErrors::ERROR_TRACKLET_HIT_OVERFLOW, tracker.ISlice(), hitout + nHits, tracker.NMaxRowHits()); CAMath::AtomicExch(tracker.NRowHits(), tracker.NMaxRowHits()); return; } - unsigned int itrout = CAMath::AtomicAdd(tracker.NTracklets(), 1u); + uint32_t itrout = CAMath::AtomicAdd(tracker.NTracklets(), 1u); if (itrout >= tracker.NMaxTracklets()) { tracker.raiseError(GPUErrors::ERROR_TRACKLET_OVERFLOW, tracker.ISlice(), itrout, tracker.NMaxTracklets()); CAMath::AtomicExch(tracker.NTracklets(), tracker.NMaxTracklets()); @@ -93,12 +93,12 @@ GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int /*nBlocks*/, int /*nThr tracklet.SetLastRow(r.mLastRow); tracklet.SetFirstHit(hitout); tracklet.SetParam(tParam.GetParam()); - int w = tracker.CalculateHitWeight(r.mNHits, tParam.GetChi2()); + int32_t w = tracker.CalculateHitWeight(r.mNHits, tParam.GetChi2()); tracklet.SetHitWeight(w); #ifdef __HIPCC__ // Todo: fixme! - for (int iRow = r.mFirstRow - 1; ++iRow <= r.mLastRow; /*iRow++*/) { + for (int32_t iRow = r.mFirstRow - 1; ++iRow <= r.mLastRow; /*iRow++*/) { #else - for (int iRow = r.mFirstRow; iRow <= r.mLastRow; iRow++) { + for (int32_t iRow = r.mFirstRow; iRow <= r.mLastRow; iRow++) { #endif calink ih = rowHits[iRow]; tracker.TrackletRowHits()[hitout + (iRow - r.mFirstRow)] = ih; @@ -110,7 +110,7 @@ GPUd() void GPUTPCTrackletConstructor::StoreTracklet(int /*nBlocks*/, int /*nThr } MEM_CLASS_PRE2_TEMPLATE(class T) -GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int /*nThreads*/, int /*iBlock*/, int /*iThread*/, GPUsharedref() T& s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, MEM_LG2(GPUTPCTrackParam) & GPUrestrict() tParam, int iRow, calink& rowHit, calink* rowHits) +GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, int32_t /*nThreads*/, int32_t /*iBlock*/, int32_t /*iThread*/, GPUsharedref() T& s, GPUTPCThreadMemory& GPUrestrict() r, GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, MEM_LG2(GPUTPCTrackParam) & GPUrestrict() tParam, int32_t iRow, calink& rowHit, calink* rowHits) { // reconstruction of tracklets, tracklets update step CA_MAKE_SHARED_REF(GPUTPCRow, row, tracker.Row(iRow), s.mRows[iRow]); @@ -132,7 +132,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int cahit2 hh = CA_TEXTURE_FETCH(cahit22, gAliTexRefu2, tracker.HitData(row), r.mCurrIH); - int seedIH = r.mCurrIH; + int32_t seedIH = r.mCurrIH; r.mCurrIH = CA_TEXTURE_FETCH(calink, gAliTexRefs, tracker.HitLinkUpData(row), r.mCurrIH); float x = row.X(); @@ -163,7 +163,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int tParam.SetX(x); tParam.SetY(y); r.mLastY = y; - CADEBUG(printf("Tracklet %5d: FIT INIT ROW %3d X %8.3f -", r.mISH, iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("Tracklet %5d: FIT INIT ROW %3d X %8.3f -", r.mISH, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); } else { float dx = x - tParam.X(); float dy, dz; @@ -195,12 +195,12 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int sinPhi = dy * ri; cosPhi = dx * ri; } - CADEBUG(printf("%14s: FIT TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: FIT TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); if (!tParam.TransportToX(x, sinPhi, cosPhi, tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI)) { rowHit = CALINK_INVAL; break; } - CADEBUG(printf("%5s hits %3d: FIT PROP ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%5s hits %3d: FIT PROP ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); float err2Y, err2Z; tracker.GetErrors2Seeding(iRow, tParam.GetZ(), sinPhi, tParam.GetDzDs(), -1.f, err2Y, err2Z); // TODO: Use correct time @@ -232,7 +232,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int rowHit = CALINK_INVAL; break; } - CADEBUG(printf("%14s: FIT FILT ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: FIT FILT ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); } rowHit = seedIH; r.mNHitsEndRow = ++r.mNHits; @@ -242,7 +242,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int } while (0); /*printf("Extrapolate Row %d X %f Y %f Z %f SinPhi %f DzDs %f QPt %f", iRow, tParam.X(), tParam.Y(), tParam.Z(), tParam.SinPhi(), tParam.DzDs(), tParam.QPt()); - for (int i = 0;i < 15;i++) printf(" C%d=%6.2f", i, tParam.GetCov(i)); + for (int32_t i = 0;i < 15;i++) printf(" C%d=%6.2f", i, tParam.GetCov(i)); printf("\n");*/ if (r.mCurrIH == CALINK_INVAL) { @@ -279,13 +279,13 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int } #endif - CADEBUG(printf("%14s: SEA TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: SEA TRACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); if (!tParam.TransportToX(x, tParam.SinPhi(), tParam.GetCosPhi(), tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI_LOW)) { r.mGo = 0; rowHit = CALINK_INVAL; break; } - CADEBUG(printf("%14s: SEA PROP ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: SEA PROP ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); bool found = false; float yUncorrected = tParam.GetY(), zUncorrected = tParam.GetZ(); @@ -322,23 +322,23 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int const float sy2 = CAMath::Min(maxWindow2, kFactor * (tParam.Err2Y() + err2Y)); const float sz2 = CAMath::Min(maxWindow2, kFactor * (tParam.Err2Z() + err2Z)); - int bin, ny, nz; + int32_t bin, ny, nz; row.Grid().GetBinArea(yUncorrected, zUncorrected + tParam.ZOffset(), CAMath::Sqrt(sy2), CAMath::Sqrt(sz2), bin, ny, nz); float ds = 1e6f; #ifdef __HIPCC__ // Todo: fixme! - for (int k = -1; ++k <= nz; /*k++*/) { + for (int32_t k = -1; ++k <= nz; /*k++*/) { #else - for (int k = 0; k <= nz; k++) { + for (int32_t k = 0; k <= nz; k++) { #endif - int nBinsY = row.Grid().Ny(); - int mybin = bin + k * nBinsY; - unsigned int hitFst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin); - unsigned int hitLst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin + ny + 1); + int32_t nBinsY = row.Grid().Ny(); + int32_t mybin = bin + k * nBinsY; + uint32_t hitFst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin); + uint32_t hitLst = CA_TEXTURE_FETCH(calink, gAliTexRefu, firsthit, mybin + ny + 1); #ifdef __HIPCC__ // Todo: fixme! - for (unsigned int ih = hitFst - 1; ++ih < hitLst; /*ih++*/) { + for (uint32_t ih = hitFst - 1; ++ih < hitLst; /*ih++*/) { #else - for (unsigned int ih = hitFst; ih < hitLst; ih++) { + for (uint32_t ih = hitFst; ih < hitLst; ih++) { #endif cahit2 hh = CA_TEXTURE_FETCH(cahit2, gAliTexRefu2, hits, ih); float y = y0 + hh.x * stepY; @@ -383,7 +383,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int rowHit = best; r.mNHits++; r.mNMissed = 0; - CADEBUG(printf("%5s hits %3d: SEA FILT ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%5s hits %3d: SEA FILT ROW %3d X %8.3f -", "", r.mNHits, iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); if (r.mStage == 1) { r.mLastRow = iRow; } else { @@ -393,7 +393,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int (void)found; #if defined(GPUCA_HAVE_O2HEADERS) && (!defined(__OPENCL__) || defined(__OPENCLCPP__)) if (!found && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer) { - unsigned int pad = CAMath::Float2UIntRn(tracker.Param().tpcGeometry.LinearY2Pad(tracker.ISlice(), iRow, yUncorrected)); + uint32_t pad = CAMath::Float2UIntRn(tracker.Param().tpcGeometry.LinearY2Pad(tracker.ISlice(), iRow, yUncorrected)); if (pad < tracker.Param().tpcGeometry.NPads(iRow) && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer->isDead(tracker.ISlice(), iRow, pad)) { r.mNMissed--; rowHit = CALINK_DEAD_CHANNEL; @@ -420,7 +420,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int /*nBlocks*/, int GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCTrackletConstructor::MEM_LOCAL(GPUSharedMemory) & s, GPUTPCThreadMemory& GPUrestrict() r) { - int iRow = 0, iRowEnd = GPUCA_ROW_COUNT; + int32_t iRow = 0, iRowEnd = GPUCA_ROW_COUNT; MEM_PLAIN(GPUTPCTrackParam) tParam; calink rowHits[GPUCA_ROW_COUNT]; @@ -438,9 +438,9 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLO CADEBUG(printf("Start tracklet\n")); #ifdef __HIPCC__ // Todo: fixme! - for (int iStage = -1; ++iStage < 2; /*iStage++*/) { + for (int32_t iStage = -1; ++iStage < 2; /*iStage++*/) { #else - for (int iStage = 0; iStage < 2; iStage++) { + for (int32_t iStage = 0; iStage < 2; iStage++) { #endif for (; iRow != iRowEnd; iRow += r.mStage == 2 ? -1 : 1) { if (!r.mGo) { @@ -478,7 +478,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLO } #endif if ((r.mGo = (tParam.TransportToX(x, tracker.Param().bzCLight, GPUCA_MAX_SIN_PHI) && tParam.Filter(r.mLastY, r.mLastZ, tParam.Err2Y() * 0.5f, tParam.Err2Z() * 0.5f, GPUCA_MAX_SIN_PHI_LOW, true)))) { - CADEBUG(printf("%14s: SEA BACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: SEA BACK ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); float err2Y, err2Z; tracker.GetErrors2Seeding(r.mEndRow, tParam, -1.f, err2Y, err2Z); // TODO: Use correct time if (tParam.GetCov(0) < err2Y) { @@ -487,7 +487,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLO if (tParam.GetCov(2) < err2Z) { tParam.SetCov(2, err2Z); } - CADEBUG(printf("%14s: SEA ADJUS ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); + CADEBUG(printf("%14s: SEA ADJUS ROW %3d X %8.3f -", "", iRow, tParam.X()); for (int32_t i = 0; i < 5; i++) { printf(" %8.3f", tParam.Par()[i]); } printf(" -"); for (int32_t i = 0; i < 15; i++) { printf(" %8.3f", tParam.Cov()[i]); } printf("\n")); r.mNHits -= r.mNHitsEndRow; } } @@ -496,7 +496,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLO } template <> -GPUdii() void GPUTPCTrackletConstructor::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCTrackletConstructor::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem, processorType& GPUrestrict() tracker) { if (get_local_id(0) == 0) { sMem.mNStartHits = *tracker.NStartHits(); @@ -512,18 +512,18 @@ GPUdii() void GPUTPCTrackletConstructor::Thread -GPUdii() void GPUTPCTrackletConstructor::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem, processorType& GPUrestrict() tracker0) +GPUdii() void GPUTPCTrackletConstructor::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem, processorType& GPUrestrict() tracker0) { GPUconstantref() MEM_GLOBAL(GPUTPCTracker) * GPUrestrict() pTracker = &tracker0; #ifdef GPUCA_GPUCODE - int mySlice = get_group_id(0) % GPUCA_NSLICES; - int currentSlice = -1; + int32_t mySlice = get_group_id(0) % GPUCA_NSLICES; + int32_t currentSlice = -1; if (get_local_id(0) == 0) { sMem.mNextStartHitFirstRun = 1; } GPUCA_UNROLL(, U()) - for (unsigned int iSlice = 0; iSlice < GPUCA_NSLICES; iSlice++) { + for (uint32_t iSlice = 0; iSlice < GPUCA_NSLICES; iSlice++) { GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker = pTracker[mySlice]; GPUTPCThreadMemory rMem; @@ -554,7 +554,7 @@ GPUdii() void GPUTPCTrackletConstructor::Thread(nBlocks, nThreads, iBlock, iThread, sMem, pTracker[iSlice]); } #endif @@ -562,21 +562,21 @@ GPUdii() void GPUTPCTrackletConstructor::ThreadnextStartHit < nStartHit) { - firstStartHit = CAMath::AtomicAdd(&tracker.GPUParameters()->nextStartHit, GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletConstructor)); + firstStartHit = CAMath::AtomicAdd(&tracker.GPUParameters()->nextStartHit, GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletConstructor)); } } - sMem.mNextStartHitFirst = firstStartHit < (int)nStartHit ? firstStartHit : -2; + sMem.mNextStartHitFirst = firstStartHit < (int32_t)nStartHit ? firstStartHit : -2; } GPUbarrier(); return (sMem.mNextStartHitFirst); @@ -586,7 +586,7 @@ GPUd() int GPUTPCTrackletConstructor::FetchTracklet(GPUconstantref() MEM_GLOBAL( #if !defined(__OPENCL__) || defined(__OPENCLCPP__) template <> -GPUd() int GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCGlobalTracking::GPUSharedMemory& sMem, MEM_LG(GPUTPCTrackParam) & GPUrestrict() tParam, int row, int increment, int iTracklet, calink* rowHits) +GPUd() int32_t GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCGlobalTracking::GPUSharedMemory& sMem, MEM_LG(GPUTPCTrackParam) & GPUrestrict() tParam, int32_t row, int32_t increment, int32_t iTracklet, calink* rowHits) { GPUTPCThreadMemory rMem; rMem.mISH = iTracklet; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h index e3f0e6236d79d..06dd941ca5cf7 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h @@ -54,17 +54,17 @@ class GPUTPCTrackletConstructor protected: // WARNING: This data is copied element by element in CopyTrackletTempData. Changes to members of this class must be reflected in CopyTrackletTempData!!! - int mISH; // track index - int mFirstRow; // first row index - int mLastRow; // last row index - int mStartRow; // row index of first hit in seed - int mEndRow; // row index of last hit in seed + int32_t mISH; // track index + int32_t mFirstRow; // first row index + int32_t mLastRow; // last row index + int32_t mStartRow; // row index of first hit in seed + int32_t mEndRow; // row index of last hit in seed calink mCurrIH; // indef of the current hit - char mGo; // do fit/searching flag - int mStage; // reco stage - int mNHits; // n track hits - int mNHitsEndRow; // n hits at end row - int mNMissed; // n missed hits during search + int8_t mGo; // do fit/searching flag + int32_t mStage; // reco stage + int32_t mNHits; // n track hits + int32_t mNHitsEndRow; // n hits at end row + int32_t mNMissed; // n missed hits during search float mLastY; // Y of the last fitted cluster float mLastZ; // Z of the last fitted cluster }; @@ -72,13 +72,13 @@ class GPUTPCTrackletConstructor MEM_CLASS_PRE() struct GPUSharedMemory { CA_SHARED_STORAGE(MEM_LG(GPUTPCRow) mRows[GPUCA_ROW_COUNT]); // rows - int mNextStartHitFirst; // First start hit to be processed by CUDA block during next iteration - int mNextStartHitCount; // Number of start hits to be processed by CUDA block during next iteration - int mNextStartHitFirstRun; // First run for dynamic scheduler? - int mNStartHits; // Total number of start hits + int32_t mNextStartHitFirst; // First start hit to be processed by CUDA block during next iteration + int32_t mNextStartHitCount; // Number of start hits to be processed by CUDA block during next iteration + int32_t mNextStartHitFirstRun; // First run for dynamic scheduler? + int32_t mNStartHits; // Total number of start hits #ifdef GPUCA_TRACKLET_CONSTRUCTOR_DO_PROFILE - int fMaxSync; // temporary shared variable during profile creation + int32_t fMaxSync; // temporary shared variable during profile creation #endif // GPUCA_TRACKLET_CONSTRUCTOR_DO_PROFILE }; @@ -86,10 +86,10 @@ class GPUTPCTrackletConstructor GPUd() static void InitTracklet(MEM_LG2(GPUTPCTrackParam) & tParam); MEM_CLASS_PRE2_TEMPLATE(class T) - GPUd() static void UpdateTracklet(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() T& s, GPUTPCThreadMemory& r, GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, MEM_LG2(GPUTPCTrackParam) & tParam, int iRow, calink& rowHit, calink* rowHits); + GPUd() static void UpdateTracklet(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() T& s, GPUTPCThreadMemory& r, GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, MEM_LG2(GPUTPCTrackParam) & tParam, int32_t iRow, calink& rowHit, calink* rowHits); MEM_CLASS_PRE23() - GPUd() static void StoreTracklet(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, GPUTPCThreadMemory& r, GPUconstantref() MEM_LG2(GPUTPCTracker) & tracker, MEM_LG3(GPUTPCTrackParam) & tParam, calink* rowHits); + GPUd() static void StoreTracklet(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, GPUTPCThreadMemory& r, GPUconstantref() MEM_LG2(GPUTPCTracker) & tracker, MEM_LG3(GPUTPCTrackParam) & tParam, calink* rowHits); MEM_CLASS_PRE2() GPUd() static bool CheckCov(MEM_LG2(GPUTPCTrackParam) & tParam); @@ -97,12 +97,12 @@ class GPUTPCTrackletConstructor GPUd() static void DoTracklet(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() GPUTPCTrackletConstructor::MEM_LOCAL(GPUSharedMemory) & sMem, GPUTPCThreadMemory& rMem); #ifdef GPUCA_GPUCODE - GPUd() static int FetchTracklet(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem); + GPUd() static int32_t FetchTracklet(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem); #endif // GPUCA_GPUCODE #if !defined(__OPENCL__) || defined(__OPENCLCPP__) template - GPUd() static int GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() T& sMem, GPUTPCTrackParam& tParam, int startrow, int increment, int iTracklet, calink* rowHits); + GPUd() static int32_t GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() T& sMem, GPUTPCTrackParam& tParam, int32_t startrow, int32_t increment, int32_t iTracklet, calink* rowHits); #endif typedef GPUconstantref() MEM_GLOBAL(GPUTPCTracker) processorType; @@ -112,8 +112,8 @@ class GPUTPCTrackletConstructor { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.cxx index 747667b9b68ed..d3da504ab4ec0 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.cxx @@ -22,7 +22,7 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCTrackletSelector::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) +GPUdii() void GPUTPCTrackletSelector::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & s, processorType& GPUrestrict() tracker) { // select best tracklets and kill clones @@ -36,23 +36,23 @@ GPUdii() void GPUTPCTrackletSelector::Thread<0>(int nBlocks, int nThreads, int i GPUTPCHitId trackHits[GPUCA_ROW_COUNT - GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE]; const float maxSharedFrac = tracker.Param().rec.tpc.trackletMaxSharedFraction; - for (int itr = s.mItr0 + iThread; itr < s.mNTracklets; itr += s.mNThreadsTotal) { + for (int32_t itr = s.mItr0 + iThread; itr < s.mNTracklets; itr += s.mNThreadsTotal) { GPUbarrierWarp(); GPUglobalref() MEM_GLOBAL(GPUTPCTracklet) & GPUrestrict() tracklet = tracker.Tracklets()[itr]; - int firstRow = tracklet.FirstRow(); - int lastRow = tracklet.LastRow(); + int32_t firstRow = tracklet.FirstRow(); + int32_t lastRow = tracklet.LastRow(); - const int w = tracklet.HitWeight(); + const int32_t w = tracklet.HitWeight(); - int irow = firstRow; + int32_t irow = firstRow; - int gap = 0; - int nShared = 0; - int nHits = 0; - const int minHits = tracker.Param().rec.tpc.minNClustersTrackSeed == -1 ? GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tracklet.Param().QPt() * tracker.Param().qptB5Scaler) : tracker.Param().rec.tpc.minNClustersTrackSeed; - const int sharingMinNorm = minHits * tracker.Param().rec.tpc.trackletMinSharedNormFactor; + int32_t gap = 0; + int32_t nShared = 0; + int32_t nHits = 0; + const int32_t minHits = tracker.Param().rec.tpc.minNClustersTrackSeed == -1 ? GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(tracklet.Param().QPt() * tracker.Param().qptB5Scaler) : tracker.Param().rec.tpc.minNClustersTrackSeed; + const int32_t sharingMinNorm = minHits * tracker.Param().rec.tpc.trackletMinSharedNormFactor; float maxShared = maxSharedFrac * sharingMinNorm; GPUCA_UNROLL(, U(1)) @@ -84,13 +84,13 @@ GPUdii() void GPUTPCTrackletSelector::Thread<0>(int nBlocks, int nThreads, int i if (gap > tracker.Param().rec.tpc.trackFollowingMaxRowGap || irow == lastRow) { // store if (nHits >= minHits) { - unsigned int nFirstTrackHit = CAMath::AtomicAdd(tracker.NTrackHits(), (unsigned int)nHits); + uint32_t nFirstTrackHit = CAMath::AtomicAdd(tracker.NTrackHits(), (uint32_t)nHits); if (nFirstTrackHit + nHits > tracker.NMaxTrackHits()) { tracker.raiseError(GPUErrors::ERROR_TRACK_HIT_OVERFLOW, tracker.ISlice(), nFirstTrackHit + nHits, tracker.NMaxTrackHits()); CAMath::AtomicExch(tracker.NTrackHits(), tracker.NMaxTrackHits()); return; } - unsigned int itrout = CAMath::AtomicAdd(tracker.NTracks(), 1u); + uint32_t itrout = CAMath::AtomicAdd(tracker.NTracks(), 1u); if (itrout >= tracker.NMaxTracks()) { tracker.raiseError(GPUErrors::ERROR_TRACK_OVERFLOW, tracker.ISlice(), itrout, tracker.NMaxTracks()); CAMath::AtomicExch(tracker.NTracks(), tracker.NMaxTracks()); @@ -100,7 +100,7 @@ GPUdii() void GPUTPCTrackletSelector::Thread<0>(int nBlocks, int nThreads, int i tracker.Tracks()[itrout].SetParam(tracklet.Param()); tracker.Tracks()[itrout].SetFirstHitID(nFirstTrackHit); tracker.Tracks()[itrout].SetNHits(nHits); - for (int jh = 0; jh < nHits; jh++) { + for (int32_t jh = 0; jh < nHits; jh++) { #if GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE != 0 if (jh < GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE) { tracker.TrackHits()[nFirstTrackHit + jh] = s.mHits[jh][iThread]; diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.h index 5ef974c225651..bae1cbe2bb876 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletSelector.h @@ -36,10 +36,10 @@ class GPUTPCTrackletSelector : public GPUKernelTemplate public: MEM_CLASS_PRE() struct GPUSharedMemory { - int mItr0; // index of the first track in the block - int mNThreadsTotal; // total n threads - int mNTracklets; // n of tracklets - int mReserved; // for alignment reasons + int32_t mItr0; // index of the first track in the block + int32_t mNThreadsTotal; // total n threads + int32_t mNTracklets; // n of tracklets + int32_t mReserved; // for alignment reasons #if GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE != 0 GPUTPCHitId mHits[GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE][GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCTrackletSelector)]; #endif // GPUCA_TRACKLET_SELECTOR_HITS_REG_SIZE != 0 @@ -52,8 +52,8 @@ class GPUTPCTrackletSelector : public GPUKernelTemplate { return processors.tpcTrackers; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& tracker); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index 52fc24b433d50..d907de6567826 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -81,8 +81,8 @@ void unique_ptr_aligned_delete(char* v) std::unique_ptr outputmemory(nullptr, unique_ptr_aligned_delete), outputmemoryPipeline(nullptr, unique_ptr_aligned_delete), inputmemory(nullptr, unique_ptr_aligned_delete); std::unique_ptr eventDisplay; std::unique_ptr tf; -int nEventsInDirectory = 0; -std::atomic nIteration, nIterationEnd; +int32_t nEventsInDirectory = 0; +std::atomic nIteration, nIterationEnd; std::vector ioPtrEvents; std::vector ioMemEvents; @@ -104,9 +104,9 @@ void SetCPUAndOSSettings() #endif // ARM } -int ReadConfiguration(int argc, char** argv) +int32_t ReadConfiguration(int argc, char** argv) { - int qcRet = qConfigParse(argc, (const char**)argv); + int32_t qcRet = qConfigParse(argc, (const char**)argv); if (qcRet) { if (qcRet != qConfig::qcrHelp) { printf("Error parsing command line parameters\n"); @@ -288,7 +288,7 @@ int ReadConfiguration(int argc, char** argv) return (0); } -int SetupReconstruction() +int32_t SetupReconstruction() { if (!configStandalone.eventGenerator) { char filename[256]; @@ -300,7 +300,7 @@ int SetupReconstruction() printf("Error reading event config file\n"); return 1; } - printf("Read event settings from dir %s (solenoidBz: %f, home-made events %d, constBz %d, maxTimeBin %d)\n", filename, rec->GetGRPSettings().solenoidBzNominalGPU, (int)rec->GetGRPSettings().homemadeEvents, (int)rec->GetGRPSettings().constBz, rec->GetGRPSettings().continuousMaxTimeBin); + printf("Read event settings from dir %s (solenoidBz: %f, home-made events %d, constBz %d, maxTimeBin %d)\n", filename, rec->GetGRPSettings().solenoidBzNominalGPU, (int32_t)rec->GetGRPSettings().homemadeEvents, (int32_t)rec->GetGRPSettings().constBz, rec->GetGRPSettings().continuousMaxTimeBin); if (configStandalone.testSyncAsync) { recAsync->ReadSettings(filename); } @@ -522,14 +522,14 @@ int SetupReconstruction() return (0); } -int ReadEvent(int n) +int32_t ReadEvent(int32_t n) { char filename[256]; snprintf(filename, 256, "events/%s/" GPUCA_EVDUMP_FILE ".%d.dump", configStandalone.eventsDir, n); if (configStandalone.inputcontrolmem && !configStandalone.preloadEvents) { rec->SetInputControl(inputmemory.get(), configStandalone.inputcontrolmem); } - int r = chainTracking->ReadData(filename); + int32_t r = chainTracking->ReadData(filename); if (r) { return r; } @@ -555,7 +555,7 @@ int ReadEvent(int n) return 0; } -int LoadEvent(int iEvent, int x) +int32_t LoadEvent(int32_t iEvent, int32_t x) { if (configStandalone.TF.bunchSim) { if (tf->LoadCreateTimeFrame(iEvent)) { @@ -587,7 +587,7 @@ int LoadEvent(int iEvent, int x) if (!configStandalone.runTransformation) { chainTracking->mIOPtrs.clustersNative = nullptr; } else { - for (int i = 0; i < chainTracking->NSLICES; i++) { + for (int32_t i = 0; i < chainTracking->NSLICES; i++) { if (chainTracking->mIOPtrs.rawClusters[i]) { if (configStandalone.proc.debugLevel >= 2) { printf("Converting Legacy Raw Cluster to Native\n"); @@ -615,13 +615,13 @@ int LoadEvent(int iEvent, int x) return 0; } -void OutputStat(GPUChainTracking* t, long* nTracksTotal = nullptr, long* nClustersTotal = nullptr) +void OutputStat(GPUChainTracking* t, int64_t* nTracksTotal = nullptr, int64_t* nClustersTotal = nullptr) { - int nTracks = 0; + int32_t nTracks = 0; if (t->GetProcessingSettings().createO2Output) { nTracks += t->mIOPtrs.nOutputTracksTPCO2; } else { - for (unsigned int k = 0; k < t->mIOPtrs.nMergedTracks; k++) { + for (uint32_t k = 0; k < t->mIOPtrs.nMergedTracks; k++) { if (t->mIOPtrs.mergedTracks[k].OK()) { nTracks++; } @@ -633,9 +633,9 @@ void OutputStat(GPUChainTracking* t, long* nTracksTotal = nullptr, long* nCluste } } -int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, int runs, int iEvent, long* nTracksTotal, long* nClustersTotal, int threadId = 0, HighResTimer* timerPipeline = nullptr) +int32_t RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, int32_t runs, int32_t iEvent, int64_t* nTracksTotal, int64_t* nClustersTotal, int32_t threadId = 0, HighResTimer* timerPipeline = nullptr) { - int iRun = 0, iteration = 0; + int32_t iRun = 0, iteration = 0; while ((iteration = nIteration.fetch_add(1)) < runs) { if (configStandalone.runs > 1) { printf("Run %d (thread %d)\n", iteration + 1, threadId); @@ -658,8 +658,8 @@ int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, rec->startGPUProfiling(); } } - int tmpRetVal = recUse->RunChains(); - int iterationEnd = nIterationEnd.fetch_add(1); + int32_t tmpRetVal = recUse->RunChains(); + int32_t iterationEnd = nIterationEnd.fetch_add(1); if (iterationEnd == configStandalone.runs - 1) { if (configStandalone.proc.doublePipeline && timerPipeline) { timerPipeline->Stop(); @@ -697,7 +697,7 @@ int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, chainTrackingAsync->mIOPtrs.nMCInfosTPCCol = 0; chainTrackingAsync->mIOPtrs.mcLabelsTPC = nullptr; chainTrackingAsync->mIOPtrs.nMCLabelsTPC = 0; - for (int i = 0; i < chainTracking->NSLICES; i++) { + for (int32_t i = 0; i < chainTracking->NSLICES; i++) { chainTrackingAsync->mIOPtrs.clusterData[i] = nullptr; chainTrackingAsync->mIOPtrs.nClusterData[i] = 0; chainTrackingAsync->mIOPtrs.rawClusters[i] = nullptr; @@ -740,7 +740,7 @@ int RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, return 0; } -int main(int argc, char** argv) +int32_t main(int argc, char** argv) { std::unique_ptr recUnique, recUniqueAsync, recUniquePipeline; @@ -805,7 +805,7 @@ int main(int argc, char** argv) if (configStandalone.seed == -1) { std::random_device rd; - configStandalone.seed = (int)rd(); + configStandalone.seed = (int32_t)rd(); printf("Using random seed %d\n", configStandalone.seed); } @@ -831,7 +831,7 @@ int main(int argc, char** argv) return 0; } - int nEvents = configStandalone.nEvents; + int32_t nEvents = configStandalone.nEvents; if (configStandalone.TF.bunchSim) { nEvents = configStandalone.nEvents > 0 ? configStandalone.nEvents : 1; } else { @@ -851,7 +851,7 @@ int main(int argc, char** argv) if (configStandalone.preloadEvents) { printf("Preloading events%s", configStandalone.proc.debugLevel >= 2 ? "\n" : ""); fflush(stdout); - for (int i = 0; i < nEvents - configStandalone.StartEvent; i++) { + for (int32_t i = 0; i < nEvents - configStandalone.StartEvent; i++) { LoadEvent(configStandalone.StartEvent + i, i); if (configStandalone.proc.debugLevel >= 2) { printf("Loading event %d\n", i); @@ -863,7 +863,7 @@ int main(int argc, char** argv) printf("\n"); } - for (int iRunOuter = 0; iRunOuter < configStandalone.runs2; iRunOuter++) { + for (int32_t iRunOuter = 0; iRunOuter < configStandalone.runs2; iRunOuter++) { if (configStandalone.QA.inputHistogramsOnly) { chainTracking->ForceInitQA(); break; @@ -871,9 +871,9 @@ int main(int argc, char** argv) if (configStandalone.runs2 > 1) { printf("RUN2: %d\n", iRunOuter); } - long nTracksTotal = 0; - long nClustersTotal = 0; - int nEventsProcessed = 0; + int64_t nTracksTotal = 0; + int64_t nClustersTotal = 0; + int32_t nEventsProcessed = 0; if (configStandalone.noEvents) { nEvents = 1; @@ -881,7 +881,7 @@ int main(int argc, char** argv) chainTracking->ClearIOPointers(); } - for (int iEvent = configStandalone.StartEvent; iEvent < nEvents; iEvent++) { + for (int32_t iEvent = configStandalone.StartEvent; iEvent < nEvents; iEvent++) { if (iEvent != configStandalone.StartEvent) { printf("\n"); } @@ -906,7 +906,7 @@ int main(int argc, char** argv) printf("Cannot override max time bin for non-continuous data!\n"); } else { grp.continuousMaxTimeBin = chainTracking->mIOPtrs.tpcZS ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcZS) : chainTracking->mIOPtrs.tpcPackedDigits ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcPackedDigits) : GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.clustersNative); - printf("Max time bin set to %d\n", (int)grp.continuousMaxTimeBin); + printf("Max time bin set to %d\n", (int32_t)grp.continuousMaxTimeBin); rec->UpdateSettings(&grp); if (recAsync) { recAsync->UpdateSettings(&grp); @@ -916,7 +916,7 @@ int main(int argc, char** argv) } } } - printf("Loading time: %'d us\n", (int)(1000000 * timerLoad.GetCurrentElapsedTime())); + printf("Loading time: %'d us\n", (int32_t)(1000000 * timerLoad.GetCurrentElapsedTime())); } printf("Processing Event %d\n", iEvent); @@ -945,7 +945,7 @@ int main(int argc, char** argv) if (configStandalone.timeFrameTime) { double nClusters = chainTracking->GetTPCMerger().NMaxClusters(); if (nClusters > 0) { - const int nOrbits = 32; + const int32_t nOrbits = 32; const double colRate = 50000; const double orbitRate = 11245; const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate; @@ -957,7 +957,7 @@ int main(int argc, char** argv) timePerTF = (configStandalone.proc.debugLevel ? recAsync->GetStatKernelTime() : recAsync->GetStatWallTime()) / 1000000. * nClsPerTF / nClusters; snprintf(stat + strlen(stat), 1024 - strlen(stat), " - Async phase: %f sec per TF", timePerTF); } - printf("%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat, configStandalone.proc.debugLevel ? "kernel" : "wall", (int)nClusters, (int)nClsPerTF); + printf("%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat, configStandalone.proc.debugLevel ? "kernel" : "wall", (int32_t)nClusters, (int32_t)nClsPerTF); } } diff --git a/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h b/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h index e0cd756d32651..fd49c89ae9073 100644 --- a/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h +++ b/GPU/GPUTracking/Standalone/tools/GPUExtractPbPbCollision.h @@ -14,50 +14,50 @@ static void GPUExtractPbPbCollision(GPUParam& param, GPUTrackingInOutPointers& ioPtrs) { - std::vector counts(param.continuousMaxTimeBin + 1); - std::vector sums(param.continuousMaxTimeBin + 1); - std::vector countsTracks(param.continuousMaxTimeBin + 1); - std::vector sumsTracks(param.continuousMaxTimeBin + 1); + std::vector counts(param.continuousMaxTimeBin + 1); + std::vector sums(param.continuousMaxTimeBin + 1); + std::vector countsTracks(param.continuousMaxTimeBin + 1); + std::vector sumsTracks(param.continuousMaxTimeBin + 1); std::vector mask(param.continuousMaxTimeBin + 1); - const int driftlength = 520; + const int32_t driftlength = 520; const bool checkAfterGlow = true; - const int afterGlowLength = checkAfterGlow ? 8000 : 0; - for (unsigned int i = 0; i < ioPtrs.clustersNative->nClustersTotal; i++) { - int time = ioPtrs.clustersNative->clustersLinear[i].getTime(); + const int32_t afterGlowLength = checkAfterGlow ? 8000 : 0; + for (uint32_t i = 0; i < ioPtrs.clustersNative->nClustersTotal; i++) { + int32_t time = ioPtrs.clustersNative->clustersLinear[i].getTime(); if (time < 0 || time > param.continuousMaxTimeBin) { fprintf(stderr, "Invalid time %d > %d\n", time, param.continuousMaxTimeBin); throw std::runtime_error("Invalid Time"); } counts[time]++; } - for (unsigned int i = 0; i < ioPtrs.nMergedTracks; i++) { + for (uint32_t i = 0; i < ioPtrs.nMergedTracks; i++) { if (ioPtrs.mergedTracks[i].NClusters() < 40) { continue; } - int time = ioPtrs.mergedTracks[i].GetParam().GetTZOffset(); + int32_t time = ioPtrs.mergedTracks[i].GetParam().GetTZOffset(); if (time < 0 || time > param.continuousMaxTimeBin) { continue; } countsTracks[time]++; } - int first = 0, last = 0; - for (int i = driftlength; i < param.continuousMaxTimeBin; i++) { + int32_t first = 0, last = 0; + for (int32_t i = driftlength; i < param.continuousMaxTimeBin; i++) { if (counts[i]) { first = i; break; } } - for (int i = param.continuousMaxTimeBin + 1 - driftlength; i > 0; i--) { + for (int32_t i = param.continuousMaxTimeBin + 1 - driftlength; i > 0; i--) { if (counts[i - 1]) { last = i; break; } } - unsigned int count = 0; - unsigned int countTracks = 0; - unsigned int min = 1e9; - unsigned long avg = 0; - for (int i = first; i < last; i++) { + uint32_t count = 0; + uint32_t countTracks = 0; + uint32_t min = 1e9; + uint64_t avg = 0; + for (int32_t i = first; i < last; i++) { count += counts[i]; countTracks += countsTracks[i]; if (i - first >= driftlength) { @@ -72,19 +72,19 @@ static void GPUExtractPbPbCollision(GPUParam& param, GPUTrackingInOutPointers& i } } avg /= (last - first - driftlength); - printf("BASELINE Min %d Avg %d\n", min, (int)avg); - /*for (int i = first; i < last - driftlength; i++) { + printf("BASELINE Min %d Avg %d\n", min, (int32_t)avg); + /*for (int32_t i = first; i < last - driftlength; i++) { printf("STAT %d: %u %u (trks %u)\n", i, sums[i], counts[i], sumsTracks[i]); }*/ bool found = false; do { found = false; - unsigned int max = 0, maxpos = 0; - for (int i = first; i < last - driftlength - afterGlowLength; i++) { + uint32_t max = 0, maxpos = 0; + for (int32_t i = first; i < last - driftlength - afterGlowLength; i++) { if (sums[i] > 10 * min && sums[i] > avg && sumsTracks[i] > 3) { bool noColInAfterGlow = true; if (checkAfterGlow) { - for (int ii = i + driftlength; ii < i + driftlength + afterGlowLength; ii++) { + for (int32_t ii = i + driftlength; ii < i + driftlength + afterGlowLength; ii++) { if (sums[ii] > 10 * min && sums[ii] > avg && sumsTracks[ii] > 3) { noColInAfterGlow = false; } @@ -98,27 +98,27 @@ static void GPUExtractPbPbCollision(GPUParam& param, GPUTrackingInOutPointers& i } } if (found) { - unsigned int glow = 0; - unsigned int glowcount = 0; + uint32_t glow = 0; + uint32_t glowcount = 0; if (checkAfterGlow) { - int glowstart = maxpos + driftlength; - int glowend = std::min(last, maxpos + driftlength + afterGlowLength); - for (int i = glowstart; i < glowend; i++) { + int32_t glowstart = maxpos + driftlength; + int32_t glowend = std::min(last, maxpos + driftlength + afterGlowLength); + for (int32_t i = glowstart; i < glowend; i++) { glowcount++; glow += counts[i]; } // printf("AFTERGLOW RANGE %d %d\n", glowstart, glowend); } printf("MAX %d: %u (Tracks %u) Glow %d (%d)\n", maxpos, max, sumsTracks[maxpos], glow, glowcount); - for (int i = std::max(first, maxpos - driftlength); i < std::min(last, maxpos + driftlength + afterGlowLength); i++) { + for (int32_t i = std::max(first, maxpos - driftlength); i < std::min(last, maxpos + driftlength + afterGlowLength); i++) { sums[i] = 0; mask[i] = true; } } } while (found && !checkAfterGlow); - unsigned int noise = 0; - unsigned int noisecount = 0; - for (int i = first; i < last; i++) { + uint32_t noise = 0; + uint32_t noisecount = 0; + for (int32_t i = first; i < last; i++) { if (!mask[i]) { noise += counts[i]; noisecount++; diff --git a/GPU/GPUTracking/Standalone/tools/dumpTRDClusterMatrices.C b/GPU/GPUTracking/Standalone/tools/dumpTRDClusterMatrices.C index 51a2b4922ab6e..757875e4199b3 100644 --- a/GPU/GPUTracking/Standalone/tools/dumpTRDClusterMatrices.C +++ b/GPU/GPUTracking/Standalone/tools/dumpTRDClusterMatrices.C @@ -22,9 +22,9 @@ printf("Cannot read file\n"); return false; } - for (int iDet = 0; iDet < constants::NCHAMBER; ++iDet) { + for (int32_t iDet = 0; iDet < constants::NCHAMBER; ++iDet) { float m[12]; - for (int j=0; j<12; ++j) { + for (int32_t j=0; j<12; ++j) { fIn.read((char*) &m[j], sizeof(float)); } mMatrixCache[iDet] = o2::gpu::Transform3D(m); @@ -56,9 +56,9 @@ void dumpTRDClusterMatrices() return; } - int nMatrices = 0; + int32_t nMatrices = 0; - for (int i = 0; i < 540; ++i) { + for (int32_t i = 0; i < 540; ++i) { // dump all available matrices to a file auto matrix = geo->GetClusterMatrix(i); if (!matrix) { @@ -73,7 +73,7 @@ void dumpTRDClusterMatrices() float m[12] = {static_cast(rot[0]), static_cast(rot[1]), static_cast(rot[2]), static_cast(tr[0]), static_cast(rot[3]), static_cast(rot[4]), static_cast(rot[5]), static_cast(tr[1]), static_cast(rot[6]), static_cast(rot[7]), static_cast(rot[8]), static_cast(tr[2])}; - for (int j = 0; j < 12; ++j) { + for (int32_t j = 0; j < 12; ++j) { fOut.write((char*)&m[j], sizeof(float)); } } diff --git a/GPU/GPUTracking/Standalone/tools/rtc/test.cu b/GPU/GPUTracking/Standalone/tools/rtc/test.cu index c99aab15f342b..f567218046ac7 100644 --- a/GPU/GPUTracking/Standalone/tools/rtc/test.cu +++ b/GPU/GPUTracking/Standalone/tools/rtc/test.cu @@ -24,10 +24,10 @@ } \ } while (0) -int main(int argc, char** argv) +int32_t main(int argc, char** argv) { //Read Sourcecode from file - unsigned int filesize; + uint32_t filesize; FILE* pFile; //Open file if ((pFile = fopen("source.cu", "rb")) == NULL) diff --git a/GPU/GPUTracking/TPCClusterFinder/CfFragment.h b/GPU/GPUTracking/TPCClusterFinder/CfFragment.h index 93d8eb8354fae..dfeed31657c65 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfFragment.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfFragment.h @@ -34,7 +34,7 @@ struct CfFragment { size_t digitsStart = 0; // Start digits in this fragment. Only used when zero suppression is skipped - unsigned int index = 0; + uint32_t index = 0; bool hasBacklog = false; bool hasFuture = false; @@ -52,7 +52,7 @@ struct CfFragment { return CfFragment{index + 1, hasFuture, tpccf::TPCTime(start + length - (hasFuture ? 2 * OverlapTimebins : 0)), totalSliceLength, maxSubSliceLength}; } - GPUdi() unsigned int count() const + GPUdi() uint32_t count() const { return (totalSliceLength + maxSubSliceLength - 4 * OverlapTimebins - 1) / (maxSubSliceLength - 2 * OverlapTimebins); } diff --git a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h index f2b7013aed32e..34ddaacb391a4 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h @@ -46,24 +46,24 @@ class CfUtils static GPUdi() bool isAboveThreshold(uchar peak) { return peak >> 1; } - static GPUdi() int warpPredicateScan(int pred, int* sum) + static GPUdi() int32_t warpPredicateScan(int32_t pred, int32_t* sum) { #ifdef __HIPCC__ - int iLane = hipThreadIdx_x % warpSize; + int32_t iLane = hipThreadIdx_x % warpSize; uint64_t waveMask = __ballot(pred); uint64_t lowerWarpMask = (1ull << iLane) - 1ull; - int myOffset = __popcll(waveMask & lowerWarpMask); + int32_t myOffset = __popcll(waveMask & lowerWarpMask); *sum = __popcll(waveMask); return myOffset; #elif defined(__CUDACC__) - int iLane = threadIdx.x % warpSize; + int32_t iLane = threadIdx.x % warpSize; uint32_t waveMask = __ballot_sync(0xFFFFFFFF, pred); uint32_t lowerWarpMask = (1u << iLane) - 1u; - int myOffset = __popc(waveMask & lowerWarpMask); + int32_t myOffset = __popc(waveMask & lowerWarpMask); *sum = __popc(waveMask); return myOffset; #else // CPU / OpenCL fallback - int myOffset = warp_scan_inclusive_add(pred ? 1 : 0); + int32_t myOffset = warp_scan_inclusive_add(pred ? 1 : 0); *sum = warp_broadcast(myOffset, GPUCA_WARP_SIZE - 1); myOffset--; return myOffset; @@ -71,38 +71,38 @@ class CfUtils } template - static GPUdi() int blockPredicateScan(SharedMemory& smem, int pred, int* sum = nullptr) + static GPUdi() int32_t blockPredicateScan(SharedMemory& smem, int32_t pred, int32_t* sum = nullptr) { #if defined(__HIPCC__) || defined(__CUDACC__) - int iThread = + int32_t iThread = #ifdef __HIPCC__ hipThreadIdx_x; #else threadIdx.x; #endif - int iWarp = iThread / warpSize; - int nWarps = BlockSize / warpSize; + int32_t iWarp = iThread / warpSize; + int32_t nWarps = BlockSize / warpSize; - int warpSum; - int laneOffset = warpPredicateScan(pred, &warpSum); + int32_t warpSum; + int32_t laneOffset = warpPredicateScan(pred, &warpSum); if (iThread % warpSize == 0) { smem.warpPredicateSum[iWarp] = warpSum; } __syncthreads(); - int warpOffset = 0; + int32_t warpOffset = 0; if (sum == nullptr) { - for (int w = 0; w < iWarp; w++) { - int s = smem.warpPredicateSum[w]; + for (int32_t w = 0; w < iWarp; w++) { + int32_t s = smem.warpPredicateSum[w]; warpOffset += s; } } else { *sum = 0; - for (int w = 0; w < nWarps; w++) { - int s = smem.warpPredicateSum[w]; + for (int32_t w = 0; w < nWarps; w++) { + int32_t s = smem.warpPredicateSum[w]; if (w < iWarp) { warpOffset += s; } @@ -112,7 +112,7 @@ class CfUtils return warpOffset + laneOffset; #else // CPU / OpenCL fallback - int lpos = work_group_scan_inclusive_add(pred ? 1 : 0); + int32_t lpos = work_group_scan_inclusive_add(pred ? 1 : 0); if (sum != nullptr) { *sum = work_group_broadcast(lpos, BlockSize - 1); } @@ -122,20 +122,20 @@ class CfUtils } template - static GPUdi() int blockPredicateSum(SharedMemory& smem, int pred) + static GPUdi() int32_t blockPredicateSum(SharedMemory& smem, int32_t pred) { #if defined(__HIPCC__) || defined(__CUDACC__) - int iThread = + int32_t iThread = #ifdef __HIPCC__ hipThreadIdx_x; #else threadIdx.x; #endif - int iWarp = iThread / warpSize; - int nWarps = BlockSize / warpSize; + int32_t iWarp = iThread / warpSize; + int32_t nWarps = BlockSize / warpSize; - int warpSum = + int32_t warpSum = #ifdef __HIPCC__ __popcll(__ballot(pred)); #else @@ -147,8 +147,8 @@ class CfUtils } __syncthreads(); - int sum = 0; - for (int w = 0; w < nWarps; w++) { + int32_t sum = 0; + for (int32_t w = 0; w < nWarps; w++) { sum += smem.warpPredicateSum[w]; } @@ -163,8 +163,8 @@ class CfUtils { bool participates = ll < partSize; - int part; - int lpos = blockPredicateScan(smem, int(!pred && participates), &part); + int32_t part; + int32_t lpos = blockPredicateScan(smem, int32_t(!pred && participates), &part); ushort pos = (participates && !pred) ? lpos : part; @@ -190,7 +190,7 @@ class CfUtils ushort y = ll / N; tpccf::Delta2 d = neighbors[x + offset]; - for (unsigned int i = y; i < wgSize; i += (elems / N)) { + for (uint32_t i = y; i < wgSize; i += (elems / N)) { ChargePos readFrom = posBcast[i]; uint writeTo = N * i + x; buf[writeTo] = map[readFrom.delta(d)]; @@ -205,7 +205,7 @@ class CfUtils GPUbarrier(); - for (unsigned int i = 0; i < N; i++) { + for (uint32_t i = 0; i < N; i++) { tpccf::Delta2 d = neighbors[i + offset]; uint writeTo = N * ll + i; @@ -234,7 +234,7 @@ class CfUtils ushort y = ll / N; ushort x = ll % N; tpccf::Delta2 d = neighbors[x + offset]; - for (unsigned int i = y; i < wgSize; i += (elems / N)) { + for (uint32_t i = y; i < wgSize; i += (elems / N)) { ChargePos readFrom = posBcast[i]; uchar above = aboveThreshold[i]; uint writeTo = N * i + x; @@ -256,7 +256,7 @@ class CfUtils uchar above = aboveThreshold[ll]; GPUbarrier(); - for (unsigned int i = 0; i < N; i++) { + for (uint32_t i = 0; i < N; i++) { tpccf::Delta2 d = neighbors[i + offset]; uint writeTo = N * ll + i; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChainContext.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChainContext.h index 97b3765e92995..99e2e998c04fc 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChainContext.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChainContext.h @@ -29,29 +29,29 @@ namespace gpu struct GPUTPCCFChainContext { struct FragmentData { - unsigned int nDigits[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; - unsigned int nPages[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; - std::vector pageDigits[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; + uint32_t nDigits[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; + uint32_t nPages[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; + std::vector pageDigits[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; GPUTPCClusterFinder::MinMaxCN minMaxCN[GPUCA_NSLICES][GPUTrackingInOutZS::NENDPOINTS]; }; struct PtrSave { GPUTPCClusterFinder::ZSOffset* zsOffsetHost; GPUTPCClusterFinder::ZSOffset* zsOffsetDevice; - unsigned char* zsDevice; + uint8_t* zsDevice; }; - int zsVersion; + int32_t zsVersion; std::vector fragmentData; - unsigned int nPagesTotal; - unsigned int nPagesFragmentMax; - unsigned int nPagesSector[GPUCA_NSLICES]; - unsigned int nDigitsEndpointMax[GPUCA_NSLICES]; - unsigned int tpcMaxTimeBin; + uint32_t nPagesTotal; + uint32_t nPagesFragmentMax; + uint32_t nPagesSector[GPUCA_NSLICES]; + uint32_t nDigitsEndpointMax[GPUCA_NSLICES]; + uint32_t tpcMaxTimeBin; bool abandonTimeframe; - unsigned int nFragments; + uint32_t nFragments; CfFragment fragmentFirst; - std::pair nextPos[GPUCA_NSLICES]; + std::pair nextPos[GPUCA_NSLICES]; PtrSave ptrSave[GPUCA_NSLICES]; const o2::tpc::ClusterNativeAccess* ptrClusterNativeSave; @@ -59,7 +59,7 @@ struct GPUTPCCFChainContext { { abandonTimeframe = false; nPagesTotal = nPagesFragmentMax = 0; - for (unsigned int i = 0; i < GPUCA_NSLICES; i++) { + for (uint32_t i = 0; i < GPUCA_NSLICES; i++) { nPagesSector[i] = 0; nDigitsEndpointMax[i] = 0; } @@ -71,9 +71,9 @@ struct GPUTPCCFChainContext { fragmentData.resize(nFragments); } - for (unsigned int i = 0; i < nFragments; i++) { - for (unsigned int j = 0; j < GPUCA_NSLICES; j++) { - for (unsigned int k = 0; k < GPUTrackingInOutZS::NENDPOINTS; k++) { + for (uint32_t i = 0; i < nFragments; i++) { + for (uint32_t j = 0; j < GPUCA_NSLICES; j++) { + for (uint32_t k = 0; k < GPUTrackingInOutZS::NENDPOINTS; k++) { fragmentData[i].nDigits[j][k] = fragmentData[i].nPages[j][k] = 0; fragmentData[i].pageDigits[j][k].clear(); } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx index 98f28e95e00c3..3b24b8795368c 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx @@ -21,13 +21,13 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFChargeMapFiller::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFChargeMapFiller::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D indexMap(clusterer.mPindexMap); fillIndexMapImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer.mPmemory->fragment, clusterer.mPdigits, indexMap, clusterer.mPmemory->counters.nDigitsInFragment); } -GPUd() void GPUTPCCFChargeMapFiller::fillIndexMapImpl(int nBlocks, int nThreads, int iBlock, int iThread, +GPUd() void GPUTPCCFChargeMapFiller::fillIndexMapImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const CfFragment& fragment, const tpc::Digit* digits, Array2D& indexMap, @@ -44,13 +44,13 @@ GPUd() void GPUTPCCFChargeMapFiller::fillIndexMapImpl(int nBlocks, int nThreads, } template <> -GPUdii() void GPUTPCCFChargeMapFiller::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFChargeMapFiller::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); fillFromDigitsImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer, clusterer.mPmemory->fragment, clusterer.mPmemory->counters.nPositions, clusterer.mPdigits, clusterer.mPpositions, chargeMap); } -GPUd() void GPUTPCCFChargeMapFiller::fillFromDigitsImpl(int nBlocks, int nThreads, int iBlock, int iThread, processorType& clusterer, const CfFragment& fragment, size_t digitNum, +GPUd() void GPUTPCCFChargeMapFiller::fillFromDigitsImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, processorType& clusterer, const CfFragment& fragment, size_t digitNum, const tpc::Digit* digits, ChargePos* positions, Array2D& chargeMap) @@ -69,7 +69,7 @@ GPUd() void GPUTPCCFChargeMapFiller::fillFromDigitsImpl(int nBlocks, int nThread } template <> -GPUdii() void GPUTPCCFChargeMapFiller::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, char setPositions) +GPUdii() void GPUTPCCFChargeMapFiller::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int8_t setPositions) { if (iThread != 0 || iBlock != 0) { return; @@ -90,7 +90,7 @@ GPUdii() void GPUTPCCFChargeMapFiller::Thread - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); - static GPUd() void fillIndexMapImpl(int, int, int, int, const CfFragment&, const tpc::Digit*, Array2D&, size_t); + static GPUd() void fillIndexMapImpl(int32_t, int32_t, int32_t, int32_t, const CfFragment&, const tpc::Digit*, Array2D&, size_t); - static GPUd() void fillFromDigitsImpl(int, int, int, int, processorType&, const CfFragment&, size_t, const tpc::Digit*, ChargePos*, Array2D&); + static GPUd() void fillFromDigitsImpl(int32_t, int32_t, int32_t, int32_t, processorType&, const CfFragment&, size_t, const tpc::Digit*, ChargePos*, Array2D&); private: - static GPUd() size_t findTransition(int, const tpc::Digit*, size_t, size_t); + static GPUd() size_t findTransition(int32_t, const tpc::Digit*, size_t, size_t); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.cxx index cfa3bb2707136..9a890202524f0 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.cxx @@ -29,12 +29,12 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { const CfFragment& fragment = clusterer.mPmemory->fragment; Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); - int basePad = iBlock * PadsPerCacheline; + int32_t basePad = iBlock * PadsPerCacheline; ChargePos basePos = padToChargePos(basePad, clusterer); if (not basePos.valid()) { @@ -44,21 +44,21 @@ GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int i #ifdef GPUCA_GPUCODE static_assert(TPC_MAX_FRAGMENT_LEN_GPU % NumOfCachedTimebins == 0); - int totalCharges = 0; - int consecCharges = 0; - int maxConsecCharges = 0; + int32_t totalCharges = 0; + int32_t consecCharges = 0; + int32_t maxConsecCharges = 0; Charge maxCharge = 0; - short localPadId = iThread / NumOfCachedTimebins; - short localTimeBin = iThread % NumOfCachedTimebins; + int16_t localPadId = iThread / NumOfCachedTimebins; + int16_t localTimeBin = iThread % NumOfCachedTimebins; bool handlePad = localTimeBin == 0; for (tpccf::TPCFragmentTime t = fragment.firstNonOverlapTimeBin(); t < fragment.lastNonOverlapTimeBin(); t += NumOfCachedTimebins) { - const ChargePos pos = basePos.delta({localPadId, short(t + localTimeBin)}); + const ChargePos pos = basePos.delta({localPadId, int16_t(t + localTimeBin)}); smem.charges[localPadId][localTimeBin] = (pos.valid()) ? chargeMap[pos].unpack() : 0; GPUbarrier(); if (handlePad) { - for (int i = 0; i < NumOfCachedTimebins; i++) { + for (int32_t i = 0; i < NumOfCachedTimebins; i++) { const Charge q = smem.charges[localPadId][i]; totalCharges += (q > 0); consecCharges = (q > 0) ? consecCharges + 1 : 0; @@ -80,7 +80,7 @@ GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int i constexpr size_t ElemsInTileRow = (size_t)TilingLayout>::WidthInTiles * TimebinsPerCacheline * PadsPerCacheline; #ifndef GPUCA_NO_VC - using UShort8 = Vc::fixed_size_simd; + using UShort8 = Vc::fixed_size_simd; using Charge8 = Vc::fixed_size_simd; UShort8 totalCharges{Vc::Zero}; @@ -88,16 +88,16 @@ GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int i UShort8 maxConsecCharges{Vc::Zero}; Charge8 maxCharge{Vc::Zero}; #else - std::array totalCharges{0}; - std::array consecCharges{0}; - std::array maxConsecCharges{0}; + std::array totalCharges{0}; + std::array consecCharges{0}; + std::array maxConsecCharges{0}; std::array maxCharge{0}; #endif tpccf::TPCFragmentTime t = fragment.firstNonOverlapTimeBin(); // Access packed charges as raw integers. We throw away the PackedCharge type here to simplify vectorization. - const unsigned short* packedChargeStart = reinterpret_cast(&chargeMap[basePos.delta({0, t})]); + const uint16_t* packedChargeStart = reinterpret_cast(&chargeMap[basePos.delta({0, t})]); for (; t < fragment.lastNonOverlapTimeBin(); t += TimebinsPerCacheline) { for (tpccf::TPCFragmentTime localtime = 0; localtime < TimebinsPerCacheline; localtime++) { @@ -124,7 +124,7 @@ GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int i } #else // Vc not available for (tpccf::Pad localpad = 0; localpad < PadsPerCacheline; localpad++) { - const unsigned short packedCharge = packedChargeStart[PadsPerCacheline * localtime + localpad]; + const uint16_t packedCharge = packedChargeStart[PadsPerCacheline * localtime + localpad]; const bool isCharge = packedCharge != 0; if (isCharge) { totalCharges[localpad]++; @@ -149,16 +149,16 @@ GPUd() void GPUTPCCFCheckPadBaseline::Thread<0>(int nBlocks, int nThreads, int i #endif } -GPUd() ChargePos GPUTPCCFCheckPadBaseline::padToChargePos(int& pad, const GPUTPCClusterFinder& clusterer) +GPUd() ChargePos GPUTPCCFCheckPadBaseline::padToChargePos(int32_t& pad, const GPUTPCClusterFinder& clusterer) { const GPUTPCGeometry& geo = clusterer.Param().tpcGeometry; - int padOffset = 0; + int32_t padOffset = 0; for (Row r = 0; r < GPUCA_ROW_COUNT; r++) { - int npads = geo.NPads(r); - int padInRow = pad - padOffset; - if (0 <= padInRow && padInRow < CAMath::nextMultipleOf(npads)) { - int cachelineOffset = padInRow % PadsPerCacheline; + int32_t npads = geo.NPads(r); + int32_t padInRow = pad - padOffset; + if (0 <= padInRow && padInRow < CAMath::nextMultipleOf(npads)) { + int32_t cachelineOffset = padInRow % PadsPerCacheline; pad -= cachelineOffset; return ChargePos{r, Pad(padInRow - cachelineOffset), 0}; } @@ -168,12 +168,12 @@ GPUd() ChargePos GPUTPCCFCheckPadBaseline::padToChargePos(int& pad, const GPUTPC return ChargePos{0, 0, INVALID_TIME_BIN}; } -GPUd() void GPUTPCCFCheckPadBaseline::updatePadBaseline(int pad, const GPUTPCClusterFinder& clusterer, int totalCharges, int consecCharges, Charge maxCharge) +GPUd() void GPUTPCCFCheckPadBaseline::updatePadBaseline(int32_t pad, const GPUTPCClusterFinder& clusterer, int32_t totalCharges, int32_t consecCharges, Charge maxCharge) { const CfFragment& fragment = clusterer.mPmemory->fragment; - const int totalChargesBaseline = clusterer.Param().rec.tpc.maxTimeBinAboveThresholdIn1000Bin * fragment.lengthWithoutOverlap() / 1000; - const int consecChargesBaseline = clusterer.Param().rec.tpc.maxConsecTimeBinAboveThreshold; - const unsigned short saturationThreshold = clusterer.Param().rec.tpc.noisyPadSaturationThreshold; + const int32_t totalChargesBaseline = clusterer.Param().rec.tpc.maxTimeBinAboveThresholdIn1000Bin * fragment.lengthWithoutOverlap() / 1000; + const int32_t consecChargesBaseline = clusterer.Param().rec.tpc.maxConsecTimeBinAboveThreshold; + const uint16_t saturationThreshold = clusterer.Param().rec.tpc.noisyPadSaturationThreshold; const bool isNoisy = (!saturationThreshold || maxCharge < saturationThreshold) && ((totalChargesBaseline > 0 && totalCharges >= totalChargesBaseline) || (consecChargesBaseline > 0 && consecCharges >= consecChargesBaseline)); if (isNoisy) { diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.h index ac13c71de70e5..0440121175f3a 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFCheckPadBaseline.h @@ -50,12 +50,12 @@ class GPUTPCCFCheckPadBaseline : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer); private: - GPUd() static ChargePos padToChargePos(int& pad, const GPUTPCClusterFinder&); - GPUd() static void updatePadBaseline(int pad, const GPUTPCClusterFinder&, int totalCharges, int consecCharges, tpccf::Charge maxCharge); + GPUd() static ChargePos padToChargePos(int32_t& pad, const GPUTPCClusterFinder&); + GPUd() static void updatePadBaseline(int32_t pad, const GPUTPCClusterFinder&, int32_t totalCharges, int32_t consecCharges, tpccf::Charge maxCharge); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx index 1763aedc4233e..4d926e3ddfffa 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx @@ -26,7 +26,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFClusterizer::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, char onlyMC) +GPUdii() void GPUTPCCFClusterizer::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int8_t onlyMC) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); CPU_ONLY( @@ -37,7 +37,7 @@ GPUdii() void GPUTPCCFClusterizer::Thread<0>(int nBlocks, int nThreads, int iBlo GPUTPCCFClusterizer::computeClustersImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer, clusterer.mPmemory->fragment, smem, chargeMap, clusterer.mPfilteredPeakPositions, clusterer.Param().rec, CPU_PTR(&labelAcc), clusterer.mPmemory->counters.nClusters, clusterer.mNMaxClusterPerRow, clusterer.mPclusterInRow, clusterOut, clusterer.mPclusterPosInRow); } -GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int nBlocks, int nThreads, int iBlock, int iThread, +GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, processorType& clusterer, const CfFragment& fragment, GPUSharedMemory& smem, diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h index a3b8d9567e45a..5836f69425e30 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h @@ -56,10 +56,10 @@ class GPUTPCCFClusterizer : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, char); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int8_t); - static GPUd() void computeClustersImpl(int, int, int, int, processorType&, const CfFragment&, GPUSharedMemory&, const Array2D&, const ChargePos*, const GPUSettingsRec&, MCLabelAccumulator*, uint, uint, uint*, tpc::ClusterNative*, uint*); + static GPUd() void computeClustersImpl(int32_t, int32_t, int32_t, int32_t, processorType&, const CfFragment&, GPUSharedMemory&, const Array2D&, const ChargePos*, const GPUSettingsRec&, MCLabelAccumulator*, uint, uint, uint*, tpc::ClusterNative*, uint*); private: static GPUd() void updateClusterInner(const GPUSettingsRec&, ushort, ushort, const PackedCharge*, const ChargePos&, ClusterAccumulator*, MCLabelAccumulator*, uchar*); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.cxx index d960960fe6924..5413878421884 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.cxx @@ -35,18 +35,18 @@ using namespace o2::tpc::constants; // =========================================================================== template <> -GPUdii() void GPUTPCCFDecodeZS::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int firstHBF) +GPUdii() void GPUTPCCFDecodeZS::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t firstHBF) { GPUTPCCFDecodeZS::decode(clusterer, smem, nBlocks, nThreads, iBlock, iThread, firstHBF); } -GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUSharedMemory& s, int nBlocks, int nThreads, int iBlock, int iThread, int firstHBF) +GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUSharedMemory& s, int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t firstHBF) { - const unsigned int slice = clusterer.mISlice; + const uint32_t slice = clusterer.mISlice; #ifdef GPUCA_GPUCODE - const unsigned int endpoint = clusterer.mPzsOffsets[iBlock].endpoint; + const uint32_t endpoint = clusterer.mPzsOffsets[iBlock].endpoint; #else - const unsigned int endpoint = iBlock; + const uint32_t endpoint = iBlock; #endif const GPUTrackingInOutZS::GPUTrackingInOutZSSlice& zs = clusterer.GetConstantMem()->ioPtrs.tpcZS->slice[slice]; if (zs.count[endpoint] == 0) { @@ -56,7 +56,7 @@ GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUShared Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); const size_t nDigits = clusterer.mPzsOffsets[iBlock].offset; if (iThread == 0) { - const int region = endpoint / 2; + const int32_t region = endpoint / 2; s.nRowsRegion = clusterer.Param().tpcGeometry.GetRegionRows(region); s.regionStartRow = clusterer.Param().tpcGeometry.GetRegionStart(region); s.nThreadsPerRow = CAMath::Max(1u, nThreads / ((s.nRowsRegion + (endpoint & 1)) / 2)); @@ -64,23 +64,23 @@ GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUShared s.rowOffsetCounter = 0; } GPUbarrier(); - const unsigned int myRow = iThread / s.nThreadsPerRow; - const unsigned int mySequence = iThread % s.nThreadsPerRow; + const uint32_t myRow = iThread / s.nThreadsPerRow; + const uint32_t mySequence = iThread % s.nThreadsPerRow; #ifdef GPUCA_GPUCODE - const unsigned int i = 0; - const unsigned int j = clusterer.mPzsOffsets[iBlock].num; + const uint32_t i = 0; + const uint32_t j = clusterer.mPzsOffsets[iBlock].num; { { #else - for (unsigned int i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) { - const unsigned int minJ = (i == clusterer.mMinMaxCN[endpoint].zsPtrFirst) ? clusterer.mMinMaxCN[endpoint].zsPageFirst : 0; - const unsigned int maxJ = (i + 1 == clusterer.mMinMaxCN[endpoint].zsPtrLast) ? clusterer.mMinMaxCN[endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; - for (unsigned int j = minJ; j < maxJ; j++) { + for (uint32_t i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) { + const uint32_t minJ = (i == clusterer.mMinMaxCN[endpoint].zsPtrFirst) ? clusterer.mMinMaxCN[endpoint].zsPageFirst : 0; + const uint32_t maxJ = (i + 1 == clusterer.mMinMaxCN[endpoint].zsPtrLast) ? clusterer.mMinMaxCN[endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; + for (uint32_t j = minJ; j < maxJ; j++) { #endif - const unsigned int* pageSrc = (const unsigned int*)(((const unsigned char*)zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE); - CA_SHARED_CACHE_REF(&s.ZSPage[0], pageSrc, TPCZSHDR::TPC_ZS_PAGE_SIZE, unsigned int, pageCache); + const uint32_t* pageSrc = (const uint32_t*)(((const uint8_t*)zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE); + CA_SHARED_CACHE_REF(&s.ZSPage[0], pageSrc, TPCZSHDR::TPC_ZS_PAGE_SIZE, uint32_t, pageCache); GPUbarrier(); - const unsigned char* page = (const unsigned char*)pageCache; + const uint8_t* page = (const uint8_t*)pageCache; const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)page; if (o2::raw::RDHUtils::getMemorySize(*rdh) == sizeof(o2::header::RAWDataHeader)) { #ifdef GPUCA_GPUCODE @@ -89,42 +89,42 @@ GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUShared continue; #endif } - const unsigned char* pagePtr = page + sizeof(o2::header::RAWDataHeader); + const uint8_t* pagePtr = page + sizeof(o2::header::RAWDataHeader); const TPCZSHDR* hdr = reinterpret_cast(pagePtr); pagePtr += sizeof(*hdr); const bool decode12bit = hdr->version == 2; - const unsigned int decodeBits = decode12bit ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; + const uint32_t decodeBits = decode12bit ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; const float decodeBitsFactor = 1.f / (1 << (decodeBits - 10)); - unsigned int mask = (1 << decodeBits) - 1; - int timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; - const int rowOffset = s.regionStartRow + ((endpoint & 1) ? (s.nRowsRegion / 2) : 0); - const int nRows = (endpoint & 1) ? (s.nRowsRegion - s.nRowsRegion / 2) : (s.nRowsRegion / 2); + uint32_t mask = (1 << decodeBits) - 1; + int32_t timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + const int32_t rowOffset = s.regionStartRow + ((endpoint & 1) ? (s.nRowsRegion / 2) : 0); + const int32_t nRows = (endpoint & 1) ? (s.nRowsRegion - s.nRowsRegion / 2) : (s.nRowsRegion / 2); - for (int l = 0; l < hdr->nTimeBinSpan; l++) { // TODO: Parallelize over time bins + for (int32_t l = 0; l < hdr->nTimeBinSpan; l++) { // TODO: Parallelize over time bins pagePtr += (pagePtr - page) & 1; // Ensure 16 bit alignment const TPCZSTBHDR* tbHdr = reinterpret_cast(pagePtr); if ((tbHdr->rowMask & 0x7FFF) == 0) { pagePtr += 2; continue; } - const int nRowsUsed = CAMath::Popcount((unsigned int)(tbHdr->rowMask & 0x7FFF)); + const int32_t nRowsUsed = CAMath::Popcount((uint32_t)(tbHdr->rowMask & 0x7FFF)); pagePtr += 2 * nRowsUsed; GPUbarrier(); - for (int n = iThread; n < nRowsUsed; n += nThreads) { - const unsigned char* rowData = n == 0 ? pagePtr : (page + tbHdr->rowAddr1()[n - 1]); - s.RowClusterOffset[n] = CAMath::AtomicAddShared(&s.rowOffsetCounter, rowData[2 * *rowData]); + for (int32_t n = iThread; n < nRowsUsed; n += nThreads) { + const uint8_t* rowData = n == 0 ? pagePtr : (page + tbHdr->rowAddr1()[n - 1]); + s.RowClusterOffset[n] = CAMath::AtomicAddShared(&s.rowOffsetCounter, rowData[2 * *rowData]); } /*if (iThread < GPUCA_WARP_SIZE) { // TODO: Seems to miscompile with HIP, CUDA performance doesn't really change, for now sticking to the AtomicAdd GPUSharedMemory& smem = s; - int o; + int32_t o; if (iThread < nRowsUsed) { - const unsigned char* rowData = iThread == 0 ? pagePtr : (page + tbHdr->rowAddr1()[iThread - 1]); + const uint8_t* rowData = iThread == 0 ? pagePtr : (page + tbHdr->rowAddr1()[iThread - 1]); o = rowData[2 * *rowData]; } else { o = 0; } - int x = warp_scan_inclusive_add(o); + int32_t x = warp_scan_inclusive_add(o); if (iThread < nRowsUsed) { s.RowClusterOffset[iThread] = s.rowOffsetCounter + x - o; } else if (iThread == GPUCA_WARP_SIZE - 1) { @@ -134,35 +134,35 @@ GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUShared GPUbarrier(); if (myRow < s.rowStride) { - for (int m = myRow; m < nRows; m += s.rowStride) { + for (int32_t m = myRow; m < nRows; m += s.rowStride) { if ((tbHdr->rowMask & (1 << m)) == 0) { continue; } - const int rowPos = CAMath::Popcount((unsigned int)(tbHdr->rowMask & ((1 << m) - 1))); + const int32_t rowPos = CAMath::Popcount((uint32_t)(tbHdr->rowMask & ((1 << m) - 1))); size_t nDigitsTmp = nDigits + s.RowClusterOffset[rowPos]; - const unsigned char* rowData = rowPos == 0 ? pagePtr : (page + tbHdr->rowAddr1()[rowPos - 1]); - const int nSeqRead = *rowData; - const int nSeqPerThread = (nSeqRead + s.nThreadsPerRow - 1) / s.nThreadsPerRow; - const int mySequenceStart = mySequence * nSeqPerThread; - const int mySequenceEnd = CAMath::Min(mySequenceStart + nSeqPerThread, nSeqRead); + const uint8_t* rowData = rowPos == 0 ? pagePtr : (page + tbHdr->rowAddr1()[rowPos - 1]); + const int32_t nSeqRead = *rowData; + const int32_t nSeqPerThread = (nSeqRead + s.nThreadsPerRow - 1) / s.nThreadsPerRow; + const int32_t mySequenceStart = mySequence * nSeqPerThread; + const int32_t mySequenceEnd = CAMath::Min(mySequenceStart + nSeqPerThread, nSeqRead); if (mySequenceEnd > mySequenceStart) { - const unsigned char* adcData = rowData + 2 * nSeqRead + 1; - const unsigned int nSamplesStart = mySequenceStart ? rowData[2 * mySequenceStart] : 0; + const uint8_t* adcData = rowData + 2 * nSeqRead + 1; + const uint32_t nSamplesStart = mySequenceStart ? rowData[2 * mySequenceStart] : 0; nDigitsTmp += nSamplesStart; - unsigned int nADCStartBits = nSamplesStart * decodeBits; - const unsigned int nADCStart = (nADCStartBits + 7) / 8; - const int nADC = (rowData[2 * mySequenceEnd] * decodeBits + 7) / 8; + uint32_t nADCStartBits = nSamplesStart * decodeBits; + const uint32_t nADCStart = (nADCStartBits + 7) / 8; + const int32_t nADC = (rowData[2 * mySequenceEnd] * decodeBits + 7) / 8; adcData += nADCStart; nADCStartBits &= 0x7; - unsigned int byte = 0, bits = 0; + uint32_t byte = 0, bits = 0; if (nADCStartBits) { // % 8 != 0 bits = 8 - nADCStartBits; byte = ((*(adcData - 1) & (0xFF ^ ((1 << nADCStartBits) - 1)))) >> nADCStartBits; } - int nSeq = mySequenceStart; - int seqLen = nSeq ? (rowData[(nSeq + 1) * 2] - rowData[nSeq * 2]) : rowData[2]; + int32_t nSeq = mySequenceStart; + int32_t seqLen = nSeq ? (rowData[(nSeq + 1) * 2] - rowData[nSeq * 2]) : rowData[2]; Pad pad = rowData[nSeq++ * 2 + 1]; - for (int n = nADCStart; n < nADC; n++) { + for (int32_t n = nADCStart; n < nADC; n++) { byte |= *(adcData++) << bits; bits += 8; while (bits >= decodeBits) { @@ -208,12 +208,12 @@ GPUdii() void GPUTPCCFDecodeZS::decode(GPUTPCClusterFinder& clusterer, GPUShared // =========================================================================== template <> -GPUdii() void GPUTPCCFDecodeZSLink::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int firstHBF) +GPUdii() void GPUTPCCFDecodeZSLink::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t firstHBF) { Decode(nBlocks, nThreads, iBlock, iThread, smem, clusterer, firstHBF); } -GPUd() size_t GPUTPCCFDecodeZSLink::DecodePage(GPUSharedMemory& smem, processorType& clusterer, int iBlock, int nThreads, int iThread, const unsigned char* page, uint32_t pageDigitOffset, int firstHBF) +GPUd() size_t GPUTPCCFDecodeZSLink::DecodePage(GPUSharedMemory& smem, processorType& clusterer, int32_t iBlock, int32_t nThreads, int32_t iThread, const uint8_t* page, uint32_t pageDigitOffset, int32_t firstHBF) { const CfFragment& fragment = clusterer.mPmemory->fragment; @@ -223,22 +223,22 @@ GPUd() size_t GPUTPCCFDecodeZSLink::DecodePage(GPUSharedMemory& smem, processorT return pageDigitOffset; } - int nDecoded = 0; + int32_t nDecoded = 0; const auto* decHdr = ConsumeHeader(page); ConsumeBytes(page, decHdr->firstZSDataOffset * 16); assert(decHdr->version == ZSVersionLinkBasedWithMeta); assert(decHdr->magicWord == o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader); - for (unsigned int t = 0; t < decHdr->nTimebinHeaders; t++) { + for (uint32_t t = 0; t < decHdr->nTimebinHeaders; t++) { const auto* tbHdr = ConsumeHeader(page); const auto* adcData = ConsumeBytes(page, tbHdr->numWordsPayload * 16); // Page now points to next timebin or past the page - int timeBin = (decHdr->timeOffset + tbHdr->bunchCrossing + (unsigned long)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdHdr) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + int32_t timeBin = (decHdr->timeOffset + tbHdr->bunchCrossing + (uint64_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdHdr) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; uint32_t channelMask[3]; GetChannelBitmask(*tbHdr, channelMask); - unsigned int nAdc = CAMath::Popcount(channelMask[0]) + CAMath::Popcount(channelMask[1]) + CAMath::Popcount(channelMask[2]); + uint32_t nAdc = CAMath::Popcount(channelMask[0]) + CAMath::Popcount(channelMask[1]) + CAMath::Popcount(channelMask[2]); bool inFragment = fragment.contains(timeBin); nDecoded += nAdc; @@ -273,7 +273,7 @@ GPUd() size_t GPUTPCCFDecodeZSLink::DecodePage(GPUSharedMemory& smem, processorT pageDigitOffset); #endif pageDigitOffset += nAdc; - } // for (unsigned int t = 0; t < decHdr->nTimebinHeaders; t++) + } // for (uint32_t t = 0; t < decHdr->nTimebinHeaders; t++) (void)nDecoded; #ifdef GPUCA_CHECK_TPCZS_CORRUPTION if (iThread == 0 && nDecoded != decHdr->nADCsamples) { @@ -290,19 +290,19 @@ GPUd() size_t GPUTPCCFDecodeZSLink::DecodePage(GPUSharedMemory& smem, processorT GPUd() void GPUTPCCFDecodeZSLink::DecodeTBSingleThread( processorType& clusterer, - const unsigned char* adcData, - unsigned int nAdc, + const uint8_t* adcData, + uint32_t nAdc, const uint32_t* channelMask, - int timeBin, - int cru, - int fecInPartition, + int32_t timeBin, + int32_t cru, + int32_t fecInPartition, uint32_t pageDigitOffset) { const CfFragment& fragment = clusterer.mPmemory->fragment; if CONSTEXPR (TPCZSHDRV2::TIGHTLY_PACKED_V3) { - unsigned int byte = 0, bits = 0, nSamplesWritten = 0, rawFECChannel = 0; + uint32_t byte = 0, bits = 0, nSamplesWritten = 0, rawFECChannel = 0; // unpack adc values, assume tightly packed data while (nSamplesWritten < nAdc) { @@ -328,13 +328,13 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBSingleThread( } // while (nSamplesWritten < nAdc) } else { // ! TPCZSHDRV2::TIGHTLY_PACKED_V3 - unsigned int rawFECChannel = 0; - const unsigned long* adcData64 = (const unsigned long*)adcData; - for (unsigned int j = 0; j < nAdc; j++) { + uint32_t rawFECChannel = 0; + const uint64_t* adcData64 = (const uint64_t*)adcData; + for (uint32_t j = 0; j < nAdc; j++) { for (; !ChannelIsActive(channelMask, rawFECChannel); rawFECChannel++) { } - unsigned int adc = (adcData64[j / TPCZSHDRV2::SAMPLESPER64BIT] >> ((j % TPCZSHDRV2::SAMPLESPER64BIT) * DECODE_BITS)) & DECODE_MASK; + uint32_t adc = (adcData64[j / TPCZSHDRV2::SAMPLESPER64BIT] >> ((j % TPCZSHDRV2::SAMPLESPER64BIT) * DECODE_BITS)) & DECODE_MASK; o2::tpc::PadPos padAndRow = GetPadAndRowFromFEC(clusterer, cru, rawFECChannel, fecInPartition); float charge = ADCToFloat(adc, DECODE_MASK, DECODE_BITS_FACTOR); @@ -346,33 +346,33 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBSingleThread( GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( processorType& clusterer, - int iThread, + int32_t iThread, GPUSharedMemory& smem, - const unsigned char* adcData, - unsigned int nAdc, + const uint8_t* adcData, + uint32_t nAdc, const uint32_t* channelMask, - int timeBin, - int cru, - int fecInPartition, + int32_t timeBin, + int32_t cru, + int32_t fecInPartition, uint32_t pageDigitOffset) { - constexpr int NTHREADS = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDecodeZSLink); + constexpr int32_t NTHREADS = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDecodeZSLink); static_assert(NTHREADS == GPUCA_WARP_SIZE, "Decoding TB Headers in parallel assumes block size is a single warp."); - unsigned char blockOffset = 0; - for (unsigned char i = iThread; blockOffset < nAdc; i += NTHREADS) { + uint8_t blockOffset = 0; + for (uint8_t i = iThread; blockOffset < nAdc; i += NTHREADS) { - unsigned char rawFECChannel = i; + uint8_t rawFECChannel = i; - unsigned char myChannelActive = ChannelIsActive(channelMask, rawFECChannel); + uint8_t myChannelActive = ChannelIsActive(channelMask, rawFECChannel); - unsigned char myOffset = warp_scan_inclusive_add(myChannelActive) - 1 + blockOffset; + uint8_t myOffset = warp_scan_inclusive_add(myChannelActive) - 1 + blockOffset; blockOffset = warp_broadcast(myOffset, NTHREADS - 1) + 1; // Decode entire timebin at once if we have enough threads // This should further improve performance, but code below is buggy... // if (nAdc <= NThreads) { - // for (int j = 1; blockOffset < nAdc; j++) { + // for (int32_t j = 1; blockOffset < nAdc; j++) { // rawFECChannel = myChannelActive ? rawFECChannel : (iThread + j*NThreads - myOffset); // bool iAmIdle = not myChannelActive; @@ -382,7 +382,7 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( // ? BitIsSet(channelMask, rawFECChannel) // : false; - // unsigned char newOffset = warp_scan_inclusive_add(static_cast(myChannelActive && iAmIdle)) - 1 + blockOffset; + // uint8_t newOffset = warp_scan_inclusive_add(static_cast(myChannelActive && iAmIdle)) - 1 + blockOffset; // blockOffset = warp_broadcast(newOffset, NThreads - 1) + 1; // myOffset = iAmIdle ? newOffset : myOffset; @@ -394,7 +394,7 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( } assert(myOffset < nAdc); - unsigned int adc = 0; + uint32_t adc = 0; if CONSTEXPR (TPCZSHDRV2::TIGHTLY_PACKED_V3) { @@ -402,20 +402,20 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( // You'd think this would improve performace, but it's actually slower... // const uint32_t* adcDataU32 = reinterpret_cast(adcData); - unsigned int adcBitOffset = myOffset * DECODE_BITS; - unsigned int adcByteOffset = adcBitOffset / CHAR_BIT; - unsigned int adcOffsetInByte = adcBitOffset - adcByteOffset * CHAR_BIT; - // unsigned int adcByteOffset = adcBitOffset / 32; - // unsigned int adcOffsetInByte = adcBitOffset - adcByteOffset * 32; + uint32_t adcBitOffset = myOffset * DECODE_BITS; + uint32_t adcByteOffset = adcBitOffset / CHAR_BIT; + uint32_t adcOffsetInByte = adcBitOffset - adcByteOffset * CHAR_BIT; + // uint32_t adcByteOffset = adcBitOffset / 32; + // uint32_t adcOffsetInByte = adcBitOffset - adcByteOffset * 32; - unsigned int byte = 0, bits = 0; + uint32_t byte = 0, bits = 0; - // unsigned int byte = adcDataU32[adcByteOffset] >> adcOffsetInByte; - // unsigned int bits = 32 - adcOffsetInByte; + // uint32_t byte = adcDataU32[adcByteOffset] >> adcOffsetInByte; + // uint32_t bits = 32 - adcOffsetInByte; // adcByteOffset++; while (bits < DECODE_BITS) { - byte |= ((unsigned int)adcData[adcByteOffset]) << bits; + byte |= ((uint32_t)adcData[adcByteOffset]) << bits; // byte |= adcDataU32[adcByteOffset] << bits; adcByteOffset++; bits += CHAR_BIT; @@ -424,7 +424,7 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( adc = byte >> adcOffsetInByte; } else { // ! TPCZSHDRV2::TIGHTLY_PACKED_V3 - const unsigned long* adcData64 = (const unsigned long*)adcData; + const uint64_t* adcData64 = (const uint64_t*)adcData; adc = (adcData64[myOffset / TPCZSHDRV2::SAMPLESPER64BIT] >> ((myOffset % TPCZSHDRV2::SAMPLESPER64BIT) * DECODE_BITS)) & DECODE_MASK; } @@ -433,7 +433,7 @@ GPUd() void GPUTPCCFDecodeZSLink::DecodeTBMultiThread( float charge = ADCToFloat(adc, DECODE_MASK, DECODE_BITS_FACTOR); WriteCharge(clusterer, charge, padAndRow, fragment.toLocal(timeBin), pageDigitOffset + myOffset); - } // for (unsigned char i = iThread; blockOffset < nAdc; i += NThreads) + } // for (uint8_t i = iThread; blockOffset < nAdc; i += NThreads) } GPUd() void GPUTPCCFDecodeZSLink::GetChannelBitmask(const zerosupp_link_based::CommonHeader& tbHdr, uint32_t* chan) @@ -443,14 +443,14 @@ GPUd() void GPUTPCCFDecodeZSLink::GetChannelBitmask(const zerosupp_link_based::C chan[2] = tbHdr.bitMaskHigh; } -GPUd() bool GPUTPCCFDecodeZSLink::ChannelIsActive(const uint32_t* chan, unsigned char chanIndex) +GPUd() bool GPUTPCCFDecodeZSLink::ChannelIsActive(const uint32_t* chan, uint8_t chanIndex) { if (chanIndex >= zerosupp_link_based::ChannelPerTBHeader) { return false; } - constexpr unsigned char N_BITS_PER_ENTRY = sizeof(*chan) * CHAR_BIT; - const unsigned char entryIndex = chanIndex / N_BITS_PER_ENTRY; - const unsigned char bitInEntry = chanIndex % N_BITS_PER_ENTRY; + constexpr uint8_t N_BITS_PER_ENTRY = sizeof(*chan) * CHAR_BIT; + const uint8_t entryIndex = chanIndex / N_BITS_PER_ENTRY; + const uint8_t bitInEntry = chanIndex % N_BITS_PER_ENTRY; return chan[entryIndex] & (1 << bitInEntry); } @@ -461,14 +461,14 @@ GPUd() bool GPUTPCCFDecodeZSLink::ChannelIsActive(const uint32_t* chan, unsigned // =========================================================================== template -GPUd() void GPUTPCCFDecodeZSLinkBase::Decode(int nBlocks, int nThreads, int iBlock, int iThread, typename Decoder::GPUSharedMemory& smem, processorType& clusterer, int firstHBF) +GPUd() void GPUTPCCFDecodeZSLinkBase::Decode(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, typename Decoder::GPUSharedMemory& smem, processorType& clusterer, int32_t firstHBF) { - const unsigned int slice = clusterer.mISlice; + const uint32_t slice = clusterer.mISlice; #ifdef GPUCA_GPUCODE - const unsigned int endpoint = clusterer.mPzsOffsets[iBlock].endpoint; + const uint32_t endpoint = clusterer.mPzsOffsets[iBlock].endpoint; #else // CPU - const unsigned int endpoint = iBlock; + const uint32_t endpoint = iBlock; #endif const GPUTrackingInOutZS::GPUTrackingInOutZSSlice& zs = clusterer.GetConstantMem()->ioPtrs.tpcZS->slice[slice]; @@ -479,22 +479,22 @@ GPUd() void GPUTPCCFDecodeZSLinkBase::Decode(int nBlocks, int nThreads, int iBlo uint32_t pageDigitOffset = clusterer.mPzsOffsets[iBlock].offset; #ifdef GPUCA_GPUCODE - const unsigned int i = 0; - const unsigned int j = clusterer.mPzsOffsets[iBlock].num; + const uint32_t i = 0; + const uint32_t j = clusterer.mPzsOffsets[iBlock].num; { { #else // CPU - for (unsigned int i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) { - const unsigned int minJ = (i == clusterer.mMinMaxCN[endpoint].zsPtrFirst) ? clusterer.mMinMaxCN[endpoint].zsPageFirst : 0; - const unsigned int maxJ = (i + 1 == clusterer.mMinMaxCN[endpoint].zsPtrLast) ? clusterer.mMinMaxCN[endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; - for (unsigned int j = minJ; j < maxJ; j++) { + for (uint32_t i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) { + const uint32_t minJ = (i == clusterer.mMinMaxCN[endpoint].zsPtrFirst) ? clusterer.mMinMaxCN[endpoint].zsPageFirst : 0; + const uint32_t maxJ = (i + 1 == clusterer.mMinMaxCN[endpoint].zsPtrLast) ? clusterer.mMinMaxCN[endpoint].zsPageLast : zs.nZSPtr[endpoint][i]; + for (uint32_t j = minJ; j < maxJ; j++) { #endif - const unsigned int* pageSrc = (const unsigned int*)(((const unsigned char*)zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE); + const uint32_t* pageSrc = (const uint32_t*)(((const uint8_t*)zs.zsPtr[endpoint][i]) + j * TPCZSHDR::TPC_ZS_PAGE_SIZE); // Cache zs page in shared memory. Curiously this actually degrades performance... - // CA_SHARED_CACHE_REF(&smem.ZSPage[0], pageSrc, TPCZSHDR::TPC_ZS_PAGE_SIZE, unsigned int, pageCache); + // CA_SHARED_CACHE_REF(&smem.ZSPage[0], pageSrc, TPCZSHDR::TPC_ZS_PAGE_SIZE, uint32_t, pageCache); // GPUbarrier(); - // const unsigned char* page = (const unsigned char*)pageCache; - const unsigned char* page = (const unsigned char*)pageSrc; + // const uint8_t* page = (const uint8_t*)pageCache; + const uint8_t* page = (const uint8_t*)pageSrc; const auto* rdHdr = Peek(page); @@ -507,8 +507,8 @@ GPUd() void GPUTPCCFDecodeZSLinkBase::Decode(int nBlocks, int nThreads, int iBlo } pageDigitOffset = Decoder::DecodePage(smem, clusterer, iBlock, nThreads, iThread, page, pageDigitOffset, firstHBF); - } // [CPU] for (unsigned int j = minJ; j < maxJ; j++) - } // [CPU] for (unsigned int i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) + } // [CPU] for (uint32_t j = minJ; j < maxJ; j++) + } // [CPU] for (uint32_t i = clusterer.mMinMaxCN[endpoint].zsPtrFirst; i < clusterer.mMinMaxCN[endpoint].zsPtrLast; i++) #ifdef GPUCA_CHECK_TPCZS_CORRUPTION if (iThread == 0 && iBlock < nBlocks - 1) { @@ -520,26 +520,26 @@ GPUd() void GPUTPCCFDecodeZSLinkBase::Decode(int nBlocks, int nThreads, int iBlo #endif } -GPUd() o2::tpc::PadPos GPUTPCCFDecodeZSLinkBase::GetPadAndRowFromFEC(processorType& clusterer, int cru, int rawFECChannel, int fecInPartition) +GPUd() o2::tpc::PadPos GPUTPCCFDecodeZSLinkBase::GetPadAndRowFromFEC(processorType& clusterer, int32_t cru, int32_t rawFECChannel, int32_t fecInPartition) { #ifdef GPUCA_TPC_GEOMETRY_O2 // Ported from tpc::Mapper (Not available on GPU...) const GPUTPCGeometry& geo = clusterer.Param().tpcGeometry; - const int regionIter = cru % 2; - const int istreamm = ((rawFECChannel % 10) / 2); - const int partitionStream = istreamm + regionIter * 5; - const int sampaOnFEC = geo.GetSampaMapping(partitionStream); - const int channel = (rawFECChannel % 2) + 2 * (rawFECChannel / 10); - const int channelOnSAMPA = channel + geo.GetChannelOffset(partitionStream); + const int32_t regionIter = cru % 2; + const int32_t istreamm = ((rawFECChannel % 10) / 2); + const int32_t partitionStream = istreamm + regionIter * 5; + const int32_t sampaOnFEC = geo.GetSampaMapping(partitionStream); + const int32_t channel = (rawFECChannel % 2) + 2 * (rawFECChannel / 10); + const int32_t channelOnSAMPA = channel + geo.GetChannelOffset(partitionStream); - const int partition = (cru % 10) / 2; - const int fecInSector = geo.GetSectorFECOffset(partition) + fecInPartition; + const int32_t partition = (cru % 10) / 2; + const int32_t fecInSector = geo.GetSectorFECOffset(partition) + fecInPartition; const TPCZSLinkMapping* gpuMapping = clusterer.GetConstantMem()->calibObjects.tpcZSLinkMapping; assert(gpuMapping != nullptr); - unsigned short globalSAMPAId = (static_cast(fecInSector) << 8) + (static_cast(sampaOnFEC) << 5) + static_cast(channelOnSAMPA); + uint16_t globalSAMPAId = (static_cast(fecInSector) << 8) + (static_cast(sampaOnFEC) << 5) + static_cast(channelOnSAMPA); const o2::tpc::PadPos pos = gpuMapping->FECIDToPadPos[globalSAMPAId]; return pos; @@ -550,7 +550,7 @@ GPUd() o2::tpc::PadPos GPUTPCCFDecodeZSLinkBase::GetPadAndRowFromFEC(processorTy GPUd() void GPUTPCCFDecodeZSLinkBase::WriteCharge(processorType& clusterer, float charge, PadPos padAndRow, TPCFragmentTime localTime, size_t positionOffset) { - const unsigned int slice = clusterer.mISlice; + const uint32_t slice = clusterer.mISlice; ChargePos* positions = clusterer.mPpositions; #ifdef GPUCA_CHECK_TPCZS_CORRUPTION if (padAndRow.getRow() >= GPUCA_ROW_COUNT) { @@ -568,9 +568,9 @@ GPUd() void GPUTPCCFDecodeZSLinkBase::WriteCharge(processorType& clusterer, floa chargeMap[pos] = PackedCharge(charge); } -GPUd() unsigned short GPUTPCCFDecodeZSLinkBase::FillWithInvalid(processorType& clusterer, int iThread, int nThreads, uint32_t pageDigitOffset, unsigned short nSamples) +GPUd() uint16_t GPUTPCCFDecodeZSLinkBase::FillWithInvalid(processorType& clusterer, int32_t iThread, int32_t nThreads, uint32_t pageDigitOffset, uint16_t nSamples) { - for (unsigned short i = iThread; i < nSamples; i += nThreads) { + for (uint16_t i = iThread; i < nSamples; i += nThreads) { clusterer.mPpositions[pageDigitOffset + i] = INVALID_CHARGE_POS; } return nSamples; @@ -583,12 +583,12 @@ GPUd() unsigned short GPUTPCCFDecodeZSLinkBase::FillWithInvalid(processorType& c // =========================================================================== template <> -GPUd() void GPUTPCCFDecodeZSDenseLink::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int firstHBF) +GPUd() void GPUTPCCFDecodeZSDenseLink::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t firstHBF) { Decode(nBlocks, nThreads, iBlock, iThread, smem, clusterer, firstHBF); } -GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, processorType& clusterer, int iBlock, int nThreads, int iThread, const unsigned char* page, uint32_t pageDigitOffset, int firstHBF) +GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, processorType& clusterer, int32_t iBlock, int32_t nThreads, int32_t iThread, const uint8_t* page, uint32_t pageDigitOffset, int32_t firstHBF) { #ifdef GPUCA_GPUCODE constexpr bool DecodeInParallel = true; @@ -596,7 +596,7 @@ GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, pro constexpr bool DecodeInParallel = false; #endif - const unsigned char* const pageStart = page; + const uint8_t* const pageStart = page; const auto* rawDataHeader = Peek(page); const auto* decHeader = Peek(page, raw::RDHUtils::getMemorySize(*rawDataHeader) - sizeof(TPCZSHDRV2)); @@ -605,23 +605,23 @@ GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, pro assert(decHeader->version >= ZSVersionDenseLinkBased); assert(decHeader->magicWord == tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader); - unsigned short nSamplesWritten = 0; - const unsigned short nSamplesInPage = decHeader->nADCsamples; + uint16_t nSamplesWritten = 0; + const uint16_t nSamplesInPage = decHeader->nADCsamples; const auto* payloadEnd = Peek(pageStart, raw::RDHUtils::getMemorySize(*rawDataHeader) - sizeof(TPCZSHDRV2) - ((decHeader->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0)); const auto* nextPage = Peek(pageStart, TPCZSHDR::TPC_ZS_PAGE_SIZE); ConsumeBytes(page, decHeader->firstZSDataOffset - sizeof(o2::header::RAWDataHeader)); - for (unsigned short i = 0; i < decHeader->nTimebinHeaders; i++) { + for (uint16_t i = 0; i < decHeader->nTimebinHeaders; i++) { [[maybe_unused]] ptrdiff_t sizeLeftInPage = payloadEnd - page; assert(sizeLeftInPage > 0); - unsigned short nSamplesWrittenTB = 0; + uint16_t nSamplesWrittenTB = 0; if (i == decHeader->nTimebinHeaders - 1 && decHeader->flags & o2::tpc::TPCZSHDRV2::ZSFlags::payloadExtendsToNextPage) { assert(o2::raw::RDHUtils::getMemorySize(*rawDataHeader) == TPCZSHDR::TPC_ZS_PAGE_SIZE); - if ((unsigned short)(raw::RDHUtils::getPageCounter(rawDataHeader) + 1) == raw::RDHUtils::getPageCounter(nextPage)) { + if ((uint16_t)(raw::RDHUtils::getPageCounter(rawDataHeader) + 1) == raw::RDHUtils::getPageCounter(nextPage)) { nSamplesWrittenTB = DecodeTB(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, decHeader->cruID, payloadEnd, nextPage); } else { nSamplesWrittenTB = FillWithInvalid(clusterer, iThread, nThreads, pageDigitOffset, nSamplesInPage - nSamplesWritten); @@ -638,7 +638,7 @@ GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, pro assert(nSamplesWritten <= nSamplesInPage); nSamplesWritten += nSamplesWrittenTB; pageDigitOffset += nSamplesWrittenTB; - } // for (unsigned short i = 0; i < decHeader->nTimebinHeaders; i++) + } // for (uint16_t i = 0; i < decHeader->nTimebinHeaders; i++) #ifdef GPUCA_CHECK_TPCZS_CORRUPTION if (iThread == 0 && nSamplesWritten != nSamplesInPage) { @@ -655,23 +655,23 @@ GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, pro } template -GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTB( +GPUd() uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTB( processorType& clusterer, [[maybe_unused]] GPUSharedMemory& smem, - int iThread, - const unsigned char*& page, + int32_t iThread, + const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, - int firstHBF, - int cru, - [[maybe_unused]] const unsigned char* payloadEnd, - [[maybe_unused]] const unsigned char* nextPage) + int32_t firstHBF, + int32_t cru, + [[maybe_unused]] const uint8_t* payloadEnd, + [[maybe_unused]] const uint8_t* nextPage) { if CONSTEXPR (DecodeInParallel) { return DecodeTBMultiThread(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, cru, payloadEnd, nextPage); } else { - unsigned short nSamplesWritten = 0; + uint16_t nSamplesWritten = 0; if (iThread == 0) { nSamplesWritten = DecodeTBSingleThread(clusterer, page, pageDigitOffset, rawDataHeader, firstHBF, cru, payloadEnd, nextPage); } @@ -680,17 +680,17 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTB( } template -GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( +GPUd() uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( processorType& clusterer, GPUSharedMemory& smem, - const int iThread, - const unsigned char*& page, + const int32_t iThread, + const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, - int firstHBF, - int cru, - [[maybe_unused]] const unsigned char* payloadEnd, - [[maybe_unused]] const unsigned char* nextPage) + int32_t firstHBF, + int32_t cru, + [[maybe_unused]] const uint8_t* payloadEnd, + [[maybe_unused]] const uint8_t* nextPage) { #define MAYBE_PAGE_OVERFLOW(pagePtr) \ if CONSTEXPR (PayloadExtendsToNextPage) { \ @@ -710,28 +710,28 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( #define TEST_BIT(x, bit) static_cast((x) & (1 << (bit))) - constexpr int NTHREADS = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDecodeZSDenseLink); + constexpr int32_t NTHREADS = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDecodeZSDenseLink); static_assert(NTHREADS == GPUCA_WARP_SIZE, "Decoding TB Headers in parallel assumes block size is a single warp."); const CfFragment& fragment = clusterer.mPmemory->fragment; // Read timebin block header - unsigned short tbbHdr = ConsumeByte(page); + uint16_t tbbHdr = ConsumeByte(page); MAYBE_PAGE_OVERFLOW(page); - tbbHdr |= static_cast(ConsumeByte(page)) << CHAR_BIT; + tbbHdr |= static_cast(ConsumeByte(page)) << CHAR_BIT; MAYBE_PAGE_OVERFLOW(page); - unsigned char nLinksInTimebin = tbbHdr & 0x000F; - unsigned short linkBC = (tbbHdr & 0xFFF0) >> 4; - int timeBin = (linkBC + (unsigned long)(raw::RDHUtils::getHeartBeatOrbit(*rawDataHeader) - firstHBF) * constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + uint8_t nLinksInTimebin = tbbHdr & 0x000F; + uint16_t linkBC = (tbbHdr & 0xFFF0) >> 4; + int32_t timeBin = (linkBC + (uint64_t)(raw::RDHUtils::getHeartBeatOrbit(*rawDataHeader) - firstHBF) * constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; - unsigned short nSamplesInTB = 0; + uint16_t nSamplesInTB = 0; GPUbarrier(); // Read timebin link headers - for (unsigned char iLink = 0; iLink < nLinksInTimebin; iLink++) { - unsigned char timebinLinkHeaderStart = ConsumeByte(page); + for (uint8_t iLink = 0; iLink < nLinksInTimebin; iLink++) { + uint8_t timebinLinkHeaderStart = ConsumeByte(page); MAYBE_PAGE_OVERFLOW(page); if (iThread == 0) { @@ -739,26 +739,26 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( } bool bitmaskIsFlat = timebinLinkHeaderStart & 0b00100000; - unsigned short bitmaskL2 = 0x03FF; + uint16_t bitmaskL2 = 0x03FF; if (not bitmaskIsFlat) { - bitmaskL2 = static_cast(timebinLinkHeaderStart & 0b11000000) << 2 | static_cast(ConsumeByte(page)); + bitmaskL2 = static_cast(timebinLinkHeaderStart & 0b11000000) << 2 | static_cast(ConsumeByte(page)); MAYBE_PAGE_OVERFLOW(page); } - int nBytesBitmask = CAMath::Popcount(bitmaskL2); + int32_t nBytesBitmask = CAMath::Popcount(bitmaskL2); assert(nBytesBitmask <= 10); - for (int chan = iThread; chan < CAMath::nextMultipleOf(80); chan += NTHREADS) { - int chanL2Idx = chan / 8; + for (int32_t chan = iThread; chan < CAMath::nextMultipleOf(80); chan += NTHREADS) { + int32_t chanL2Idx = chan / 8; bool l2 = TEST_BIT(bitmaskL2, chanL2Idx); - int chanByteOffset = nBytesBitmask - 1 - CAMath::Popcount(bitmaskL2 >> (chanL2Idx + 1)); + int32_t chanByteOffset = nBytesBitmask - 1 - CAMath::Popcount(bitmaskL2 >> (chanL2Idx + 1)); - unsigned char myChannelHasData = (chan < 80 && l2 ? TEST_BIT(PEEK_OVERFLOW(page, chanByteOffset), chan % 8) : 0); + uint8_t myChannelHasData = (chan < 80 && l2 ? TEST_BIT(PEEK_OVERFLOW(page, chanByteOffset), chan % 8) : 0); assert(myChannelHasData == 0 || myChannelHasData == 1); - int nSamplesStep; - int threadSampleOffset = CfUtils::warpPredicateScan(myChannelHasData, &nSamplesStep); + int32_t nSamplesStep; + int32_t threadSampleOffset = CfUtils::warpPredicateScan(myChannelHasData, &nSamplesStep); if (myChannelHasData) { smem.rawFECChannels[nSamplesInTB + threadSampleOffset] = chan; @@ -774,9 +774,9 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( smem.samplesPerLinkEnd[iLink] = nSamplesInTB; } - } // for (unsigned char iLink = 0; iLink < nLinksInTimebin; iLink++) + } // for (uint8_t iLink = 0; iLink < nLinksInTimebin; iLink++) - const unsigned char* adcData = ConsumeBytes(page, (nSamplesInTB * DECODE_BITS + 7) / 8); + const uint8_t* adcData = ConsumeBytes(page, (nSamplesInTB * DECODE_BITS + 7) / 8); MAYBE_PAGE_OVERFLOW(page); // TODO: We don't need this check? if (not fragment.contains(timeBin)) { @@ -786,19 +786,19 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( GPUbarrier(); // Unpack ADC - int iLink = 0; - for (unsigned short sample = iThread; sample < nSamplesInTB; sample += NTHREADS) { - const unsigned short adcBitOffset = sample * DECODE_BITS; - unsigned short adcByteOffset = adcBitOffset / CHAR_BIT; - const unsigned char adcOffsetInByte = adcBitOffset - adcByteOffset * CHAR_BIT; + int32_t iLink = 0; + for (uint16_t sample = iThread; sample < nSamplesInTB; sample += NTHREADS) { + const uint16_t adcBitOffset = sample * DECODE_BITS; + uint16_t adcByteOffset = adcBitOffset / CHAR_BIT; + const uint8_t adcOffsetInByte = adcBitOffset - adcByteOffset * CHAR_BIT; - unsigned char bits = 0; - unsigned short byte = 0; + uint8_t bits = 0; + uint16_t byte = 0; - static_assert(DECODE_BITS <= sizeof(unsigned short) * CHAR_BIT); + static_assert(DECODE_BITS <= sizeof(uint16_t) * CHAR_BIT); while (bits < DECODE_BITS) { - byte |= static_cast(PEEK_OVERFLOW(adcData, adcByteOffset)) << bits; + byte |= static_cast(PEEK_OVERFLOW(adcData, adcByteOffset)) << bits; adcByteOffset++; bits += CHAR_BIT; } @@ -808,7 +808,7 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( iLink++; } - int rawFECChannelLink = smem.rawFECChannels[sample]; + int32_t rawFECChannelLink = smem.rawFECChannels[sample]; // Unpack data for cluster finder o2::tpc::PadPos padAndRow = GetPadAndRowFromFEC(clusterer, cru, rawFECChannelLink, smem.linkIds[iLink]); @@ -816,7 +816,7 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( float charge = ADCToFloat(byte, DECODE_MASK, DECODE_BITS_FACTOR); WriteCharge(clusterer, charge, padAndRow, fragment.toLocal(timeBin), pageDigitOffset + sample); - } // for (unsigned short sample = iThread; sample < nSamplesInTB; sample += NTHREADS) + } // for (uint16_t sample = iThread; sample < nSamplesInTB; sample += NTHREADS) assert(PayloadExtendsToNextPage || adcData <= page); assert(PayloadExtendsToNextPage || page <= payloadEnd); @@ -829,15 +829,15 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread( } template -GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( +GPUd() uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( processorType& clusterer, - const unsigned char*& page, + const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, - int firstHBF, - int cru, - [[maybe_unused]] const unsigned char* payloadEnd, - [[maybe_unused]] const unsigned char* nextPage) + int32_t firstHBF, + int32_t cru, + [[maybe_unused]] const uint8_t* payloadEnd, + [[maybe_unused]] const uint8_t* nextPage) { #define MAYBE_PAGE_OVERFLOW(pagePtr) \ if CONSTEXPR (PayloadExtendsToNextPage) { \ @@ -854,38 +854,38 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( const CfFragment& fragment = clusterer.mPmemory->fragment; - unsigned char linkIds[MaxNLinksPerTimebin]; - unsigned char channelMasks[MaxNLinksPerTimebin * 10] = {0}; - unsigned short nSamplesWritten = 0; + uint8_t linkIds[MaxNLinksPerTimebin]; + uint8_t channelMasks[MaxNLinksPerTimebin * 10] = {0}; + uint16_t nSamplesWritten = 0; // Read timebin block header - unsigned short tbbHdr = ConsumeByte(page); + uint16_t tbbHdr = ConsumeByte(page); MAYBE_PAGE_OVERFLOW(page); - tbbHdr |= static_cast(ConsumeByte(page)) << CHAR_BIT; + tbbHdr |= static_cast(ConsumeByte(page)) << CHAR_BIT; MAYBE_PAGE_OVERFLOW(page); - unsigned char nLinksInTimebin = tbbHdr & 0x000F; - unsigned short linkBC = (tbbHdr & 0xFFF0) >> 4; - int timeBin = (linkBC + (unsigned long)(raw::RDHUtils::getHeartBeatOrbit(*rawDataHeader) - firstHBF) * constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; + uint8_t nLinksInTimebin = tbbHdr & 0x000F; + uint16_t linkBC = (tbbHdr & 0xFFF0) >> 4; + int32_t timeBin = (linkBC + (uint64_t)(raw::RDHUtils::getHeartBeatOrbit(*rawDataHeader) - firstHBF) * constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN; - unsigned short nSamplesInTB = 0; + uint16_t nSamplesInTB = 0; // Read timebin link headers - for (unsigned char iLink = 0; iLink < nLinksInTimebin; iLink++) { - unsigned char timebinLinkHeaderStart = ConsumeByte(page); + for (uint8_t iLink = 0; iLink < nLinksInTimebin; iLink++) { + uint8_t timebinLinkHeaderStart = ConsumeByte(page); MAYBE_PAGE_OVERFLOW(page); linkIds[iLink] = timebinLinkHeaderStart & 0b00011111; bool bitmaskIsFlat = timebinLinkHeaderStart & 0b00100000; - unsigned short bitmaskL2 = 0x0FFF; + uint16_t bitmaskL2 = 0x0FFF; if (not bitmaskIsFlat) { - bitmaskL2 = static_cast(timebinLinkHeaderStart & 0b11000000) << 2 | static_cast(ConsumeByte(page)); + bitmaskL2 = static_cast(timebinLinkHeaderStart & 0b11000000) << 2 | static_cast(ConsumeByte(page)); MAYBE_PAGE_OVERFLOW(page); } - for (int i = 0; i < 10; i++) { + for (int32_t i = 0; i < 10; i++) { if (bitmaskL2 & 1 << i) { nSamplesInTB += CAMath::Popcount(*Peek(page)); channelMasks[10 * iLink + i] = ConsumeByte(page); @@ -893,9 +893,9 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( } } - } // for (unsigned char iLink = 0; iLink < nLinksInTimebin; iLink++) + } // for (uint8_t iLink = 0; iLink < nLinksInTimebin; iLink++) - const unsigned char* adcData = ConsumeBytes(page, (nSamplesInTB * DECODE_BITS + 7) / 8); + const uint8_t* adcData = ConsumeBytes(page, (nSamplesInTB * DECODE_BITS + 7) / 8); MAYBE_PAGE_OVERFLOW(page); if (not fragment.contains(timeBin)) { @@ -904,12 +904,12 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( } // Unpack ADC - unsigned int byte = 0, bits = 0; - unsigned short rawFECChannel = 0; + uint32_t byte = 0, bits = 0; + uint16_t rawFECChannel = 0; // unpack adc values, assume tightly packed data while (nSamplesWritten < nSamplesInTB) { - byte |= static_cast(ConsumeByte(adcData)) << bits; + byte |= static_cast(ConsumeByte(adcData)) << bits; MAYBE_PAGE_OVERFLOW(adcData); bits += CHAR_BIT; while (bits >= DECODE_BITS) { @@ -918,8 +918,8 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( for (; !ChannelIsActive(channelMasks, rawFECChannel); rawFECChannel++) { } - int iLink = rawFECChannel / ChannelPerTBHeader; - int rawFECChannelLink = rawFECChannel % ChannelPerTBHeader; + int32_t iLink = rawFECChannel / ChannelPerTBHeader; + int32_t rawFECChannelLink = rawFECChannel % ChannelPerTBHeader; // Unpack data for cluster finder o2::tpc::PadPos padAndRow = GetPadAndRowFromFEC(clusterer, cru, rawFECChannelLink, linkIds[iLink]); @@ -943,10 +943,10 @@ GPUd() unsigned short GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread( #undef MAYBE_PAGE_OVERFLOW } -GPUd() bool GPUTPCCFDecodeZSDenseLink::ChannelIsActive(const uint8_t* chan, unsigned short chanIndex) +GPUd() bool GPUTPCCFDecodeZSDenseLink::ChannelIsActive(const uint8_t* chan, uint16_t chanIndex) { - constexpr unsigned char N_BITS_PER_ENTRY = sizeof(*chan) * CHAR_BIT; - const unsigned char entryIndex = chanIndex / N_BITS_PER_ENTRY; - const unsigned char bitInEntry = chanIndex % N_BITS_PER_ENTRY; + constexpr uint8_t N_BITS_PER_ENTRY = sizeof(*chan) * CHAR_BIT; + const uint8_t entryIndex = chanIndex / N_BITS_PER_ENTRY; + const uint8_t bitInEntry = chanIndex % N_BITS_PER_ENTRY; return chan[entryIndex] & (1 << bitInEntry); } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h index 0b393d2d547b0..3d5f4dd4380d4 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h @@ -31,21 +31,21 @@ class GPUTPCClusterFinder; class GPUTPCCFDecodeZS : public GPUKernelTemplate { public: - struct GPUSharedMemory /*: public GPUKernelTemplate::GPUSharedMemoryScan64*/ { - CA_SHARED_STORAGE(unsigned int ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned int)]); - unsigned int RowClusterOffset[o2::tpc::TPCZSHDR::TPC_MAX_ZS_ROW_IN_ENDPOINT]; - unsigned int nRowsRegion; - unsigned int regionStartRow; - unsigned int nThreadsPerRow; - unsigned int rowStride; - GPUAtomic(unsigned int) rowOffsetCounter; + struct GPUSharedMemory /*: public GPUKernelTemplate::GPUSharedMemoryScan64*/ { + CA_SHARED_STORAGE(uint32_t ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint32_t)]); + uint32_t RowClusterOffset[o2::tpc::TPCZSHDR::TPC_MAX_ZS_ROW_IN_ENDPOINT]; + uint32_t nRowsRegion; + uint32_t regionStartRow; + uint32_t nThreadsPerRow; + uint32_t rowStride; + GPUAtomic(uint32_t) rowOffsetCounter; }; - enum K : int { + enum K : int32_t { decodeZS, }; - static GPUd() void decode(GPUTPCClusterFinder& clusterer, GPUSharedMemory& s, int nBlocks, int nThreads, int iBlock, int iThread, int firstHBF); + static GPUd() void decode(GPUTPCClusterFinder& clusterer, GPUSharedMemory& s, int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, int32_t firstHBF); #ifdef GPUCA_HAVE_O2HEADERS typedef GPUTPCClusterFinder processorType; @@ -60,8 +60,8 @@ class GPUTPCCFDecodeZS : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); }; class GPUTPCCFDecodeZSLinkBase : public GPUKernelTemplate @@ -82,33 +82,33 @@ class GPUTPCCFDecodeZSLinkBase : public GPUKernelTemplate } template - GPUd() static void Decode(int nBlocks, int nThreads, int iBlock, int iThread, typename Decoder::GPUSharedMemory& smem, processorType& clusterer, int firstHBF); + GPUd() static void Decode(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, typename Decoder::GPUSharedMemory& smem, processorType& clusterer, int32_t firstHBF); - GPUd() static o2::tpc::PadPos GetPadAndRowFromFEC(processorType& clusterer, int cru, int rawFecChannel, int fecInPartition); + GPUd() static o2::tpc::PadPos GetPadAndRowFromFEC(processorType& clusterer, int32_t cru, int32_t rawFecChannel, int32_t fecInPartition); GPUd() static void WriteCharge(processorType& clusterer, float charge, o2::tpc::PadPos pos, tpccf::TPCFragmentTime localTime, size_t positionOffset); - GPUd() static unsigned short FillWithInvalid(processorType& clusterer, int iThread, int nThreads, uint32_t pageDigitOffset, unsigned short nSamples); + GPUd() static uint16_t FillWithInvalid(processorType& clusterer, int32_t iThread, int32_t nThreads, uint32_t pageDigitOffset, uint16_t nSamples); - GPUdi() static const unsigned char* ConsumeBytes(const unsigned char*& page, size_t nbytes) + GPUdi() static const uint8_t* ConsumeBytes(const uint8_t*& page, size_t nbytes) { - const unsigned char* oldPage = page; + const uint8_t* oldPage = page; page += nbytes; return oldPage; } - GPUdi() static unsigned char ConsumeByte(const unsigned char*& page) + GPUdi() static uint8_t ConsumeByte(const uint8_t*& page) { return *(page++); } template - GPUdi() static const T* ConsumeHeader(const unsigned char*& page) + GPUdi() static const T* ConsumeHeader(const uint8_t*& page) { assert(size_t(page) % alignof(T) == 0); return reinterpret_cast(ConsumeBytes(page, sizeof(T))); } - template - GPUdi() static const T* Peek(const unsigned char* page, ptrdiff_t offset = 0) + template + GPUdi() static const T* Peek(const uint8_t* page, ptrdiff_t offset = 0) { // if ((size_t(page) + offset) % alignof(T) != 0) { // printf("page = %zu, offset = %zu, alignof = %zu\n", size_t(page), offset, alignof(T)); @@ -117,7 +117,7 @@ class GPUTPCCFDecodeZSLinkBase : public GPUKernelTemplate return reinterpret_cast(page + offset); } - GPUdi() static float ADCToFloat(unsigned int adc, unsigned int decodeMask, float decodeBitsFactor) + GPUdi() static float ADCToFloat(uint32_t adc, uint32_t decodeMask, float decodeBitsFactor) { return float(adc & decodeMask) * decodeBitsFactor; } @@ -127,58 +127,58 @@ class GPUTPCCFDecodeZSLink : public GPUTPCCFDecodeZSLinkBase { public: // constants for decoding - static inline constexpr int DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34; + static inline constexpr int32_t DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34; static inline constexpr float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10)); - static inline constexpr unsigned int DECODE_MASK = (1 << DECODE_BITS) - 1; + static inline constexpr uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1; - struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 { - // CA_SHARED_STORAGE(unsigned int ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned int)]); + struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 { + // CA_SHARED_STORAGE(uint32_t ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint32_t)]); }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); - GPUd() static size_t DecodePage(GPUSharedMemory& smem, processorType& clusterer, int iBlock, int nThreads, int iThread, const unsigned char* page, uint32_t pageDigitOffset, int firstHBF); + GPUd() static size_t DecodePage(GPUSharedMemory& smem, processorType& clusterer, int32_t iBlock, int32_t nThreads, int32_t iThread, const uint8_t* page, uint32_t pageDigitOffset, int32_t firstHBF); GPUd() static void GetChannelBitmask(const tpc::zerosupp_link_based::CommonHeader& tbHdr, uint32_t* chan); - GPUd() static bool ChannelIsActive(const uint32_t* chan, unsigned char chanIndex); + GPUd() static bool ChannelIsActive(const uint32_t* chan, uint8_t chanIndex); - GPUd() static void DecodeTBSingleThread(processorType& clusterer, const unsigned char* adcData, unsigned int nAdc, const uint32_t* channelMask, int timeBin, int cru, int fecInPartition, uint32_t pageDigitOffset); - GPUd() static void DecodeTBMultiThread(processorType& clusterer, int iThread, GPUSharedMemory& smem, const unsigned char* adcData, unsigned int nAdc, const uint32_t* channelMask, int timeBin, int cru, int fecInPartition, uint32_t pageDigitOffset); + GPUd() static void DecodeTBSingleThread(processorType& clusterer, const uint8_t* adcData, uint32_t nAdc, const uint32_t* channelMask, int32_t timeBin, int32_t cru, int32_t fecInPartition, uint32_t pageDigitOffset); + GPUd() static void DecodeTBMultiThread(processorType& clusterer, int32_t iThread, GPUSharedMemory& smem, const uint8_t* adcData, uint32_t nAdc, const uint32_t* channelMask, int32_t timeBin, int32_t cru, int32_t fecInPartition, uint32_t pageDigitOffset); }; class GPUTPCCFDecodeZSDenseLink : public GPUTPCCFDecodeZSLinkBase { public: // constants for decoding - static inline constexpr int DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34; + static inline constexpr int32_t DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34; static inline constexpr float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10)); - static inline constexpr unsigned int DECODE_MASK = (1 << DECODE_BITS) - 1; + static inline constexpr uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1; - static inline constexpr int MaxNLinksPerTimebin = 16; + static inline constexpr int32_t MaxNLinksPerTimebin = 16; - struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 { - // CA_SHARED_STORAGE(unsigned int ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(unsigned int)]); - unsigned short samplesPerLinkEnd[MaxNLinksPerTimebin]; // Offset from end of TB link header to first sample not in this link - unsigned char linkIds[MaxNLinksPerTimebin]; - unsigned char rawFECChannels[MaxNLinksPerTimebin * 80]; + struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 { + // CA_SHARED_STORAGE(uint32_t ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint32_t)]); + uint16_t samplesPerLinkEnd[MaxNLinksPerTimebin]; // Offset from end of TB link header to first sample not in this link + uint8_t linkIds[MaxNLinksPerTimebin]; + uint8_t rawFECChannels[MaxNLinksPerTimebin * 80]; }; - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); - GPUd() static uint32_t DecodePage(GPUSharedMemory& smem, processorType& clusterer, int iBlock, int nThreads, int iThread, const unsigned char* page, uint32_t pageDigitOffset, int firstHBF); + GPUd() static uint32_t DecodePage(GPUSharedMemory& smem, processorType& clusterer, int32_t iBlock, int32_t nThreads, int32_t iThread, const uint8_t* page, uint32_t pageDigitOffset, int32_t firstHBF); - GPUd() static bool ChannelIsActive(const uint8_t* chan, unsigned short chanIndex); + GPUd() static bool ChannelIsActive(const uint8_t* chan, uint16_t chanIndex); template - GPUd() static unsigned short DecodeTB(processorType& clusterer, GPUSharedMemory& smem, int iThread, const unsigned char*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int firstHBF, int cru, const unsigned char* payloadEnd, const unsigned char* nextPage); + GPUd() static uint16_t DecodeTB(processorType& clusterer, GPUSharedMemory& smem, int32_t iThread, const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int32_t firstHBF, int32_t cru, const uint8_t* payloadEnd, const uint8_t* nextPage); template - GPUd() static unsigned short DecodeTBSingleThread(processorType& clusterer, const unsigned char*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int firstHBF, int cru, const unsigned char* payloadEnd, const unsigned char* nextPage); + GPUd() static uint16_t DecodeTBSingleThread(processorType& clusterer, const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int32_t firstHBF, int32_t cru, const uint8_t* payloadEnd, const uint8_t* nextPage); template - GPUd() static unsigned short DecodeTBMultiThread(processorType& clusterer, GPUSharedMemory& smem, const int iThread, const unsigned char*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int firstHBF, int cru, const unsigned char* payloadEnd, const unsigned char* nextPage); + GPUd() static uint16_t DecodeTBMultiThread(processorType& clusterer, GPUSharedMemory& smem, const int32_t iThread, const uint8_t*& page, uint32_t pageDigitOffset, const header::RAWDataHeader* rawDataHeader, int32_t firstHBF, int32_t cru, const uint8_t* payloadEnd, const uint8_t* nextPage); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx index 18fffd46d707f..7444fd4e639a2 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx @@ -22,14 +22,14 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFDeconvolution::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFDeconvolution::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); Array2D isPeakMap(clusterer.mPpeakMap); GPUTPCCFDeconvolution::deconvolutionImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), smem, isPeakMap, chargeMap, clusterer.mPpositions, clusterer.mPmemory->counters.nPositions); } -GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, +GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, const Array2D& peakMap, Array2D& chargeMap, const ChargePos* positions, @@ -44,7 +44,7 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int nBlocks, int nThreads bool iamPeak = CfUtils::isPeak(peakMap[pos]); - char peakCount = (iamPeak) ? 1 : 0; + int8_t peakCount = (iamPeak) ? 1 : 0; ushort ll = get_local_id(0); ushort partId = ll; @@ -105,7 +105,7 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int nBlocks, int nThreads } bool has3x3 = (peakCount > 0); - peakCount = CAMath::Abs(int(peakCount)); + peakCount = CAMath::Abs(int32_t(peakCount)); bool split = (peakCount > 1); peakCount = (peakCount == 0) ? 1 : peakCount; @@ -116,12 +116,12 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int nBlocks, int nThreads chargeMap[pos] = p; } -GPUdi() char GPUTPCCFDeconvolution::countPeaksInner( +GPUdi() uint8_t GPUTPCCFDeconvolution::countPeaksInner( ushort ll, const uchar* isPeak, uchar* aboveThreshold) { - char peaks = 0; + uint8_t peaks = 0; GPUCA_UNROLL(U(), U()) for (uchar i = 0; i < 8; i++) { uchar p = isPeak[ll * 8 + i]; @@ -132,12 +132,12 @@ GPUdi() char GPUTPCCFDeconvolution::countPeaksInner( return peaks; } -GPUdi() char GPUTPCCFDeconvolution::countPeaksOuter( +GPUdi() uint8_t GPUTPCCFDeconvolution::countPeaksOuter( ushort ll, uchar aboveThreshold, const uchar* isPeak) { - char peaks = 0; + uint8_t peaks = 0; GPUCA_UNROLL(U(), U()) for (uchar i = 0; i < 16; i++) { uchar p = isPeak[ll * 16 + i]; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h index e7371b1cb83f6..55753f163f482 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h @@ -30,7 +30,7 @@ class GPUTPCCFDeconvolution : public GPUKernelTemplate { public: static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDeconvolution); - struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { ChargePos posBcast1[SCRATCH_PAD_WORK_GROUP_SIZE]; uchar aboveThresholdBcast[SCRATCH_PAD_WORK_GROUP_SIZE]; uchar buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_COUNT_N]; @@ -49,14 +49,14 @@ class GPUTPCCFDeconvolution : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void deconvolutionImpl(int, int, int, int, GPUSharedMemory&, const Array2D&, Array2D&, const ChargePos*, const uint); + static GPUd() void deconvolutionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, Array2D&, const ChargePos*, const uint); - static GPUdi() char countPeaksInner(ushort, const uchar*, uchar*); - static GPUdi() char countPeaksOuter(ushort, uchar, const uchar*); + static GPUdi() uint8_t countPeaksInner(ushort, const uchar*, uchar*); + static GPUdi() uint8_t countPeaksOuter(ushort, uchar, const uchar*); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.cxx index 41174f8622bbc..baba573b67aa8 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.cxx @@ -17,12 +17,12 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFGather::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, o2::tpc::ClusterNative* ptr) +GPUdii() void GPUTPCCFGather::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, o2::tpc::ClusterNative* ptr) { - for (int i = 0; i < iBlock; i++) { + for (int32_t i = 0; i < iBlock; i++) { ptr += clusterer.mPclusterInRow[i]; } - for (unsigned int i = iThread; i < clusterer.mPclusterInRow[iBlock]; i += nThreads) { + for (uint32_t i = iThread; i < clusterer.mPclusterInRow[iBlock]; i += nThreads) { ptr[i] = clusterer.mPclusterByRow[iBlock * clusterer.mNMaxClusterPerRow + i]; } } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.h index 0917409e01a40..681c3c9b5c380 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFGather.h @@ -39,8 +39,8 @@ class GPUTPCCFGather : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx index ebc87f6fc8fb2..510c651a8671d 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx @@ -43,7 +43,7 @@ void GPUTPCCFMCLabelFlattener::setGlobalOffsetsAndAllocate( #endif template <> -GPUd() void GPUTPCCFMCLabelFlattener::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory&, processorType& clusterer) +GPUd() void GPUTPCCFMCLabelFlattener::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory&, processorType& clusterer) { #if !defined(GPUCA_GPUCODE) Row row = get_global_id(0); @@ -61,7 +61,7 @@ GPUd() void GPUTPCCFMCLabelFlattener::Thread -GPUd() void GPUTPCCFMCLabelFlattener::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory&, processorType& clusterer, GPUTPCLinearLabels* out) +GPUd() void GPUTPCCFMCLabelFlattener::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory&, processorType& clusterer, GPUTPCLinearLabels* out) { #if !defined(GPUCA_GPUCODE) uint row = get_global_id(0); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.h index 0fa1810cd6ea3..bb1473ec832df 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.h @@ -33,7 +33,7 @@ class GPUTPCCFMCLabelFlattener : public GPUKernelTemplate struct GPUSharedMemory { }; - enum K : int { + enum K : int32_t { setRowOffsets, flatten, }; @@ -51,8 +51,8 @@ class GPUTPCCFMCLabelFlattener : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); static void setGlobalOffsetsAndAllocate(GPUTPCClusterFinder&, GPUTPCLinearLabels&); }; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx index ec24ac6d6b84b..9307a53a24d90 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx @@ -22,7 +22,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFNoiseSuppression::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFNoiseSuppression::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); Array2D isPeakMap(clusterer.mPpeakMap); @@ -30,13 +30,13 @@ GPUdii() void GPUTPCCFNoiseSuppression::Thread -GPUdii() void GPUTPCCFNoiseSuppression::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFNoiseSuppression::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D isPeakMap(clusterer.mPpeakMap); updatePeaksImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer.mPpeakPositions, clusterer.mPisPeak, clusterer.mPmemory->counters.nPeaks, isPeakMap); } -GPUdii() void GPUTPCCFNoiseSuppression::noiseSuppressionImpl(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, +GPUdii() void GPUTPCCFNoiseSuppression::noiseSuppressionImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, const GPUSettingsRec& calibration, const Array2D& chargeMap, const Array2D& peakMap, @@ -74,7 +74,7 @@ GPUdii() void GPUTPCCFNoiseSuppression::noiseSuppressionImpl(int nBlocks, int nT isPeakPredicate[idx] = keepMe; } -GPUd() void GPUTPCCFNoiseSuppression::updatePeaksImpl(int nBlocks, int nThreads, int iBlock, int iThread, +GPUd() void GPUTPCCFNoiseSuppression::updatePeaksImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const ChargePos* peakPositions, const uchar* isPeak, const uint peakNum, @@ -99,7 +99,7 @@ GPUdi() void GPUTPCCFNoiseSuppression::checkForMinima( const float epsilon, const float epsilonRelative, PackedCharge other, - int pos, + int32_t pos, ulong* minimas, ulong* bigger) { @@ -115,8 +115,8 @@ GPUdi() void GPUTPCCFNoiseSuppression::checkForMinima( GPUdi() void GPUTPCCFNoiseSuppression::findMinima( const PackedCharge* buf, const ushort ll, - const int N, - int pos, + const int32_t N, + int32_t pos, const float q, const float epsilon, const float epsilonRelative, @@ -124,7 +124,7 @@ GPUdi() void GPUTPCCFNoiseSuppression::findMinima( ulong* bigger) { GPUCA_UNROLL(U(), U()) - for (int i = 0; i < N; i++, pos++) { + for (int32_t i = 0; i < N; i++, pos++) { PackedCharge other = buf[N * ll + i]; checkForMinima(q, epsilon, epsilonRelative, other, pos, minimas, bigger); @@ -134,12 +134,12 @@ GPUdi() void GPUTPCCFNoiseSuppression::findMinima( GPUdi() void GPUTPCCFNoiseSuppression::findPeaks( const uchar* buf, const ushort ll, - const int N, - int pos, + const int32_t N, + int32_t pos, ulong* peaks) { GPUCA_UNROLL(U(), U()) - for (int i = 0; i < N; i++, pos++) { + for (int32_t i = 0; i < N; i++, pos++) { ulong p = CfUtils::isPeak(buf[N * ll + i]); *peaks |= (p << pos); @@ -153,7 +153,7 @@ GPUdi() bool GPUTPCCFNoiseSuppression::keepPeak( bool keepMe = true; GPUCA_UNROLL(U(), U()) - for (int i = 0; i < NOISE_SUPPRESSION_NEIGHBOR_NUM; i++) { + for (int32_t i = 0; i < NOISE_SUPPRESSION_NEIGHBOR_NUM; i++) { bool otherPeak = (peaks & (ulong(1) << i)); bool minimaBetween = (minima & cfconsts::NoiseSuppressionMinima[i]); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h index f37ff8377960f..83f5c062fe08a 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h @@ -30,7 +30,7 @@ struct ChargePos; class GPUTPCCFNoiseSuppression : public GPUKernelTemplate { public: - enum K : int { + enum K : int32_t { noiseSuppression = 0, updatePeaks = 1, }; @@ -53,19 +53,19 @@ class GPUTPCCFNoiseSuppression : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void noiseSuppressionImpl(int, int, int, int, GPUSharedMemory&, const GPUSettingsRec&, const Array2D&, const Array2D&, const ChargePos*, const uint, uchar*); + static GPUd() void noiseSuppressionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const GPUSettingsRec&, const Array2D&, const Array2D&, const ChargePos*, const uint, uchar*); - static GPUd() void updatePeaksImpl(int, int, int, int, const ChargePos*, const uchar*, const uint, Array2D&); + static GPUd() void updatePeaksImpl(int32_t, int32_t, int32_t, int32_t, const ChargePos*, const uchar*, const uint, Array2D&); - static GPUdi() void checkForMinima(const float, const float, const float, PackedCharge, int, ulong*, ulong*); + static GPUdi() void checkForMinima(const float, const float, const float, PackedCharge, int32_t, ulong*, ulong*); - static GPUdi() void findMinima(const PackedCharge*, const ushort, const int, int, const float, const float, const float, ulong*, ulong*); + static GPUdi() void findMinima(const PackedCharge*, const ushort, const int32_t, int32_t, const float, const float, const float, ulong*, ulong*); - static GPUdi() void findPeaks(const uchar*, const ushort, const int, int, ulong*); + static GPUdi() void findPeaks(const uchar*, const ushort, const int32_t, int32_t, ulong*); static GPUdi() bool keepPeak(ulong, ulong); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx index cc7e0daed1476..6e2f67fee0d37 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx @@ -23,7 +23,7 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFPeakFinder::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer) +GPUdii() void GPUTPCCFPeakFinder::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); Array2D isPeakMap(clusterer.mPpeakMap); @@ -72,11 +72,11 @@ GPUdii() bool GPUTPCCFPeakFinder::isPeak( return false; } - // Ensure q has the same float->int->float conversion error + // Ensure q has the same float->int32_t->float conversion error // as values in chargeMap, so identical charges are actually identical q = PackedCharge(q).unpack(); - int idx = N * partId; + int32_t idx = N * partId; bool peak = true; peak = peak && buf[idx + 0].unpack() <= q; peak = peak && buf[idx + 1].unpack() <= q; @@ -90,7 +90,7 @@ GPUdii() bool GPUTPCCFPeakFinder::isPeak( return peak; } -GPUd() void GPUTPCCFPeakFinder::findPeaksImpl(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, +GPUd() void GPUTPCCFPeakFinder::findPeaksImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, const Array2D& chargeMap, const uchar* padHasLostBaseline, const ChargePos* positions, diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h index 9f532dac82ada..0383e8a4d13e1 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h @@ -31,7 +31,7 @@ class GPUTPCCFPeakFinder : public GPUKernelTemplate { public: static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFPeakFinder); - struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { ChargePos posBcast[SCRATCH_PAD_WORK_GROUP_SIZE]; PackedCharge buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_SEARCH_N]; }; @@ -49,11 +49,11 @@ class GPUTPCCFPeakFinder : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void findPeaksImpl(int, int, int, int, GPUSharedMemory&, const Array2D&, const uchar*, const ChargePos*, tpccf::SizeT, const GPUSettingsRec&, const TPCPadGainCalib&, uchar*, Array2D&); + static GPUd() void findPeaksImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, const uchar*, const ChargePos*, tpccf::SizeT, const GPUSettingsRec&, const TPCPadGainCalib&, uchar*, Array2D&); static GPUd() bool isPeak(GPUSharedMemory&, tpccf::Charge, const ChargePos&, ushort, const Array2D&, const GPUSettingsRec&, ChargePos*, PackedCharge*); }; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.cxx index f4489146f583d..909d7eb6b7192 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.cxx @@ -22,54 +22,54 @@ using namespace GPUCA_NAMESPACE::gpu; using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> -GPUdii() void GPUTPCCFStreamCompaction::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int iBuf, int stage) +GPUdii() void GPUTPCCFStreamCompaction::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t iBuf, int32_t stage) { - int nElems = CompactionElems(clusterer, stage); + int32_t nElems = CompactionElems(clusterer, stage); const auto* predicate = clusterer.mPisPeak; auto* scanOffset = clusterer.GetScanBuffer(iBuf); - int iThreadGlobal = get_global_id(0); - int pred = 0; + int32_t iThreadGlobal = get_global_id(0); + int32_t pred = 0; if (iThreadGlobal < nElems) { pred = predicate[iThreadGlobal]; } - int nElemsInBlock = CfUtils::blockPredicateSum(smem, pred); + int32_t nElemsInBlock = CfUtils::blockPredicateSum(smem, pred); - int lastThread = nThreads - 1; + int32_t lastThread = nThreads - 1; if (iThread == lastThread) { scanOffset[iBlock] = nElemsInBlock; } } template <> -GPUdii() void GPUTPCCFStreamCompaction::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int iBuf, int nElems) +GPUdii() void GPUTPCCFStreamCompaction::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t iBuf, int32_t nElems) { auto* scanOffset = clusterer.GetScanBuffer(iBuf - 1); auto* scanOffsetNext = clusterer.GetScanBuffer(iBuf); - int iThreadGlobal = get_global_id(0); - int offsetInBlock = work_group_scan_inclusive_add((iThreadGlobal < nElems) ? scanOffset[iThreadGlobal] : 0); + int32_t iThreadGlobal = get_global_id(0); + int32_t offsetInBlock = work_group_scan_inclusive_add((iThreadGlobal < nElems) ? scanOffset[iThreadGlobal] : 0); // TODO: This write isn't needed?? scanOffset[iThreadGlobal] = offsetInBlock; - int lastThread = nThreads - 1; + int32_t lastThread = nThreads - 1; if (iThread == lastThread) { scanOffsetNext[iBlock] = offsetInBlock; } } template <> -GPUdii() void GPUTPCCFStreamCompaction::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int iBuf, int nElems) +GPUdii() void GPUTPCCFStreamCompaction::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t iBuf, int32_t nElems) { - int iThreadGlobal = get_global_id(0); - int* scanOffset = clusterer.GetScanBuffer(iBuf - 1); + int32_t iThreadGlobal = get_global_id(0); + int32_t* scanOffset = clusterer.GetScanBuffer(iBuf - 1); bool inBounds = (iThreadGlobal < nElems); - int offsetInBlock = work_group_scan_inclusive_add(inBounds ? scanOffset[iThreadGlobal] : 0); + int32_t offsetInBlock = work_group_scan_inclusive_add(inBounds ? scanOffset[iThreadGlobal] : 0); if (inBounds) { scanOffset[iThreadGlobal] = offsetInBlock; @@ -77,14 +77,14 @@ GPUdii() void GPUTPCCFStreamCompaction::Thread -GPUdii() void GPUTPCCFStreamCompaction::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& /*smem*/, processorType& clusterer, int iBuf, unsigned int offset, int nElems) +GPUdii() void GPUTPCCFStreamCompaction::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& /*smem*/, processorType& clusterer, int32_t iBuf, uint32_t offset, int32_t nElems) { - int iThreadGlobal = get_global_id(0) + offset; + int32_t iThreadGlobal = get_global_id(0) + offset; - int* scanOffsetPrev = clusterer.GetScanBuffer(iBuf - 1); - const int* scanOffset = clusterer.GetScanBuffer(iBuf); + int32_t* scanOffsetPrev = clusterer.GetScanBuffer(iBuf - 1); + const int32_t* scanOffset = clusterer.GetScanBuffer(iBuf); - int shift = scanOffset[iBlock]; + int32_t shift = scanOffset[iBlock]; if (iThreadGlobal < nElems) { scanOffsetPrev[iThreadGlobal] += shift; @@ -92,20 +92,20 @@ GPUdii() void GPUTPCCFStreamCompaction::Thread -GPUdii() void GPUTPCCFStreamCompaction::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, int iBuf, int stage, ChargePos* in, ChargePos* out) +GPUdii() void GPUTPCCFStreamCompaction::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int32_t iBuf, int32_t stage, ChargePos* in, ChargePos* out) { - unsigned int nElems = CompactionElems(clusterer, stage); + uint32_t nElems = CompactionElems(clusterer, stage); SizeT bufferSize = (stage) ? clusterer.mNMaxClusters : clusterer.mNMaxPeaks; - unsigned int iThreadGlobal = get_global_id(0); + uint32_t iThreadGlobal = get_global_id(0); const auto* predicate = clusterer.mPisPeak; const auto* scanOffset = clusterer.GetScanBuffer(iBuf); bool iAmDummy = (iThreadGlobal >= nElems); - int pred = (iAmDummy) ? 0 : predicate[iThreadGlobal]; - int offsetInBlock = CfUtils::blockPredicateScan(smem, pred); + int32_t pred = (iAmDummy) ? 0 : predicate[iThreadGlobal]; + int32_t offsetInBlock = CfUtils::blockPredicateScan(smem, pred); SizeT globalOffsetOut = offsetInBlock; if (iBlock > 0) { @@ -116,7 +116,7 @@ GPUdii() void GPUTPCCFStreamCompaction::Thread bufferSize) { @@ -131,7 +131,7 @@ GPUdii() void GPUTPCCFStreamCompaction::Threadcounters.nPeaks : clusterer.mPmemory->counters.nPositions; } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.h index 207c9075ba444..2ea7c8012e53f 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFStreamCompaction.h @@ -27,7 +27,7 @@ class GPUTPCCFStreamCompaction : public GPUKernelTemplate { public: - enum K : int { + enum K : int32_t { scanStart = 0, scanUp = 1, scanTop = 2, @@ -35,7 +35,7 @@ class GPUTPCCFStreamCompaction : public GPUKernelTemplate compactDigits = 4, }; - struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { + struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { }; #ifdef GPUCA_HAVE_O2HEADERS @@ -51,11 +51,11 @@ class GPUTPCCFStreamCompaction : public GPUKernelTemplate return GPUDataTypes::RecoStep::TPCClusterFinding; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() int CompactionElems(processorType& clusterer, int stage); + static GPUd() int32_t CompactionElems(processorType& clusterer, int32_t stage); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx index 08e0d0e0df204..a5c44e413bc8d 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx @@ -53,7 +53,7 @@ void* GPUTPCClusterFinder::SetPointersInput(void* mem) void* GPUTPCClusterFinder::SetPointersZSOffset(void* mem) { - const int n = (mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding) ? mNMaxPages : GPUTrackingInOutZS::NENDPOINTS; + const int32_t n = (mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding) ? mNMaxPages : GPUTrackingInOutZS::NENDPOINTS; if (n) { computePointerWithAlignment(mem, mPzsOffsets, n); } @@ -99,15 +99,15 @@ void GPUTPCClusterFinder::RegisterMemoryAllocation() AllocateAndInitializeLate(); mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersInput, GPUMemoryResource::MEMORY_INPUT | GPUMemoryResource::MEMORY_GPU | GPUMemoryResource::MEMORY_STACK, "TPCClustererInput"); - int scratchType = GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK; + int32_t scratchType = GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_STACK; if (mRec->GetProcessingSettings().runMC) { scratchType |= GPUMemoryResource::MEMORY_HOST | GPUMemoryResource::MEMORY_GPU; } - mScratchId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersScratch, scratchType, "TPCClustererScratch", GPUMemoryReuse{GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::ClustererScratch, (unsigned short)(mISlice % mRec->GetProcessingSettings().nTPCClustererLanes)}); + mScratchId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersScratch, scratchType, "TPCClustererScratch", GPUMemoryReuse{GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::ClustererScratch, (uint16_t)(mISlice % mRec->GetProcessingSettings().nTPCClustererLanes)}); mMemoryId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersMemory, GPUMemoryResource::MEMORY_PERMANENT, "TPCClustererMemory"); mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersOutput, GPUMemoryResource::MEMORY_OUTPUT | GPUMemoryResource::MEMORY_STACK, "TPCClustererOutput"); - mZSId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersZS, GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_CUSTOM_TRANSFER | GPUMemoryResource::MEMORY_GPU | GPUMemoryResource::MEMORY_STACK, "TPCClustererZSData", GPUMemoryReuse{GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::ClustererZS, (unsigned short)(mISlice % mRec->GetProcessingSettings().nTPCClustererLanes)}); + mZSId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersZS, GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_CUSTOM_TRANSFER | GPUMemoryResource::MEMORY_GPU | GPUMemoryResource::MEMORY_STACK, "TPCClustererZSData", GPUMemoryReuse{GPUMemoryReuse::REUSE_1TO1, GPUMemoryReuse::ClustererZS, (uint16_t)(mISlice % mRec->GetProcessingSettings().nTPCClustererLanes)}); mZSOffsetId = mRec->RegisterMemoryAllocation(this, &GPUTPCClusterFinder::SetPointersZSOffset, GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_CUSTOM_TRANSFER | GPUMemoryResource::MEMORY_INPUT | GPUMemoryResource::MEMORY_STACK, "TPCClustererZSOffsets"); } @@ -117,35 +117,35 @@ void GPUTPCClusterFinder::SetMaxData(const GPUTrackingInOutPointers& io) mNMaxClusters = mRec->MemoryScalers()->NTPCClusters(mNMaxDigitsFragment, true); mNMaxClusterPerRow = 0.01f * mRec->MemoryScalers()->NTPCClusters(mNMaxDigits, true); // TODO: Can save some memory hery by using mNMaxClusters, and copying the computed clusters out after every fragment if (io.settingsTF && io.settingsTF->hasNHBFPerTF) { - unsigned int threshold = 300000 * io.settingsTF->nHBFPerTF / 128; // TODO: Probably one would need to do this on a row-basis for a better estimate, but currently not supported - mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, std::min(threshold, mNMaxClusterPerRow * 10)); // Relative increased value up until a threshold, for noisy pads - mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, io.settingsTF->nHBFPerTF * 20000 / 256); // Absolute increased value, to have a minimum for noisy pads + uint32_t threshold = 300000 * io.settingsTF->nHBFPerTF / 128; // TODO: Probably one would need to do this on a row-basis for a better estimate, but currently not supported + mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, std::min(threshold, mNMaxClusterPerRow * 10)); // Relative increased value up until a threshold, for noisy pads + mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, io.settingsTF->nHBFPerTF * 20000 / 256); // Absolute increased value, to have a minimum for noisy pads } if (mNMaxDigitsEndpoint) { - mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, 0.0085f * mRec->MemoryScalers()->NTPCClusters(mNMaxDigitsEndpoint * GPUTrackingInOutZS::NENDPOINTS, true)); + mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, 0.0085f * mRec->MemoryScalers()->NTPCClusters(mNMaxDigitsEndpoint * GPUTrackingInOutZS::NENDPOINTS, true)); } if (mRec->GetProcessingSettings().tpcIncreasedMinClustersPerRow) { - mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, mRec->GetProcessingSettings().tpcIncreasedMinClustersPerRow); + mNMaxClusterPerRow = std::max(mNMaxClusterPerRow, mRec->GetProcessingSettings().tpcIncreasedMinClustersPerRow); } - mBufSize = nextMultipleOf(GPUCA_MEMALIGN, mScanWorkGroupSize)>(mNMaxDigitsFragment); + mBufSize = nextMultipleOf(GPUCA_MEMALIGN, mScanWorkGroupSize)>(mNMaxDigitsFragment); mNBufs = getNSteps(mBufSize); } void GPUTPCClusterFinder::SetNMaxDigits(size_t nDigits, size_t nPages, size_t nDigitsFragment, size_t nDigitsEndpointMax) { - mNMaxDigits = nextMultipleOf(GPUCA_MEMALIGN, mScanWorkGroupSize)>(nDigits); + mNMaxDigits = nextMultipleOf(GPUCA_MEMALIGN, mScanWorkGroupSize)>(nDigits); mNMaxPages = nPages; mNMaxDigitsFragment = nDigitsFragment; mNMaxDigitsEndpoint = nDigitsEndpointMax; } -unsigned int GPUTPCClusterFinder::getNSteps(size_t items) const +uint32_t GPUTPCClusterFinder::getNSteps(size_t items) const { if (items == 0) { return 0; } - unsigned int c = 1; + uint32_t c = 1; size_t capacity = mScanWorkGroupSize; while (items > capacity) { capacity *= mScanWorkGroupSize; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.h index ca89053797a47..d4838dda26fdd 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.h @@ -60,20 +60,20 @@ class GPUTPCClusterFinder : public GPUProcessor tpccf::SizeT nPositions = 0; tpccf::SizeT nPeaks = 0; tpccf::SizeT nClusters = 0; - unsigned int maxTimeBin = 0; - unsigned int nPagesSubslice = 0; + uint32_t maxTimeBin = 0; + uint32_t nPagesSubslice = 0; } counters; CfFragment fragment; }; struct ZSOffset { - unsigned int offset; - unsigned short endpoint; - unsigned short num; + uint32_t offset; + uint16_t endpoint; + uint16_t num; }; struct MinMaxCN { - unsigned int zsPtrFirst, zsPageFirst, zsPtrLast, zsPageLast; + uint32_t zsPtrFirst, zsPageFirst, zsPtrLast, zsPageLast; }; #ifndef GPUCA_GPUCODE @@ -89,57 +89,57 @@ class GPUTPCClusterFinder : public GPUProcessor void* SetPointersZS(void* mem); void* SetPointersZSOffset(void* mem); - unsigned int getNSteps(size_t items) const; + uint32_t getNSteps(size_t items) const; void SetNMaxDigits(size_t nDigits, size_t nPages, size_t nDigitsFragment, size_t nDigitsEndpointMax); void PrepareMC(); void clearMCMemory(); #endif - unsigned char* mPzs = nullptr; + uint8_t* mPzs = nullptr; ZSOffset* mPzsOffsets = nullptr; MinMaxCN* mMinMaxCN = nullptr; - unsigned char* mPpadIsNoisy = nullptr; + uint8_t* mPpadIsNoisy = nullptr; tpc::Digit* mPdigits = nullptr; // input digits, only set if ZS is skipped ChargePos* mPpositions = nullptr; ChargePos* mPpeakPositions = nullptr; ChargePos* mPfilteredPeakPositions = nullptr; - unsigned char* mPisPeak = nullptr; - unsigned int* mPclusterPosInRow = nullptr; // store the index where the corresponding cluster is stored in a bucket. - // Required when MC are enabled to write the mc data to the correct position. - // Set to >= mNMaxClusterPerRow if cluster was discarded. - unsigned short* mPchargeMap = nullptr; - unsigned char* mPpeakMap = nullptr; - unsigned int* mPindexMap = nullptr; - unsigned int* mPclusterInRow = nullptr; + uint8_t* mPisPeak = nullptr; + uint32_t* mPclusterPosInRow = nullptr; // store the index where the corresponding cluster is stored in a bucket. + // Required when MC are enabled to write the mc data to the correct position. + // Set to >= mNMaxClusterPerRow if cluster was discarded. + uint16_t* mPchargeMap = nullptr; + uint8_t* mPpeakMap = nullptr; + uint32_t* mPindexMap = nullptr; + uint32_t* mPclusterInRow = nullptr; tpc::ClusterNative* mPclusterByRow = nullptr; GPUTPCClusterMCInterimArray* mPlabelsByRow = nullptr; - int* mPbuf = nullptr; + int32_t* mPbuf = nullptr; Memory* mPmemory = nullptr; - GPUdi() int* GetScanBuffer(int iBuf) const { return mPbuf + iBuf * mBufSize; } + GPUdi() int32_t* GetScanBuffer(int32_t iBuf) const { return mPbuf + iBuf * mBufSize; } o2::dataformats::ConstMCTruthContainerView const* mPinputLabels = nullptr; - unsigned int* mPlabelsInRow = nullptr; - unsigned int mPlabelsHeaderGlobalOffset = 0; - unsigned int mPlabelsDataGlobalOffset = 0; - - int mISlice = 0; - constexpr static int mScanWorkGroupSize = GPUCA_THREAD_COUNT_SCAN; - unsigned int mNMaxClusterPerRow = 0; - unsigned int mNMaxClusters = 0; - unsigned int mNMaxPages = 0; + uint32_t* mPlabelsInRow = nullptr; + uint32_t mPlabelsHeaderGlobalOffset = 0; + uint32_t mPlabelsDataGlobalOffset = 0; + + int32_t mISlice = 0; + constexpr static int32_t mScanWorkGroupSize = GPUCA_THREAD_COUNT_SCAN; + uint32_t mNMaxClusterPerRow = 0; + uint32_t mNMaxClusters = 0; + uint32_t mNMaxPages = 0; size_t mNMaxDigits = 0; size_t mNMaxDigitsFragment = 0; size_t mNMaxDigitsEndpoint = 0; size_t mNMaxPeaks = 0; size_t mBufSize = 0; - unsigned int mNBufs = 0; + uint32_t mNBufs = 0; - short mMemoryId = -1; - short mScratchId = -1; - short mZSId = -1; - short mZSOffsetId = -1; - short mOutputId = -1; + int16_t mMemoryId = -1; + int16_t mScratchId = -1; + int16_t mZSId = -1; + int16_t mZSOffsetId = -1; + int16_t mOutputId = -1; #ifndef GPUCA_GPUCODE void DumpDigits(std::ostream& out); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx index 389209d9bb884..ba52167426137 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx @@ -45,7 +45,7 @@ void GPUTPCClusterFinder::DumpChargeMap(std::ostream& out, std::string_view titl TPCFragmentTime end = TPC_MAX_FRAGMENT_LEN_PADDED(mRec->GetProcessingSettings().overrideClusterizerFragmentLen); for (TPCFragmentTime i = start; i < end; i++) { - int zeros = 0; + int32_t zeros = 0; for (GlobalPad j = 0; j < TPC_NUM_OF_PADS; j++) { ushort q = map[{j, i}]; zeros += (q == 0); @@ -79,7 +79,7 @@ void GPUTPCClusterFinder::DumpPeakMap(std::ostream& out, std::string_view title) TPCFragmentTime end = TPC_MAX_FRAGMENT_LEN_PADDED(mRec->GetProcessingSettings().overrideClusterizerFragmentLen); for (TPCFragmentTime i = start; i < end; i++) { - int zeros = 0; + int32_t zeros = 0; out << i << ":"; for (GlobalPad j = 0; j < TPC_NUM_OF_PADS; j++) { @@ -91,7 +91,7 @@ void GPUTPCClusterFinder::DumpPeakMap(std::ostream& out, std::string_view title) zeros = 0; } - out << " p" << int{q}; + out << " p" << int32_t{q}; } } if (zeros > 0) { @@ -106,8 +106,8 @@ void GPUTPCClusterFinder::DumpPeakMap(std::ostream& out, std::string_view title) void GPUTPCClusterFinder::DumpPeaks(std::ostream& out) { out << "\nClusterer - Peaks - Slice " << mISlice << " - Fragment " << mPmemory->fragment.index << "\n"; - for (unsigned int i = 0; i < mPmemory->counters.nPositions; i++) { - out << int{mPisPeak[i]}; + for (uint32_t i = 0; i < mPmemory->counters.nPositions; i++) { + out << int32_t{mPisPeak[i]}; if ((i + 1) % 100 == 0) { out << "\n"; } @@ -121,7 +121,7 @@ void GPUTPCClusterFinder::DumpPeaksCompacted(std::ostream& out) out << "\nClusterer - Compacted Peaks - Slice " << mISlice << " - Fragment " << mPmemory->fragment.index << ": " << nPeaks << "\n"; for (size_t i = 0; i < nPeaks; i++) { const auto& pos = mPpeakPositions[i]; - out << pos.time() << " " << int{pos.pad()} << " " << int{pos.row()} << "\n"; + out << pos.time() << " " << int32_t{pos.pad()} << " " << int32_t{pos.row()} << "\n"; } } @@ -131,8 +131,8 @@ void GPUTPCClusterFinder::DumpSuppressedPeaks(std::ostream& out) const auto nPeaks = mPmemory->counters.nPeaks; out << "\nClusterer - NoiseSuppression - Slice " << mISlice << " - Fragment " << fragment.index << mISlice << "\n"; - for (unsigned int i = 0; i < nPeaks; i++) { - out << int{mPisPeak[i]}; + for (uint32_t i = 0; i < nPeaks; i++) { + out << int32_t{mPisPeak[i]}; if ((i + 1) % 100 == 0) { out << "\n"; } @@ -147,7 +147,7 @@ void GPUTPCClusterFinder::DumpSuppressedPeaksCompacted(std::ostream& out) out << "\nClusterer - Noise Suppression Peaks Compacted - Slice " << mISlice << " - Fragment " << fragment.index << ": " << nPeaks << "\n"; for (size_t i = 0; i < nPeaks; i++) { const auto& peak = mPfilteredPeakPositions[i]; - out << peak.time() << " " << int{peak.pad()} << " " << int{peak.row()} << "\n"; + out << peak.time() << " " << int32_t{peak.pad()} << " " << int32_t{peak.row()} << "\n"; } } @@ -155,7 +155,7 @@ void GPUTPCClusterFinder::DumpClusters(std::ostream& out) { out << "\nClusterer - Clusters - Slice " << mISlice << " - Fragment " << mPmemory->fragment.index << "\n"; - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { size_t N = mPclusterInRow[i]; const tpc::ClusterNative* row = &mPclusterByRow[i * mNMaxClusterPerRow]; @@ -165,7 +165,7 @@ void GPUTPCClusterFinder::DumpClusters(std::ostream& out) out << "Row: " << i << ": " << N << "\n"; for (const auto& cl : sortedCluster) { - out << std::hex << cl.timeFlagsPacked << std::dec << " " << cl.padPacked << " " << int{cl.sigmaTimePacked} << " " << int{cl.sigmaPadPacked} << " " << cl.qMax << " " << cl.qTot << "\n"; + out << std::hex << cl.timeFlagsPacked << std::dec << " " << cl.padPacked << " " << int32_t{cl.sigmaTimePacked} << " " << int32_t{cl.sigmaPadPacked} << " " << cl.qMax << " " << cl.qTot << "\n"; } } } diff --git a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx index eadddd1a8766a..f6a8fc44025bc 100644 --- a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx @@ -37,7 +37,7 @@ void MCLabelAccumulator::collect(const ChargePos& pos, Charge q) const auto& labels = mLabels->getLabels(index); for (const auto& label : labels) { - int h = label.getRawValue() % mMaybeHasLabel.size(); + int32_t h = label.getRawValue() % mMaybeHasLabel.size(); if (mMaybeHasLabel[h]) { auto lookup = std::find(mClusterLabels.begin(), mClusterLabels.end(), label); diff --git a/GPU/GPUTracking/TPCClusterFinder/PackedCharge.h b/GPU/GPUTracking/TPCClusterFinder/PackedCharge.h index 34a11b85a43bd..644e2074d92ca 100644 --- a/GPU/GPUTracking/TPCClusterFinder/PackedCharge.h +++ b/GPU/GPUTracking/TPCClusterFinder/PackedCharge.h @@ -24,7 +24,7 @@ namespace GPUCA_NAMESPACE::gpu class PackedCharge { public: - using BasicType = unsigned short; + using BasicType = uint16_t; static_assert(sizeof(BasicType) == 2); enum Constants : BasicType { diff --git a/GPU/GPUTracking/TPCConvert/GPUTPCConvert.h b/GPU/GPUTracking/TPCConvert/GPUTPCConvert.h index 3e6c7bb61cae5..3e46b31d1a597 100644 --- a/GPU/GPUTracking/TPCConvert/GPUTPCConvert.h +++ b/GPU/GPUTracking/TPCConvert/GPUTPCConvert.h @@ -39,7 +39,7 @@ class GPUTPCConvert : public GPUProcessor void* SetPointersMemory(void* mem); #endif - constexpr static unsigned int NSLICES = GPUCA_NSLICES; + constexpr static uint32_t NSLICES = GPUCA_NSLICES; struct Memory { GPUTPCClusterData* clusters[NSLICES]; @@ -48,10 +48,10 @@ class GPUTPCConvert : public GPUProcessor protected: Memory* mMemory = nullptr; GPUTPCClusterData* mClusters = nullptr; - unsigned int mNClustersTotal = 0; + uint32_t mNClustersTotal = 0; - short mMemoryResOutput = -1; - short mMemoryResMemory = -1; + int16_t mMemoryResOutput = -1; + int16_t mMemoryResMemory = -1; }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h b/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h index e8d777a3b23c1..8df31462d4995 100644 --- a/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h +++ b/GPU/GPUTracking/TPCConvert/GPUTPCConvertImpl.h @@ -28,7 +28,7 @@ namespace gpu class GPUTPCConvertImpl { public: - GPUd() static void convert(const GPUConstantMem& GPUrestrict() cm, int slice, int row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) + GPUd() static void convert(const GPUConstantMem& GPUrestrict() cm, int32_t slice, int32_t row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) { if (cm.param.par.continuousTracking) { cm.calibObjects.fastTransformHelper->getCorrMap()->TransformInTimeFrame(slice, row, pad, time, x, y, z, cm.param.continuousMaxTimeBin); @@ -36,7 +36,7 @@ class GPUTPCConvertImpl cm.calibObjects.fastTransformHelper->Transform(slice, row, pad, time, x, y, z); } } - GPUd() static void convert(const TPCFastTransform& GPUrestrict() transform, const GPUParam& GPUrestrict() param, int slice, int row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) + GPUd() static void convert(const TPCFastTransform& GPUrestrict() transform, const GPUParam& GPUrestrict() param, int32_t slice, int32_t row, float pad, float time, float& GPUrestrict() x, float& GPUrestrict() y, float& GPUrestrict() z) { if (param.par.continuousTracking) { transform.TransformInTimeFrame(slice, row, pad, time, x, y, z, param.continuousMaxTimeBin); diff --git a/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.cxx b/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.cxx index 139b0906f2690..4d59a3ca4e428 100644 --- a/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.cxx +++ b/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.cxx @@ -22,17 +22,17 @@ using namespace GPUCA_NAMESPACE::gpu; template <> -GPUdii() void GPUTPCConvertKernel::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) +GPUdii() void GPUTPCConvertKernel::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors) { - const int iSlice = iBlock / GPUCA_ROW_COUNT; - const int iRow = iBlock % GPUCA_ROW_COUNT; + const int32_t iSlice = iBlock / GPUCA_ROW_COUNT; + const int32_t iRow = iBlock % GPUCA_ROW_COUNT; GPUTPCConvert& GPUrestrict() convert = processors.tpcConverter; const o2::tpc::ClusterNativeAccess* GPUrestrict() native = processors.ioPtrs.clustersNative; GPUTPCClusterData* GPUrestrict() clusters = convert.mMemory->clusters[iSlice]; - const int idOffset = native->clusterOffset[iSlice][iRow]; - const int indexOffset = native->clusterOffset[iSlice][iRow] - native->clusterOffset[iSlice][0]; + const int32_t idOffset = native->clusterOffset[iSlice][iRow]; + const int32_t indexOffset = native->clusterOffset[iSlice][iRow] - native->clusterOffset[iSlice][0]; - for (unsigned int k = get_local_id(0); k < native->nClusters[iSlice][iRow]; k += get_local_size(0)) { + for (uint32_t k = get_local_id(0); k < native->nClusters[iSlice][iRow]; k += get_local_size(0)) { const auto& GPUrestrict() clin = native->clusters[iSlice][iRow][k]; float x, y, z; GPUTPCConvertImpl::convert(processors, iSlice, iRow, clin.getPad(), clin.getTime(), x, y, z); diff --git a/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.h b/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.h index f7b0eb201806c..cf743d059b3f7 100644 --- a/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.h +++ b/GPU/GPUTracking/TPCConvert/GPUTPCConvertKernel.h @@ -25,8 +25,8 @@ class GPUTPCConvertKernel : public GPUKernelTemplate { public: GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUDataTypes::RecoStep::TPCConversion; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h b/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h index 7dda1c8bd244e..8cde81cec9626 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h @@ -36,10 +36,10 @@ class GPUTRDGeometry : public AliTRDgeometry static bool CheckGeometryAvailable() { return AliGeomManager::GetGeometry(); } // Make sub-functionality available directly in GPUTRDGeometry - double GetPadPlaneWidthIPad(int det) const { return GetPadPlane(det)->GetWidthIPad(); } - double GetPadPlaneRowPos(int layer, int stack, int row) const { return GetPadPlane(layer, stack)->GetRowPos(row); } - double GetPadPlaneRowSize(int layer, int stack, int row) const { return GetPadPlane(layer, stack)->GetRowSize(row); } - int GetGeomManagerVolUID(int det, int modId) const { return AliGeomManager::LayerToVolUID(AliGeomManager::ELayerID(AliGeomManager::kTRD1 + GetLayer(det)), modId); } + double GetPadPlaneWidthIPad(int32_t det) const { return GetPadPlane(det)->GetWidthIPad(); } + double GetPadPlaneRowPos(int32_t layer, int32_t stack, int32_t row) const { return GetPadPlane(layer, stack)->GetRowPos(row); } + double GetPadPlaneRowSize(int32_t layer, int32_t stack, int32_t row) const { return GetPadPlane(layer, stack)->GetRowSize(row); } + int32_t GetGeomManagerVolUID(int32_t det, int32_t modId) const { return AliGeomManager::LayerToVolUID(AliGeomManager::ELayerID(AliGeomManager::kTRD1 + GetLayer(det)), modId); } float GetCdrHght() const { return CdrHght(); } }; } // namespace gpu @@ -63,17 +63,17 @@ class GPUTRDpadPlane : private o2::trd::PadPlane { public: GPUd() float GetTiltingAngle() const { return getTiltingAngle(); } - GPUd() float GetRowSize(int row) const { return getRowSize(row); } - GPUd() float GetColSize(int col) const { return getColSize(col); } + GPUd() float GetRowSize(int32_t row) const { return getRowSize(row); } + GPUd() float GetColSize(int32_t col) const { return getColSize(col); } GPUd() float GetRow0() const { return getRow0(); } GPUd() float GetCol0() const { return getCol0(); } GPUd() float GetRowEnd() const { return getRowEnd(); } GPUd() float GetColEnd() const { return getColEnd(); } - GPUd() float GetRowPos(int row) const { return getRowPos(row); } - GPUd() float GetColPos(int col) const { return getColPos(col); } + GPUd() float GetRowPos(int32_t row) const { return getRowPos(row); } + GPUd() float GetColPos(int32_t col) const { return getColPos(col); } GPUd() float GetNrows() const { return getNrows(); } GPUd() float GetNcols() const { return getNcols(); } - GPUd() int GetPadRowNumber(double z) const { return getPadRowNumber(z); } + GPUd() int32_t GetPadRowNumber(double z) const { return getPadRowNumber(z); } }; class GPUTRDGeometry : private o2::trd::GeometryFlat @@ -82,31 +82,31 @@ class GPUTRDGeometry : private o2::trd::GeometryFlat GPUd() static bool CheckGeometryAvailable() { return true; } // Make sub-functionality available directly in GPUTRDGeometry - GPUd() float GetPadPlaneWidthIPad(int det) const { return getPadPlane(det)->getWidthIPad(); } - GPUd() float GetPadPlaneRowPos(int layer, int stack, int row) const { return getPadPlane(layer, stack)->getRowPos(row); } - GPUd() float GetPadPlaneRowSize(int layer, int stack, int row) const { return getPadPlane(layer, stack)->getRowSize(row); } - GPUd() int GetGeomManagerVolUID(int det, int modId) const { return 0; } + GPUd() float GetPadPlaneWidthIPad(int32_t det) const { return getPadPlane(det)->getWidthIPad(); } + GPUd() float GetPadPlaneRowPos(int32_t layer, int32_t stack, int32_t row) const { return getPadPlane(layer, stack)->getRowPos(row); } + GPUd() float GetPadPlaneRowSize(int32_t layer, int32_t stack, int32_t row) const { return getPadPlane(layer, stack)->getRowSize(row); } + GPUd() int32_t GetGeomManagerVolUID(int32_t det, int32_t modId) const { return 0; } // Base functionality of Geometry - GPUd() float GetTime0(int layer) const { return getTime0(layer); } - GPUd() float GetCol0(int layer) const { return getCol0(layer); } + GPUd() float GetTime0(int32_t layer) const { return getTime0(layer); } + GPUd() float GetCol0(int32_t layer) const { return getCol0(layer); } GPUd() float GetCdrHght() const { return cdrHght(); } - GPUd() int GetLayer(int det) const { return getLayer(det); } + GPUd() int32_t GetLayer(int32_t det) const { return getLayer(det); } GPUd() bool CreateClusterMatrixArray() const { return false; } GPUd() float AnodePos() const { return anodePos(); } - GPUd() const Transform3D* GetClusterMatrix(int det) const { return getMatrixT2L(det); } - GPUd() int GetDetector(int layer, int stack, int sector) const { return getDetector(layer, stack, sector); } - GPUd() const GPUTRDpadPlane* GetPadPlane(int layer, int stack) const { return (GPUTRDpadPlane*)getPadPlane(layer, stack); } - GPUd() const GPUTRDpadPlane* GetPadPlane(int detector) const { return (GPUTRDpadPlane*)getPadPlane(detector); } - GPUd() int GetSector(int det) const { return getSector(det); } - GPUd() int GetStack(int det) const { return getStack(det); } - GPUd() int GetStack(float z, int layer) const { return getStack(z, layer); } + GPUd() const Transform3D* GetClusterMatrix(int32_t det) const { return getMatrixT2L(det); } + GPUd() int32_t GetDetector(int32_t layer, int32_t stack, int32_t sector) const { return getDetector(layer, stack, sector); } + GPUd() const GPUTRDpadPlane* GetPadPlane(int32_t layer, int32_t stack) const { return (GPUTRDpadPlane*)getPadPlane(layer, stack); } + GPUd() const GPUTRDpadPlane* GetPadPlane(int32_t detector) const { return (GPUTRDpadPlane*)getPadPlane(detector); } + GPUd() int32_t GetSector(int32_t det) const { return getSector(det); } + GPUd() int32_t GetStack(int32_t det) const { return getStack(det); } + GPUd() int32_t GetStack(float z, int32_t layer) const { return getStack(z, layer); } GPUd() float GetAlpha() const { return getAlpha(); } - GPUd() bool IsHole(int la, int st, int se) const { return isHole(la, st, se); } - GPUd() int GetRowMax(int layer, int stack, int sector) const { return getRowMax(layer, stack, sector); } - GPUd() bool ChamberInGeometry(int det) const { return chamberInGeometry(det); } + GPUd() bool IsHole(int32_t la, int32_t st, int32_t se) const { return isHole(la, st, se); } + GPUd() int32_t GetRowMax(int32_t layer, int32_t stack, int32_t sector) const { return getRowMax(layer, stack, sector); } + GPUd() bool ChamberInGeometry(int32_t det) const { return chamberInGeometry(det); } - static constexpr int kNstack = o2::trd::constants::NSTACK; + static constexpr int32_t kNstack = o2::trd::constants::NSTACK; }; } // namespace gpu } // namespace GPUCA_NAMESPACE @@ -133,15 +133,15 @@ class GPUTRDpadPlane { public: GPUd() float GetTiltingAngle() const { return 0; } - GPUd() float GetRowSize(int row) const { return 0; } - GPUd() float GetRowPos(int row) const { return 0; } + GPUd() float GetRowSize(int32_t row) const { return 0; } + GPUd() float GetRowPos(int32_t row) const { return 0; } GPUd() float GetRow0() const { return 0; } GPUd() float GetRowEnd() const { return 0; } GPUd() float GetCol0() const { return 0; } GPUd() float GetColEnd() const { return 0; } - GPUd() float GetColPos(int col) const { return 0; } + GPUd() float GetColPos(int32_t col) const { return 0; } GPUd() float GetNrows() const { return 0; } - GPUd() int GetPadRowNumber(double z) const { return 0; } + GPUd() int32_t GetPadRowNumber(double z) const { return 0; } }; class GPUTRDGeometry @@ -151,31 +151,31 @@ class GPUTRDGeometry void clearInternalBufferUniquePtr() const {} // Make sub-functionality available directly in GPUTRDGeometry - GPUd() float GetPadPlaneWidthIPad(int det) const { return 0; } - GPUd() float GetPadPlaneRowPos(int layer, int stack, int row) const { return 0; } - GPUd() float GetPadPlaneRowSize(int layer, int stack, int row) const { return 0; } - GPUd() int GetGeomManagerVolUID(int det, int modId) const { return 0; } + GPUd() float GetPadPlaneWidthIPad(int32_t det) const { return 0; } + GPUd() float GetPadPlaneRowPos(int32_t layer, int32_t stack, int32_t row) const { return 0; } + GPUd() float GetPadPlaneRowSize(int32_t layer, int32_t stack, int32_t row) const { return 0; } + GPUd() int32_t GetGeomManagerVolUID(int32_t det, int32_t modId) const { return 0; } // Base functionality of Geometry - GPUd() float GetTime0(int layer) const { return 0; } - GPUd() float GetCol0(int layer) const { return 0; } + GPUd() float GetTime0(int32_t layer) const { return 0; } + GPUd() float GetCol0(int32_t layer) const { return 0; } GPUd() float GetCdrHght() const { return 0; } - GPUd() int GetLayer(int det) const { return 0; } + GPUd() int32_t GetLayer(int32_t det) const { return 0; } GPUd() bool CreateClusterMatrixArray() const { return false; } GPUd() float AnodePos() const { return 0; } - GPUd() const TGeoHMatrix* GetClusterMatrix(int det) const { return nullptr; } - GPUd() int GetDetector(int layer, int stack, int sector) const { return 0; } - GPUd() const GPUTRDpadPlane* GetPadPlane(int layer, int stack) const { return nullptr; } - GPUd() const GPUTRDpadPlane* GetPadPlane(int detector) const { return nullptr; } - GPUd() int GetSector(int det) const { return 0; } - GPUd() int GetStack(int det) const { return 0; } - GPUd() int GetStack(float z, int layer) const { return 0; } + GPUd() const TGeoHMatrix* GetClusterMatrix(int32_t det) const { return nullptr; } + GPUd() int32_t GetDetector(int32_t layer, int32_t stack, int32_t sector) const { return 0; } + GPUd() const GPUTRDpadPlane* GetPadPlane(int32_t layer, int32_t stack) const { return nullptr; } + GPUd() const GPUTRDpadPlane* GetPadPlane(int32_t detector) const { return nullptr; } + GPUd() int32_t GetSector(int32_t det) const { return 0; } + GPUd() int32_t GetStack(int32_t det) const { return 0; } + GPUd() int32_t GetStack(float z, int32_t layer) const { return 0; } GPUd() float GetAlpha() const { return 0; } - GPUd() bool IsHole(int la, int st, int se) const { return false; } - GPUd() int GetRowMax(int layer, int stack, int /* sector */) const { return 0; } - GPUd() bool ChamberInGeometry(int det) const { return false; } + GPUd() bool IsHole(int32_t la, int32_t st, int32_t se) const { return false; } + GPUd() int32_t GetRowMax(int32_t layer, int32_t stack, int32_t /* sector */) const { return 0; } + GPUd() bool ChamberInGeometry(int32_t det) const { return false; } - static CONSTEXPR const int kNstack = 0; + static CONSTEXPR const int32_t kNstack = 0; }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDInterfaces.h b/GPU/GPUTracking/TRDTracking/GPUTRDInterfaces.h index 8915408c63f87..240c786d8f9ba 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDInterfaces.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDInterfaces.h @@ -106,7 +106,7 @@ class propagatorInterface : public AliTrackerBase propagatorInterface& operator=(const propagatorInterface&) CON_DELETE; bool propagateToX(float x, float maxSnp, float maxStep) { return PropagateTrackToBxByBz(mParam, x, 0.13957f, maxStep, false, maxSnp); } - int getPropagatedYZ(float x, float& projY, float& projZ) + int32_t getPropagatedYZ(float x, float& projY, float& projZ) { Double_t yz[2] = {0.}; mParam->GetYZAt(x, GetBz(), yz); @@ -152,7 +152,7 @@ class propagatorInterface GPUd() propagatorInterface& operator=(const propagatorInterface&) = delete; GPUdi() bool propagateToX(float x, float maxSnp, float maxStep) { return mProp->PropagateToXBxByBz(*mParam, x, maxSnp, maxStep); } - GPUdi() int getPropagatedYZ(float x, float& projY, float& projZ) { return static_cast(mParam->getYZAt(x, mProp->getNominalBz(), projY, projZ)); } + GPUdi() int32_t getPropagatedYZ(float x, float& projY, float& projZ) { return static_cast(mParam->getYZAt(x, mProp->getNominalBz(), projY, projZ)); } GPUdi() void setTrack(trackInterface* trk) { mParam = trk; } GPUdi() void setFitInProjections(bool flag) {} @@ -212,10 +212,10 @@ class trackInterface : public GPUTPCGMTrackParam GPUd() trackInterface(const gputpcgmmergertypes::GPUTPCOuterParam& param) : GPUTPCGMTrackParam(), mAlpha(param.alpha) { SetX(param.X); - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { SetPar(i, param.P[i]); } - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { SetCov(i, param.C[i]); } }; @@ -232,7 +232,7 @@ class trackInterface : public GPUTPCGMTrackParam SetPar(2, param.fSinPhi); SetPar(3, param.fTgl); SetPar(4, param.fq1Pt); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { SetCov(i, param.fC[i]); } }; @@ -246,7 +246,7 @@ class trackInterface : public GPUTPCGMTrackParam SetPar(2, param.getParamOut().getSnp()); SetPar(3, param.getParamOut().getTgl()); SetPar(4, param.getParamOut().getQ2Pt()); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { SetCov(i, param.getParamOut().getCov()[i]); } } @@ -258,7 +258,7 @@ class trackInterface : public GPUTPCGMTrackParam SetPar(2, param.getParamOut().getSnp()); SetPar(3, param.getParamOut().getTgl()); SetPar(4, param.getParamOut().getQ2Pt()); - for (int i = 0; i < 15; i++) { + for (int32_t i = 0; i < 15; i++) { SetCov(i, param.getParamOut().getCov()[i]); } } @@ -287,10 +287,10 @@ class trackInterface : public GPUTPCGMTrackParam GPUd() void set(float x, float alpha, const float param[5], const float cov[15]) { SetX(x); - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { SetPar(i, param[i]); } - for (int j = 0; j < 15; j++) { + for (int32_t j = 0; j < 15; j++) { SetCov(j, cov[j]); } setAlpha(alpha); @@ -326,12 +326,12 @@ class propagatorInterface : public GPUTPCGMPropagator GPUd() bool propagateToX(float x, float maxSnp, float maxStep) { //bool ok = PropagateToXAlpha(x, GetAlpha(), true) == 0 ? true : false; - int retVal = PropagateToXAlpha(x, GetAlpha(), true); + int32_t retVal = PropagateToXAlpha(x, GetAlpha(), true); bool ok = (retVal == 0) ? true : false; ok = mTrack->CheckNumericalQuality(); return ok; } - GPUd() int getPropagatedYZ(float x, float& projY, float& projZ) { return GetPropagatedYZ(x, projY, projZ); } + GPUd() int32_t getPropagatedYZ(float x, float& projY, float& projZ) { return GetPropagatedYZ(x, projY, projZ); } GPUd() void setFitInProjections(bool flag) { SetFitInProjections(flag); } GPUd() bool rotate(float alpha) { diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackData.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackData.h index 4dc19c92a3fda..6a6e13fe84e36 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackData.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackData.h @@ -26,14 +26,14 @@ struct GPUTRDTrackDataRecord { float fTgl; // tangent of the track momentum dip angle float fq1Pt; // 1/pt (1/(GeV/c)) float fC[15]; // covariance matrix - int fTPCTrackID; // id of corresponding TPC track - int fAttachedTracklets[6]; // IDs for attached tracklets sorted by layer - unsigned char mIsPadrowCrossing; // bits 0 to 5 indicate whether a padrow was crossed + int32_t fTPCTrackID; // id of corresponding TPC track + int32_t fAttachedTracklets[6]; // IDs for attached tracklets sorted by layer + uint8_t mIsPadrowCrossing; // bits 0 to 5 indicate whether a padrow was crossed - int GetNTracklets() const + int32_t GetNTracklets() const { - int n = 0; - for (int i = 0; i < 6; i++) { + int32_t n = 0; + for (int32_t i = 0; i < 6; i++) { if (fAttachedTracklets[i] >= 0) { n++; } @@ -45,13 +45,13 @@ struct GPUTRDTrackDataRecord { typedef struct GPUTRDTrackDataRecord GPUTRDTrackDataRecord; struct GPUTRDTrackData { - unsigned int fCount; // number of tracklets + uint32_t fCount; // number of tracklets #if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC) GPUTRDTrackDataRecord fTracks[1]; // array of tracklets #else GPUTRDTrackDataRecord fTracks[0]; // array of tracklets #endif - static size_t GetSize(unsigned int nTracks) + static size_t GetSize(uint32_t nTracks) { return sizeof(GPUTRDTrackData) + nTracks * sizeof(GPUTRDTrackDataRecord); } diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackPoint.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackPoint.h index a8c95b74fa8d4..d4d970884979e 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackPoint.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackPoint.h @@ -19,11 +19,11 @@ struct GPUTRDTrackPoint { float fX[3]; - short fVolumeId; + int16_t fVolumeId; }; struct GPUTRDTrackPointData { - unsigned int fCount; // number of space points + uint32_t fCount; // number of space points #if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC) GPUTRDTrackPoint fPoints[1]; // array of space points #else diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx index 20c7e2932367a..0f184036e73ea 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.cxx @@ -126,7 +126,7 @@ void GPUTRDTracker_t::InitializeProcessor() //-------------------------------------------------------------------- #ifdef GPUCA_ALIROOT_LIB - for (int iCandidate = 0; iCandidate < mNCandidates * 2 * mMaxThreads; ++iCandidate) { + for (int32_t iCandidate = 0; iCandidate < mNCandidates * 2 * mMaxThreads; ++iCandidate) { new (&mCandidates[iCandidate]) TRDTRK; } #endif @@ -188,7 +188,7 @@ void GPUTRDTracker_t::UpdateGeometry() auto* matrix = mGeo->GetClusterMatrix(0); My_Float loc[3] = {mGeo->AnodePos(), 0.f, 0.f}; My_Float glb[3] = {0.f, 0.f, 0.f}; - for (int iDet = 0; iDet < kNChambers; ++iDet) { + for (int32_t iDet = 0; iDet < kNChambers; ++iDet) { matrix = mGeo->GetClusterMatrix(iDet); if (!matrix) { mR[iDet] = x0[mGeo->GetLayer(iDet)]; @@ -216,13 +216,13 @@ void GPUTRDTracker_t::PrepareTracking(GPUChainTracking* chainTrack // in part duplicated from DoTracking() method to allow for calling // this function on the host prior to GPU processing //-------------------------------------------------------------------- - for (unsigned int iColl = 0; iColl < GetConstantMem()->ioPtrs.nTRDTriggerRecords; ++iColl) { + for (uint32_t iColl = 0; iColl < GetConstantMem()->ioPtrs.nTRDTriggerRecords; ++iColl) { if (GetConstantMem()->ioPtrs.trdTrigRecMask && GetConstantMem()->ioPtrs.trdTrigRecMask[iColl] == 0) { // this trigger is masked as there is no ITS information available for it continue; } - int nTrklts = 0; - int idxOffset = 0; + int32_t nTrklts = 0; + int32_t idxOffset = 0; if (mProcessPerTimeFrame) { idxOffset = GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iColl]; nTrklts = (iColl < GetConstantMem()->ioPtrs.nTRDTriggerRecords - 1) ? GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iColl + 1] - GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iColl] : GetConstantMem()->ioPtrs.nTRDTracklets - GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iColl]; @@ -230,22 +230,22 @@ void GPUTRDTracker_t::PrepareTracking(GPUChainTracking* chainTrack nTrklts = GetConstantMem()->ioPtrs.nTRDTracklets; } const GPUTRDTrackletWord* tracklets = &((GetConstantMem()->ioPtrs.trdTracklets)[idxOffset]); - int* trkltIndexArray = &mTrackletIndexArray[iColl * (kNChambers + 1) + 1]; + int32_t* trkltIndexArray = &mTrackletIndexArray[iColl * (kNChambers + 1) + 1]; trkltIndexArray[-1] = 0; - int currDet = 0; - int nextDet = 0; - int trkltCounter = 0; - for (int iTrklt = 0; iTrklt < nTrklts; ++iTrklt) { + int32_t currDet = 0; + int32_t nextDet = 0; + int32_t trkltCounter = 0; + for (int32_t iTrklt = 0; iTrklt < nTrklts; ++iTrklt) { if (tracklets[iTrklt].GetDetector() > currDet) { nextDet = tracklets[iTrklt].GetDetector(); - for (int iDet = currDet; iDet < nextDet; ++iDet) { + for (int32_t iDet = currDet; iDet < nextDet; ++iDet) { trkltIndexArray[iDet] = trkltCounter; } currDet = nextDet; } ++trkltCounter; } - for (int iDet = currDet; iDet <= kNChambers; ++iDet) { + for (int32_t iDet = currDet; iDet <= kNChambers; ++iDet) { trkltIndexArray[iDet] = trkltCounter; } if (mGenerateSpacePoints) { @@ -262,7 +262,7 @@ void GPUTRDTracker_t::PrepareTracking(GPUChainTracking* chainTrack } template -void GPUTRDTracker_t::SetNCandidates(int n) +void GPUTRDTracker_t::SetNCandidates(int32_t n) { //-------------------------------------------------------------------- // set the number of candidates to be used @@ -327,7 +327,7 @@ GPUd() bool GPUTRDTracker_t::CheckTrackTRDCandidate(const TRDTRK& } template -GPUd() int GPUTRDTracker_t::LoadTrack(const TRDTRK& trk, unsigned int tpcTrackId, bool checkTrack, HelperTrackAttributes* attribs) +GPUd() int32_t GPUTRDTracker_t::LoadTrack(const TRDTRK& trk, uint32_t tpcTrackId, bool checkTrack, HelperTrackAttributes* attribs) { if (mNTracks >= mNMaxTracks) { #ifndef GPUCA_GPUCODE @@ -360,14 +360,14 @@ GPUd() void GPUTRDTracker_t::DumpTracks() //-------------------------------------------------------------------- GPUInfo("There are in total %i tracklets loaded", GetConstantMem()->ioPtrs.nTRDTracklets); GPUInfo("There are %i tracks loaded. mNMaxTracks(%i)", mNTracks, mNMaxTracks); - for (int i = 0; i < mNTracks; ++i) { + for (int32_t i = 0; i < mNTracks; ++i) { auto* trk = &(mTracks[i]); GPUInfo("track %i: x=%f, alpha=%f, nTracklets=%i, pt=%f, time=%f", i, trk->getX(), trk->getAlpha(), trk->getNtracklets(), trk->getPt(), mTrackAttribs[i].mTime); } } template -GPUd() int GPUTRDTracker_t::GetCollisionIDs(int iTrk, int* collisionIds) const +GPUd() int32_t GPUTRDTracker_t::GetCollisionIDs(int32_t iTrk, int32_t* collisionIds) const { //-------------------------------------------------------------------- // Check which TRD trigger times possibly match given input track. @@ -376,8 +376,8 @@ GPUd() int GPUTRDTracker_t::GetCollisionIDs(int iTrk, int* collisi // For TPC-only tracks the collision IDs are stored in collisionIds array // and the number of valid entries in the array is returned //-------------------------------------------------------------------- - int nColls = 0; - for (unsigned int iColl = 0; iColl < GetConstantMem()->ioPtrs.nTRDTriggerRecords; ++iColl) { + int32_t nColls = 0; + for (uint32_t iColl = 0; iColl < GetConstantMem()->ioPtrs.nTRDTriggerRecords; ++iColl) { if (GetConstantMem()->ioPtrs.trdTrigRecMask && GetConstantMem()->ioPtrs.trdTrigRecMask[iColl] == 0) { continue; } @@ -393,13 +393,13 @@ GPUd() int GPUTRDTracker_t::GetCollisionIDs(int iTrk, int* collisi } template -GPUd() void GPUTRDTracker_t::DoTrackingThread(int iTrk, int threadId) +GPUd() void GPUTRDTracker_t::DoTrackingThread(int32_t iTrk, int32_t threadId) { //-------------------------------------------------------------------- // perform the tracking for one track (must be threadsafe) //-------------------------------------------------------------------- - int collisionIds[20] = {0}; // due to the dead time there will never exist more possible TRD triggers for a single track - int nCollisionIds = 1; // initialize with 1 for AliRoot compatibility + int32_t collisionIds[20] = {0}; // due to the dead time there will never exist more possible TRD triggers for a single track + int32_t nCollisionIds = 1; // initialize with 1 for AliRoot compatibility if (mProcessPerTimeFrame) { nCollisionIds = GetCollisionIDs(iTrk, collisionIds); if (nCollisionIds == 0) { @@ -413,7 +413,7 @@ GPUd() void GPUTRDTracker_t::DoTrackingThread(int iTrk, int thread PROP prop(getPropagatorParam()); mTracks[iTrk].setChi2(Param().rec.trd.penaltyChi2); // TODO check if this should not be higher auto trkStart = mTracks[iTrk]; - for (int iColl = 0; iColl < nCollisionIds; ++iColl) { + for (int32_t iColl = 0; iColl < nCollisionIds; ++iColl) { // do track following for each collision candidate and keep best track auto trkCopy = trkStart; prop.setTrack(&trkCopy); @@ -434,7 +434,7 @@ GPUd() bool GPUTRDTracker_t::ConvertTrkltToSpacePoint(const GPUTRD { // converts a single GPUTRDTrackletWord into GPUTRDSpacePoint // returns true if successfull - int det = trklt.GetDetector(); + int32_t det = trklt.GetDetector(); if (!geo.ChamberInGeometry(det)) { return false; } @@ -443,7 +443,7 @@ GPUd() bool GPUTRDTracker_t::ConvertTrkltToSpacePoint(const GPUTRD return false; } const GPUTRDpadPlane* pp = geo.GetPadPlane(det); - int trkltZbin = trklt.GetZbin(); + int32_t trkltZbin = trklt.GetZbin(); My_Float xTrkltDet[3] = {0.f}; // trklt position in chamber coordinates My_Float xTrkltSec[3] = {0.f}; // trklt position in sector coordinates xTrkltDet[0] = geo.AnodePos() - sRadialOffset; @@ -460,7 +460,7 @@ GPUd() bool GPUTRDTracker_t::ConvertTrkltToSpacePoint(const GPUTRD #endif template -GPUd() bool GPUTRDTracker_t::CalculateSpacePoints(int iCollision) +GPUd() bool GPUTRDTracker_t::CalculateSpacePoints(int32_t iCollision) { //-------------------------------------------------------------------- // Calculates TRD space points in sector tracking coordinates @@ -468,14 +468,14 @@ GPUd() bool GPUTRDTracker_t::CalculateSpacePoints(int iCollision) //-------------------------------------------------------------------- bool result = true; - int idxOffset = iCollision * (kNChambers + 1); // offset for accessing mTrackletIndexArray for collision iCollision + int32_t idxOffset = iCollision * (kNChambers + 1); // offset for accessing mTrackletIndexArray for collision iCollision const GPUTRDTrackletWord* tracklets = GetConstantMem()->ioPtrs.trdTracklets; - for (int iDet = 0; iDet < kNChambers; ++iDet) { - int iFirstTrackletInDet = mTrackletIndexArray[idxOffset + iDet]; - int iFirstTrackletInNextDet = mTrackletIndexArray[idxOffset + iDet + 1]; - int nTrackletsInDet = iFirstTrackletInNextDet - iFirstTrackletInDet; + for (int32_t iDet = 0; iDet < kNChambers; ++iDet) { + int32_t iFirstTrackletInDet = mTrackletIndexArray[idxOffset + iDet]; + int32_t iFirstTrackletInNextDet = mTrackletIndexArray[idxOffset + iDet + 1]; + int32_t nTrackletsInDet = iFirstTrackletInNextDet - iFirstTrackletInDet; if (nTrackletsInDet == 0) { continue; } @@ -491,10 +491,10 @@ GPUd() bool GPUTRDTracker_t::CalculateSpacePoints(int iCollision) } const GPUTRDpadPlane* pp = mGeo->GetPadPlane(iDet); - int trkltIdxOffset = (mProcessPerTimeFrame) ? GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iCollision] : 0; // global index of first tracklet in iCollision - int trkltIdxStart = trkltIdxOffset + iFirstTrackletInDet; - for (int trkltIdx = trkltIdxStart; trkltIdx < trkltIdxStart + nTrackletsInDet; ++trkltIdx) { - int trkltZbin = tracklets[trkltIdx].GetZbin(); + int32_t trkltIdxOffset = (mProcessPerTimeFrame) ? GetConstantMem()->ioPtrs.trdTrackletIdxFirst[iCollision] : 0; // global index of first tracklet in iCollision + int32_t trkltIdxStart = trkltIdxOffset + iFirstTrackletInDet; + for (int32_t trkltIdx = trkltIdxStart; trkltIdx < trkltIdxStart + nTrackletsInDet; ++trkltIdx) { + int32_t trkltZbin = tracklets[trkltIdx].GetZbin(); My_Float xTrkltDet[3] = {0.f}; // trklt position in chamber coordinates My_Float xTrkltSec[3] = {0.f}; // trklt position in sector coordinates xTrkltDet[0] = mGeo->AnodePos() + sRadialOffset; @@ -514,7 +514,7 @@ GPUd() bool GPUTRDTracker_t::CalculateSpacePoints(int iCollision) } template -GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK* t, int iTrk, int threadId, int collisionId) +GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK* t, int32_t iTrk, int32_t threadId, int32_t collisionId) { //-------------------------------------------------------------------- // Propagate TPC track layerwise through TRD and pick up closest @@ -544,10 +544,10 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK TRDTRK trackNoUp(*t); #endif - int candidateIdxOffset = threadId * 2 * mNCandidates; - int hypothesisIdxOffset = threadId * mNCandidates; - int trkltIdxOffset = collisionId * (kNChambers + 1); // offset for accessing mTrackletIndexArray for given collision - int glbTrkltIdxOffset = (mProcessPerTimeFrame) ? GetConstantMem()->ioPtrs.trdTrackletIdxFirst[collisionId] : 0; // offset of first tracklet in given collision in global tracklet array + int32_t candidateIdxOffset = threadId * 2 * mNCandidates; + int32_t hypothesisIdxOffset = threadId * mNCandidates; + int32_t trkltIdxOffset = collisionId * (kNChambers + 1); // offset for accessing mTrackletIndexArray for given collision + int32_t glbTrkltIdxOffset = (mProcessPerTimeFrame) ? GetConstantMem()->ioPtrs.trdTrackletIdxFirst[collisionId] : 0; // offset of first tracklet in given collision in global tracklet array auto trkWork = t; if (mNCandidates > 1) { @@ -555,21 +555,21 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK mCandidates[candidateIdxOffset] = *t; } - int nCandidates = 1; // we always start with one candidate - int nCurrHypothesis = 0; // the number of track hypothesis in given iLayer + int32_t nCandidates = 1; // we always start with one candidate + int32_t nCurrHypothesis = 0; // the number of track hypothesis in given iLayer // search window float roadY = 0.f; float roadZ = 0.f; - const int nMaxChambersToSearch = 4; + const int32_t nMaxChambersToSearch = 4; mDebug->SetGeneralInfo(mNEvents, mNTracks, iTrk, t->getPt()); - for (int iLayer = 0; iLayer < kNLayers; ++iLayer) { + for (int32_t iLayer = 0; iLayer < kNLayers; ++iLayer) { nCurrHypothesis = 0; bool isOK = false; // if at least one candidate could be propagated or the track was stopped this becomes true - int currIdx = candidateIdxOffset + iLayer % 2; - int nextIdx = candidateIdxOffset + (iLayer + 1) % 2; + int32_t currIdx = candidateIdxOffset + iLayer % 2; + int32_t nextIdx = candidateIdxOffset + (iLayer + 1) % 2; pad = mGeo->GetPadPlane(iLayer, 0); float tilt = CAMath::Tan(CAMath::Pi() / 180.f * pad->GetTiltingAngle()); // tilt is signed! const float zMaxTRD = pad->GetRow0(); @@ -579,9 +579,9 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK // for each candidate, propagate to layer radius and look for close tracklets // // -------------------------------------------------------------------------------- - for (int iCandidate = 0; iCandidate < nCandidates; iCandidate++) { + for (int32_t iCandidate = 0; iCandidate < nCandidates; iCandidate++) { - int det[nMaxChambersToSearch] = {-1, -1, -1, -1}; // TRD chambers to be searched for tracklets + int32_t det[nMaxChambersToSearch] = {-1, -1, -1, -1}; // TRD chambers to be searched for tracklets if (mNCandidates > 1) { trkWork = &mCandidates[2 * iCandidate + currIdx]; @@ -635,13 +635,13 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK mDebug->SetTrackParameter(*trkWork, iLayer); // look for tracklets in chamber(s) - for (int iDet = 0; iDet < nMaxChambersToSearch; iDet++) { - int currDet = det[iDet]; + for (int32_t iDet = 0; iDet < nMaxChambersToSearch; iDet++) { + int32_t currDet = det[iDet]; if (currDet == -1) { continue; } pad = mGeo->GetPadPlane(currDet); - int currSec = mGeo->GetSector(currDet); + int32_t currSec = mGeo->GetSector(currDet); if (currSec != GetSector(prop->getAlpha())) { if (!prop->rotate(GetAlphaOfSector(currSec))) { if (ENABLE_WARNING) { @@ -661,7 +661,7 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK } } // first propagate track to x of tracklet - for (int trkltIdx = glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet]; trkltIdx < glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet + 1]; ++trkltIdx) { + for (int32_t trkltIdx = glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet]; trkltIdx < glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet + 1]; ++trkltIdx) { if (CAMath::Abs(trkWork->getY() - spacePoints[trkltIdx].getY()) > roadY || CAMath::Abs(trkWork->getZ() + zShiftTrk - spacePoints[trkltIdx].getZ()) > roadZ) { // skip tracklets which are too far away // although the radii of space points and tracks may differ by ~ few mm the roads are large enough to allow no efficiency loss by this cut @@ -694,8 +694,8 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK Hypothesis hypo(trkWork->getNlayersFindable(), iCandidate, trkltIdx, trkWork->getChi2() + chi2); InsertHypothesis(hypo, nCurrHypothesis, hypothesisIdxOffset); } // end tracklet in window - } // tracklet loop - } // chamber loop + } // tracklet loop + } // chamber loop // add no update to hypothesis list Hypothesis hypoNoUpdate(trkWork->getNlayersFindable(), iCandidate, -1, trkWork->getChi2() + Param().rec.trd.penaltyChi2); @@ -712,8 +712,8 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK // // -------------------------------------------------------------------------------- // GPUInfo("nCurrHypothesis=%i, nCandidates=%i", nCurrHypothesis, nCandidates); - // for (int idx=0; idx<10; ++idx) { GPUInfo("mHypothesis[%i]: candidateId=%i, nLayers=%i, trackletId=%i, chi2=%f", idx, mHypothesis[idx].mCandidateId, mHypothesis[idx].mLayers, mHypothesis[idx].mTrackletId, mHypothesis[idx].mChi2); } - for (int iUpdate = 0; iUpdate < nCurrHypothesis && iUpdate < mNCandidates; iUpdate++) { + // for (int32_t idx=0; idx<10; ++idx) { GPUInfo("mHypothesis[%i]: candidateId=%i, nLayers=%i, trackletId=%i, chi2=%f", idx, mHypothesis[idx].mCandidateId, mHypothesis[idx].mLayers, mHypothesis[idx].mTrackletId, mHypothesis[idx].mChi2); } + for (int32_t iUpdate = 0; iUpdate < nCurrHypothesis && iUpdate < mNCandidates; iUpdate++) { if (mHypothesis[iUpdate + hypothesisIdxOffset].mCandidateId == -1) { // no more candidates if (iUpdate == 0) { @@ -743,7 +743,7 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK if (mNCandidates > 1) { prop->setTrack(trkWork); } - int trkltSec = mGeo->GetSector(tracklets[mHypothesis[iUpdate + hypothesisIdxOffset].mTrackletId].GetDetector()); + int32_t trkltSec = mGeo->GetSector(tracklets[mHypothesis[iUpdate + hypothesisIdxOffset].mTrackletId].GetDetector()); if (trkltSec != GetSector(prop->getAlpha())) { // if after a matching tracklet was found another sector was searched for tracklets the track needs to be rotated back prop->rotate(GetAlphaOfSector(trkltSec)); @@ -838,7 +838,7 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK } const auto currDet = tracklets[mHypothesis[iUpdate + hypothesisIdxOffset].mTrackletId].GetDetector(); // Mark tracklets as Padrow crossing if they have a neighboring tracklet. - for (int trkltIdx = glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet]; trkltIdx < glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet + 1]; ++trkltIdx) { + for (int32_t trkltIdx = glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet]; trkltIdx < glbTrkltIdxOffset + mTrackletIndexArray[trkltIdxOffset + currDet + 1]; ++trkltIdx) { // skip orig tracklet if (mHypothesis[iUpdate + hypothesisIdxOffset].mTrackletId == trkltIdx) { continue; @@ -883,7 +883,7 @@ GPUd() bool GPUTRDTracker_t::FollowProlongation(PROP* prop, TRDTRK } template -GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int& nCurrHypothesis, int idxOffset) +GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int32_t& nCurrHypothesis, int32_t idxOffset) { // Insert hypothesis into the array. If the array is full and the reduced chi2 is worse // than the worst hypothesis in the array it is dropped. @@ -895,9 +895,9 @@ GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int ++nCurrHypothesis; } else if (nCurrHypothesis > 0 && nCurrHypothesis < mNCandidates) { // insert the hypothesis into the right position and shift all worse hypothesis to the right - for (int i = idxOffset; i < nCurrHypothesis + idxOffset; ++i) { + for (int32_t i = idxOffset; i < nCurrHypothesis + idxOffset; ++i) { if (hypo.GetReducedChi2() < mHypothesis[i].GetReducedChi2()) { - for (int k = nCurrHypothesis + idxOffset; k > i; --k) { + for (int32_t k = nCurrHypothesis + idxOffset; k > i; --k) { mHypothesis[k] = mHypothesis[k - 1]; } mHypothesis[i] = hypo; @@ -910,7 +910,7 @@ GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int return; } else { // array is already full, check if new hypothesis should be inserted - int i = nCurrHypothesis + idxOffset - 1; + int32_t i = nCurrHypothesis + idxOffset - 1; for (; i >= idxOffset; --i) { if (mHypothesis[i].GetReducedChi2() < hypo.GetReducedChi2()) { break; @@ -918,7 +918,7 @@ GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int } if (i < (nCurrHypothesis + idxOffset - 1)) { // new hypothesis should be inserted into the array - for (int k = nCurrHypothesis + idxOffset - 1; k > i + 1; --k) { + for (int32_t k = nCurrHypothesis + idxOffset - 1; k > i + 1; --k) { mHypothesis[k] = mHypothesis[k - 1]; } mHypothesis[i + 1] = hypo; @@ -927,17 +927,17 @@ GPUd() void GPUTRDTracker_t::InsertHypothesis(Hypothesis hypo, int } template -GPUd() int GPUTRDTracker_t::GetDetectorNumber(const float zPos, const float alpha, const int layer) const +GPUd() int32_t GPUTRDTracker_t::GetDetectorNumber(const float zPos, const float alpha, const int32_t layer) const { //-------------------------------------------------------------------- // if track position is within chamber return the chamber number // otherwise return -1 //-------------------------------------------------------------------- - int stack = mGeo->GetStack(zPos, layer); + int32_t stack = mGeo->GetStack(zPos, layer); if (stack < 0) { return -1; } - int sector = GetSector(alpha); + int32_t sector = GetSector(alpha); return mGeo->GetDetector(layer, stack, sector); } @@ -963,12 +963,12 @@ GPUd() bool GPUTRDTracker_t::AdjustSector(PROP* prop, TRDTRK* t) c return false; } - int nTries = 0; + int32_t nTries = 0; while (CAMath::Abs(y) > yMax) { if (nTries >= 2) { return false; } - int sign = (y > 0) ? 1 : -1; + int32_t sign = (y > 0) ? 1 : -1; float alphaNew = alphaCurr + alpha * sign; if (alphaNew > CAMath::Pi()) { alphaNew -= 2 * CAMath::Pi(); @@ -988,7 +988,7 @@ GPUd() bool GPUTRDTracker_t::AdjustSector(PROP* prop, TRDTRK* t) c } template -GPUd() int GPUTRDTracker_t::GetSector(float alpha) const +GPUd() int32_t GPUTRDTracker_t::GetSector(float alpha) const { //-------------------------------------------------------------------- // TRD sector number for reference system alpha @@ -998,11 +998,11 @@ GPUd() int GPUTRDTracker_t::GetSector(float alpha) const } else if (alpha >= 2.f * CAMath::Pi()) { alpha -= 2.f * CAMath::Pi(); } - return (int)(alpha * (float)kNSectors / (2.f * CAMath::Pi())); + return (int32_t)(alpha * (float)kNSectors / (2.f * CAMath::Pi())); } template -GPUd() float GPUTRDTracker_t::GetAlphaOfSector(const int sec) const +GPUd() float GPUTRDTracker_t::GetAlphaOfSector(const int32_t sec) const { //-------------------------------------------------------------------- // rotation angle for TRD sector sec @@ -1042,7 +1042,7 @@ GPUd() float GPUTRDTracker_t::GetAngularPull(float dYtracklet, flo } template -GPUd() void GPUTRDTracker_t::FindChambersInRoad(const TRDTRK* t, const float roadY, const float roadZ, const int iLayer, int* det, const float zMax, const float alpha, const float zShiftTrk) const +GPUd() void GPUTRDTracker_t::FindChambersInRoad(const TRDTRK* t, const float roadY, const float roadZ, const int32_t iLayer, int32_t* det, const float zMax, const float alpha, const float zShiftTrk) const { //-------------------------------------------------------------------- // determine initial chamber where the track ends up @@ -1053,22 +1053,21 @@ GPUd() void GPUTRDTracker_t::FindChambersInRoad(const TRDTRK* t, c const float yMax = CAMath::Abs(mGeo->GetCol0(iLayer)); float zTrk = t->getZ() + zShiftTrk; - int currStack = mGeo->GetStack(zTrk, iLayer); - int currSec = GetSector(alpha); - int currDet; - - int nDets = 0; + int32_t currStack = mGeo->GetStack(zTrk, iLayer); + int32_t currSec = GetSector(alpha); + int32_t currDet; + int32_t nDets = 0; if (currStack > -1) { // chamber unambiguous currDet = mGeo->GetDetector(iLayer, currStack, currSec); det[nDets++] = currDet; const GPUTRDpadPlane* pp = mGeo->GetPadPlane(iLayer, currStack); - int lastPadRow = mGeo->GetRowMax(iLayer, currStack, 0); + int32_t lastPadRow = mGeo->GetRowMax(iLayer, currStack, 0); float zCenter = pp->GetRowPos(lastPadRow / 2); if ((zTrk + roadZ) > pp->GetRow0() || (zTrk - roadZ) < pp->GetRowEnd()) { - int addStack = zTrk > zCenter ? currStack - 1 : currStack + 1; + int32_t addStack = zTrk > zCenter ? currStack - 1 : currStack + 1; if (addStack < kNStacks && addStack > -1) { det[nDets++] = mGeo->GetDetector(iLayer, addStack, currSec); } @@ -1098,20 +1097,20 @@ GPUd() void GPUTRDTracker_t::FindChambersInRoad(const TRDTRK* t, c } // add chamber(s) from neighbouring sector in case the track is close to the boundary if ((CAMath::Abs(t->getY()) + roadY) > yMax) { - const int nStacksToSearch = nDets; - int newSec; + const int32_t nStacksToSearch = nDets; + int32_t newSec; if (t->getY() > 0) { newSec = (currSec + 1) % kNSectors; } else { newSec = (currSec > 0) ? currSec - 1 : kNSectors - 1; } - for (int idx = 0; idx < nStacksToSearch; ++idx) { + for (int32_t idx = 0; idx < nStacksToSearch; ++idx) { currStack = mGeo->GetStack(det[idx]); det[nDets++] = mGeo->GetDetector(iLayer, currStack, newSec); } } // skip PHOS hole and non-existing chamber 17_4_4 - for (int iDet = 0; iDet < nDets; iDet++) { + for (int32_t iDet = 0; iDet < nDets; iDet++) { if (!mGeo->ChamberInGeometry(det[iDet])) { det[iDet] = -1; } @@ -1119,7 +1118,7 @@ GPUd() void GPUTRDTracker_t::FindChambersInRoad(const TRDTRK* t, c } template -GPUd() bool GPUTRDTracker_t::IsGeoFindable(const TRDTRK* t, const int layer, const float alpha, const float zShiftTrk) const +GPUd() bool GPUTRDTracker_t::IsGeoFindable(const TRDTRK* t, const int32_t layer, const float alpha, const float zShiftTrk) const { //-------------------------------------------------------------------- // returns true if track position inside active area of the TRD @@ -1128,7 +1127,7 @@ GPUd() bool GPUTRDTracker_t::IsGeoFindable(const TRDTRK* t, const float zTrk = t->getZ() + zShiftTrk; - int det = GetDetectorNumber(zTrk, alpha, layer); + int32_t det = GetDetectorNumber(zTrk, alpha, layer); // reject tracks between stacks if (det < 0) { diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h index 743d8512f0281..3d387d3694fe5 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h @@ -67,7 +67,7 @@ class GPUTRDTracker_t : public GPUProcessor void* SetPointersTracks(void* base); void PrepareTracking(GPUChainTracking* chainTracking); - void SetNCandidates(int n); + void SetNCandidates(int32_t n); void PrintSettings() const; bool IsInitialized() const { return mIsInitialized; } void StartDebugging(); @@ -83,24 +83,24 @@ class GPUTRDTracker_t : public GPUProcessor float mTime; // time estimate for seeding track in us float mTimeAddMax; // max. time that can be added to this track seed in us float mTimeSubMax; // max. time that can be subtracted to this track seed in us - short mSide; // -1 : A-side, +1 : C-side (relevant only for TPC-only tracks) + int16_t mSide; // -1 : A-side, +1 : C-side (relevant only for TPC-only tracks) GPUd() float GetTimeMin() const { return mTime - mTimeSubMax; } GPUd() float GetTimeMax() const { return mTime + mTimeAddMax; } GPUd() HelperTrackAttributes() : mTime(-1.f), mTimeAddMax(0.f), mTimeSubMax(0.f), mSide(0) {} }; struct Hypothesis { - int mLayers; // number of layers with TRD space point - int mCandidateId; // to which track candidate the hypothesis belongs - int mTrackletId; // tracklet index to be used for update (global index within tracklet array) + int32_t mLayers; // number of layers with TRD space point + int32_t mCandidateId; // to which track candidate the hypothesis belongs + int32_t mTrackletId; // tracklet index to be used for update (global index within tracklet array) float mChi2; // predicted chi2 for given space point GPUd() float GetReducedChi2() { return mLayers > 0 ? mChi2 / mLayers : mChi2; } GPUd() Hypothesis() : mLayers(0), mCandidateId(-1), mTrackletId(-1), mChi2(9999.f) {} - GPUd() Hypothesis(int layers, int candidateId, int trackletId, float chi2) : mLayers(layers), mCandidateId(candidateId), mTrackletId(trackletId), mChi2(chi2) {} + GPUd() Hypothesis(int32_t layers, int32_t candidateId, int32_t trackletId, float chi2) : mLayers(layers), mCandidateId(candidateId), mTrackletId(trackletId), mChi2(chi2) {} }; - short MemoryPermanent() const { return mMemoryPermanent; } + int16_t MemoryPermanent() const { return mMemoryPermanent; } GPUhd() void OverrideGPUGeometry(TRD_GEOMETRY_CONST GPUTRDGeometry* geo) { mGeo = geo; } void Reset(); @@ -111,26 +111,25 @@ class GPUTRDTracker_t : public GPUProcessor } GPUd() bool PreCheckTrackTRDCandidate(const GPUTPCGMMergedTrack& trk) const { return trk.OK() && !trk.Looper(); } GPUd() bool CheckTrackTRDCandidate(const TRDTRK& trk) const; - GPUd() int LoadTrack(const TRDTRK& trk, unsigned int tpcTrackId, bool checkTrack = true, HelperTrackAttributes* attribs = nullptr); + GPUd() int32_t LoadTrack(const TRDTRK& trk, uint32_t tpcTrackId, bool checkTrack = true, HelperTrackAttributes* attribs = nullptr); - GPUd() int GetCollisionIDs(int iTrk, int* collisionIds) const; - GPUd() void DoTrackingThread(int iTrk, int threadId = 0); + GPUd() int32_t GetCollisionIDs(int32_t iTrk, int32_t* collisionIds) const; + GPUd() void DoTrackingThread(int32_t iTrk, int32_t threadId = 0); static GPUd() bool ConvertTrkltToSpacePoint(const GPUTRDGeometry& geo, GPUTRDTrackletWord& trklt, GPUTRDSpacePoint& sp); - GPUd() bool CalculateSpacePoints(int iCollision = 0); - GPUd() bool FollowProlongation(PROP* prop, TRDTRK* t, int iTrk, int threadId, int collisionId); - GPUd() int GetDetectorNumber(const float zPos, const float alpha, const int layer) const; + GPUd() bool CalculateSpacePoints(int32_t iCollision = 0); + GPUd() bool FollowProlongation(PROP* prop, TRDTRK* t, int32_t iTrk, int32_t threadId, int32_t collisionId); + GPUd() int32_t GetDetectorNumber(const float zPos, const float alpha, const int32_t layer) const; GPUd() bool AdjustSector(PROP* prop, TRDTRK* t) const; - GPUd() int GetSector(float alpha) const; - GPUd() float GetAlphaOfSector(const int sec) const; + GPUd() int32_t GetSector(float alpha) const; + GPUd() float GetAlphaOfSector(const int32_t sec) const; GPUd() float GetRPhiRes(float snp) const { return (mRPhiA2 + mRPhiC2 * (snp - mRPhiB) * (snp - mRPhiB)); } // parametrization obtained from track-tracklet residuals: GPUd() float GetAngularResolution(float snp) const { return mDyA2 + mDyC2 * (snp - mDyB) * (snp - mDyB); } // a^2 + c^2 * (snp - b)^2 GPUd() float ConvertAngleToDy(float snp) const { return mAngleToDyA + mAngleToDyB * snp + mAngleToDyC * snp * snp; } // a + b*snp + c*snp^2 is more accurate than sin(phi) = (dy / xDrift) / sqrt(1+(dy/xDrift)^2) GPUd() float GetAngularPull(float dYtracklet, float snp) const; GPUd() void RecalcTrkltCov(const float tilt, const float snp, const float rowSize, My_Float (&cov)[3]); - GPUd() void FindChambersInRoad(const TRDTRK* t, const float roadY, const float roadZ, const int iLayer, int* det, const float zMax, const float alpha, const float zShiftTrk) const; - GPUd() bool IsGeoFindable(const TRDTRK* t, const int layer, const float alpha, const float zShiftTrk) const; - GPUd() void InsertHypothesis(Hypothesis hypo, int& nCurrHypothesis, int idxOffset); - + GPUd() void FindChambersInRoad(const TRDTRK* t, const float roadY, const float roadZ, const int32_t iLayer, int32_t* det, const float zMax, const float alpha, const float zShiftTrk) const; + GPUd() bool IsGeoFindable(const TRDTRK* t, const int32_t layer, const float alpha, const float zShiftTrk) const; + GPUd() void InsertHypothesis(Hypothesis hypo, int32_t& nCurrHypothesis, int32_t idxOffset); // settings GPUd() void SetGenerateSpacePoints(bool flag) { mGenerateSpacePoints = flag; } @@ -144,11 +143,11 @@ class GPUTRDTracker_t : public GPUProcessor GPUd() bool GetIsDebugOutputOn() const { return mDebugOutput; } GPUd() float GetMaxEta() const { return mMaxEta; } - GPUd() int GetNCandidates() const { return mNCandidates; } + GPUd() int32_t GetNCandidates() const { return mNCandidates; } GPUd() float GetRoadZ() const { return mRoadZ; } // output - GPUd() int NTracks() const { return mNTracks; } + GPUd() int32_t NTracks() const { return mNTracks; } GPUd() GPUTRDSpacePoint* SpacePoints() const { return mSpacePoints; } GPUd() TRDTRK* Tracks() const { return mTracks; } GPUd() void DumpTracks(); @@ -161,24 +160,24 @@ class GPUTRDTracker_t : public GPUProcessor bool mIsInitialized; // flag is set upon initialization bool mGenerateSpacePoints; // if true, only tracklets are provided as input and they will be converted into space points by the tracker bool mProcessPerTimeFrame; // if true, tracking is done per time frame instead of on a single events basis - short mNAngleHistogramBins; // number of bins per chamber for the angular difference histograms + int16_t mNAngleHistogramBins; // number of bins per chamber for the angular difference histograms float mAngleHistogramRange; // range of impact angles covered by each histogram - short mMemoryPermanent; // memory id of permanent memory for the tracker - short mMemoryTracklets; // memory id of memory for TRD tracklets - short mMemoryTracks; // memory id of memory for tracks (used for i/o) - int mNMaxCollisions; // max number of collisions to process (per time frame) - int mNMaxTracks; // max number of tracks the tracker can handle (per event) - int mNMaxSpacePoints; // max number of space points hold by the tracker (per event) + int16_t mMemoryPermanent; // memory id of permanent memory for the tracker + int16_t mMemoryTracklets; // memory id of memory for TRD tracklets + int16_t mMemoryTracks; // memory id of memory for tracks (used for i/o) + int32_t mNMaxCollisions; // max number of collisions to process (per time frame) + int32_t mNMaxTracks; // max number of tracks the tracker can handle (per event) + int32_t mNMaxSpacePoints; // max number of space points hold by the tracker (per event) TRDTRK* mTracks; // array of trd-updated tracks HelperTrackAttributes* mTrackAttribs; // array with additional (transient) track attributes - int mNCandidates; // max. track hypothesis per layer - int mNTracks; // number of TPC tracks to be matched - int mNEvents; // number of processed events - int mMaxThreads; // maximum number of supported threads + int32_t mNCandidates; // max. track hypothesis per layer + int32_t mNTracks; // number of TPC tracks to be matched + int32_t mNEvents; // number of processed events + int32_t mMaxThreads; // maximum number of supported threads // index of first tracklet for each chamber within tracklets array, last entry is total number of tracklets for given collision // the array has (kNChambers + 1) * numberOfCollisions entries // note, that for collision iColl one has to add an offset corresponding to the index of the first tracklet of iColl to the index stored in mTrackletIndexArray - int* mTrackletIndexArray; + int32_t* mTrackletIndexArray; Hypothesis* mHypothesis; // array with multiple track hypothesis TRDTRK* mCandidates; // array of tracks for multiple hypothesis tracking GPUTRDSpacePoint* mSpacePoints; // array with tracklet coordinates in global tracking frame diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.cxx index 9ee57e9578e99..c6a60afc9b4bd 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.cxx @@ -84,7 +84,7 @@ void GPUTRDTrackerComponent::GetInputDataTypes(std::vectorGetEntries() : 0; + int32_t nArgs = pTokens ? pTokens->GetEntries() : 0; - for (int i = 0; i < nArgs; i++) { + for (int32_t i = 0; i < nArgs; i++) { argument = ((TObjString*)pTokens->At(i))->GetString(); if (argument.IsNull()) { continue; @@ -151,11 +151,11 @@ int GPUTRDTrackerComponent::ReadConfigurationString(const char* arguments) } // ################################################################################# -int GPUTRDTrackerComponent::DoInit(int argc, const char** argv) +int32_t GPUTRDTrackerComponent::DoInit(int argc, const char** argv) { // see header file for class documentation - int iResult = 0; + int32_t iResult = 0; if (fTracker) { return -EINPROGRESS; } @@ -175,7 +175,7 @@ int GPUTRDTrackerComponent::DoInit(int argc, const char** argv) fTrackList->SetOwner(kFALSE); TString arguments = ""; - for (int i = 0; i < argc; i++) { + for (int32_t i = 0; i < argc; i++) { if (!arguments.IsNull()) { arguments += " "; } @@ -221,7 +221,7 @@ int GPUTRDTrackerComponent::DoInit(int argc, const char** argv) } // ################################################################################# -int GPUTRDTrackerComponent::DoDeinit() +int32_t GPUTRDTrackerComponent::DoDeinit() { // see header file for class documentation delete fTracker; @@ -232,7 +232,7 @@ int GPUTRDTrackerComponent::DoDeinit() } // ################################################################################# -int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, std::vector& outputBlocks) +int32_t GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, std::vector& outputBlocks) { // process event @@ -251,29 +251,29 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con AliHLTUInt32_t maxBufferSize = size; size = 0; // output size - int iResult = 0; + int32_t iResult = 0; if (fTrackList->GetEntries() != 0) { fTrackList->Clear(); // tracks are owned by GPUTRDTrackerGPU } - int nBlocks = evtData.fBlockCnt; + int32_t nBlocks = evtData.fBlockCnt; const AliHLTTracksData* tpcData = nullptr; const AliHLTTracksData* itsData = nullptr; const AliHLTTrackMCData* tpcDataMC = nullptr; std::vector tracksTPC; - std::vector tracksTPCId; + std::vector tracksTPCId; bool hasMCtracklets = false; - int nTrackletsTotal = 0; - int nTrackletsTotalMC = 0; + int32_t nTrackletsTotal = 0; + int32_t nTrackletsTotalMC = 0; const GPUTRDTrackletWord* tracklets = nullptr; const GPUTRDTrackletLabels* trackletsMC = nullptr; - for (int iBlock = 0; iBlock < nBlocks; iBlock++) { + for (int32_t iBlock = 0; iBlock < nBlocks; iBlock++) { if (blocks[iBlock].fDataType == (kAliHLTDataTypeTrack | kAliHLTDataOriginITS) && fRequireITStrack) { itsData = (const AliHLTTracksData*)blocks[iBlock].fPtr; fBenchmark.AddInput(blocks[iBlock].fSize); @@ -312,41 +312,41 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con // copy tracklets into temporary vector to allow for sorting them (the input array is const) std::vector trackletsTmp(nTrackletsTotal); - for (int iTrklt = 0; iTrklt < nTrackletsTotal; ++iTrklt) { + for (int32_t iTrklt = 0; iTrklt < nTrackletsTotal; ++iTrklt) { trackletsTmp[iTrklt] = tracklets[iTrklt]; } - int nTPCtracks = tpcData->fCount; + int32_t nTPCtracks = tpcData->fCount; std::vector itsAvail(nTPCtracks, false); if (itsData) { // look for ITS tracks with >= 2 hits - int nITStracks = itsData->fCount; + int32_t nITStracks = itsData->fCount; const AliHLTExternalTrackParam* currITStrack = itsData->fTracklets; - for (int iTrkITS = 0; iTrkITS < nITStracks; iTrkITS++) { + for (int32_t iTrkITS = 0; iTrkITS < nITStracks; iTrkITS++) { if (currITStrack->fNPoints >= 2) { itsAvail.at(currITStrack->fTrackID) = true; } - unsigned int dSize = sizeof(AliHLTExternalTrackParam) + currITStrack->fNPoints * sizeof(unsigned int); + uint32_t dSize = sizeof(AliHLTExternalTrackParam) + currITStrack->fNPoints * sizeof(uint32_t); currITStrack = (AliHLTExternalTrackParam*)(((Byte_t*)currITStrack) + dSize); } } - std::map mcLabels; + std::map mcLabels; if (tpcDataMC) { // look for TPC track MC labels - int nMCtracks = tpcDataMC->fCount; - for (int iMC = 0; iMC < nMCtracks; iMC++) { + int32_t nMCtracks = tpcDataMC->fCount; + for (int32_t iMC = 0; iMC < nMCtracks; iMC++) { const AliHLTTrackMCLabel& lab = tpcDataMC->fLabels[iMC]; mcLabels[lab.fTrackID] = lab.fMCLabel; } } const AliHLTExternalTrackParam* currOutTrackTPC = tpcData->fTracklets; - for (int iTrk = 0; iTrk < nTPCtracks; iTrk++) { + for (int32_t iTrk = 0; iTrk < nTPCtracks; iTrk++) { // store TPC tracks (if required only the ones with >=2 ITS hits) if (itsData != nullptr && !itsAvail.at(currOutTrackTPC->fTrackID)) { continue; } GPUTRDTrackGPU t(*currOutTrackTPC); - int mcLabel = -1; + int32_t mcLabel = -1; if (tpcDataMC) { if (mcLabels.find(currOutTrackTPC->fTrackID) != mcLabels.end()) { mcLabel = mcLabels[currOutTrackTPC->fTrackID]; @@ -354,7 +354,7 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con } tracksTPC.push_back(t); tracksTPCId.push_back(currOutTrackTPC->fTrackID); - unsigned int dSize = sizeof(AliHLTExternalTrackParam) + currOutTrackTPC->fNPoints * sizeof(unsigned int); + uint32_t dSize = sizeof(AliHLTExternalTrackParam) + currOutTrackTPC->fNPoints * sizeof(uint32_t); currOutTrackTPC = (AliHLTExternalTrackParam*)+(((Byte_t*)currOutTrackTPC) + dSize); } @@ -367,7 +367,7 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con fChain->mIOPtrs.nMergedTracks = tracksTPC.size(); fChain->mIOPtrs.nTRDTracklets = nTrackletsTotal; fChain->mIOPtrs.nTRDTriggerRecords = 1; - char trigRecMaskDummy[1] = {1}; + uint8_t trigRecMaskDummy[1] = {1}; fChain->mIOPtrs.trdTrigRecMask = &(trigRecMaskDummy[0]); fRec->PrepareEvent(); fRec->SetupGPUProcessor(fTracker, true); @@ -376,7 +376,7 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con fChain->mIOPtrs.trdTracklets = &(trackletsTmp[0]); // loop over all tracks - for (unsigned int iTrack = 0; iTrack < tracksTPC.size(); ++iTrack) { + for (uint32_t iTrack = 0; iTrack < tracksTPC.size(); ++iTrack) { fTracker->LoadTrack(tracksTPC[iTrack], tracksTPCId[iTrack]); } @@ -385,11 +385,11 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con fBenchmark.Stop(1); GPUTRDTrackGPU* trackArray = fTracker->Tracks(); - int nTracks = fTracker->NTracks(); + int32_t nTracks = fTracker->NTracks(); GPUTRDSpacePoint* spacePoints = fTracker->SpacePoints(); // TODO delete fTrackList since it only works for TObjects (or use compiler flag after tests with GPU track type) - // for (int iTrack=0; iTrackAddLast(&trackArray[iTrack]); //} @@ -408,9 +408,9 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con GPUTRDTrackData* outTracks = (GPUTRDTrackData*)(outputPtr); outTracks->fCount = 0; - int assignedTracklets = 0; + int32_t assignedTracklets = 0; - for (int iTrk = 0; iTrk < nTracks; ++iTrk) { + for (int32_t iTrk = 0; iTrk < nTracks; ++iTrk) { GPUTRDTrackGPU& t = trackArray[iTrk]; if (t.getNtracklets() == 0) { continue; @@ -452,21 +452,21 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con empty.fX[1] = 0; empty.fX[2] = 0; empty.fVolumeId = 0; - for (int i = 0; i < nTrackletsTotal; ++i) { + for (int32_t i = 0; i < nTrackletsTotal; ++i) { outTrackPoints->fPoints[i] = empty; } } - for (int i = 0; i < nTrackletsTotal; ++i) { + for (int32_t i = 0; i < nTrackletsTotal; ++i) { const GPUTRDSpacePoint& sp = spacePoints[i]; GPUTRDTrackPoint* currOutPoint = &outTrackPoints->fPoints[i]; currOutPoint->fX[0] = sp.getX(); // x in sector coordinates currOutPoint->fX[1] = sp.getY(); // y in sector coordinates currOutPoint->fX[2] = sp.getZ(); // z in sector coordinates - int detId = trackletsTmp[i].GetDetector(); - int layer = detId % 6; // TRD layer number for given detector - int modId = (detId / 18) * 5 + ((detId % 30) / 6); // global TRD stack number [0..89] - int volId = (UShort_t(9 + layer) << 11) | UShort_t(modId); // taken from AliGeomManager::LayerToVolUID(). AliGeomManager::ELayerID(AliGeomManager::kTRD1) == 9 + int32_t detId = trackletsTmp[i].GetDetector(); + int32_t layer = detId % 6; // TRD layer number for given detector + int32_t modId = (detId / 18) * 5 + ((detId % 30) / 6); // global TRD stack number [0..89] + int32_t volId = (UShort_t(9 + layer) << 11) | UShort_t(modId); // taken from AliGeomManager::LayerToVolUID(). AliGeomManager::ELayerID(AliGeomManager::kTRD1) == 9 currOutPoint->fVolumeId = volId; } AliHLTComponentBlockData resultDataSP; @@ -489,11 +489,11 @@ int GPUTRDTrackerComponent::DoEvent(const AliHLTComponentEventData& evtData, con } // ################################################################################# -int GPUTRDTrackerComponent::Reconfigure(const char* cdbEntry, const char* chainId) +int32_t GPUTRDTrackerComponent::Reconfigure(const char* cdbEntry, const char* chainId) { // see header file for class documentation - int iResult = 0; + int32_t iResult = 0; TString cdbPath; if (cdbEntry) { cdbPath = cdbEntry; diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.h index 28267c1ae5d71..e6d4ef609e101 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerComponent.h @@ -77,15 +77,15 @@ class GPUTRDTrackerComponent : public AliHLTProcessor AliHLTComponentDataType GetOutputDataType(); /** @see component interface @ref AliHLTComponent::GetOutputDataType */ - int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); + int32_t GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); /** interface function, see @ref AliHLTComponent for description */ - void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); /** interface function, see @ref AliHLTComponent for description */ AliHLTComponent* Spawn(); - int ReadConfigurationString(const char* arguments); + int32_t ReadConfigurationString(const char* arguments); protected: /* @@ -99,16 +99,16 @@ class GPUTRDTrackerComponent : public AliHLTProcessor // AliHLTComponent interface functions /** interface function, see @ref AliHLTComponent for description */ - int DoInit(int argc, const char** argv); + int32_t DoInit(int argc, const char** argv); /** interface function, see @ref AliHLTComponent for description */ - int DoDeinit(); + int32_t DoDeinit(); /** interface function, see @ref AliHLTComponent for description */ - int DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); + int32_t DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size, vector& outputBlocks); /** interface function, see @ref AliHLTComponent for description */ - int Reconfigure(const char* cdbEntry, const char* chainId); + int32_t Reconfigure(const char* cdbEntry, const char* chainId); /////////////////////////////////////////////////////////////////////////////////// diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h index e05b2e719c3d2..ed590ff7b89ad 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerDebug.h @@ -42,12 +42,12 @@ class GPUTRDTrackerDebug fStreamer = new TTreeSRedirector("TRDhlt.root", "recreate"); } - int GetSector(float alpha) + int32_t GetSector(float alpha) { if (alpha < 0) { alpha += 2.f * M_PI; } - return (int)(alpha * 18 / (2.f * M_PI)); + return (int32_t)(alpha * 18 / (2.f * M_PI)); } void ExpandVectors() @@ -134,7 +134,7 @@ class GPUTRDTrackerDebug } // general information - void SetGeneralInfo(int iEv, int nTPCtracks, int iTrk, float pt) + void SetGeneralInfo(int32_t iEv, int32_t nTPCtracks, int32_t iTrk, float pt) { fEv = iEv; fNTPCtracks = nTPCtracks; @@ -143,7 +143,7 @@ class GPUTRDTrackerDebug } // track parameters - void SetTrackParameter(const T& trk, int ly) + void SetTrackParameter(const T& trk, int32_t ly) { fTrackX(ly) = trk.getX(); fTrackY(ly) = trk.getY(); @@ -156,7 +156,7 @@ class GPUTRDTrackerDebug fTrackYerr(ly) = trk.getSigmaY2(); fTrackZerr(ly) = trk.getSigmaZ2(); } - void SetTrackParameterNoUp(const T& trk, int ly) + void SetTrackParameterNoUp(const T& trk, int32_t ly) { fTrackNoUpX(ly) = trk.getX(); fTrackNoUpY(ly) = trk.getY(); @@ -173,7 +173,7 @@ class GPUTRDTrackerDebug fChi2 = trk.getChi2(); fNlayers = trk.getNlayers(); fNtrklts = trk.getNtracklets(); - for (int iLy = 0; iLy < 6; iLy++) { + for (int32_t iLy = 0; iLy < 6; iLy++) { if (trk.getIsFindable(iLy)) { fFindable(iLy) = 1; } @@ -181,34 +181,34 @@ class GPUTRDTrackerDebug } // tracklet parameters - void SetRawTrackletPosition(const float fX, const float fY, const float fZ, int ly) + void SetRawTrackletPosition(const float fX, const float fY, const float fZ, int32_t ly) { fTrackletX(ly) = fX; fTrackletY(ly) = fY; fTrackletZ(ly) = fZ; } - void SetCorrectedTrackletPosition(const My_Float* fYZ, int ly) + void SetCorrectedTrackletPosition(const My_Float* fYZ, int32_t ly) { fTrackletYcorr(ly) = fYZ[0]; fTrackletZcorr(ly) = fYZ[1]; } - void SetTrackletCovariance(const My_Float* fCov, int ly) + void SetTrackletCovariance(const My_Float* fCov, int32_t ly) { fTrackletY2err(ly) = fCov[0]; fTrackletYZerr(ly) = fCov[1]; fTrackletZ2err(ly) = fCov[2]; } - void SetTrackletProperties(const float dy, const int det, int ly) + void SetTrackletProperties(const float dy, const int32_t det, int32_t ly) { fTrackletDy(ly) = dy; fTrackletDet(ly) = det; } // update information - void SetChi2Update(float chi2, int ly) { fChi2Update(ly) = chi2; } + void SetChi2Update(float chi2, int32_t ly) { fChi2Update(ly) = chi2; } // other infos - void SetRoad(float roadY, float roadZ, int ly) + void SetRoad(float roadY, float roadZ, int32_t ly) { fRoadY(ly) = roadY; fRoadZ(ly) = roadZ; @@ -261,11 +261,11 @@ class GPUTRDTrackerDebug } private: - int fEv; - int fNTPCtracks; - int fTrk; + int32_t fEv; + int32_t fNTPCtracks; + int32_t fTrk; float fPtTPC; - int fNlayers; + int32_t fNlayers; float fChi2; TVectorF fTrackX; TVectorF fTrackY; @@ -323,25 +323,25 @@ class GPUTRDTrackerDebug GPUd() void Reset() {} // general information - GPUd() void SetGeneralInfo(int iEv, int nTPCtracks, int iTrk, float pt) {} + GPUd() void SetGeneralInfo(int32_t iEv, int32_t nTPCtracks, int32_t iTrk, float pt) {} // track parameters - GPUd() void SetTrackParameter(const T& trk, int ly) {} - GPUd() void SetTrackParameterNoUp(const T& trk, int ly) {} + GPUd() void SetTrackParameter(const T& trk, int32_t ly) {} + GPUd() void SetTrackParameterNoUp(const T& trk, int32_t ly) {} GPUd() void SetTrack(const T& trk) {} // tracklet parameters - GPUd() void SetRawTrackletPosition(const float fX, const float fY, const float fZ, int ly) {} - GPUd() void SetCorrectedTrackletPosition(const My_Float* fYZ, int ly) {} - GPUd() void SetTrackletCovariance(const My_Float* fCov, int ly) {} - GPUd() void SetTrackletProperties(const float dy, const int det, int ly) {} + GPUd() void SetRawTrackletPosition(const float fX, const float fY, const float fZ, int32_t ly) {} + GPUd() void SetCorrectedTrackletPosition(const My_Float* fYZ, int32_t ly) {} + GPUd() void SetTrackletCovariance(const My_Float* fCov, int32_t ly) {} + GPUd() void SetTrackletProperties(const float dy, const int32_t det, int32_t ly) {} // update information - GPUd() void SetChi2Update(float chi2, int ly) {} - GPUd() void SetChi2YZPhiUpdate(float chi2, int ly) {} + GPUd() void SetChi2Update(float chi2, int32_t ly) {} + GPUd() void SetChi2YZPhiUpdate(float chi2, int32_t ly) {} // other infos - GPUd() void SetRoad(float roadY, float roadZ, int ly) {} + GPUd() void SetRoad(float roadY, float roadZ, int32_t ly) {} GPUd() void SetFindable(bool* findable) {} GPUd() void Output() {} }; diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx index 20db05948c598..a69bb9394f735 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.cxx @@ -22,8 +22,8 @@ using namespace GPUCA_NAMESPACE::gpu; -template -GPUdii() void GPUTRDTrackerKernels::Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, T* externalInstance) +template +GPUdii() void GPUTRDTrackerKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, T* externalInstance) { auto* trdTracker = &processors.getTRDTracker(); #ifndef GPUCA_GPUCODE_DEVICE @@ -37,14 +37,14 @@ GPUdii() void GPUTRDTrackerKernels::Thread(int nBlocks, int nThreads, int iBlock } #endif GPUCA_OPENMP(parallel for if(!trdTracker->GetRec().GetProcessingSettings().ompKernels) num_threads(trdTracker->GetRec().GetProcessingSettings().ompThreads)) - for (int i = get_global_id(0); i < trdTracker->NTracks(); i += get_global_size(0)) { + for (int32_t i = get_global_id(0); i < trdTracker->NTracks(); i += get_global_size(0)) { trdTracker->DoTrackingThread(i, get_global_id(0)); } } #if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code. -template GPUdni() void GPUTRDTrackerKernels::Thread<0>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTrackerGPU* externalInstance); +template GPUdni() void GPUTRDTrackerKernels::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTrackerGPU* externalInstance); #ifdef GPUCA_HAVE_O2HEADERS -template GPUdni() void GPUTRDTrackerKernels::Thread<1>(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTracker* externalInstance); +template GPUdni() void GPUTRDTrackerKernels::Thread<1>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, GPUTRDTracker* externalInstance); #endif // GPUCA_HAVE_O2HEADERS #endif diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.h index d773ce612bbc1..79e996ab79c71 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackerKernels.h @@ -29,8 +29,8 @@ class GPUTRDTrackerKernels : public GPUKernelTemplate gpuVersion = 0, o2Version = 1 }; GPUhdi() CONSTEXPR static GPUDataTypes::RecoStep GetRecoStep() { return GPUCA_RECO_STEP::TRDTracking; } - template - GPUd() static void Thread(int nBlocks, int nThreads, int iBlock, int iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, T* externalInstance = nullptr); + template + GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, T* externalInstance = nullptr); }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletLabels.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletLabels.h index 5e0e1ee71ddc2..dea3f5ffe4d27 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletLabels.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletLabels.h @@ -23,7 +23,7 @@ namespace gpu { struct GPUTRDTrackletLabels { - int mLabel[3]; + int32_t mLabel[3]; }; } // namespace gpu } // namespace GPUCA_NAMESPACE diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx index dfba6baa96c0d..02c6891fc45b4 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.cxx @@ -85,7 +85,7 @@ void GPUTRDTrackletReaderComponent::GetInputDataTypes(vector remainingArgs; - for (int i = 0; i < argc; ++i) { + for (int32_t i = 0; i < argc; ++i) { remainingArgs.push_back(argv[i]); } @@ -193,7 +193,7 @@ int GPUTRDTrackletReaderComponent::DoInit(int argc, const char** argv) return iResult; } -int GPUTRDTrackletReaderComponent::DoDeinit() +int32_t GPUTRDTrackletReaderComponent::DoDeinit() { if (fRawReaderTrd) { @@ -216,7 +216,7 @@ int GPUTRDTrackletReaderComponent::DoDeinit() // void GPUTRDTrackletReaderComponent::DbgLog(const char* prefix, const char* msg){ // AliHLTEventID_t eventNumber = fEventId; -// int runNumber = -1; +// int32_t runNumber = -1; // HLTInfo("TRDGM %s-%s: [PRE] %s%s", // (runNumber >= 0) ? Form("%06d", runNumber) : "XXXXXX", // (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX", @@ -227,7 +227,7 @@ void GPUTRDTrackletReaderComponent::DbgLog(const char* prefix, ...) { #ifdef __TRDHLTDEBUG AliHLTEventID_t eventNumber = fEventId; - int runNumber = -1; + int32_t runNumber = -1; printf("TRDHLTGM %s-X-%s: [PRE] %s", (runNumber >= 0) ? Form("%06d", runNumber) : "XXXXXX", (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX", (strlen(prefix) > 0) ? Form("<%s> ", prefix) : ""); #endif va_list args; @@ -238,7 +238,7 @@ void GPUTRDTrackletReaderComponent::DbgLog(const char* prefix, ...) va_end(args); } -int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEventData, AliHLTComponentTriggerData& /*trigData*/) +int32_t GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEventData, AliHLTComponentTriggerData& /*trigData*/) { fEventId = hltEventData.fEventID; @@ -246,7 +246,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv HLTInfo("### START DoEvent [event id: %lu, %d blocks, size: %d]", hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize); // event processing function - int iResult = 0; + int32_t iResult = 0; fTrackletArray->Clear(); fRawReaderMem->ClearBuffers(); @@ -262,12 +262,12 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv { // read raw data TString infoStr(""); - unsigned int sourceSectors = 0; + uint32_t sourceSectors = 0; // loop over all incoming TRD raw data blocks for (const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD); pBlock != nullptr && iResult >= 0; pBlock = GetNextInputBlock()) { - int trdSector = -1; + int32_t trdSector = -1; // determine sector from block specification for (unsigned pos = 0; pos < 8 * sizeof(AliHLTUInt32_t); pos++) { @@ -287,7 +287,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv // add data block to rawreader infoStr += Form("%02d, ", trdSector); sourceSectors |= pBlock->fSpecification; - if (!fRawReaderMem->AddBuffer((unsigned char*)pBlock->fPtr, pBlock->fSize, trdSector + 1024)) { + if (!fRawReaderMem->AddBuffer((uint8_t*)pBlock->fPtr, pBlock->fSize, trdSector + 1024)) { LogError("Could not add buffer of data block %s, 0x%08x to rawreader", DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification); continue; } @@ -301,10 +301,10 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv fRawReaderTrd->ReadEvent(); // read and process TRD tracklets - int nTracklets = fTrackletArray->GetEntriesFast(); + int32_t nTracklets = fTrackletArray->GetEntriesFast(); HLTInfo("There are %i tracklets in this event\n", nTracklets); - for (int iTracklet = 0; iTracklet < nTracklets; ++iTracklet) { + for (int32_t iTracklet = 0; iTracklet < nTracklets; ++iTracklet) { GPUTRDTrackletWord trkl = *((AliTRDtrackletWord*)fTrackletArray->At(iTracklet)); outputTrkls.push_back(trkl); } @@ -327,7 +327,7 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv HLTFatal("No tracklet branch found in tracklet tree"); return -EINVAL; } - int nTracklets = trklbranch->GetEntries(); + int32_t nTracklets = trklbranch->GetEntries(); HLTInfo("Input tree with %d TRD MCM tracklets", nTracklets); //----------------------------------- @@ -366,8 +366,8 @@ int GPUTRDTrackletReaderComponent::DoEvent(const AliHLTComponentEventData& hltEv AliTRDtrackletMCM* trkl = 0x0; trklbranch->SetAddress(&trkl); - for (int iTracklet = 0; iTracklet < nTracklets; iTracklet++) { - int nbytes = trklbranch->GetEntry(iTracklet, 1); + for (int32_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) { + int32_t nbytes = trklbranch->GetEntry(iTracklet, 1); if (!trkl || nbytes <= 0) { HLTWarning("Can not read entry from tracklet branch"); continue; diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.h index 983c93148ba70..5aa60cc68291f 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletReaderComponent.h @@ -81,8 +81,8 @@ class GPUTRDTrackletReaderComponent : public AliHLTProcessor const char* GetComponentID(); void GetInputDataTypes(vector& list); AliHLTComponentDataType GetOutputDataType(); - int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); - void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + int32_t GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList); + void GetOutputDataSize(uint64_t& constBase, double& inputMultiplier); void GetOCDBObjectDescription(TMap* const targetMap); // Spawn function, return new class instance @@ -90,12 +90,12 @@ class GPUTRDTrackletReaderComponent : public AliHLTProcessor protected: // AliHLTComponent interface functions - int DoInit(int argc, const char** argv); - int DoDeinit(); - int DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData); - int ScanConfigurationArgument(int argc, const char** argv); - int Reconfigure(const char* cdbEntry, const char* chainId); - int ReadPreprocessorValues(const char* modules); + int32_t DoInit(int argc, const char** argv); + int32_t DoDeinit(); + int32_t DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData); + int32_t ScanConfigurationArgument(int argc, const char** argv); + int32_t Reconfigure(const char* cdbEntry, const char* chainId); + int32_t ReadPreprocessorValues(const char* modules); using AliHLTProcessor::DoEvent; diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.cxx b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.cxx index 00bb31a0794aa..cc7b6b77fd4a0 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.cxx +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.cxx @@ -17,10 +17,10 @@ using namespace GPUCA_NAMESPACE::gpu; #ifndef GPUCA_TPC_GEOMETRY_O2 -GPUd() GPUTRDTrackletWord::GPUTRDTrackletWord(unsigned int trackletWord) : mHCId(-1), mTrackletWord(trackletWord) +GPUd() GPUTRDTrackletWord::GPUTRDTrackletWord(uint32_t trackletWord) : mHCId(-1), mTrackletWord(trackletWord) { } -GPUd() GPUTRDTrackletWord::GPUTRDTrackletWord(unsigned int trackletWord, int hcid) : mHCId(hcid), mTrackletWord(trackletWord) {} +GPUd() GPUTRDTrackletWord::GPUTRDTrackletWord(uint32_t trackletWord, int32_t hcid) : mHCId(hcid), mTrackletWord(trackletWord) {} #ifdef GPUCA_ALIROOT_LIB #include "AliTRDtrackletWord.h" @@ -40,7 +40,7 @@ GPUTRDTrackletWord& GPUTRDTrackletWord::operator=(const AliTRDtrackletMCM& rhs) #endif // GPUCA_ALIROOT_LIB -GPUd() int GPUTRDTrackletWord::GetYbin() const +GPUd() int32_t GPUTRDTrackletWord::GetYbin() const { // returns (signed) value of Y if (mTrackletWord & 0x1000) { @@ -50,7 +50,7 @@ GPUd() int GPUTRDTrackletWord::GetYbin() const } } -GPUd() int GPUTRDTrackletWord::GetdYbin() const +GPUd() int32_t GPUTRDTrackletWord::GetdYbin() const { // returns (signed) value of the deflection length if (mTrackletWord & (1 << 19)) { diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.h b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.h index 89c8296c71a91..2b6c058323704 100644 --- a/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.h +++ b/GPU/GPUTracking/TRDTracking/GPUTRDTrackletWord.h @@ -32,8 +32,8 @@ namespace gpu class GPUTRDTrackletWord { public: - GPUd() GPUTRDTrackletWord(unsigned int trackletWord = 0); - GPUd() GPUTRDTrackletWord(unsigned int trackletWord, int hcid); + GPUd() GPUTRDTrackletWord(uint32_t trackletWord = 0); + GPUd() GPUTRDTrackletWord(uint32_t trackletWord, int32_t hcid); GPUdDefault() GPUTRDTrackletWord(const GPUTRDTrackletWord& rhs) CON_DEFAULT; GPUdDefault() GPUTRDTrackletWord& operator=(const GPUTRDTrackletWord& rhs) CON_DEFAULT; GPUdDefault() ~GPUTRDTrackletWord() CON_DEFAULT; @@ -49,28 +49,28 @@ class GPUTRDTrackletWord GPUd() bool operator<=(const GPUTRDTrackletWord& t) const { return (GetHCId() < t.GetHCId()) || (GetHCId() == t.GetHCId()); } // ----- Getters for contents of tracklet word ----- - GPUd() int GetYbin() const; - GPUd() int GetdYbin() const; - GPUd() int GetZbin() const { return ((mTrackletWord >> 20) & 0xf); } - GPUd() int GetPID() const { return ((mTrackletWord >> 24) & 0xff); } + GPUd() int32_t GetYbin() const; + GPUd() int32_t GetdYbin() const; + GPUd() int32_t GetZbin() const { return ((mTrackletWord >> 20) & 0xf); } + GPUd() int32_t GetPID() const { return ((mTrackletWord >> 24) & 0xff); } // ----- Getters for offline corresponding values ----- - GPUd() double GetPID(int /* is */) const { return (double)GetPID() / 256.f; } - GPUd() int GetDetector() const { return mHCId / 2; } - GPUd() int GetHCId() const { return mHCId; } + GPUd() double GetPID(int32_t /* is */) const { return (double)GetPID() / 256.f; } + GPUd() int32_t GetDetector() const { return mHCId / 2; } + GPUd() int32_t GetHCId() const { return mHCId; } GPUd() float GetdYdX() const { return (GetdYbin() * 140e-4f / 3.f); } GPUd() float GetdY() const { return GetdYbin() * 140e-4f; } GPUd() float GetY() const { return (GetYbin() * 160e-4f); } - GPUd() unsigned int GetTrackletWord() const { return mTrackletWord; } + GPUd() uint32_t GetTrackletWord() const { return mTrackletWord; } - GPUd() void SetTrackletWord(unsigned int trackletWord) { mTrackletWord = trackletWord; } - GPUd() void SetDetector(int id) { mHCId = 2 * id + (GetYbin() < 0 ? 0 : 1); } - GPUd() void SetHCId(int id) { mHCId = id; } + GPUd() void SetTrackletWord(uint32_t trackletWord) { mTrackletWord = trackletWord; } + GPUd() void SetDetector(int32_t id) { mHCId = 2 * id + (GetYbin() < 0 ? 0 : 1); } + GPUd() void SetHCId(int32_t id) { mHCId = id; } protected: - int mHCId; // half-chamber ID - unsigned int mTrackletWord; // tracklet word: PID | Z | deflection length | Y - // bits: 8 4 7 13 + int32_t mHCId; // half-chamber ID + uint32_t mTrackletWord; // tracklet word: PID | Z | deflection length | Y + // bits: 8 4 7 13 }; } // namespace gpu } // namespace GPUCA_NAMESPACE @@ -97,11 +97,11 @@ class GPUTRDTrackletWord : private o2::trd::Tracklet64 GPUd() bool operator>(const GPUTRDTrackletWord& t) const { return (getHCID() > t.getHCID()); } GPUd() bool operator<=(const GPUTRDTrackletWord& t) const { return (getHCID() < t.getHCID()) || (getHCID() == t.getHCID()); } - GPUd() int GetZbin() const { return getPadRow(); } + GPUd() int32_t GetZbin() const { return getPadRow(); } GPUd() float GetY() const { return getUncalibratedY(); } GPUd() float GetdY() const { return getUncalibratedDy(); } - GPUd() int GetDetector() const { return getDetector(); } - GPUd() int GetHCId() const { return getHCID(); } + GPUd() int32_t GetDetector() const { return getDetector(); } + GPUd() int32_t GetHCId() const { return getHCID(); } // IMPORTANT: Do not add members, this class must keep the same memory layout as o2::trd::Tracklet64 }; diff --git a/GPU/GPUTracking/TRDTracking/macros/checkDbgOutput.C b/GPU/GPUTracking/TRDTracking/macros/checkDbgOutput.C index 23d444a72435f..fcfe3b3cf2d50 100644 --- a/GPU/GPUTracking/TRDTracking/macros/checkDbgOutput.C +++ b/GPU/GPUTracking/TRDTracking/macros/checkDbgOutput.C @@ -770,7 +770,7 @@ void MakeLogScale(TH1* hist, Double_t xMin = -1, Double_t xMax = -1) Double_t logXmin = TMath::Log10(xMin); Double_t logXmax = TMath::Log10(xMax); Double_t binWidth = (logXmax - logXmin) / nBins; - for (int i = 0; i <= nBins; i++) { + for (int32_t i = 0; i <= nBins; i++) { xBins[i] = xMin + TMath::Power(10, logXmin + i * binWidth); } hist->GetXaxis()->Set(nBins, xBins); @@ -1149,8 +1149,8 @@ void LoopFakes(Int_t nEntries = -1) if ((*nMatchingTracklets)[iLy] > 0) { // matching tracklet would have been available hFracAvailable->Fill(trkPt); - int trackSector = (*trackSec)[iLy]; - int trackletSector = (*trackletSecReal)[iLy]; + int32_t trackSector = (*trackSec)[iLy]; + int32_t trackletSector = (*trackletSecReal)[iLy]; if ((*trackSec)[iLy] == (*trackletSecReal)[iLy] && TMath::Abs((*trackYreal)[iLy] - (*trackletYreal)[iLy]) < (*roadY)[iLy] && TMath::Abs((*trackZreal)[iLy] - (*trackletZreal)[iLy]) < (*roadZ)[iLy]) { // matching tracklet available and in search road hChi2Real->Fill((*chi2Real)[iLy]); @@ -1500,7 +1500,7 @@ void RecreateDyPlotJochen() TH2F* hDy = new TH2F("dy", ";#it{y} (cm);#it{q}/#it{p}_{T} (#it{c}/GeV)", nBinsPerDim, -60, 60, nBinsPerDim, -2, 2); TAxis* axX = hDy->GetXaxis(); TAxis* axY = hDy->GetYaxis(); - std::vector nEntries(nBins); // number of entries for given bin + std::vector nEntries(nBins); // number of entries for given bin std::vector dYacc(nBins); // accumulated values for dy for specific bin for (Int_t i = 0; i < tree->GetEntries(); i++) { // loop over all tracks diff --git a/GPU/GPUTracking/TRDTracking/macros/run_trd_tracker.C b/GPU/GPUTracking/TRDTracking/macros/run_trd_tracker.C index 3266a72749216..b098d3e16b5ea 100644 --- a/GPU/GPUTracking/TRDTracking/macros/run_trd_tracker.C +++ b/GPU/GPUTracking/TRDTracking/macros/run_trd_tracker.C @@ -49,7 +49,7 @@ void run_trd_tracker(std::string path = "./", { //-------- debug time information from tracks and tracklets std::vector trdTriggerTimes; - std::vector trdTriggerIndices; + std::vector trdTriggerIndices; //-------- init geometry and field --------// o2::base::GeometryManager::loadGeometry(); @@ -113,7 +113,7 @@ void run_trd_tracker(std::string path = "./", printf("Attached ITS-TPC tracks branch with %lli entries\n", (tracksItsTpc.GetBranch("TPCITS"))->GetEntries()); tracksItsTpc.GetEntry(0); - unsigned int nTracks = tracksInArrayPtr->size(); + uint32_t nTracks = tracksInArrayPtr->size(); printf("There are %u tracks in total\n", nTracks); // and load input tracklets @@ -125,14 +125,14 @@ void run_trd_tracker(std::string path = "./", std::vector* trackletsInArrayPtr = nullptr; trdTracklets.SetBranchAddress("Tracklet", &trackletsInArrayPtr); trdTracklets.GetEntry(0); - int nCollisions = triggerRecordsInArrayPtr->size(); - int nTracklets = trackletsInArrayPtr->size(); + int32_t nCollisions = triggerRecordsInArrayPtr->size(); + int32_t nTracklets = trackletsInArrayPtr->size(); printf("There are %i tracklets in total from %i trigger records\n", nTracklets, nCollisions); - for (int iEv = 0; iEv < nCollisions; ++iEv) { + for (int32_t iEv = 0; iEv < nCollisions; ++iEv) { o2::trd::TriggerRecord& trg = triggerRecordsInArrayPtr->at(iEv); - int nTrackletsCurrent = trg.getNumberOfTracklets(); - int iFirstTracklet = trg.getFirstTracklet(); + int32_t nTrackletsCurrent = trg.getNumberOfTracklets(); + int32_t iFirstTracklet = trg.getFirstTracklet(); int64_t evTime = trg.getBCData().toLong() * o2::constants::lhc::LHCBunchSpacingNS; // event time in ns trdTriggerTimes.push_back(evTime / 1000.); trdTriggerIndices.push_back(iFirstTracklet); @@ -153,7 +153,7 @@ void run_trd_tracker(std::string path = "./", printf("Start loading input tracks into TRD tracker\n"); // load everything into the tracker - for (unsigned int iTrk = 0; iTrk < nTracks; ++iTrk) { + for (uint32_t iTrk = 0; iTrk < nTracks; ++iTrk) { const auto& trkITSTPC = tracksInArrayPtr->at(iTrk); GPUTRDTracker::HelperTrackAttributes trkAttribs; trkAttribs.mTime = trkITSTPC.getTimeMUS().getTimeStamp(); diff --git a/GPU/GPUTracking/dEdx/GPUdEdx.cxx b/GPU/GPUTracking/dEdx/GPUdEdx.cxx index e13c7087d3b26..6ea59c4c2c9fe 100644 --- a/GPU/GPUTracking/dEdx/GPUdEdx.cxx +++ b/GPU/GPUTracking/dEdx/GPUdEdx.cxx @@ -30,12 +30,12 @@ GPUd() void GPUdEdx::clear() GPUd() void GPUdEdx::computedEdx(GPUdEdxInfo& GPUrestrict() output, const GPUParam& GPUrestrict() param) { checkSubThresh(255); - const int truncLow = param.rec.tpc.dEdxTruncLow; - const int truncHigh = param.rec.tpc.dEdxTruncHigh; - const int countIROC = mNClsROC[0]; - const int countOROC1 = mNClsROC[1]; - const int countOROC2 = mNClsROC[2]; - const int countOROC3 = mNClsROC[3]; + const int32_t truncLow = param.rec.tpc.dEdxTruncLow; + const int32_t truncHigh = param.rec.tpc.dEdxTruncHigh; + const int32_t countIROC = mNClsROC[0]; + const int32_t countOROC1 = mNClsROC[1]; + const int32_t countOROC2 = mNClsROC[2]; + const int32_t countOROC3 = mNClsROC[3]; output.dEdxTotIROC = GetSortTruncMean(mChargeTot + countOROC3 + countOROC2 + countOROC1, countIROC, truncLow, truncHigh); output.dEdxTotOROC1 = GetSortTruncMean(mChargeTot + countOROC3 + countOROC2, countOROC1, truncLow, truncHigh); output.dEdxTotOROC2 = GetSortTruncMean(mChargeTot + countOROC3, countOROC2, truncLow, truncHigh); @@ -56,7 +56,7 @@ GPUd() void GPUdEdx::computedEdx(GPUdEdxInfo& GPUrestrict() output, const GPUPar output.NHitsSubThresholdOROC3 = countOROC3; } -GPUd() float GPUdEdx::GetSortTruncMean(GPUCA_DEDX_STORAGE_TYPE* GPUrestrict() array, int count, int trunclow, int trunchigh) +GPUd() float GPUdEdx::GetSortTruncMean(GPUCA_DEDX_STORAGE_TYPE* GPUrestrict() array, int32_t count, int32_t trunclow, int32_t trunchigh) { trunclow = count * trunclow / 128; trunchigh = count * trunchigh / 128; @@ -65,7 +65,7 @@ GPUd() float GPUdEdx::GetSortTruncMean(GPUCA_DEDX_STORAGE_TYPE* GPUrestrict() ar } CAAlgo::sort(array, array + count); float mean = 0; - for (int i = trunclow; i < trunchigh; i++) { + for (int32_t i = trunclow; i < trunchigh; i++) { mean += (float)array[i] * (1.f / scalingFactor::factor); } return (mean / (trunchigh - trunclow)); diff --git a/GPU/GPUTracking/dEdx/GPUdEdx.h b/GPU/GPUTracking/dEdx/GPUdEdx.h index 3a0543b75c35e..9a1784e2be49a 100644 --- a/GPU/GPUTracking/dEdx/GPUdEdx.h +++ b/GPU/GPUTracking/dEdx/GPUdEdx.h @@ -36,8 +36,8 @@ class GPUdEdx { public: GPUd() void clear() {} - GPUd() void fillCluster(float qtot, float qmax, int padRow, unsigned char slice, float trackSnp, float trackTgl, const GPUParam& param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime) {} - GPUd() void fillSubThreshold(int padRow, const GPUParam& param) {} + GPUd() void fillCluster(float qtot, float qmax, int32_t padRow, uint8_t slice, float trackSnp, float trackTgl, const GPUParam& param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime) {} + GPUd() void fillSubThreshold(int32_t padRow, const GPUParam& param) {} GPUd() void computedEdx(GPUdEdxInfo& output, const GPUParam& param) {} }; @@ -48,18 +48,18 @@ class GPUdEdx public: // The driver must call clear(), fill clusters row by row outside-in, then run computedEdx() to get the result GPUd() void clear(); - GPUd() void fillCluster(float qtot, float qmax, int padRow, unsigned char slice, float trackSnp, float trackTgl, const GPUParam& param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime); - GPUd() void fillSubThreshold(int padRow, const GPUParam& param); + GPUd() void fillCluster(float qtot, float qmax, int32_t padRow, uint8_t slice, float trackSnp, float trackTgl, const GPUParam& param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime); + GPUd() void fillSubThreshold(int32_t padRow, const GPUParam& param); GPUd() void computedEdx(GPUdEdxInfo& output, const GPUParam& param); private: - GPUd() float GetSortTruncMean(GPUCA_DEDX_STORAGE_TYPE* array, int count, int trunclow, int trunchigh); - GPUd() void checkSubThresh(int roc); + GPUd() float GetSortTruncMean(GPUCA_DEDX_STORAGE_TYPE* array, int32_t count, int32_t trunclow, int32_t trunchigh); + GPUd() void checkSubThresh(int32_t roc); template struct scalingFactor; template - struct scalingFactor { + struct scalingFactor { static constexpr float factor = 4.f; static constexpr float round = 0.5f; }; @@ -76,24 +76,24 @@ class GPUdEdx }; #endif - static constexpr int MAX_NCL = GPUCA_ROW_COUNT; // Must fit in mNClsROC (unsigned char)! + static constexpr int32_t MAX_NCL = GPUCA_ROW_COUNT; // Must fit in mNClsROC (uint8_t)! GPUCA_DEDX_STORAGE_TYPE mChargeTot[MAX_NCL]; // No need for default, just some memory GPUCA_DEDX_STORAGE_TYPE mChargeMax[MAX_NCL]; // No need for default, just some memory float mSubThreshMinTot = 0.f; float mSubThreshMinMax = 0.f; - unsigned char mNClsROC[4] = {0}; - unsigned char mNClsROCSubThresh[4] = {0}; - unsigned char mCount = 0; - unsigned char mLastROC = 255; - char mNSubThresh = 0; + uint8_t mNClsROC[4] = {0}; + uint8_t mNClsROCSubThresh[4] = {0}; + uint8_t mCount = 0; + uint8_t mLastROC = 255; + uint8_t mNSubThresh = 0; }; -GPUdi() void GPUdEdx::checkSubThresh(int roc) +GPUdi() void GPUdEdx::checkSubThresh(int32_t roc) { if (roc != mLastROC) { if (mNSubThresh && mCount + mNSubThresh <= MAX_NCL) { - for (int i = 0; i < mNSubThresh; i++) { + for (int32_t i = 0; i < mNSubThresh; i++) { mChargeTot[mCount] = (GPUCA_DEDX_STORAGE_TYPE)(mSubThreshMinTot * scalingFactor::factor + scalingFactor::round); mChargeMax[mCount++] = (GPUCA_DEDX_STORAGE_TYPE)(mSubThreshMinMax * scalingFactor::factor + scalingFactor::round); } @@ -108,7 +108,7 @@ GPUdi() void GPUdEdx::checkSubThresh(int roc) mLastROC = roc; } -GPUdnii() void GPUdEdx::fillCluster(float qtot, float qmax, int padRow, unsigned char slice, float trackSnp, float trackTgl, const GPUParam& GPUrestrict() param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime) +GPUdnii() void GPUdEdx::fillCluster(float qtot, float qmax, int32_t padRow, uint8_t slice, float trackSnp, float trackTgl, const GPUParam& GPUrestrict() param, const GPUCalibObjectsConst& calib, float z, float pad, float relTime) { if (mCount >= MAX_NCL) { return; @@ -117,7 +117,7 @@ GPUdnii() void GPUdEdx::fillCluster(float qtot, float qmax, int padRow, unsigned // container containing all the dE/dx corrections auto calibContainer = calib.dEdxCalibContainer; - const int roc = param.tpcGeometry.GetROC(padRow); + const int32_t roc = param.tpcGeometry.GetROC(padRow); checkSubThresh(roc); float snp2 = trackSnp * trackSnp; if (snp2 > GPUCA_MAX_SIN_PHI_LOW) { @@ -133,9 +133,9 @@ GPUdnii() void GPUdEdx::fillCluster(float qtot, float qmax, int padRow, unsigned const float tanTheta = CAMath::Sqrt(tgl2 * sec2); // getting the topology correction - const unsigned int padPos = CAMath::Float2UIntRn(pad); // position of the pad is shifted half a pad ( pad=3 -> centre position of third pad) + const uint32_t padPos = CAMath::Float2UIntRn(pad); // position of the pad is shifted half a pad ( pad=3 -> centre position of third pad) const float absRelPad = CAMath::Abs(pad - padPos); - const int region = param.tpcGeometry.GetRegion(padRow); + const int32_t region = param.tpcGeometry.GetRegion(padRow); z = CAMath::Abs(z); const float threshold = calibContainer->getZeroSupressionThreshold(slice, padRow, padPos); // TODO: Use the mean zero supresion threshold of all pads in the cluster? const bool useFullGainMap = calibContainer->isUsageOfFullGainMap(); @@ -205,9 +205,9 @@ GPUdnii() void GPUdEdx::fillCluster(float qtot, float qmax, int padRow, unsigned }) } -GPUdi() void GPUdEdx::fillSubThreshold(int padRow, const GPUParam& GPUrestrict() param) +GPUdi() void GPUdEdx::fillSubThreshold(int32_t padRow, const GPUParam& GPUrestrict() param) { - const int roc = param.tpcGeometry.GetROC(padRow); + const int32_t roc = param.tpcGeometry.GetROC(padRow); checkSubThresh(roc); mNSubThresh++; } diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 49bfd813de3d6..74d89fbf6de81 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -109,9 +109,9 @@ void GPUDisplay::calcXYZ(const float* matrix) }*/ } -void GPUDisplay::SetCollisionFirstCluster(unsigned int collision, int slice, int cluster) +void GPUDisplay::SetCollisionFirstCluster(uint32_t collision, int32_t slice, int32_t cluster) { - mNCollissions = std::max(mNCollissions, collision + 1); + mNCollissions = std::max(mNCollissions, collision + 1); mOverlayTFClusters.resize(mNCollissions); mOverlayTFClusters[collision][slice] = cluster; } @@ -128,13 +128,13 @@ void GPUDisplay::mAnimateCloseQuaternion(float* v, float lastx, float lasty, flo float distPos2 = (lastx - v[0]) * (lastx - v[0]) + (lasty - v[1]) * (lasty - v[1]) + (lastz - v[2]) * (lastz - v[2]) + (lastw - v[3]) * (lastw - v[3]); float distNeg2 = (lastx + v[0]) * (lastx + v[0]) + (lasty + v[1]) * (lasty + v[1]) + (lastz + v[2]) * (lastz + v[2]) + (lastw + v[3]) * (lastw + v[3]); if (distPos2 > distNeg2) { - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { v[i] = -v[i]; } } } -void GPUDisplay::ResizeScene(int width, int height, bool init) +void GPUDisplay::ResizeScene(int32_t width, int32_t height, bool init) { if (height == 0) { // Prevent A Divide By Zero By height = 1; // Making Height Equal One @@ -160,9 +160,9 @@ inline void GPUDisplay::drawVertices(const vboList& v, const GPUDisplayBackend:: mNDrawCalls += mBackend->drawVertices(v, t); } -int GPUDisplay::InitDisplay(bool initFailure) +int32_t GPUDisplay::InitDisplay(bool initFailure) { - int retVal = initFailure; + int32_t retVal = initFailure; try { if (!initFailure) { retVal = InitDisplay_internal(); @@ -175,7 +175,7 @@ int GPUDisplay::InitDisplay(bool initFailure) return (retVal); } -int GPUDisplay::InitDisplay_internal() +int32_t GPUDisplay::InitDisplay_internal() { mThreadBuffers.resize(getNumThreads()); mThreadTracks.resize(getNumThreads()); @@ -184,7 +184,7 @@ int GPUDisplay::InitDisplay_internal() } mYFactor = mBackend->getYFactor(); mDrawTextInCompatMode = !mBackend->mFreetypeInitialized && mFrontend->mCanDrawText == 1; - int height = 0, width = 0; + int32_t height = 0, width = 0; mFrontend->getSize(width, height); if (height == 0 || width == 0) { width = GPUDisplayFrontend::INIT_WIDTH; @@ -199,12 +199,12 @@ void GPUDisplay::ExitDisplay() mBackend->ExitBackend(); } -int GPUDisplay::DrawGLScene() +int32_t GPUDisplay::DrawGLScene() { // Make sure event gets not overwritten during display mSemLockDisplay.Lock(); - int retVal = 0; + int32_t retVal = 0; if (mChain) { mIOPtrs = &mChain->mIOPtrs; mCalib = &mChain->calib(); @@ -227,7 +227,7 @@ int GPUDisplay::DrawGLScene() void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix) { - int mMouseWheelTmp = mFrontend->mMouseWheel; + int32_t mMouseWheelTmp = mFrontend->mMouseWheel; mFrontend->mMouseWheel = 0; bool lookOrigin = mCfgR.camLookOrigin ^ mFrontend->mKeys[mFrontend->KEY_ALT]; bool yUp = mCfgR.camYUp ^ mFrontend->mKeys[mFrontend->KEY_CTRL] ^ lookOrigin; @@ -270,10 +270,10 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla mResetScene = 0; } else { - float moveZ = scalefactor * ((float)mMouseWheelTmp / 150 + (float)(mFrontend->mKeys[(unsigned char)'W'] - mFrontend->mKeys[(unsigned char)'S']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale); + float moveZ = scalefactor * ((float)mMouseWheelTmp / 150 + (float)(mFrontend->mKeys[(uint8_t)'W'] - mFrontend->mKeys[(uint8_t)'S']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale); float moveY = scalefactor * ((float)(mFrontend->mKeys[mFrontend->KEY_PAGEDOWN] - mFrontend->mKeys[mFrontend->KEY_PAGEUP]) * 0.2f * mFPSScale); - float moveX = scalefactor * ((float)(mFrontend->mKeys[(unsigned char)'A'] - mFrontend->mKeys[(unsigned char)'D']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale); - float rotRoll = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[(unsigned char)'E'] - mFrontend->mKeys[(unsigned char)'F']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]); + float moveX = scalefactor * ((float)(mFrontend->mKeys[(uint8_t)'A'] - mFrontend->mKeys[(uint8_t)'D']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale); + float rotRoll = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[(uint8_t)'E'] - mFrontend->mKeys[(uint8_t)'F']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]); float rotYaw = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[mFrontend->KEY_RIGHT] - mFrontend->mKeys[mFrontend->KEY_LEFT]); float rotPitch = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[mFrontend->KEY_DOWN] - mFrontend->mKeys[mFrontend->KEY_UP]); @@ -289,7 +289,7 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla rotPitch += rotatescalefactor * mouseScale * ((float)mFrontend->mMouseMvY - (float)mFrontend->mMouseDnY); } - if (mFrontend->mKeys[(unsigned char)'<'] && !mFrontend->mKeysShift[(unsigned char)'<']) { + if (mFrontend->mKeys[(uint8_t)'<'] && !mFrontend->mKeysShift[(uint8_t)'<']) { mAnimationDelay += moveX; if (mAnimationDelay < 0.05f) { mAnimationDelay = 0.05f; @@ -379,7 +379,7 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla // Graphichs Options float minSize = 0.4f / (mCfgR.drawQualityDownsampleFSAA > 1 ? mCfgR.drawQualityDownsampleFSAA : 1); - int deltaLine = mFrontend->mKeys[(unsigned char)'+'] * mFrontend->mKeysShift[(unsigned char)'+'] - mFrontend->mKeys[(unsigned char)'-'] * mFrontend->mKeysShift[(unsigned char)'-']; + int32_t deltaLine = mFrontend->mKeys[(uint8_t)'+'] * mFrontend->mKeysShift[(uint8_t)'+'] - mFrontend->mKeys[(uint8_t)'-'] * mFrontend->mKeysShift[(uint8_t)'-']; mCfgL.lineWidth += (float)deltaLine * mFPSScale * 0.02f * mCfgL.lineWidth; if (mCfgL.lineWidth < minSize) { mCfgL.lineWidth = minSize; @@ -389,7 +389,7 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla mUpdateDrawCommands = 1; } minSize *= 2; - int deltaPoint = mFrontend->mKeys[(unsigned char)'+'] * (!mFrontend->mKeysShift[(unsigned char)'+']) - mFrontend->mKeys[(unsigned char)'-'] * (!mFrontend->mKeysShift[(unsigned char)'-']); + int32_t deltaPoint = mFrontend->mKeys[(uint8_t)'+'] * (!mFrontend->mKeysShift[(uint8_t)'+']) - mFrontend->mKeys[(uint8_t)'-'] * (!mFrontend->mKeysShift[(uint8_t)'-']); mCfgL.pointSize += (float)deltaPoint * mFPSScale * 0.02f * mCfgL.pointSize; if (mCfgL.pointSize < minSize) { mCfgL.pointSize = minSize; @@ -414,9 +414,9 @@ void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSla void GPUDisplay::DrawGLScene_drawCommands() { -#define LOOP_SLICE for (int iSlice = (mCfgL.drawSlice == -1 ? 0 : mCfgL.drawRelatedSlices ? (mCfgL.drawSlice % (NSLICES / 4)) : mCfgL.drawSlice); iSlice < NSLICES; iSlice += (mCfgL.drawSlice == -1 ? 1 : mCfgL.drawRelatedSlices ? (NSLICES / 4) : NSLICES)) -#define LOOP_SLICE2 for (int iSlice = (mCfgL.drawSlice == -1 ? 0 : mCfgL.drawRelatedSlices ? (mCfgL.drawSlice % (NSLICES / 4)) : mCfgL.drawSlice) % (NSLICES / 2); iSlice < NSLICES / 2; iSlice += (mCfgL.drawSlice == -1 ? 1 : mCfgL.drawRelatedSlices ? (NSLICES / 4) : NSLICES)) -#define LOOP_COLLISION for (int iCol = (mCfgL.showCollision == -1 ? 0 : mCfgL.showCollision); iCol < mNCollissions; iCol += (mCfgL.showCollision == -1 ? 1 : mNCollissions)) +#define LOOP_SLICE for (int32_t iSlice = (mCfgL.drawSlice == -1 ? 0 : mCfgL.drawRelatedSlices ? (mCfgL.drawSlice % (NSLICES / 4)) : mCfgL.drawSlice); iSlice < NSLICES; iSlice += (mCfgL.drawSlice == -1 ? 1 : mCfgL.drawRelatedSlices ? (NSLICES / 4) : NSLICES)) +#define LOOP_SLICE2 for (int32_t iSlice = (mCfgL.drawSlice == -1 ? 0 : mCfgL.drawRelatedSlices ? (mCfgL.drawSlice % (NSLICES / 4)) : mCfgL.drawSlice) % (NSLICES / 2); iSlice < NSLICES / 2; iSlice += (mCfgL.drawSlice == -1 ? 1 : mCfgL.drawRelatedSlices ? (NSLICES / 4) : NSLICES)) +#define LOOP_COLLISION for (int32_t iCol = (mCfgL.showCollision == -1 ? 0 : mCfgL.showCollision); iCol < mNCollissions; iCol += (mCfgL.showCollision == -1 ? 1 : mNCollissions)) #define LOOP_COLLISION_COL(cmd) \ LOOP_COLLISION \ { \ @@ -636,7 +636,7 @@ void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) if (mUpdateVertexLists && mIOPtrs) { size_t totalVertizes = DrawGLScene_updateVertexList(); if (showTimer) { - printf("Event visualization time: %'d us (vertices %'ld / %'ld bytes)\n", (int)(mTimerDraw.GetCurrentElapsedTime() * 1000000.), (long)totalVertizes, (long)(totalVertizes * sizeof(mVertexBuffer[0][0]))); + printf("Event visualization time: %'d us (vertices %'ld / %'ld bytes)\n", (int32_t)(mTimerDraw.GetCurrentElapsedTime() * 1000000.), (int64_t)totalVertizes, (int64_t)(totalVertizes * sizeof(mVertexBuffer[0][0]))); } } @@ -714,7 +714,7 @@ void GPUDisplay::ShowNextEvent(const GPUTrackingInOutPointers* ptrs) void GPUDisplay::WaitForNextEvent() { mSemLockDisplay.Lock(); } -int GPUDisplay::StartDisplay() +int32_t GPUDisplay::StartDisplay() { if (mFrontend->StartDisplay()) { return (1); diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index 78638bfaca4a6..38dacae60c51a 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -44,30 +44,30 @@ class GPUDisplay : public GPUDisplayInterface GPUDisplay(const GPUDisplay&) = delete; ~GPUDisplay() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void ShowNextEvent(const GPUTrackingInOutPointers* ptrs = nullptr) override; void WaitForNextEvent() override; - void SetCollisionFirstCluster(unsigned int collision, int slice, int cluster) override; + void SetCollisionFirstCluster(uint32_t collision, int32_t slice, int32_t cluster) override; void UpdateCalib(const GPUCalibObjectsConst* calib) override { mCalib = calib; } void UpdateParam(const GPUParam* param) override { mParam = param; } - void HandleKey(unsigned char key); - int DrawGLScene(); - void HandleSendKey(int key); - int InitDisplay(bool initFailure = false); + void HandleKey(uint8_t key); + int32_t DrawGLScene(); + void HandleSendKey(int32_t key); + int32_t InitDisplay(bool initFailure = false); void ExitDisplay(); - void ResizeScene(int width, int height, bool init = false); + void ResizeScene(int32_t width, int32_t height, bool init = false); const GPUSettingsDisplayRenderer& cfgR() const { return mCfgR; } const GPUSettingsDisplayLight& cfgL() const { return mCfgL; } const GPUSettingsDisplayHeavy& cfgH() const { return mCfgH; } const GPUSettingsDisplay& cfg() const { return mConfig; } bool useMultiVBO() const { return mUseMultiVBO; } - int updateDrawCommands() const { return mUpdateDrawCommands; } - int updateRenderPipeline() const { return mUpdateRenderPipeline; } + int32_t updateDrawCommands() const { return mUpdateDrawCommands; } + int32_t updateRenderPipeline() const { return mUpdateRenderPipeline; } GPUDisplayBackend* backend() const { return mBackend.get(); } - vecpod* vertexBufferStart() { return mVertexBufferStart; } - const vecpod* vertexBufferCount() const { return mVertexBufferCount; } + vecpod* vertexBufferStart() { return mVertexBufferStart; } + const vecpod* vertexBufferCount() const { return mVertexBufferCount; } struct vtx { float x, y, z; vtx(float a, float b, float c) : x(a), y(b), z(c) {} @@ -76,20 +76,20 @@ class GPUDisplay : public GPUDisplayInterface const GPUParam* param() { return mParam; } GPUDisplayFrontend* frontend() { return mFrontend; } bool drawTextInCompatMode() const { return mDrawTextInCompatMode; } - int& drawTextFontSize() { return mDrawTextFontSize; } + int32_t& drawTextFontSize() { return mDrawTextFontSize; } private: - static constexpr int NSLICES = GPUChainTracking::NSLICES; + static constexpr int32_t NSLICES = GPUChainTracking::NSLICES; static constexpr float GL_SCALE_FACTOR = (1.f / 100.f); - static constexpr const int N_POINTS_TYPE = 15; - static constexpr const int N_POINTS_TYPE_TPC = 9; - static constexpr const int N_POINTS_TYPE_TRD = 2; - static constexpr const int N_POINTS_TYPE_TOF = 2; - static constexpr const int N_POINTS_TYPE_ITS = 2; - static constexpr const int N_LINES_TYPE = 7; - static constexpr const int N_FINAL_TYPE = 4; - static constexpr int TRACK_TYPE_ID_LIMIT = 100; + static constexpr const int32_t N_POINTS_TYPE = 15; + static constexpr const int32_t N_POINTS_TYPE_TPC = 9; + static constexpr const int32_t N_POINTS_TYPE_TRD = 2; + static constexpr const int32_t N_POINTS_TYPE_TOF = 2; + static constexpr const int32_t N_POINTS_TYPE_ITS = 2; + static constexpr const int32_t N_LINES_TYPE = 7; + static constexpr const int32_t N_FINAL_TYPE = 4; + static constexpr int32_t TRACK_TYPE_ID_LIMIT = 100; enum PointTypes { tCLUSTER = 0, tINITLINK = 1, tLINK = 2, @@ -111,19 +111,19 @@ class GPUDisplay : public GPUDisplayInterface struct threadVertexBuffer { vecpod buffer; - vecpod start[N_FINAL_TYPE]; - vecpod count[N_FINAL_TYPE]; - std::pair*, vecpod*> vBuf[N_FINAL_TYPE]; + vecpod start[N_FINAL_TYPE]; + vecpod count[N_FINAL_TYPE]; + std::pair*, vecpod*> vBuf[N_FINAL_TYPE]; threadVertexBuffer() : buffer() { - for (int i = 0; i < N_FINAL_TYPE; i++) { + for (int32_t i = 0; i < N_FINAL_TYPE; i++) { vBuf[i].first = start + i; vBuf[i].second = count + i; } } void clear() { - for (int i = 0; i < N_FINAL_TYPE; i++) { + for (int32_t i = 0; i < N_FINAL_TYPE; i++) { start[i].clear(); count[i].clear(); } @@ -148,15 +148,15 @@ class GPUDisplay : public GPUDisplayInterface void DrawGLScene_cameraAndAnimation(float animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix); size_t DrawGLScene_updateVertexList(); void DrawGLScene_drawCommands(); - int InitDisplay_internal(); - int getNumThreads(); + int32_t InitDisplay_internal(); + int32_t getNumThreads(); void disableUnsupportedOptions(); - int buildTrackFilter(); - const GPUTPCTracker& sliceTracker(int iSlice); + int32_t buildTrackFilter(); + const GPUTPCTracker& sliceTracker(int32_t iSlice); const GPUTRDGeometry* trdGeometry(); const GPUTrackingInOutPointers* mIOPtrs = nullptr; - void insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last); - void insertVertexList(int iSlice, size_t first, size_t last); + void insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last); + void insertVertexList(int32_t iSlice, size_t first, size_t last); template void SetInfo(Args... args) { @@ -175,7 +175,7 @@ class GPUDisplay : public GPUDisplayInterface void resetAnimation(); void removeAnimationPoint(); void startAnimation(); - int animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix); + int32_t animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix); void showInfo(const char* info); void ActivateColor(); void SetColorTRD(); @@ -192,23 +192,23 @@ class GPUDisplay : public GPUDisplayInterface void SetColorGrid(); void SetColorGridTRD(); void SetColorMarked(); - void SetCollisionColor(int col); + void SetCollisionColor(int32_t col); void updateConfig(); - void drawPointLinestrip(int iSlice, int cid, int id, int id_limit = TRACK_TYPE_ID_LIMIT); - vboList DrawClusters(int iSlice, int select, unsigned int iCol); - vboList DrawSpacePointsTRD(int iSlice, int select, int iCol); - vboList DrawSpacePointsTOF(int iSlice, int select, int iCol); - vboList DrawSpacePointsITS(int iSlice, int select, int iCol); - vboList DrawLinks(const GPUTPCTracker& tracker, int id, bool dodown = false); + void drawPointLinestrip(int32_t iSlice, int32_t cid, int32_t id, int32_t id_limit = TRACK_TYPE_ID_LIMIT); + vboList DrawClusters(int32_t iSlice, int32_t select, uint32_t iCol); + vboList DrawSpacePointsTRD(int32_t iSlice, int32_t select, int32_t iCol); + vboList DrawSpacePointsTOF(int32_t iSlice, int32_t select, int32_t iCol); + vboList DrawSpacePointsITS(int32_t iSlice, int32_t select, int32_t iCol); + vboList DrawLinks(const GPUTPCTracker& tracker, int32_t id, bool dodown = false); vboList DrawSeeds(const GPUTPCTracker& tracker); vboList DrawTracklets(const GPUTPCTracker& tracker); - vboList DrawTracks(const GPUTPCTracker& tracker, int global); - void DrawTrackITS(int trackId, int iSlice); + vboList DrawTracks(const GPUTPCTracker& tracker, int32_t global); + void DrawTrackITS(int32_t trackId, int32_t iSlice); GPUDisplay::vboList DrawFinalITS(); template - void DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer); + void DrawFinal(int32_t iSlice, int32_t /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer); vboList DrawGrid(const GPUTPCTracker& tracker); - vboList DrawGridTRD(int sector); + vboList DrawGridTRD(int32_t sector); void DoScreenshot(const char* filename, std::vector& pixels, float animateTime = -1.f); void PrintHelp(); void createQuaternionFromMatrix(float* v, const float* mat); @@ -228,15 +228,15 @@ class GPUDisplay : public GPUDisplayInterface qSem mSemLockDisplay; bool mDrawTextInCompatMode = false; - int mDrawTextFontSize = 0; + int32_t mDrawTextFontSize = 0; - int mNDrawCalls = 0; + int32_t mNDrawCalls = 0; bool mUseMultiVBO = false; std::array mDrawColor = {1.f, 1.f, 1.f, 1.f}; - int mTestSetting = 0; + int32_t mTestSetting = 0; float mAngleRollOrigin = -1e9; float mMaxClusterZ = -1; @@ -248,12 +248,12 @@ class GPUDisplay : public GPUDisplayInterface float mRPhiTheta[3]; float mQuat[4]; - vecpod> mOverlayTFClusters; - int mNCollissions = 1; + vecpod> mOverlayTFClusters; + int32_t mNCollissions = 1; vecpod mVertexBuffer[NSLICES]; - vecpod mVertexBufferStart[NSLICES]; - vecpod mVertexBufferCount[NSLICES]; + vecpod mVertexBufferStart[NSLICES]; + vecpod mVertexBufferCount[NSLICES]; std::unique_ptr mGlobalPosPtr; std::unique_ptr mGlobalPosPtrTRD; @@ -265,48 +265,48 @@ class GPUDisplay : public GPUDisplayInterface float4* mGlobalPosTRD2; float4* mGlobalPosITS; float4* mGlobalPosTOF; - int mNMaxClusters = 0; - int mNMaxSpacePointsTRD = 0; - int mNMaxClustersITS = 0; - int mNMaxClustersTOF = 0; - int mCurrentClusters = 0; - int mCurrentSpacePointsTRD = 0; - int mCurrentClustersITS = 0; - int mCurrentClustersTOF = 0; - vecpod mTRDTrackIds; + int32_t mNMaxClusters = 0; + int32_t mNMaxSpacePointsTRD = 0; + int32_t mNMaxClustersITS = 0; + int32_t mNMaxClustersTOF = 0; + int32_t mCurrentClusters = 0; + int32_t mCurrentSpacePointsTRD = 0; + int32_t mCurrentClustersITS = 0; + int32_t mCurrentClustersTOF = 0; + vecpod mTRDTrackIds; vecpod mITSStandaloneTracks; std::vector mTrackFilter; bool mUpdateTrackFilter = false; - int mUpdateVertexLists = 1; - int mUpdateEventData = 0; - int mUpdateDrawCommands = 1; - int mUpdateRenderPipeline = 0; - volatile int mResetScene = 0; + int32_t mUpdateVertexLists = 1; + int32_t mUpdateEventData = 0; + int32_t mUpdateDrawCommands = 1; + int32_t mUpdateRenderPipeline = 0; + volatile int32_t mResetScene = 0; - int mAnimate = 0; + int32_t mAnimate = 0; HighResTimer mAnimationTimer; - int mAnimationFrame = 0; - int mAnimationLastBase = 0; - int mAnimateScreenshot = 0; - int mAnimationExport = 0; + int32_t mAnimationFrame = 0; + int32_t mAnimationLastBase = 0; + int32_t mAnimateScreenshot = 0; + int32_t mAnimationExport = 0; bool mAnimationChangeConfig = true; float mAnimationDelay = 2.f; vecpod mAnimateVectors[9]; vecpod mAnimateConfig; opengl_spline mAnimationSplines[8]; - int mPrintInfoText = 1; + int32_t mPrintInfoText = 1; bool mPrintInfoTextAlways = 0; char mInfoText2[1024]; HighResTimer mInfoText2Timer, mInfoHelpTimer; std::vector mThreadBuffers; - std::vector, 2>, NSLICES>>> mThreadTracks; - volatile int mInitResult = 0; + std::vector, 2>, NSLICES>>> mThreadTracks; + volatile int32_t mInitResult = 0; float mFPSScale = 1, mFPSScaleadjust = 0; - int mFramesDone = 0, mFramesDoneFPS = 0; + int32_t mFramesDone = 0, mFramesDoneFPS = 0; HighResTimer mTimerFPS, mTimerDisplay, mTimerDraw; vboList mGlDLLines[NSLICES][N_LINES_TYPE]; vecpod> mGlDLFinal[NSLICES]; diff --git a/GPU/GPUTracking/display/GPUDisplayInterface.h b/GPU/GPUTracking/display/GPUDisplayInterface.h index 431da46de33b9..49cdb7e9e2038 100644 --- a/GPU/GPUTracking/display/GPUDisplayInterface.h +++ b/GPU/GPUTracking/display/GPUDisplayInterface.h @@ -30,10 +30,10 @@ class GPUDisplayInterface public: GPUDisplayInterface(const GPUDisplayInterface&) = delete; virtual ~GPUDisplayInterface(); - virtual int StartDisplay() = 0; + virtual int32_t StartDisplay() = 0; virtual void ShowNextEvent(const GPUTrackingInOutPointers* ptrs = nullptr) = 0; virtual void WaitForNextEvent() = 0; - virtual void SetCollisionFirstCluster(unsigned int collision, int slice, int cluster) = 0; + virtual void SetCollisionFirstCluster(uint32_t collision, int32_t slice, int32_t cluster) = 0; virtual void UpdateCalib(const GPUCalibObjectsConst* calib) = 0; virtual void UpdateParam(const GPUParam* param) = 0; static GPUDisplayInterface* getDisplay(GPUDisplayFrontendInterface* frontend, GPUChainTracking* chain, GPUQA* qa, const GPUParam* param = nullptr, const GPUCalibObjectsConst* calib = nullptr, const GPUSettingsDisplay* config = nullptr); @@ -49,12 +49,12 @@ class GPUDisplayFrontendInterface static GPUDisplayFrontendInterface* getFrontend(const char* type); virtual void DisplayExit() = 0; virtual bool EnableSendKey() = 0; - virtual int getDisplayControl() const = 0; - virtual int getSendKey() const = 0; - virtual int getNeedUpdate() const = 0; - virtual void setDisplayControl(int v) = 0; - virtual void setSendKey(int v) = 0; - virtual void setNeedUpdate(int v) = 0; + virtual int32_t getDisplayControl() const = 0; + virtual int32_t getSendKey() const = 0; + virtual int32_t getNeedUpdate() const = 0; + virtual void setDisplayControl(int32_t v) = 0; + virtual void setSendKey(int32_t v) = 0; + virtual void setNeedUpdate(int32_t v) = 0; virtual const char* frontendName() const = 0; protected: diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx index 86722d5d44df6..15b759e658354 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx @@ -56,9 +56,9 @@ GPUDisplayBackend* GPUDisplayBackend::getBackend(const char* type) return nullptr; } -int GPUDisplayBackend::InitBackend() +int32_t GPUDisplayBackend::InitBackend() { - int retVal = InitBackendA(); + int32_t retVal = InitBackendA(); if (retVal) { return retVal; } @@ -100,14 +100,14 @@ int GPUDisplayBackend::InitBackend() return 0; } - int fontSize = mDisplay->cfg().fontSize; + int32_t fontSize = mDisplay->cfg().fontSize; mDisplay->drawTextFontSize() = fontSize; if (smoothFont()) { fontSize *= 4; // Font size scaled by 4, can be downsampled } FT_Set_Pixel_Sizes(face, 0, fontSize); - for (unsigned int i = 0; i < 128; i++) { + for (uint32_t i = 0; i < 128; i++) { if (FT_Load_Char(face, i, FT_LOAD_RENDER)) { GPUError("Error loading freetype symbol"); return 0; @@ -140,9 +140,9 @@ void GPUDisplayBackend::fillIndirectCmdBuffer() mCmdBuffer.clear(); mIndirectSliceOffset.resize(GPUCA_NSLICES); // TODO: Check if this can be parallelized - for (int iSlice = 0; iSlice < GPUCA_NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < GPUCA_NSLICES; iSlice++) { mIndirectSliceOffset[iSlice] = mCmdBuffer.size(); - for (unsigned int k = 0; k < mDisplay->vertexBufferStart()[iSlice].size(); k++) { + for (uint32_t k = 0; k < mDisplay->vertexBufferStart()[iSlice].size(); k++) { mCmdBuffer.emplace_back(mDisplay->vertexBufferCount()[iSlice][k], 1, mDisplay->vertexBufferStart()[iSlice][k], 0); } } @@ -151,8 +151,8 @@ void GPUDisplayBackend::fillIndirectCmdBuffer() float GPUDisplayBackend::getDownsampleFactor(bool screenshot) { float factor = 1.0f; - int fsaa = mDisplay->cfgR().drawQualityDownsampleFSAA; - int screenshotScale = mDisplay->cfgR().screenshotScaleFactor; + int32_t fsaa = mDisplay->cfgR().drawQualityDownsampleFSAA; + int32_t screenshotScale = mDisplay->cfgR().screenshotScaleFactor; if (fsaa) { factor *= fsaa; } diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackend.h b/GPU/GPUTracking/display/backend/GPUDisplayBackend.h index 1ce279f6f9bb7..8f00f39b97ce3 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackend.h +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackend.h @@ -42,11 +42,11 @@ class GPUDisplayBackend GPUDisplayBackend(); virtual ~GPUDisplayBackend(); - virtual int ExtInit() { return 0; }; + virtual int32_t ExtInit() { return 0; }; virtual bool CoreProfile() { return false; }; - virtual unsigned int DepthBits() = 0; + virtual uint32_t DepthBits() = 0; - typedef std::tuple vboList; + typedef std::tuple vboList; enum drawType { POINTS = 0, @@ -61,30 +61,30 @@ class GPUDisplayBackend }; struct DrawArraysIndirectCommand { - DrawArraysIndirectCommand(unsigned int a = 0, unsigned int b = 0, unsigned int c = 0, unsigned int d = 0) : count(a), instanceCount(b), first(c), baseInstance(d) {} - unsigned int count; - unsigned int instanceCount; + DrawArraysIndirectCommand(uint32_t a = 0, uint32_t b = 0, uint32_t c = 0, uint32_t d = 0) : count(a), instanceCount(b), first(c), baseInstance(d) {} + uint32_t count; + uint32_t instanceCount; - unsigned int first; - unsigned int baseInstance; + uint32_t first; + uint32_t baseInstance; }; struct FontSymbol { - int size[2]; - int offset[2]; - int advance; + int32_t size[2]; + int32_t offset[2]; + int32_t advance; }; - virtual unsigned int drawVertices(const vboList& v, const drawType t) = 0; - virtual unsigned int drawField() { return 0; } + virtual uint32_t drawVertices(const vboList& v, const drawType t) = 0; + virtual uint32_t drawField() { return 0; } virtual void ActivateColor(std::array& color) = 0; virtual void setQuality() {}; virtual void SetVSync(bool enable) {}; virtual bool backendNeedRedraw() { return true; } virtual void setDepthBuffer() = 0; - virtual int InitBackendA() = 0; + virtual int32_t InitBackendA() = 0; virtual void ExitBackendA() = 0; - int InitBackend(); + int32_t InitBackend(); void ExitBackend(); virtual void loadDataToGPU(size_t totalVertizes) = 0; virtual void prepareDraw(const hmm_mat4& proj, const hmm_mat4& view, bool requestScreenshot = false, bool toMixBuffer = false, float includeMixImage = 0.f) = 0; @@ -96,16 +96,16 @@ class GPUDisplayBackend virtual void lineWidthFactor(float factor) = 0; backendTypes backendType() const { return mBackendType; } const char* backendName() const { return mBackendName; } - virtual void resizeScene(unsigned int width, unsigned int height) {} + virtual void resizeScene(uint32_t width, uint32_t height) {} virtual size_t needMultiVBO() { return 0; } virtual void OpenGLPrint(const char* s, float x, float y, float* color, float scale) = 0; static GPUDisplayBackend* getBackend(const char* type); std::vector getPixels(); virtual float getYFactor() const { return 1.0f; } - virtual int getMaxMSAA() const { return 16; } + virtual int32_t getMaxMSAA() const { return 16; } protected: - virtual void addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) = 0; + virtual void addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) = 0; virtual void initializeTextDrawing() = 0; float getDownsampleFactor(bool screenshot = false); @@ -113,18 +113,18 @@ class GPUDisplayBackend bool smoothFont(); GPUDisplay* mDisplay = nullptr; - std::vector mIndirectSliceOffset; + std::vector mIndirectSliceOffset; vecpod mCmdBuffer; bool mFreetypeInitialized = false; bool mFrontendCompatTextDraw = false; std::vector mScreenshotPixels; - int mDownsampleFactor = 1; + int32_t mDownsampleFactor = 1; - unsigned int mRenderWidth = 0; - unsigned int mRenderHeight = 0; - unsigned int mScreenWidth = 0; - unsigned int mScreenHeight = 0; + uint32_t mRenderWidth = 0; + uint32_t mRenderHeight = 0; + uint32_t mScreenWidth = 0; + uint32_t mScreenHeight = 0; backendTypes mBackendType = TYPE_INVALID; const char* mBackendName = nullptr; diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx index c25fbede428ca..b92872a79c6de 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx @@ -60,12 +60,12 @@ GPUDisplayBackendOpenGL::GPUDisplayBackendOpenGL() } #ifdef GPUCA_DISPLAY_GL3W -int GPUDisplayBackendOpenGL::ExtInit() +int32_t GPUDisplayBackendOpenGL::ExtInit() { return gl3wInit(); } #else -int GPUDisplayBackendOpenGL::ExtInit() +int32_t GPUDisplayBackendOpenGL::ExtInit() { return glewInit(); } @@ -83,17 +83,17 @@ bool GPUDisplayBackendOpenGL::CoreProfile() #endif // #define CHKERR(cmd) {cmd;} -#define CHKERR(cmd) \ - do { \ - (cmd); \ - GLenum err = glGetError(); \ - while (err != GL_NO_ERROR) { \ - GPUError("OpenGL Error %d: %s (%s: %d)", (int)err, (const char*)gluErrorString(err), __FILE__, __LINE__); \ - throw std::runtime_error("OpenGL Failure"); \ - } \ +#define CHKERR(cmd) \ + do { \ + (cmd); \ + GLenum err = glGetError(); \ + while (err != GL_NO_ERROR) { \ + GPUError("OpenGL Error %d: %s (%s: %d)", (int32_t)err, (const char*)gluErrorString(err), __FILE__, __LINE__); \ + throw std::runtime_error("OpenGL Failure"); \ + } \ } while (false) -unsigned int GPUDisplayBackendOpenGL::DepthBits() +uint32_t GPUDisplayBackendOpenGL::DepthBits() { GLint depthBits = 0; #ifndef GPUCA_DISPLAY_OPENGL_CORE @@ -102,7 +102,7 @@ unsigned int GPUDisplayBackendOpenGL::DepthBits() return depthBits; } -void GPUDisplayBackendOpenGL::createFB(GLfb& fb, bool tex, bool withDepth, bool msaa, unsigned int width, unsigned int height) +void GPUDisplayBackendOpenGL::createFB(GLfb& fb, bool tex, bool withDepth, bool msaa, uint32_t width, uint32_t height) { fb.tex = tex; fb.depth = withDepth; @@ -154,7 +154,7 @@ void GPUDisplayBackendOpenGL::createFB(GLfb& fb, bool tex, bool withDepth, bool GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { - GPUError("Error creating framebuffer (tex %d) - incomplete (%d)", (int)tex, status); + GPUError("Error creating framebuffer (tex %d) - incomplete (%d)", (int32_t)tex, status); exit(1); } CHKERR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFboId)); @@ -180,7 +180,7 @@ void GPUDisplayBackendOpenGL::deleteFB(GLfb& fb) fb.created = false; } -unsigned int GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType tt) +uint32_t GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType tt) { static constexpr GLenum types[3] = {GL_POINTS, GL_LINES, GL_LINE_STRIP}; GLenum t = types[tt]; @@ -210,7 +210,7 @@ unsigned int GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawT if (mDisplay->cfgR().useGLIndirectDraw) { CHKERR(glMultiDrawArraysIndirect(t, (void*)(size_t)((mIndirectSliceOffset[iSlice] + first) * sizeof(DrawArraysIndirectCommand)), count, 0)); } else if (OPENGL_EMULATE_MULTI_DRAW) { - for (unsigned int k = 0; k < count; k++) { + for (uint32_t k = 0; k < count; k++) { CHKERR(glDrawArrays(t, mDisplay->vertexBufferStart()[iSlice][first + k], mDisplay->vertexBufferCount()[iSlice][first + k])); } } else { @@ -257,7 +257,7 @@ void GPUDisplayBackendOpenGL::setDepthBuffer() } } -void GPUDisplayBackendOpenGL::setFrameBuffer(unsigned int newID) +void GPUDisplayBackendOpenGL::setFrameBuffer(uint32_t newID) { if (newID == 0) { CHKERR(glBindFramebuffer(GL_FRAMEBUFFER, 0)); @@ -269,9 +269,9 @@ void GPUDisplayBackendOpenGL::setFrameBuffer(unsigned int newID) } } -int GPUDisplayBackendOpenGL::checkShaderStatus(unsigned int shader) +int32_t GPUDisplayBackendOpenGL::checkShaderStatus(uint32_t shader) { - int status, loglen; + int32_t status, loglen; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (!status) { printf("failed to compile shader\n"); @@ -285,9 +285,9 @@ int GPUDisplayBackendOpenGL::checkShaderStatus(unsigned int shader) return 0; } -int GPUDisplayBackendOpenGL::checkProgramStatus(unsigned int program) +int32_t GPUDisplayBackendOpenGL::checkProgramStatus(uint32_t program) { - int status, loglen; + int32_t status, loglen; glGetProgramiv(program, GL_LINK_STATUS, &status); if (!status) { printf("failed to link program\n"); @@ -301,14 +301,14 @@ int GPUDisplayBackendOpenGL::checkProgramStatus(unsigned int program) return 0; } -int GPUDisplayBackendOpenGL::InitBackendA() +int32_t GPUDisplayBackendOpenGL::InitBackendA() { if (mDisplay->param()->par.debugLevel >= 2) { auto renderer = glGetString(GL_RENDERER); GPUInfo("Renderer: %s", (const char*)renderer); } - int glVersion[2] = {0, 0}; + int32_t glVersion[2] = {0, 0}; glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); if (glVersion[0] < GPUDisplayFrontend::GL_MIN_VERSION_MAJOR || (glVersion[0] == GPUDisplayFrontend::GL_MIN_VERSION_MAJOR && glVersion[1] < GPUDisplayFrontend::GL_MIN_VERSION_MINOR)) { @@ -457,7 +457,7 @@ void GPUDisplayBackendOpenGL::loadDataToGPU(size_t totalVertizes) { // TODO: Check if this can be parallelized if (mDisplay->useMultiVBO()) { - for (int i = 0; i < GPUCA_NSLICES; i++) { + for (int32_t i = 0; i < GPUCA_NSLICES; i++) { CHKERR(glNamedBufferData(mVBOId[i], mDisplay->vertexBuffer()[i].size() * sizeof(mDisplay->vertexBuffer()[i][0]), mDisplay->vertexBuffer()[i].data(), GL_STATIC_DRAW)); } } else { @@ -551,7 +551,7 @@ void GPUDisplayBackendOpenGL::finishDraw(bool doScreenshot, bool toMixBuffer, fl } if (mDisplay->cfgR().drawQualityMSAA) { - unsigned int dstId = toMixBuffer ? mMixBuffer.fb_id : (mDownsampleFactor != 1 ? mOffscreenBuffer.fb_id : 0); + uint32_t dstId = toMixBuffer ? mMixBuffer.fb_id : (mDownsampleFactor != 1 ? mOffscreenBuffer.fb_id : 0); CHKERR(glBlitNamedFramebuffer(mOffscreenBufferMSAA.fb_id, dstId, 0, 0, mRenderWidth, mRenderHeight, 0, 0, mRenderWidth, mRenderHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR)); } if (includeMixImage > 0) { @@ -569,9 +569,9 @@ void GPUDisplayBackendOpenGL::finishDraw(bool doScreenshot, bool toMixBuffer, fl void GPUDisplayBackendOpenGL::readImageToPixels() { - int scaleFactor = mDisplay->cfgR().screenshotScaleFactor; - unsigned int width = mScreenWidth * scaleFactor; - unsigned int height = mScreenHeight * scaleFactor; + int32_t scaleFactor = mDisplay->cfgR().screenshotScaleFactor; + uint32_t width = mScreenWidth * scaleFactor; + uint32_t height = mScreenHeight * scaleFactor; GLfb tmpBuffer; if (mDisplay->cfgR().drawQualityDownsampleFSAA && mDisplay->cfgR().screenshotScaleFactor != 1) { createFB(tmpBuffer, false, true, false, width, height); @@ -680,21 +680,21 @@ void GPUDisplayBackendOpenGL::lineWidthFactor(float factor) CHKERR(glLineWidth(mDisplay->cfgL().lineWidth * mDownsampleFactor * factor)); } -void GPUDisplayBackendOpenGL::addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) +void GPUDisplayBackendOpenGL::addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) { - int oldAlign; + int32_t oldAlign; CHKERR(glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldAlign)); CHKERR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - if (symbol != (int)mFontSymbols.size()) { + if (symbol != (int32_t)mFontSymbols.size()) { throw std::runtime_error("Incorrect symbol ID"); } - unsigned int texId; + uint32_t texId; glGenTextures(1, &texId); - std::vector tmp; + std::vector tmp; if (!smoothFont()) { tmp.resize(sizex * sizey); - unsigned char* src = (unsigned char*)data; - for (int i = 0; i < sizex * sizey; i++) { + uint8_t* src = (uint8_t*)data; + for (int32_t i = 0; i < sizex * sizey; i++) { tmp[i] = src[i] > 128 ? 255 : 0; } data = tmp.data(); @@ -736,8 +736,8 @@ void GPUDisplayBackendOpenGL::OpenGLPrint(const char* s, float x, float y, float scale *= 0.25f; // Font size is 48 to have nice bitmap, scale to size 12 } for (const char* c = s; *c; c++) { - if ((int)*c > (int)mFontSymbols.size()) { - GPUError("Trying to draw unsupported symbol: %d > %d\n", (int)*c, (int)mFontSymbols.size()); + if ((int32_t)*c > (int32_t)mFontSymbols.size()) { + GPUError("Trying to draw unsupported symbol: %d > %d\n", (int32_t)*c, (int32_t)mFontSymbols.size()); continue; } FontSymbolOpenGL sym = mFontSymbols[*c]; @@ -779,7 +779,7 @@ void GPUDisplayBackendOpenGL::ClearOffscreenBuffers() } } -void GPUDisplayBackendOpenGL::resizeScene(unsigned int width, unsigned int height) +void GPUDisplayBackendOpenGL::resizeScene(uint32_t width, uint32_t height) { mScreenWidth = width; mScreenHeight = height; @@ -821,27 +821,27 @@ void GPUDisplayBackendOpenGL::updateRenderer(bool withScreenshot) GPUDisplayBackendOpenGL::GPUDisplayBackendOpenGL() { } -int GPUDisplayBackendOpenGL::checkShaderStatus(unsigned int shader) { return 0; } -int GPUDisplayBackendOpenGL::checkProgramStatus(unsigned int program) { return 0; } -int GPUDisplayBackendOpenGL::ExtInit() { throw std::runtime_error("Insufficnet OpenGL version"); } +int32_t GPUDisplayBackendOpenGL::checkShaderStatus(uint32_t shader) { return 0; } +int32_t GPUDisplayBackendOpenGL::checkProgramStatus(uint32_t program) { return 0; } +int32_t GPUDisplayBackendOpenGL::ExtInit() { throw std::runtime_error("Insufficnet OpenGL version"); } bool GPUDisplayBackendOpenGL::CoreProfile() { return false; } -unsigned int GPUDisplayBackendOpenGL::DepthBits() { return 0; } -unsigned int GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType t) { return 0; } +uint32_t GPUDisplayBackendOpenGL::DepthBits() { return 0; } +uint32_t GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType t) { return 0; } void GPUDisplayBackendOpenGL::ActivateColor(std::array& color) {} void GPUDisplayBackendOpenGL::setQuality() {} void GPUDisplayBackendOpenGL::setDepthBuffer() {} -int GPUDisplayBackendOpenGL::InitBackendA() { throw std::runtime_error("Insufficnet OpenGL version"); } +int32_t GPUDisplayBackendOpenGL::InitBackendA() { throw std::runtime_error("Insufficnet OpenGL version"); } void GPUDisplayBackendOpenGL::ExitBackendA() {} void GPUDisplayBackendOpenGL::loadDataToGPU(size_t totalVertizes) {} void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4& view, bool requestScreenshot, bool toMixBuffer, float includeMixImage) {} -void GPUDisplayBackendOpenGL::resizeScene(unsigned int width, unsigned int height) {} +void GPUDisplayBackendOpenGL::resizeScene(uint32_t width, uint32_t height) {} void GPUDisplayBackendOpenGL::finishDraw(bool doScreenshot, bool toMixBuffer, float includeMixImage) {} void GPUDisplayBackendOpenGL::finishFrame(bool doScreenshot, bool toMixBuffer, float includeMixImage) {} void GPUDisplayBackendOpenGL::prepareText() {} void GPUDisplayBackendOpenGL::finishText() {} void GPUDisplayBackendOpenGL::pointSizeFactor(float factor) {} void GPUDisplayBackendOpenGL::lineWidthFactor(float factor) {} -void GPUDisplayBackendOpenGL::addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) {} +void GPUDisplayBackendOpenGL::addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) {} void GPUDisplayBackendOpenGL::initializeTextDrawing() {} void GPUDisplayBackendOpenGL::OpenGLPrint(const char* s, float x, float y, float* color, float scale) {} #endif // GPUCA_BUILD_EVENT_DISPLAY_OPENGL diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h index f7e2d4ee44460..b1bcb25740ed4 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h @@ -22,7 +22,7 @@ namespace GPUCA_NAMESPACE::gpu { struct GLfb { - unsigned int fb_id = 0, fbCol_id = 0, fbDepth_id = 0; + uint32_t fb_id = 0, fbCol_id = 0, fbDepth_id = 0; bool tex = false; bool msaa = false; bool depth = false; @@ -33,30 +33,30 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend public: GPUDisplayBackendOpenGL(); ~GPUDisplayBackendOpenGL() override = default; - int ExtInit() override; + int32_t ExtInit() override; bool CoreProfile() override; - unsigned int DepthBits() override; + uint32_t DepthBits() override; protected: - void createFB(GLfb& fb, bool tex, bool withDepth, bool msaa, unsigned int width, unsigned int height); + void createFB(GLfb& fb, bool tex, bool withDepth, bool msaa, uint32_t width, uint32_t height); void deleteFB(GLfb& fb); - unsigned int drawVertices(const vboList& v, const drawType t) override; - unsigned int drawField() override; + uint32_t drawVertices(const vboList& v, const drawType t) override; + uint32_t drawField() override; void ActivateColor(std::array& color) override; void setQuality() override; void setDepthBuffer() override; - void setFrameBuffer(unsigned int newID = 0); - int InitBackendA() override; - int InitMagFieldVisualization(); + void setFrameBuffer(uint32_t newID = 0); + int32_t InitBackendA() override; + int32_t InitMagFieldVisualization(); void ExitBackendA() override; void ExitMagFieldVisualization(); - static int checkShaderStatus(unsigned int shader); - static int checkProgramStatus(unsigned int program); + static int32_t checkShaderStatus(uint32_t shader); + static int32_t checkProgramStatus(uint32_t program); void clearScreen(bool alphaOnly = false); void loadDataToGPU(size_t totalVertizes) override; void prepareDraw(const hmm_mat4& proj, const hmm_mat4& view, bool requestScreenshot, bool toMixBuffer, float includeMixImage) override; - void resizeScene(unsigned int width, unsigned int height) override; + void resizeScene(uint32_t width, uint32_t height) override; void updateRenderer(bool withScreenshot); void ClearOffscreenBuffers(); void finishDraw(bool doScreenshot, bool toMixBuffer, float includeMixImage) override; @@ -69,51 +69,51 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend size_t needMultiVBO() override { return 0x100000000ll; } void readImageToPixels(); - void addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) override; + void addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) override; void initializeTextDrawing() override; void OpenGLPrint(const char* s, float x, float y, float* color, float scale) override; struct FontSymbolOpenGL : public FontSymbol { - unsigned int texId; + uint32_t texId; }; - unsigned int mVertexShader; - unsigned int mFragmentShader; - unsigned int mVertexShaderTexture; - unsigned int mVertexShaderPassthrough; - unsigned int mFragmentShaderTexture; - unsigned int mFragmentShaderText; - unsigned int mGeometryShader; - unsigned int mShaderProgram; - unsigned int mShaderProgramText; - unsigned int mShaderProgramTexture; - unsigned int mShaderProgramField; - unsigned int mVertexArray; - - unsigned int mIndirectId; - std::vector mVBOId; + uint32_t mVertexShader; + uint32_t mFragmentShader; + uint32_t mVertexShaderTexture; + uint32_t mVertexShaderPassthrough; + uint32_t mFragmentShaderTexture; + uint32_t mFragmentShaderText; + uint32_t mGeometryShader; + uint32_t mShaderProgram; + uint32_t mShaderProgramText; + uint32_t mShaderProgramTexture; + uint32_t mShaderProgramField; + uint32_t mVertexArray; + + uint32_t mIndirectId; + std::vector mVBOId; std::vector mFontSymbols; - int mModelViewProjId; - int mColorId; - int mModelViewProjIdTexture; - int mAlphaIdTexture; - int mModelViewProjIdText; - int mColorIdText; - unsigned int mSPIRVModelViewBuffer; - unsigned int mSPIRVColorBuffer; - - unsigned int mFieldModelViewBuffer; - unsigned int mFieldModelConstantsBuffer; - unsigned int mSolenoidSegmentsBuffer; - unsigned int mSolenoidParameterizationBuffer; - unsigned int mDipoleSegmentsBuffer; - unsigned int mDipoleParameterizationBuffer; - - unsigned int VAO_text, VBO_text; - - unsigned int VAO_texture, VBO_texture; - - unsigned int VAO_field, VBO_field; + int32_t mModelViewProjId; + int32_t mColorId; + int32_t mModelViewProjIdTexture; + int32_t mAlphaIdTexture; + int32_t mModelViewProjIdText; + int32_t mColorIdText; + uint32_t mSPIRVModelViewBuffer; + uint32_t mSPIRVColorBuffer; + + uint32_t mFieldModelViewBuffer; + uint32_t mFieldModelConstantsBuffer; + uint32_t mSolenoidSegmentsBuffer; + uint32_t mSolenoidParameterizationBuffer; + uint32_t mDipoleSegmentsBuffer; + uint32_t mDipoleParameterizationBuffer; + + uint32_t VAO_text, VBO_text; + + uint32_t VAO_texture, VBO_texture; + + uint32_t VAO_field, VBO_field; bool mSPIRVShaders = false; diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx index a6920942b9990..5491555ace8d2 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx @@ -32,13 +32,13 @@ QGET_LD_BINARY_SYMBOLS(shaders_shaders_fragmentTexture_frag_spv); QGET_LD_BINARY_SYMBOLS(shaders_shaders_fragmentText_frag_spv); // #define CHKERR(cmd) {cmd;} -#define CHKERR(cmd) \ - do { \ - auto tmp_internal_retVal = cmd; \ - if ((int)tmp_internal_retVal < 0) { \ - GPUError("VULKAN ERROR: %d: %s (%s: %d)", (int)tmp_internal_retVal, "ERROR", __FILE__, __LINE__); \ - throw std::runtime_error("Vulkan Failure"); \ - } \ +#define CHKERR(cmd) \ + do { \ + auto tmp_internal_retVal = cmd; \ + if ((int32_t)tmp_internal_retVal < 0) { \ + GPUError("VULKAN ERROR: %d: %s (%s: %d)", (int32_t)tmp_internal_retVal, "ERROR", __FILE__, __LINE__); \ + throw std::runtime_error("Vulkan Failure"); \ + } \ } while (false) GPUDisplayBackendVulkan::GPUDisplayBackendVulkan() @@ -50,7 +50,7 @@ GPUDisplayBackendVulkan::~GPUDisplayBackendVulkan() = default; // ---------------------------- VULKAN HELPERS ---------------------------- -static int checkVulkanLayersSupported(const std::vector& validationLayers) +static int32_t checkVulkanLayersSupported(const std::vector& validationLayers) { std::vector availableLayers = vk::enumerateInstanceLayerProperties(); for (const char* layerName : validationLayers) { @@ -113,7 +113,7 @@ vk::Extent2D GPUDisplayBackendVulkan::chooseSwapExtent(const vk::SurfaceCapabili if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } else { - int width, height; + int32_t width, height; mDisplay->frontend()->getSize(width, height); vk::Extent2D actualExtent = {(uint32_t)width, (uint32_t)height}; actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); @@ -221,7 +221,7 @@ static void createImageI(vk::Device device, vk::PhysicalDevice physicalDevice, v device.bindImageMemory(image, imageMemory, 0); } -static unsigned int getMaxUsableSampleCount(vk::PhysicalDeviceProperties& physicalDeviceProperties) +static uint32_t getMaxUsableSampleCount(vk::PhysicalDeviceProperties& physicalDeviceProperties) { vk::SampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts; if (counts & vk::SampleCountFlagBits::e64) { @@ -240,7 +240,7 @@ static unsigned int getMaxUsableSampleCount(vk::PhysicalDeviceProperties& physic return 1; } -static vk::SampleCountFlagBits getMSAASamplesFlag(unsigned int msaa) +static vk::SampleCountFlagBits getMSAASamplesFlag(uint32_t msaa) { if (msaa == 2) { return vk::SampleCountFlagBits::e2; @@ -281,7 +281,7 @@ double GPUDisplayBackendVulkan::checkDevice(vk::PhysicalDevice device, const std std::vector queueFamilies = device.getQueueFamilyProperties(); bool found = false; - for (unsigned int i = 0; i < queueFamilies.size(); i++) { + for (uint32_t i = 0; i < queueFamilies.size(); i++) { if (!(queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)) { return (-1); } @@ -299,9 +299,9 @@ double GPUDisplayBackendVulkan::checkDevice(vk::PhysicalDevice device, const std } std::vector availableExtensions = device.enumerateDeviceExtensionProperties(nullptr); - unsigned int extensionsFound = 0; - for (unsigned int i = 0; i < reqDeviceExtensions.size(); i++) { - for (unsigned int j = 0; j < availableExtensions.size(); j++) { + uint32_t extensionsFound = 0; + for (uint32_t i = 0; i < reqDeviceExtensions.size(); i++) { + for (uint32_t j = 0; j < availableExtensions.size(); j++) { if (strcmp(reqDeviceExtensions[i], availableExtensions[j].extensionName) == 0) { extensionsFound++; break; @@ -326,7 +326,7 @@ double GPUDisplayBackendVulkan::checkDevice(vk::PhysicalDevice device, const std score += 1e11; } - for (unsigned int i = 0; i < memoryProperties.memoryHeapCount; i++) { + for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; i++) { if (memoryProperties.memoryHeaps[i].flags & vk::MemoryHeapFlagBits::eDeviceLocal) { score += memoryProperties.memoryHeaps[i].size; } @@ -354,7 +354,7 @@ void GPUDisplayBackendVulkan::createDevice() const std::vector reqValidationLayers = { "VK_LAYER_KHRONOS_validation"}; auto debugCallback = [](VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) -> VkBool32 { - static int throwOnError = getenv("GPUCA_VULKAN_VALIDATION_THROW") ? atoi(getenv("GPUCA_VULKAN_VALIDATION_THROW")) : 0; + static int32_t throwOnError = getenv("GPUCA_VULKAN_VALIDATION_THROW") ? atoi(getenv("GPUCA_VULKAN_VALIDATION_THROW")) : 0; static bool showVulkanValidationInfo = getenv("GPUCA_VULKAN_VALIDATION_INFO") && atoi(getenv("GPUCA_VULKAN_VALIDATION_INFO")); switch (messageSeverity) { case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: @@ -429,7 +429,7 @@ void GPUDisplayBackendVulkan::createDevice() throw std::runtime_error("No Vulkan device present!"); } double bestScore = -1.; - for (unsigned int i = 0; i < devices.size(); i++) { + for (uint32_t i = 0; i < devices.size(); i++) { double score = checkDevice(devices[i], reqDeviceExtensions); if (mDisplay->param()->par.debugLevel >= 2) { vk::PhysicalDeviceProperties deviceProperties = devices[i].getProperties(); @@ -441,7 +441,7 @@ void GPUDisplayBackendVulkan::createDevice() } } if (mDisplay->cfg().vulkan.forceDevice != -1) { - if (mDisplay->cfg().vulkan.forceDevice < 0 || mDisplay->cfg().vulkan.forceDevice >= (int)devices.size()) { + if (mDisplay->cfg().vulkan.forceDevice < 0 || mDisplay->cfg().vulkan.forceDevice >= (int32_t)devices.size()) { throw std::runtime_error("Invalid Vulkan device selected"); } mPhysicalDevice = devices[mDisplay->cfg().vulkan.forceDevice]; @@ -463,7 +463,7 @@ void GPUDisplayBackendVulkan::createDevice() mCubicFilterSupported = (bool)(formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eSampledImageFilterCubicEXT); bool mailboxSupported = std::find(mSwapChainDetails.presentModes.begin(), mSwapChainDetails.presentModes.end(), vk::PresentModeKHR::eMailbox) != mSwapChainDetails.presentModes.end(); if (mDisplay->param()->par.debugLevel >= 2) { - GPUInfo("Max MSAA: %d, 32 bit Z buffer %d, 32 bit Z buffer + stencil buffer %d, Cubic Filtering %d, Mailbox present mode %d\n", (int)mMaxMSAAsupported, (int)mZSupported, (int)mStencilSupported, (int)mCubicFilterSupported, (int)mailboxSupported); + GPUInfo("Max MSAA: %d, 32 bit Z buffer %d, 32 bit Z buffer + stencil buffer %d, Cubic Filtering %d, Mailbox present mode %d\n", (int32_t)mMaxMSAAsupported, (int32_t)mZSupported, (int32_t)mStencilSupported, (int32_t)mCubicFilterSupported, (int32_t)mailboxSupported); } vk::DeviceQueueCreateInfo queueCreateInfo{}; @@ -536,7 +536,7 @@ void GPUDisplayBackendVulkan::createSemaphoresAndFences() mMixFinishedSemaphore.resize(mFramesInFlight); mDownsampleFinishedSemaphore.resize(mFramesInFlight); mInFlightFence.resize(mFramesInFlight); - for (unsigned int i = 0; i < mFramesInFlight; i++) { + for (uint32_t i = 0; i < mFramesInFlight; i++) { mImageAvailableSemaphore[i] = mDevice.createSemaphore(semaphoreInfo, nullptr); mRenderFinishedSemaphore[i] = mDevice.createSemaphore(semaphoreInfo, nullptr); mTextFinishedSemaphore[i] = mDevice.createSemaphore(semaphoreInfo, nullptr); @@ -563,10 +563,10 @@ void GPUDisplayBackendVulkan::clearSemaphoresAndFences() void GPUDisplayBackendVulkan::createUniformLayoutsAndBuffers() { - for (int j = 0; j < 3; j++) { + for (int32_t j = 0; j < 3; j++) { mUniformBuffersMat[j].resize(mFramesInFlight); mUniformBuffersCol[j].resize(mFramesInFlight); - for (unsigned int i = 0; i < mFramesInFlight; i++) { + for (uint32_t i = 0; i < mFramesInFlight; i++) { mUniformBuffersMat[j][i] = createBuffer(sizeof(hmm_mat4), nullptr, vk::BufferUsageFlagBits::eUniformBuffer, mDisplay->cfg().vulkan.uniformBuffersInDeviceMemory ? 2 : 0); mUniformBuffersCol[j][i] = createBuffer(sizeof(float) * 4, nullptr, vk::BufferUsageFlagBits::eUniformBuffer, mDisplay->cfg().vulkan.uniformBuffersInDeviceMemory ? 2 : 0); } @@ -608,14 +608,14 @@ void GPUDisplayBackendVulkan::createUniformLayoutsAndBuffers() vk::DescriptorSetAllocateInfo allocInfo{}; allocInfo.descriptorPool = mDescriptorPool; allocInfo.descriptorSetCount = (uint32_t)mFramesInFlight; - for (int j = 0; j < 3; j++) { // 0 = Render, 1 = Text, 2 = Texture + for (int32_t j = 0; j < 3; j++) { // 0 = Render, 1 = Text, 2 = Texture std::vector layouts(mFramesInFlight, j ? mUniformDescriptorTexture : mUniformDescriptor); allocInfo.pSetLayouts = layouts.data(); mDescriptorSets[j] = mDevice.allocateDescriptorSets(allocInfo); - for (int k = 0; k < 2; k++) { + for (int32_t k = 0; k < 2; k++) { auto& mUniformBuffers = k ? mUniformBuffersCol[j] : mUniformBuffersMat[j]; - for (unsigned int i = 0; i < mFramesInFlight; i++) { + for (uint32_t i = 0; i < mFramesInFlight; i++) { vk::DescriptorBufferInfo bufferInfo{}; bufferInfo.buffer = mUniformBuffers[i].buffer; bufferInfo.offset = 0; @@ -645,13 +645,13 @@ void GPUDisplayBackendVulkan::clearUniformLayoutsAndBuffers() mDevice.destroyDescriptorSetLayout(mUniformDescriptor, nullptr); mDevice.destroyDescriptorSetLayout(mUniformDescriptorTexture, nullptr); mDevice.destroyDescriptorPool(mDescriptorPool, nullptr); - for (int j = 0; j < 3; j++) { + for (int32_t j = 0; j < 3; j++) { clearVector(mUniformBuffersMat[j], [&](auto& x) { clearBuffer(x); }); clearVector(mUniformBuffersCol[j], [&](auto& x) { clearBuffer(x); }); } } -void GPUDisplayBackendVulkan::setMixDescriptor(int descriptorIndex, int imageIndex) +void GPUDisplayBackendVulkan::setMixDescriptor(int32_t descriptorIndex, int32_t imageIndex) { vk::DescriptorImageInfo imageInfo{}; imageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; @@ -741,7 +741,7 @@ void GPUDisplayBackendVulkan::createSwapChain(bool forScreenshot, bool forMixing mSwapChain = mDevice.createSwapchainKHR(swapCreateInfo, nullptr); mSwapChainImages = mDevice.getSwapchainImagesKHR(mSwapChain); - unsigned int oldFramesInFlight = mFramesInFlight; + uint32_t oldFramesInFlight = mFramesInFlight; mImageCount = mSwapChainImages.size(); mFramesInFlight = mDisplay->cfg().vulkan.nFramesInFlight == 0 ? mImageCount : mDisplay->cfg().vulkan.nFramesInFlight; mCommandBufferPerImage = mFramesInFlight == mImageCount; @@ -759,7 +759,7 @@ void GPUDisplayBackendVulkan::createSwapChain(bool forScreenshot, bool forMixing } mSwapChainImageViews.resize(mImageCount); - for (unsigned int i = 0; i < mImageCount; i++) { + for (uint32_t i = 0; i < mImageCount; i++) { mSwapChainImageViews[i] = createImageViewI(mDevice, mSwapChainImages[i], mSurfaceFormat.format); } } @@ -774,7 +774,7 @@ void GPUDisplayBackendVulkan::recreateRendering(bool forScreenshot, bool forMixi { mDevice.waitIdle(); bool needUpdateSwapChain = mMustUpdateSwapChain || mDownsampleFactor != getDownsampleFactor(forScreenshot) || mSwapchainImageReadable != forScreenshot; - bool needUpdateOffscreenBuffers = needUpdateSwapChain || mMSAASampleCount != getMSAASamplesFlag(std::min(mMaxMSAAsupported, mDisplay->cfgR().drawQualityMSAA)) || mZActive != (mZSupported && mDisplay->cfgL().depthBuffer) || mMixingSupported != forMixing; + bool needUpdateOffscreenBuffers = needUpdateSwapChain || mMSAASampleCount != getMSAASamplesFlag(std::min(mMaxMSAAsupported, mDisplay->cfgR().drawQualityMSAA)) || mZActive != (mZSupported && mDisplay->cfgL().depthBuffer) || mMixingSupported != forMixing; clearPipeline(); if (needUpdateOffscreenBuffers) { clearOffscreenBuffers(); @@ -792,7 +792,7 @@ void GPUDisplayBackendVulkan::recreateRendering(bool forScreenshot, bool forMixi void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool forMixing) { - mMSAASampleCount = getMSAASamplesFlag(std::min(mMaxMSAAsupported, mDisplay->cfgR().drawQualityMSAA)); + mMSAASampleCount = getMSAASamplesFlag(std::min(mMaxMSAAsupported, mDisplay->cfgR().drawQualityMSAA)); mZActive = mZSupported && mDisplay->cfgL().depthBuffer; mMixingSupported = forMixing; @@ -823,7 +823,7 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo colorAttachmentResolve.stencilStoreOp = vk::AttachmentStoreOp::eDontCare; colorAttachmentResolve.initialLayout = vk::ImageLayout::eUndefined; colorAttachmentResolve.finalLayout = mDownsampleFSAA ? vk::ImageLayout::eColorAttachmentOptimal : vk::ImageLayout::ePresentSrcKHR; - int nAttachments = 0; + int32_t nAttachments = 0; vk::AttachmentReference colorAttachmentRef{}; colorAttachmentRef.attachment = nAttachments++; colorAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal; @@ -866,7 +866,7 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo renderPassInfo.pDependencies = &dependency; mRenderPass = mDevice.createRenderPass(renderPassInfo, nullptr); - const unsigned int imageCountWithMixImages = mImageCount * (mMixingSupported ? 2 : 1); + const uint32_t imageCountWithMixImages = mImageCount * (mMixingSupported ? 2 : 1); mRenderTargetView.resize(imageCountWithMixImages); mFramebuffers.resize(imageCountWithMixImages); if (mDownsampleFSAA) { @@ -919,7 +919,7 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo mRenderPassTexture = mDevice.createRenderPass(renderPassInfo, nullptr); } - for (unsigned int i = 0; i < imageCountWithMixImages; i++) { + for (uint32_t i = 0; i < imageCountWithMixImages; i++) { if (i < mImageCount) { // Main render chain // primary buffer mSwapChainImageViews[i] created as part of createSwapChain, not here } else if (!mDownsampleFSAA) { // for rendering to mixBuffer @@ -990,7 +990,7 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo mMixingTextureVertexArray = createBuffer(sizeof(vertices), &vertices[0][0], vk::BufferUsageFlagBits::eVertexBuffer, 1); if (mCommandBufferPerImage) { - for (unsigned int i = 0; i < mFramesInFlight; i++) { + for (uint32_t i = 0; i < mFramesInFlight; i++) { setMixDescriptor(i, i); } } @@ -1157,7 +1157,7 @@ void GPUDisplayBackendVulkan::createPipeline() mPipelines.resize(mMixingSupported ? 5 : 4); static constexpr vk::PrimitiveTopology types[3] = {vk::PrimitiveTopology::ePointList, vk::PrimitiveTopology::eLineList, vk::PrimitiveTopology::eLineStrip}; - for (unsigned int i = 0; i < mPipelines.size(); i++) { + for (uint32_t i = 0; i < mPipelines.size(); i++) { if (i == 4) { // Texture rendering bindingDescription.stride = 4 * sizeof(float); attributeDescriptions.format = vk::Format::eR32G32B32A32Sfloat; @@ -1203,7 +1203,7 @@ void GPUDisplayBackendVulkan::createPipeline() } } -void GPUDisplayBackendVulkan::startFillCommandBuffer(vk::CommandBuffer& commandBuffer, unsigned int imageIndex, bool toMixBuffer) +void GPUDisplayBackendVulkan::startFillCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex, bool toMixBuffer) { commandBuffer.reset({}); @@ -1284,7 +1284,7 @@ void GPUDisplayBackendVulkan::writeToBuffer(VulkanBuffer& buffer, size_t size, c } } -GPUDisplayBackendVulkan::VulkanBuffer GPUDisplayBackendVulkan::createBuffer(size_t size, const void* srcData, vk::BufferUsageFlags type, int deviceMemory) +GPUDisplayBackendVulkan::VulkanBuffer GPUDisplayBackendVulkan::createBuffer(size_t size, const void* srcData, vk::BufferUsageFlags type, int32_t deviceMemory) { vk::MemoryPropertyFlags properties; if (deviceMemory) { @@ -1372,7 +1372,7 @@ void GPUDisplayBackendVulkan::writeToImage(VulkanImage& image, const void* srcDa clearBuffer(tmp); } -GPUDisplayBackendVulkan::VulkanImage GPUDisplayBackendVulkan::createImage(unsigned int sizex, unsigned int sizey, const void* srcData, size_t srcSize, vk::Format format) +GPUDisplayBackendVulkan::VulkanImage GPUDisplayBackendVulkan::createImage(uint32_t sizex, uint32_t sizey, const void* srcData, size_t srcSize, vk::Format format) { VulkanImage image; createImageI(mDevice, mPhysicalDevice, image.image, image.memory, sizex, sizey, format, vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, vk::MemoryPropertyFlagBits::eDeviceLocal, vk::ImageTiling::eOptimal, vk::SampleCountFlagBits::e1); @@ -1398,7 +1398,7 @@ void GPUDisplayBackendVulkan::clearImage(VulkanImage& image) // ---------------------------- VULKAN INIT EXIT ---------------------------- -int GPUDisplayBackendVulkan::InitBackendA() +int32_t GPUDisplayBackendVulkan::InitBackendA() { mEnableValidationLayers = mDisplay->param() && mDisplay->param()->par.debugLevel >= 2; mFramesInFlight = 2; @@ -1436,7 +1436,7 @@ void GPUDisplayBackendVulkan::ExitBackendA() // ---------------------------- USER CODE ---------------------------- -void GPUDisplayBackendVulkan::resizeScene(unsigned int width, unsigned int height) +void GPUDisplayBackendVulkan::resizeScene(uint32_t width, uint32_t height) { if (mScreenWidth == width && mScreenHeight == height) { return; @@ -1461,7 +1461,7 @@ void GPUDisplayBackendVulkan::loadDataToGPU(size_t totalVertizes) needRecordCommandBuffers(); } -unsigned int GPUDisplayBackendVulkan::drawVertices(const vboList& v, const drawType tt) +uint32_t GPUDisplayBackendVulkan::drawVertices(const vboList& v, const drawType tt) { auto first = std::get<0>(v); auto count = std::get<1>(v); @@ -1480,7 +1480,7 @@ unsigned int GPUDisplayBackendVulkan::drawVertices(const vboList& v, const drawT if (mDisplay->cfgR().useGLIndirectDraw) { mCurrentCommandBuffer.drawIndirect(mIndirectCommandBuffer.buffer, (mIndirectSliceOffset[iSlice] + first) * sizeof(DrawArraysIndirectCommand), count, sizeof(DrawArraysIndirectCommand)); } else { - for (unsigned int k = 0; k < count; k++) { + for (uint32_t k = 0; k < count; k++) { mCurrentCommandBuffer.draw(mDisplay->vertexBufferCount()[iSlice][first + k], 1, mDisplay->vertexBufferStart()[iSlice][first + k], 0); } } @@ -1777,9 +1777,9 @@ void GPUDisplayBackendVulkan::needRecordCommandBuffers() std::fill(mCommandBufferUpToDate.begin(), mCommandBufferUpToDate.end(), false); } -void GPUDisplayBackendVulkan::addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) +void GPUDisplayBackendVulkan::addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) { - if (symbol != (int)mFontSymbols.size()) { + if (symbol != (int32_t)mFontSymbols.size()) { throw std::runtime_error("Incorrect symbol ID"); } mFontSymbols.emplace_back(FontSymbolVulkan{{{sizex, sizey}, {offsetx, offsety}, advance}, nullptr, 0.f, 0.f, 0.f, 0.f}); @@ -1792,29 +1792,29 @@ void GPUDisplayBackendVulkan::addFontSymbol(int symbol, int sizex, int sizey, in void GPUDisplayBackendVulkan::initializeTextDrawing() { - int maxSizeX = 0, maxSizeY = 0, maxBigX = 0, maxBigY = 0, maxRowY = 0; + int32_t maxSizeX = 0, maxSizeY = 0, maxBigX = 0, maxBigY = 0, maxRowY = 0; bool smooth = smoothFont(); // Build a mega texture containing all fonts for (auto& symbol : mFontSymbols) { maxSizeX = std::max(maxSizeX, symbol.size[0]); maxSizeY = std::max(maxSizeY, symbol.size[1]); } - unsigned int nn = ceil(std::sqrt(mFontSymbols.size())); - int sizex = nn * maxSizeX; - int sizey = nn * maxSizeY; + uint32_t nn = ceil(std::sqrt(mFontSymbols.size())); + int32_t sizex = nn * maxSizeX; + int32_t sizey = nn * maxSizeY; std::unique_ptr bigImage{new char[sizex * sizey]}; memset(bigImage.get(), 0, sizex * sizey); - int rowy = 0, colx = 0; - for (unsigned int i = 0; i < mFontSymbols.size(); i++) { + int32_t rowy = 0, colx = 0; + for (uint32_t i = 0; i < mFontSymbols.size(); i++) { auto& s = mFontSymbols[i]; if (colx + s.size[0] > sizex) { colx = 0; rowy += maxRowY; maxRowY = 0; } - for (int k = 0; k < s.size[1]; k++) { - for (int j = 0; j < s.size[0]; j++) { - char val = s.data.get()[j + k * s.size[0]]; + for (int32_t k = 0; k < s.size[1]; k++) { + for (int32_t j = 0; j < s.size[0]; j++) { + int8_t val = s.data.get()[j + k * s.size[0]]; if (!smooth) { val = val < 0 ? 0xFF : 0; } @@ -1832,13 +1832,13 @@ void GPUDisplayBackendVulkan::initializeTextDrawing() colx += s.size[0]; } if (maxBigX != sizex) { - for (int y = 1; y < maxBigY; y++) { + for (int32_t y = 1; y < maxBigY; y++) { memmove(bigImage.get() + y * maxBigX, bigImage.get() + y * sizex, maxBigX); } } sizex = maxBigX; sizey = maxBigY; - for (unsigned int i = 0; i < mFontSymbols.size(); i++) { + for (uint32_t i = 0; i < mFontSymbols.size(); i++) { auto& s = mFontSymbols[i]; s.x0 /= sizex; s.x1 /= sizex; @@ -1856,7 +1856,7 @@ void GPUDisplayBackendVulkan::updateFontTextureDescriptor() imageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; imageInfo.imageView = mFontImage.view; imageInfo.sampler = mTextureSampler; - for (unsigned int i = 0; i < mFramesInFlight; i++) { + for (uint32_t i = 0; i < mFramesInFlight; i++) { vk::WriteDescriptorSet descriptorWrite{}; descriptorWrite.dstSet = mDescriptorSets[1][i]; descriptorWrite.dstBinding = 2; @@ -1880,8 +1880,8 @@ void GPUDisplayBackendVulkan::OpenGLPrint(const char* s, float x, float y, float } for (const char* c = s; *c; c++) { - if ((int)*c > (int)mFontSymbols.size()) { - GPUError("Trying to draw unsupported symbol: %d > %d\n", (int)*c, (int)mFontSymbols.size()); + if ((int32_t)*c > (int32_t)mFontSymbols.size()) { + GPUError("Trying to draw unsupported symbol: %d > %d\n", (int32_t)*c, (int32_t)mFontSymbols.size()); continue; } const FontSymbolVulkan& sym = mFontSymbols[*c]; @@ -1919,9 +1919,9 @@ void GPUDisplayBackendVulkan::OpenGLPrint(const char* s, float x, float y, float void GPUDisplayBackendVulkan::readImageToPixels(vk::Image image, vk::ImageLayout layout, std::vector& pixels) { - unsigned int width = mScreenWidth * mDisplay->cfgR().screenshotScaleFactor; - unsigned int height = mScreenHeight * mDisplay->cfgR().screenshotScaleFactor; - static constexpr int bytesPerPixel = 4; + uint32_t width = mScreenWidth * mDisplay->cfgR().screenshotScaleFactor; + uint32_t height = mScreenHeight * mDisplay->cfgR().screenshotScaleFactor; + static constexpr int32_t bytesPerPixel = 4; pixels.resize(width * height * bytesPerPixel); vk::Image dstImage, dstImage2, src2; @@ -1932,8 +1932,8 @@ void GPUDisplayBackendVulkan::readImageToPixels(vk::Image image, vk::ImageLayout if (mDisplay->cfgR().screenshotScaleFactor != 1) { createImageI(mDevice, mPhysicalDevice, dstImage2, dstImageMemory2, width, height, mSurfaceFormat.format, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal, vk::ImageTiling::eOptimal); cmdImageMemoryBarrier(cmdBuffer, dstImage2, {}, vk::AccessFlagBits::eTransferWrite, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer); - vk::Offset3D blitSizeSrc = {(int)mRenderWidth, (int)mRenderHeight, 1}; - vk::Offset3D blitSizeDst = {(int)width, (int)height, 1}; + vk::Offset3D blitSizeSrc = {(int32_t)mRenderWidth, (int32_t)mRenderHeight, 1}; + vk::Offset3D blitSizeDst = {(int32_t)width, (int32_t)height, 1}; vk::ImageBlit imageBlitRegion{}; imageBlitRegion.srcSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; imageBlitRegion.srcSubresource.layerCount = 1; @@ -1968,7 +1968,7 @@ void GPUDisplayBackendVulkan::readImageToPixels(vk::Image image, vk::ImageLayout const char* data; CHKERR(mDevice.mapMemory(dstImageMemory, 0, VK_WHOLE_SIZE, {}, (void**)&data)); data += subResourceLayout.offset; - for (unsigned int i = 0; i < height; i++) { + for (uint32_t i = 0; i < height; i++) { memcpy(pixels.data() + i * width * bytesPerPixel, data + (height - i - 1) * width * bytesPerPixel, width * bytesPerPixel); } mDevice.unmapMemory(dstImageMemory); @@ -1980,7 +1980,7 @@ void GPUDisplayBackendVulkan::readImageToPixels(vk::Image image, vk::ImageLayout } } -unsigned int GPUDisplayBackendVulkan::DepthBits() +uint32_t GPUDisplayBackendVulkan::DepthBits() { return 32; } diff --git a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h index 480dd321dbfdb..00310e58dd5a8 100644 --- a/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h +++ b/GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h @@ -31,7 +31,7 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend GPUDisplayBackendVulkan(); ~GPUDisplayBackendVulkan() override; - unsigned int DepthBits() override; + uint32_t DepthBits() override; protected: struct SwapChainSupportDetails { @@ -43,13 +43,13 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend vk::Buffer buffer; vk::DeviceMemory memory; size_t size = 0; - int deviceMemory; + int32_t deviceMemory; }; struct VulkanImage { vk::Image image; vk::ImageView view; vk::DeviceMemory memory; - unsigned int sizex = 0, sizey = 0; + uint32_t sizex = 0, sizey = 0; vk::Format format; }; struct FontSymbolVulkan : public GPUDisplayBackend::FontSymbol { @@ -62,12 +62,12 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend float color[4]; }; - unsigned int drawVertices(const vboList& v, const drawType t) override; + uint32_t drawVertices(const vboList& v, const drawType t) override; void ActivateColor(std::array& color) override; void SetVSync(bool enable) override { mMustUpdateSwapChain = true; }; void setDepthBuffer() override {}; bool backendNeedRedraw() override; - int InitBackendA() override; + int32_t InitBackendA() override; void ExitBackendA() override; void loadDataToGPU(size_t totalVertizes) override; void prepareDraw(const hmm_mat4& proj, const hmm_mat4& view, bool requestScreenshot, bool toMixBuffer, float includeMixImage) override; @@ -76,25 +76,25 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend void prepareText() override; void finishText() override; void mixImages(vk::CommandBuffer cmdBuffer, float mixSlaveImage); - void setMixDescriptor(int descriptorIndex, int imageIndex); + void setMixDescriptor(int32_t descriptorIndex, int32_t imageIndex); void pointSizeFactor(float factor) override; void lineWidthFactor(float factor) override; - void resizeScene(unsigned int width, unsigned int height) override; + void resizeScene(uint32_t width, uint32_t height) override; float getYFactor() const override { return -1.0f; } - int getMaxMSAA() const override { return mMaxMSAAsupported; } + int32_t getMaxMSAA() const override { return mMaxMSAAsupported; } double checkDevice(vk::PhysicalDevice device, const std::vector& reqDeviceExtensions); vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities); void transitionImageLayout(vk::CommandBuffer commandBuffer, vk::Image image, vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout); - VulkanBuffer createBuffer(size_t size, const void* srcData = nullptr, vk::BufferUsageFlags type = vk::BufferUsageFlagBits::eVertexBuffer, int deviceMemory = 1); + VulkanBuffer createBuffer(size_t size, const void* srcData = nullptr, vk::BufferUsageFlags type = vk::BufferUsageFlagBits::eVertexBuffer, int32_t deviceMemory = 1); void writeToBuffer(VulkanBuffer& buffer, size_t size, const void* srcData); void clearBuffer(VulkanBuffer& buffer); - VulkanImage createImage(unsigned int sizex, unsigned int sizey, const void* srcData = nullptr, size_t srcSize = 0, vk::Format format = vk::Format::eR8G8B8A8Srgb); + VulkanImage createImage(uint32_t sizex, uint32_t sizey, const void* srcData = nullptr, size_t srcSize = 0, vk::Format format = vk::Format::eR8G8B8A8Srgb); void writeToImage(VulkanImage& image, const void* srcData, size_t srcSize); void clearImage(VulkanImage& image); void clearVertexBuffers(); - void startFillCommandBuffer(vk::CommandBuffer& commandBuffer, unsigned int imageIndex, bool toMixBuffer = false); + void startFillCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex, bool toMixBuffer = false); void endFillCommandBuffer(vk::CommandBuffer& commandBuffer); vk::CommandBuffer getSingleTimeCommandBuffer(); void submitSingleTimeCommandBuffer(vk::CommandBuffer commandBuffer); @@ -124,11 +124,11 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend void recreateRendering(bool forScreenshot = false, bool forMixing = false); void needRecordCommandBuffers(); - void addFontSymbol(int symbol, int sizex, int sizey, int offsetx, int offsety, int advance, void* data) override; + void addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) override; void initializeTextDrawing() override; void OpenGLPrint(const char* s, float x, float y, float* color, float scale) override; - unsigned int mGraphicsFamily; + uint32_t mGraphicsFamily; SwapChainSupportDetails mSwapChainDetails; bool mEnableValidationLayers = false; @@ -165,13 +165,13 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend bool mCommandBufferPerImage = false; bool mCommandInfrastructureCreated = false; - unsigned int mImageCount = 0; - unsigned int mFramesInFlight = 0; - int mCurrentFrame = 0; + uint32_t mImageCount = 0; + uint32_t mFramesInFlight = 0; + int32_t mCurrentFrame = 0; uint32_t mCurrentImageIndex = 0; - int mCurrentBufferSet = 0; + int32_t mCurrentBufferSet = 0; vk::CommandBuffer mCurrentCommandBuffer; - int mCurrentCommandBufferLastPipeline = -1; + int32_t mCurrentCommandBufferLastPipeline = -1; std::vector mCommandBuffers; std::vector mCommandBuffersDownsample; @@ -205,7 +205,7 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend bool mSwapchainImageReadable = false; vk::SampleCountFlagBits mMSAASampleCount = vk::SampleCountFlagBits::e16; - unsigned int mMaxMSAAsupported = 0; + uint32_t mMaxMSAAsupported = 0; bool mZActive = false; bool mZSupported = false; bool mStencilSupported = false; diff --git a/GPU/GPUTracking/display/filterMacros/TRDCandidate.C b/GPU/GPUTracking/display/filterMacros/TRDCandidate.C index a58558b0b52a0..f00681d0ca335 100644 --- a/GPU/GPUTracking/display/filterMacros/TRDCandidate.C +++ b/GPU/GPUTracking/display/filterMacros/TRDCandidate.C @@ -4,7 +4,7 @@ using namespace o2::gpu; void gpuDisplayTrackFilter(std::vector* filter, const GPUTrackingInOutPointers* ioPtrs, const GPUConstantMem* processors) { - for (unsigned int i = 0; i < filter->size(); i++) { + for (uint32_t i = 0; i < filter->size(); i++) { (*filter)[i] = processors->trdTrackerGPU.PreCheckTrackTRDCandidate(ioPtrs->mergedTracks[i]) && processors->trdTrackerGPU.CheckTrackTRDCandidate((GPUTRDTrackGPU)ioPtrs->mergedTracks[i]); } } diff --git a/GPU/GPUTracking/display/filterMacros/filterGPUTrack.C b/GPU/GPUTracking/display/filterMacros/filterGPUTrack.C index 1c70fbd7768fa..886ed29611553 100644 --- a/GPU/GPUTracking/display/filterMacros/filterGPUTrack.C +++ b/GPU/GPUTracking/display/filterMacros/filterGPUTrack.C @@ -10,7 +10,7 @@ using namespace o2::gpu; void gpuDisplayTrackFilter(std::vector* filter, const GPUTrackingInOutPointers* ioPtrs, const GPUConstantMem* processors) { - for (unsigned int i = 0; i < filter->size(); i++) { + for (uint32_t i = 0; i < filter->size(); i++) { auto& trk = ioPtrs->mergedTracks[i]; (*filter)[i] = fabsf(trk.GetParam().GetQPt()) < 1.0f; } diff --git a/GPU/GPUTracking/display/filterMacros/filterTPCTrack.C b/GPU/GPUTracking/display/filterMacros/filterTPCTrack.C index b2d161d967f2f..636cdd0319011 100644 --- a/GPU/GPUTracking/display/filterMacros/filterTPCTrack.C +++ b/GPU/GPUTracking/display/filterMacros/filterTPCTrack.C @@ -12,7 +12,7 @@ using namespace o2::gpu; void gpuDisplayTrackFilter(std::vector* filter, const GPUTrackingInOutPointers* ioPtrs, const GPUConstantMem* processors) { - for (unsigned int i = 0; i < filter->size(); i++) { + for (uint32_t i = 0; i < filter->size(); i++) { auto& trk = ioPtrs->outputTracksTPCO2[i]; (*filter)[i] = fabsf(trk.getQ2Pt()) < 1.0f; } diff --git a/GPU/GPUTracking/display/filterMacros/hasTRD.C b/GPU/GPUTracking/display/filterMacros/hasTRD.C index 355fd213c57fd..cd98fb2fe349b 100644 --- a/GPU/GPUTracking/display/filterMacros/hasTRD.C +++ b/GPU/GPUTracking/display/filterMacros/hasTRD.C @@ -6,7 +6,7 @@ void gpuDisplayTrackFilter(std::vector* filter, const GPUTrackingInOutPoin if (!ioPtrs->tpcLinkTRD) { return; } - for (unsigned int i = 0; i < filter->size(); i++) { + for (uint32_t i = 0; i < filter->size(); i++) { (*filter)[i] = ioPtrs->tpcLinkTRD[i] != -1; } } diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx index fc5bec4a3d6fb..b48d5b994fcf8 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.cxx @@ -48,7 +48,7 @@ GPUDisplayFrontend::~GPUDisplayFrontend() = default; void* GPUDisplayFrontend::FrontendThreadWrapper(void* ptr) { GPUDisplayFrontend* me = reinterpret_cast(ptr); - int retVal = me->FrontendMain(); + int32_t retVal = me->FrontendMain(); if (retVal == -1) { me->InitDisplay(true); } @@ -63,15 +63,15 @@ void GPUDisplayFrontend::HandleSendKey() } } -void GPUDisplayFrontend::HandleKey(unsigned char key) { mDisplay->HandleKey(key); } -int GPUDisplayFrontend::DrawGLScene() { return mDisplay->DrawGLScene(); } -void GPUDisplayFrontend::ResizeScene(int width, int height) +void GPUDisplayFrontend::HandleKey(uint8_t key) { mDisplay->HandleKey(key); } +int32_t GPUDisplayFrontend::DrawGLScene() { return mDisplay->DrawGLScene(); } +void GPUDisplayFrontend::ResizeScene(int32_t width, int32_t height) { mDisplayHeight = height; mDisplayWidth = width; mDisplay->ResizeScene(width, height); } -int GPUDisplayFrontend::InitDisplay(bool initFailure) { return mDisplay->InitDisplay(initFailure); } +int32_t GPUDisplayFrontend::InitDisplay(bool initFailure) { return mDisplay->InitDisplay(initFailure); } void GPUDisplayFrontend::ExitDisplay() { mDisplay->ExitDisplay(); @@ -89,9 +89,9 @@ void GPUDisplayFrontend::stopGUI() #endif } -int GPUDisplayFrontend::startGUI() +int32_t GPUDisplayFrontend::startGUI() { - int retVal = 1; + int32_t retVal = 1; #ifdef GPUCA_BUILD_EVENT_DISPLAY_QT if (!mGUI) { mGUI.reset(new GPUDisplayGUIWrapper); @@ -156,7 +156,7 @@ GPUDisplayBackend* GPUDisplayFrontend::backend() return mDisplay->backend(); } -int& GPUDisplayFrontend::drawTextFontSize() +int32_t& GPUDisplayFrontend::drawTextFontSize() { return mDisplay->drawTextFontSize(); } diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h index c1e41eac81bb7..1c459d77beee9 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontend.h @@ -44,10 +44,10 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface }; // Compile time minimum version defined in GPUDisplay.h, keep in sync! - static constexpr int GL_MIN_VERSION_MAJOR = 4; - static constexpr int GL_MIN_VERSION_MINOR = 5; + static constexpr int32_t GL_MIN_VERSION_MAJOR = 4; + static constexpr int32_t GL_MIN_VERSION_MINOR = 5; - virtual int StartDisplay() = 0; // Start the display. This function returns, and should spawn a thread that runs the display, and calls InitDisplay + virtual int32_t StartDisplay() = 0; // Start the display. This function returns, and should spawn a thread that runs the display, and calls InitDisplay void DisplayExit() override = 0; // Stop the display. Display thread should call ExitDisplay and the function returns after the thread has terminated virtual void SwitchFullscreen(bool set) = 0; // Toggle full-screen mode virtual void ToggleMaximized(bool set) = 0; // Maximize window @@ -56,79 +56,79 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface virtual void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) = 0; // Print text on the display (needs the backend to build the font) GPUDisplayBackend* backend(); static GPUDisplayFrontend* getFrontend(const char* type); - virtual void getSize(int& width, int& height) { width = height = 0; } - virtual int getVulkanSurface(void* instance, void* surface) { return 1; } - virtual unsigned int getReqVulkanExtensions(const char**& p) { return 0; }; + virtual void getSize(int32_t& width, int32_t& height) { width = height = 0; } + virtual int32_t getVulkanSurface(void* instance, void* surface) { return 1; } + virtual uint32_t getReqVulkanExtensions(const char**& p) { return 0; }; - int getDisplayControl() const override { return mDisplayControl; } - int getSendKey() const override { return mSendKey; } - int getNeedUpdate() const override { return mNeedUpdate; } - void setDisplayControl(int v) override { mDisplayControl = v; } - void setSendKey(int v) override { mSendKey = v; } - void setNeedUpdate(int v) override { mNeedUpdate = v; } + int32_t getDisplayControl() const override { return mDisplayControl; } + int32_t getSendKey() const override { return mSendKey; } + int32_t getNeedUpdate() const override { return mNeedUpdate; } + void setDisplayControl(int32_t v) override { mDisplayControl = v; } + void setSendKey(int32_t v) override { mSendKey = v; } + void setNeedUpdate(int32_t v) override { mNeedUpdate = v; } frontendTypes frontendType() const { return mFrontendType; } const char* frontendName() const override { return mFrontendName; } - int startGUI(); + int32_t startGUI(); void stopGUI(); bool isGUIRunning(); // volatile variables to exchange control informations between display and backend - volatile int mDisplayControl = 0; // Control for next event (=1) or quit (=2) - volatile int mSendKey = 0; // Key sent by external entity (usually console), may be ignored by backend. - volatile int mNeedUpdate = 0; // flag that backend shall update the GL window, and call DrawGLScene + volatile int32_t mDisplayControl = 0; // Control for next event (=1) or quit (=2) + volatile int32_t mSendKey = 0; // Key sent by external entity (usually console), may be ignored by backend. + volatile int32_t mNeedUpdate = 0; // flag that backend shall update the GL window, and call DrawGLScene protected: - virtual int FrontendMain() = 0; + virtual int32_t FrontendMain() = 0; static void* FrontendThreadWrapper(void*); - static constexpr int INIT_WIDTH = 1024, INIT_HEIGHT = 768; // Initial window size, before maximizing + static constexpr int32_t INIT_WIDTH = 1024, INIT_HEIGHT = 768; // Initial window size, before maximizing static constexpr const char* DISPLAY_WINDOW_NAME = "GPU CA Standalone Event Display"; // Title of event display set by backend // Constant key codes for special mKeys (to unify different treatment in X11 / Windows / GLUT / etc.) - static constexpr int KEY_UP = 1; - static constexpr int KEY_DOWN = 2; - static constexpr int KEY_LEFT = 3; - static constexpr int KEY_RIGHT = 4; - static constexpr int KEY_PAGEUP = 5; - static constexpr int KEY_PAGEDOWN = 6; - static constexpr int KEY_SHIFT = 8; - static constexpr int KEY_ALT = 9; - static constexpr int KEY_RALT = 10; - static constexpr int KEY_CTRL = 11; - static constexpr int KEY_RCTRL = 12; - static constexpr int KEY_ENTER = 13; // fixed at 13 - static constexpr int KEY_F1 = 14; - static constexpr int KEY_F2 = 15; - static constexpr int KEY_F3 = 26; - static constexpr int KEY_F4 = 17; - static constexpr int KEY_F5 = 18; - static constexpr int KEY_F6 = 19; - static constexpr int KEY_F7 = 20; - static constexpr int KEY_F8 = 21; - static constexpr int KEY_F9 = 22; - static constexpr int KEY_F10 = 23; - static constexpr int KEY_F11 = 24; - static constexpr int KEY_F12 = 25; - static constexpr int KEY_INSERT = 26; - static constexpr int KEY_ESCAPE = 27; // fixed at 27 - static constexpr int KEY_HOME = 28; - static constexpr int KEY_END = 29; - static constexpr int KEY_SPACE = 32; // fixed at 32 + static constexpr int32_t KEY_UP = 1; + static constexpr int32_t KEY_DOWN = 2; + static constexpr int32_t KEY_LEFT = 3; + static constexpr int32_t KEY_RIGHT = 4; + static constexpr int32_t KEY_PAGEUP = 5; + static constexpr int32_t KEY_PAGEDOWN = 6; + static constexpr int32_t KEY_SHIFT = 8; + static constexpr int32_t KEY_ALT = 9; + static constexpr int32_t KEY_RALT = 10; + static constexpr int32_t KEY_CTRL = 11; + static constexpr int32_t KEY_RCTRL = 12; + static constexpr int32_t KEY_ENTER = 13; // fixed at 13 + static constexpr int32_t KEY_F1 = 14; + static constexpr int32_t KEY_F2 = 15; + static constexpr int32_t KEY_F3 = 26; + static constexpr int32_t KEY_F4 = 17; + static constexpr int32_t KEY_F5 = 18; + static constexpr int32_t KEY_F6 = 19; + static constexpr int32_t KEY_F7 = 20; + static constexpr int32_t KEY_F8 = 21; + static constexpr int32_t KEY_F9 = 22; + static constexpr int32_t KEY_F10 = 23; + static constexpr int32_t KEY_F11 = 24; + static constexpr int32_t KEY_F12 = 25; + static constexpr int32_t KEY_INSERT = 26; + static constexpr int32_t KEY_ESCAPE = 27; // fixed at 27 + static constexpr int32_t KEY_HOME = 28; + static constexpr int32_t KEY_END = 29; + static constexpr int32_t KEY_SPACE = 32; // fixed at 32 // Keyboard / Mouse actions bool mMouseDn = false; // Mouse button down bool mMouseDnR = false; // Right mouse button down float mMouseDnX, mMouseDnY; // X/Y position where mouse button was pressed float mMouseMvX, mMouseMvY; // Current mouse pointer position - int mMouseWheel = 0; // Incremental value of mouse wheel, ca +/- 100 per wheel tick + int32_t mMouseWheel = 0; // Incremental value of mouse wheel, ca +/- 100 per wheel tick bool mKeys[256] = {false}; // Array of mKeys currently pressed bool mKeysShift[256] = {false}; // Array whether shift was held during key-press - int mDisplayHeight = INIT_HEIGHT; - int mDisplayWidth = INIT_WIDTH; - int mCanDrawText = 0; // 1 = in compat mode, 2 = with shader + int32_t mDisplayHeight = INIT_HEIGHT; + int32_t mDisplayWidth = INIT_WIDTH; + int32_t mCanDrawText = 0; // 1 = in compat mode, 2 = with shader - int mMaxFPSRate = 0; // run at highest possible frame rate, do not sleep in between frames + int32_t mMaxFPSRate = 0; // run at highest possible frame rate, do not sleep in between frames GPUDisplay* mDisplay = nullptr; // Ptr to display, not owning, set by display when it connects to backend GPUDisplayBackend* mBackend = nullptr; // Ptr to backend, not owning @@ -138,13 +138,13 @@ class GPUDisplayFrontend : public GPUDisplayFrontendInterface std::unique_ptr mGUI; - void HandleKey(unsigned char key); // Callback for handling key presses - int DrawGLScene(); // Callback to draw the GL scene + void HandleKey(uint8_t key); // Callback for handling key presses + int32_t DrawGLScene(); // Callback to draw the GL scene void HandleSendKey(); // Optional callback to handle key press from external source (e.g. stdin by default) - void ResizeScene(int width, int height); // Callback when GL window is resized - int InitDisplay(bool initFailure = false); // Callback to initialize the GL Display (to be called in StartDisplay) + void ResizeScene(int32_t width, int32_t height); // Callback when GL window is resized + int32_t InitDisplay(bool initFailure = false); // Callback to initialize the GL Display (to be called in StartDisplay) void ExitDisplay(); // Callback to clean up the GL Display - int& drawTextFontSize(); + int32_t& drawTextFontSize(); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx index 1644bb23d5b94..d9cfbedf3ba53 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.cxx @@ -22,7 +22,7 @@ #endif #if defined(GPUCA_O2_LIB) && !defined(GPUCA_DISPLAY_GL3W) // Hack: we have to define this in order to initialize gl3w, cannot include the header as it clashes with glew -extern "C" int gl3wInit(); +extern "C" int32_t gl3wInit(); #endif #ifdef GPUCA_BUILD_EVENT_DISPLAY_VULKAN @@ -56,7 +56,7 @@ GPUDisplayFrontendGlfw::GPUDisplayFrontendGlfw() static GPUDisplayFrontendGlfw* me = nullptr; -int GPUDisplayFrontendGlfw::GetKey(int key) +int32_t GPUDisplayFrontendGlfw::GetKey(int32_t key) { if (key == GLFW_KEY_KP_SUBTRACT) { return ('-'); @@ -154,31 +154,31 @@ int GPUDisplayFrontendGlfw::GetKey(int key) return (0); } -void GPUDisplayFrontendGlfw::GetKey(int key, int scancode, int mods, int& keyOut, int& keyPressOut) +void GPUDisplayFrontendGlfw::GetKey(int32_t key, int32_t scancode, int32_t mods, int32_t& keyOut, int32_t& keyPressOut) { - int specialKey = GetKey(key); + int32_t specialKey = GetKey(key); const char* str = glfwGetKeyName(key, scancode); char localeKey = str ? str[0] : 0; if ((mods & GLFW_MOD_SHIFT) && localeKey >= 'a' && localeKey <= 'z') { localeKey += 'A' - 'a'; } - // GPUInfo("Key: key %d (%c) scancode %d -> %d (%c) special %d (%c)", key, (char)key, scancode, (int)localeKey, localeKey, specialKey, (char)specialKey); + // GPUInfo("Key: key %d (%c) scancode %d -> %d (%c) special %d (%c)", key, (char)key, scancode, (int32_t)localeKey, localeKey, specialKey, (char)specialKey); if (specialKey) { keyOut = keyPressOut = specialKey; } else { - keyOut = keyPressOut = (unsigned char)localeKey; + keyOut = keyPressOut = (uint8_t)localeKey; if (keyPressOut >= 'a' && keyPressOut <= 'z') { keyPressOut += 'A' - 'a'; } } } -void GPUDisplayFrontendGlfw::error_callback(int error, const char* description) { fprintf(stderr, "Error: %s\n", description); } +void GPUDisplayFrontendGlfw::error_callback(int32_t error, const char* description) { fprintf(stderr, "Error: %s\n", description); } -void GPUDisplayFrontendGlfw::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +void GPUDisplayFrontendGlfw::key_callback(GLFWwindow* window, int32_t key, int32_t scancode, int32_t action, int32_t mods) { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(key, scancode, mods, handleKey, keyPress); if (handleKey < 32) { if (action == GLFW_PRESS) { @@ -193,27 +193,29 @@ void GPUDisplayFrontendGlfw::key_callback(GLFWwindow* window, int key, int scanc if (action == GLFW_PRESS) { me->mLastKeyDown = handleKey; } else if (action == GLFW_RELEASE) { - keyPress = (unsigned char)me->mKeyDownMap[handleKey]; + keyPress = (uint8_t)me->mKeyDownMap[handleKey]; me->mKeys[keyPress] = false; me->mKeysShift[keyPress] = false; } } } -void GPUDisplayFrontendGlfw::char_callback(GLFWwindow* window, unsigned int codepoint) +void GPUDisplayFrontendGlfw::char_callback(GLFWwindow* window, uint32_t codepoint) { - // GPUInfo("Key (char callback): %d %c - key: %d", codepoint, (char)codepoint, (int)me->mLastKeyDown); - int keyPress = codepoint; - if (keyPress >= 'a' && keyPress <= 'z') { - keyPress += 'A' - 'a'; - } - me->mKeyDownMap[me->mLastKeyDown] = keyPress; - me->mKeys[keyPress] = true; - me->mKeysShift[keyPress] = me->mKeys[KEY_SHIFT]; - me->HandleKey(codepoint); + // GPUInfo("Key (char callback): %d %c - key: %d", codepoint, (char)codepoint, (int32_t)me->mLastKeyDown); + if (codepoint < 256) { + uint8_t keyPress = codepoint; + if (keyPress >= 'a' && keyPress <= 'z') { + keyPress += 'A' - 'a'; + } + me->mKeyDownMap[me->mLastKeyDown] = keyPress; + me->mKeys[keyPress] = true; + me->mKeysShift[keyPress] = me->mKeys[KEY_SHIFT]; + me->HandleKey(codepoint); + } } -void GPUDisplayFrontendGlfw::mouseButton_callback(GLFWwindow* window, int button, int action, int mods) +void GPUDisplayFrontendGlfw::mouseButton_callback(GLFWwindow* window, int32_t button, int32_t action, int32_t mods) { if (action == GLFW_PRESS) { if (button == 0) { @@ -240,7 +242,7 @@ void GPUDisplayFrontendGlfw::cursorPos_callback(GLFWwindow* window, double x, do me->mMouseMvY = y; } -void GPUDisplayFrontendGlfw::resize_callback(GLFWwindow* window, int width, int height) { me->ResizeScene(width, height); } +void GPUDisplayFrontendGlfw::resize_callback(GLFWwindow* window, int32_t width, int32_t height) { me->ResizeScene(width, height); } #ifdef GPUCA_O2_LIB void GPUDisplayFrontendGlfw::DisplayLoop() @@ -254,7 +256,7 @@ void GPUDisplayFrontendGlfw::DisplayLoop() } #endif -int GPUDisplayFrontendGlfw::FrontendMain() +int32_t GPUDisplayFrontendGlfw::FrontendMain() { me = this; @@ -392,7 +394,7 @@ void GPUDisplayFrontendGlfw::OpenGLPrint(const char* s, float x, float y, float void GPUDisplayFrontendGlfw::SwitchFullscreen(bool set) { - GPUInfo("Setting Full Screen %d", (int)set); + GPUInfo("Setting Full Screen %d", (int32_t)set); if (set) { glfwGetWindowPos(mWindow, &mWindowX, &mWindowY); glfwGetWindowSize(mWindow, &mWindowWidth, &mWindowHeight); @@ -415,7 +417,7 @@ void GPUDisplayFrontendGlfw::ToggleMaximized(bool set) void GPUDisplayFrontendGlfw::SetVSync(bool enable) { glfwSwapInterval(enable); } -int GPUDisplayFrontendGlfw::StartDisplay() +int32_t GPUDisplayFrontendGlfw::StartDisplay() { static pthread_t hThread; if (pthread_create(&hThread, nullptr, FrontendThreadWrapper, this)) { @@ -434,12 +436,12 @@ bool GPUDisplayFrontendGlfw::EnableSendKey() #endif } -void GPUDisplayFrontendGlfw::getSize(int& width, int& height) +void GPUDisplayFrontendGlfw::getSize(int32_t& width, int32_t& height) { glfwGetFramebufferSize(mWindow, &width, &height); } -int GPUDisplayFrontendGlfw::getVulkanSurface(void* instance, void* surface) +int32_t GPUDisplayFrontendGlfw::getVulkanSurface(void* instance, void* surface) { #ifdef GPUCA_BUILD_EVENT_DISPLAY_VULKAN return glfwCreateWindowSurface(*(VkInstance*)instance, mWindow, nullptr, (VkSurfaceKHR*)surface) != VK_SUCCESS; @@ -448,7 +450,7 @@ int GPUDisplayFrontendGlfw::getVulkanSurface(void* instance, void* surface) #endif } -unsigned int GPUDisplayFrontendGlfw::getReqVulkanExtensions(const char**& p) +uint32_t GPUDisplayFrontendGlfw::getReqVulkanExtensions(const char**& p) { uint32_t glfwExtensionCount = 0; #ifdef GPUCA_BUILD_EVENT_DISPLAY_VULKAN diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h index 5f2bd26ed9375..792abcf64b839 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlfw.h @@ -28,41 +28,41 @@ class GPUDisplayFrontendGlfw : public GPUDisplayFrontend GPUDisplayFrontendGlfw(); ~GPUDisplayFrontendGlfw() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void DisplayExit() override; void SwitchFullscreen(bool set) override; void ToggleMaximized(bool set) override; void SetVSync(bool enable) override; void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) override; bool EnableSendKey() override; - void getSize(int& width, int& height) override; - int getVulkanSurface(void* instance, void* surface) override; - unsigned int getReqVulkanExtensions(const char**& p) override; + void getSize(int32_t& width, int32_t& height) override; + int32_t getVulkanSurface(void* instance, void* surface) override; + uint32_t getReqVulkanExtensions(const char**& p) override; private: - int FrontendMain() override; + int32_t FrontendMain() override; static void DisplayLoop(); - static void error_callback(int error, const char* description); - static void key_callback(GLFWwindow* mWindow, int key, int scancode, int action, int mods); - static void char_callback(GLFWwindow* window, unsigned int codepoint); - static void mouseButton_callback(GLFWwindow* mWindow, int button, int action, int mods); + static void error_callback(int32_t error, const char* description); + static void key_callback(GLFWwindow* mWindow, int32_t key, int32_t scancode, int32_t action, int32_t mods); + static void char_callback(GLFWwindow* window, uint32_t codepoint); + static void mouseButton_callback(GLFWwindow* mWindow, int32_t button, int32_t action, int32_t mods); static void scroll_callback(GLFWwindow* mWindow, double x, double y); static void cursorPos_callback(GLFWwindow* mWindow, double x, double y); - static void resize_callback(GLFWwindow* mWindow, int width, int height); - static int GetKey(int key); - static void GetKey(int keyin, int scancode, int mods, int& keyOut, int& keyPressOut); + static void resize_callback(GLFWwindow* mWindow, int32_t width, int32_t height); + static int32_t GetKey(int32_t key); + static void GetKey(int32_t keyin, int32_t scancode, int32_t mods, int32_t& keyOut, int32_t& keyPressOut); GLFWwindow* mWindow; volatile bool mGlfwRunning = false; pthread_mutex_t mSemLockExit = PTHREAD_MUTEX_INITIALIZER; - int mWindowX = 0; - int mWindowY = 0; - int mWindowWidth = INIT_WIDTH; - int mWindowHeight = INIT_HEIGHT; - char mKeyDownMap[256] = {0}; - unsigned char mLastKeyDown = 0; + int32_t mWindowX = 0; + int32_t mWindowY = 0; + int32_t mWindowWidth = INIT_WIDTH; + int32_t mWindowHeight = INIT_HEIGHT; + uint8_t mKeyDownMap[256] = {0}; + uint8_t mLastKeyDown = 0; bool mUseIMGui = false; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx index a165e51840e0c..ab435586820e8 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.cxx @@ -44,7 +44,7 @@ void GPUDisplayFrontendGlut::glutLoopFunc() displayFunc(); } -int GPUDisplayFrontendGlut::GetKey(int key) +int32_t GPUDisplayFrontendGlut::GetKey(int32_t key) { if (key == GLUT_KEY_UP) { return KEY_UP; @@ -125,10 +125,10 @@ int GPUDisplayFrontendGlut::GetKey(int key) return (0); } -void GPUDisplayFrontendGlut::GetKey(int key, int& keyOut, int& keyPressOut, bool special) +void GPUDisplayFrontendGlut::GetKey(int32_t key, int32_t& keyOut, int32_t& keyPressOut, bool special) { - int specialKey = special ? GetKey(key) : 0; - // GPUInfo("Key: key %d (%c) (special %d) -> %d (%c) special %d (%c)", key, (char) key, (int) special, (int) key, key, specialKey, (char) specialKey); + int32_t specialKey = special ? GetKey(key) : 0; + // GPUInfo("Key: key %d (%c) (special %d) -> %d (%c) special %d (%c)", key, (char) key, (int32_t) special, (int32_t) key, key, specialKey, (char) specialKey); if (specialKey) { keyOut = keyPressOut = specialKey; @@ -140,41 +140,41 @@ void GPUDisplayFrontendGlut::GetKey(int key, int& keyOut, int& keyPressOut, bool } } -void GPUDisplayFrontendGlut::keyboardDownFunc(unsigned char key, int x, int y) +void GPUDisplayFrontendGlut::keyboardDownFunc(uint8_t key, int32_t x, int32_t y) { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(key, handleKey, keyPress, false); me->mKeysShift[keyPress] = glutGetModifiers() & GLUT_ACTIVE_SHIFT; me->mKeys[keyPress] = true; me->HandleKey(handleKey); } -void GPUDisplayFrontendGlut::keyboardUpFunc(unsigned char key, int x, int y) +void GPUDisplayFrontendGlut::keyboardUpFunc(uint8_t key, int32_t x, int32_t y) { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(key, handleKey, keyPress, false); me->mKeys[keyPress] = false; me->mKeysShift[keyPress] = false; } -void GPUDisplayFrontendGlut::specialDownFunc(int key, int x, int y) +void GPUDisplayFrontendGlut::specialDownFunc(int32_t key, int32_t x, int32_t y) { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(key, handleKey, keyPress, true); me->mKeysShift[keyPress] = glutGetModifiers() & GLUT_ACTIVE_SHIFT; me->mKeys[keyPress] = true; me->HandleKey(handleKey); } -void GPUDisplayFrontendGlut::specialUpFunc(int key, int x, int y) +void GPUDisplayFrontendGlut::specialUpFunc(int32_t key, int32_t x, int32_t y) { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(key, handleKey, keyPress, true); me->mKeys[keyPress] = false; me->mKeysShift[keyPress] = false; } -void GPUDisplayFrontendGlut::ResizeSceneWrapper(int width, int height) +void GPUDisplayFrontendGlut::ResizeSceneWrapper(int32_t width, int32_t height) { if (!me->mFullScreen) { me->mWidth = width; @@ -183,7 +183,7 @@ void GPUDisplayFrontendGlut::ResizeSceneWrapper(int width, int height) me->ResizeScene(width, height); } -void GPUDisplayFrontendGlut::mouseFunc(int button, int state, int x, int y) +void GPUDisplayFrontendGlut::mouseFunc(int32_t button, int32_t state, int32_t x, int32_t y) { if (button == 3) { me->mMouseWheel += 100; @@ -206,15 +206,15 @@ void GPUDisplayFrontendGlut::mouseFunc(int button, int state, int x, int y) } } -void GPUDisplayFrontendGlut::mouseMoveFunc(int x, int y) +void GPUDisplayFrontendGlut::mouseMoveFunc(int32_t x, int32_t y) { me->mMouseMvX = x; me->mMouseMvY = y; } -void GPUDisplayFrontendGlut::mMouseWheelFunc(int button, int dir, int x, int y) { me->mMouseWheel += dir; } +void GPUDisplayFrontendGlut::mMouseWheelFunc(int32_t button, int32_t dir, int32_t x, int32_t y) { me->mMouseWheel += dir; } -int GPUDisplayFrontendGlut::FrontendMain() +int32_t GPUDisplayFrontendGlut::FrontendMain() { if (backend()->backendType() != GPUDisplayBackend::TYPE_OPENGL) { fprintf(stderr, "Only OpenGL backend supported\n"); @@ -226,7 +226,7 @@ int GPUDisplayFrontendGlut::FrontendMain() drawTextFontSize() = 12; } - int nopts = 2; + int32_t nopts = 2; char opt1[] = "progname"; char opt2[] = "-direct"; char* opts[] = {opt1, opt2}; @@ -293,7 +293,7 @@ void GPUDisplayFrontendGlut::OpenGLPrint(const char* s, float x, float y, float } glColor4f(r, g, b, a); glRasterPos2f(x, y); - glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)s); + glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const uint8_t*)s); #endif } @@ -310,7 +310,7 @@ void GPUDisplayFrontendGlut::SwitchFullscreen(bool set) void GPUDisplayFrontendGlut::ToggleMaximized(bool set) {} void GPUDisplayFrontendGlut::SetVSync(bool enable) {} -int GPUDisplayFrontendGlut::StartDisplay() +int32_t GPUDisplayFrontendGlut::StartDisplay() { static pthread_t hThread; if (pthread_create(&hThread, nullptr, FrontendThreadWrapper, this)) { diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h index 90d69a48ef79f..71d7d17c935c8 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendGlut.h @@ -26,7 +26,7 @@ class GPUDisplayFrontendGlut : public GPUDisplayFrontend GPUDisplayFrontendGlut(); ~GPUDisplayFrontendGlut() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void DisplayExit() override; void SwitchFullscreen(bool set) override; void ToggleMaximized(bool set) override; @@ -34,26 +34,26 @@ class GPUDisplayFrontendGlut : public GPUDisplayFrontend void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) override; private: - int FrontendMain() override; + int32_t FrontendMain() override; static void displayFunc(); static void glutLoopFunc(); - static void keyboardUpFunc(unsigned char key, int x, int y); - static void keyboardDownFunc(unsigned char key, int x, int y); - static void specialUpFunc(int key, int x, int y); - static void specialDownFunc(int key, int x, int y); - static void mouseMoveFunc(int x, int y); - static void mMouseWheelFunc(int button, int dir, int x, int y); - static void mouseFunc(int button, int state, int x, int y); - static void ResizeSceneWrapper(int width, int height); - static int GetKey(int key); - static void GetKey(int keyin, int& keyOut, int& keyPressOut, bool special); + static void keyboardUpFunc(uint8_t key, int32_t x, int32_t y); + static void keyboardDownFunc(uint8_t key, int32_t x, int32_t y); + static void specialUpFunc(int32_t key, int32_t x, int32_t y); + static void specialDownFunc(int32_t key, int32_t x, int32_t y); + static void mouseMoveFunc(int32_t x, int32_t y); + static void mMouseWheelFunc(int32_t button, int32_t dir, int32_t x, int32_t y); + static void mouseFunc(int32_t button, int32_t state, int32_t x, int32_t y); + static void ResizeSceneWrapper(int32_t width, int32_t height); + static int32_t GetKey(int32_t key); + static void GetKey(int32_t keyin, int32_t& keyOut, int32_t& keyPressOut, bool special); volatile bool mGlutRunning = false; pthread_mutex_t mSemLockExit = PTHREAD_MUTEX_INITIALIZER; - int mWidth = INIT_WIDTH; - int mHeight = INIT_HEIGHT; + int32_t mWidth = INIT_WIDTH; + int32_t mHeight = INIT_HEIGHT; bool mFullScreen = false; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h index 6eebbf2c9c168..c95927c6655b9 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendNone.h @@ -24,7 +24,7 @@ class GPUDisplayFrontendNone : public GPUDisplayFrontend GPUDisplayFrontendNone() = default; ~GPUDisplayFrontendNone() override = default; - int StartDisplay() override { return 1; } + int32_t StartDisplay() override { return 1; } void DisplayExit() override {} void SwitchFullscreen(bool set) override {} void ToggleMaximized(bool set) override {} diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx index 6c85336f9791a..7233ab1d86e33 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx @@ -59,9 +59,9 @@ struct CCallWrapper { } }; -int GPUDisplayFrontendWayland::GetKey(unsigned int key, unsigned int state) +int32_t GPUDisplayFrontendWayland::GetKey(uint32_t key, uint32_t state) { - int retVal = 0; + int32_t retVal = 0; if (mXKBkeymap) { xkb_keysym_t sym = xkb_state_key_get_one_sym(mXKBstate, key + 8); if (sym == 65453) { @@ -138,10 +138,10 @@ int GPUDisplayFrontendWayland::GetKey(unsigned int key, unsigned int state) return retVal; } -void GPUDisplayFrontendWayland::createBuffer(unsigned int width, unsigned int height) +void GPUDisplayFrontendWayland::createBuffer(uint32_t width, uint32_t height) { - const unsigned int stride = width * 4; - const unsigned int size = stride * height; + const uint32_t stride = width * 4; + const uint32_t size = stride * height; if (ftruncate(mFd, size) < 0) { throw std::runtime_error("Error setting waysland shm file size"); } @@ -160,7 +160,7 @@ void GPUDisplayFrontendWayland::createBuffer(unsigned int width, unsigned int he wl_surface_commit(mSurface); } -void GPUDisplayFrontendWayland::recreateBuffer(unsigned int width, unsigned int height) +void GPUDisplayFrontendWayland::recreateBuffer(uint32_t width, uint32_t height) { wl_surface_attach(mSurface, nullptr, 0, 0); wl_surface_commit(mSurface); @@ -169,7 +169,7 @@ void GPUDisplayFrontendWayland::recreateBuffer(unsigned int width, unsigned int createBuffer(width, height); } -int GPUDisplayFrontendWayland::FrontendMain() +int32_t GPUDisplayFrontendWayland::FrontendMain() { if (backend()->backendType() != GPUDisplayBackend::TYPE_VULKAN) { fprintf(stderr, "Only Vulkan backend supported\n"); @@ -232,7 +232,7 @@ int GPUDisplayFrontendWayland::FrontendMain() const wl_pointer_listener pointer_listener = {.enter = pointer_enter, .leave = pointer_leave, .motion = pointer_motion, .button = pointer_button, .axis = pointer_axis, .frame = nullptr, .axis_source = nullptr, .axis_stop = nullptr, .axis_discrete = nullptr}; #pragma GCC diagnostic pop - auto keyboard_keymap = [](void* data, wl_keyboard* wl_keyboard, uint format, int fd, uint size) { + auto keyboard_keymap = [](void* data, wl_keyboard* wl_keyboard, uint format, int32_t fd, uint size) { GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; if (me->mXKBkeymap) { xkb_state_unref(me->mXKBstate); @@ -248,8 +248,8 @@ int GPUDisplayFrontendWayland::FrontendMain() auto keyboard_leave = [](void* data, wl_keyboard* wl_keyboard, uint serial, wl_surface* surface) {}; auto keyboard_key = [](void* data, wl_keyboard* wl_keyboard, uint serial, uint time, uint key, uint state) { GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; - int symbol = me->GetKey(key, state); - int keyPress = (symbol >= 'a' && symbol <= 'z') ? symbol + 'A' - 'a' : symbol; + int32_t symbol = me->GetKey(key, state); + int32_t keyPress = (symbol >= 'a' && symbol <= 'z') ? symbol + 'A' - 'a' : symbol; if (state == XKB_KEY_DOWN) { me->mKeys[keyPress] = true; me->mKeysShift[keyPress] = me->mKeys[KEY_SHIFT]; @@ -263,7 +263,7 @@ int GPUDisplayFrontendWayland::FrontendMain() GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; xkb_state_update_mask(me->mXKBstate, mods_depressed, mods_latched, mods_locked, 0, 0, group); }; - auto keyboard_repat = [](void* data, wl_keyboard* wl_keyboard, int rate, int delay) {}; + auto keyboard_repat = [](void* data, wl_keyboard* wl_keyboard, int32_t rate, int32_t delay) {}; const wl_keyboard_listener keyboard_listener = {.keymap = keyboard_keymap, .enter = keyboard_enter, .leave = keyboard_leave, .key = keyboard_key, .modifiers = keyboard_modifiers, .repeat_info = keyboard_repat}; auto xdg_wm_base_ping = [](void* data, struct xdg_wm_base* xdg_wm_base, uint32_t serial) { @@ -471,7 +471,7 @@ void GPUDisplayFrontendWayland::SetVSync(bool enable) { } -int GPUDisplayFrontendWayland::StartDisplay() +int32_t GPUDisplayFrontendWayland::StartDisplay() { static pthread_t hThread; if (pthread_create(&hThread, nullptr, FrontendThreadWrapper, this)) { @@ -481,13 +481,13 @@ int GPUDisplayFrontendWayland::StartDisplay() return (0); } -void GPUDisplayFrontendWayland::getSize(int& width, int& height) +void GPUDisplayFrontendWayland::getSize(int32_t& width, int32_t& height) { width = mDisplayWidth; height = mDisplayHeight; } -int GPUDisplayFrontendWayland::getVulkanSurface(void* instance, void* surface) +int32_t GPUDisplayFrontendWayland::getVulkanSurface(void* instance, void* surface) { VkWaylandSurfaceCreateInfoKHR info{}; info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; @@ -497,7 +497,7 @@ int GPUDisplayFrontendWayland::getVulkanSurface(void* instance, void* surface) return vkCreateWaylandSurfaceKHR(*(VkInstance*)instance, &info, nullptr, (VkSurfaceKHR*)surface) != VK_SUCCESS; } -unsigned int GPUDisplayFrontendWayland::getReqVulkanExtensions(const char**& p) +uint32_t GPUDisplayFrontendWayland::getReqVulkanExtensions(const char**& p) { static const char* exts[] = {"VK_KHR_surface", "VK_KHR_wayland_surface"}; p = exts; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h index 1ae8b8acbe243..f13c6fe831e0d 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.h @@ -36,21 +36,21 @@ class GPUDisplayFrontendWayland : public GPUDisplayFrontend GPUDisplayFrontendWayland(); ~GPUDisplayFrontendWayland() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void DisplayExit() override; void SwitchFullscreen(bool set) override; void ToggleMaximized(bool set) override; void SetVSync(bool enable) override; void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) override; - void getSize(int& width, int& height) override; - int getVulkanSurface(void* instance, void* surface) override; - unsigned int getReqVulkanExtensions(const char**& p) override; + void getSize(int32_t& width, int32_t& height) override; + int32_t getVulkanSurface(void* instance, void* surface) override; + uint32_t getReqVulkanExtensions(const char**& p) override; private: - int FrontendMain() override; - int GetKey(unsigned int key, unsigned int state); - void createBuffer(unsigned int width, unsigned int height); - void recreateBuffer(unsigned int width, unsigned int height); + int32_t FrontendMain() override; + int32_t GetKey(uint32_t key, uint32_t state); + void createBuffer(uint32_t width, uint32_t height); + void recreateBuffer(uint32_t width, uint32_t height); pthread_mutex_t mSemLockExit = PTHREAD_MUTEX_INITIALIZER; volatile bool mDisplayRunning = false; @@ -71,7 +71,7 @@ class GPUDisplayFrontendWayland : public GPUDisplayFrontend wl_output* mOutput = nullptr; - int mFd = 0; + int32_t mFd = 0; wl_shm_pool* mPool; wl_buffer* mBuffer; @@ -82,8 +82,8 @@ class GPUDisplayFrontendWayland : public GPUDisplayFrontend zxdg_decoration_manager_v1* mDecManager = nullptr; // zxdg_toplevel_decoration_v1* mXdgDecoration = nullptr; - int mWidthRequested = 0; - int mHeightRequested = 0; + int32_t mWidthRequested = 0; + int32_t mHeightRequested = 0; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx index 75a1d04e2fc51..d8e05a3f03b9b 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.cxx @@ -37,7 +37,7 @@ bool fullscreen = TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default POINT mouseCursorPos; -volatile int mouseReset = false; +volatile int32_t mouseReset = false; void KillGLWindow() // Properly Kill The Window { @@ -78,17 +78,17 @@ void KillGLWindow() // Properly Kill The Window } } -BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) +BOOL CreateGLWindow(char* title, int32_t width, int32_t height, int32_t bits, bool fullscreenflag) { GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values - WindowRect.left = (long)0; // Set Left Value To 0 - WindowRect.right = (long)width; // Set Right Value To Requested Width - WindowRect.top = (long)0; // Set Top Value To 0 - WindowRect.bottom = (long)height; // Set Bottom Value To Requested Height + WindowRect.left = (int64_t)0; // Set Left Value To 0 + WindowRect.right = (int64_t)width; // Set Right Value To Requested Width + WindowRect.top = (int64_t)0; // Set Top Value To 0 + WindowRect.bottom = (int64_t)height; // Set Bottom Value To Requested Height fullscreen = fullscreenflag; // Set The Global Fullscreen Flag @@ -150,7 +150,7 @@ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscree PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format - (unsigned char)bits, // Select Our Color Depth + (uint8_t)bits, // Select Our Color Depth 0, 0, 0, @@ -217,7 +217,7 @@ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscree return TRUE; } -int GetKey(int key) +int32_t GetKey(int32_t key) { if (key == 107 || key == 187) { return ('+'); @@ -322,7 +322,7 @@ GPUDisplayFrontendWindows::GPUDisplayFrontendWindows() mFrontendName = "Win32"; } -int GPUDisplayFrontendWindows::FrontendMain() +int32_t GPUDisplayFrontendWindows::FrontendMain() { MSG msg; BOOL done = FALSE; @@ -376,7 +376,7 @@ void SwitchFullscreen(bool set) {} void ToggleMaximized(bool set) {} void SetVSync(bool enable) {} -int GPUDisplayFrontendWindows::StartDisplay() +int32_t GPUDisplayFrontendWindows::StartDisplay() { HANDLE hThread; if ((hThread = CreateThread(nullptr, nullptr, &OpenGLWrapper, this, nullptr, nullptr)) == nullptr) { diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h index cd5e333931628..62b1a7437a58f 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWindows.h @@ -25,7 +25,7 @@ class GPUDisplayFrontendWindows : public GPUDisplayFrontend GPUDisplayFrontendWindows(); ~GPUDisplayFrontendWindows() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void DisplayExit() override; void SwitchFullscreen(bool set) override; void ToggleMaximized(bool set) override; @@ -33,7 +33,7 @@ class GPUDisplayFrontendWindows : public GPUDisplayFrontend void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) override; private: - int FrontendMain() override; + int32_t FrontendMain() override; }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx index c1fae89b7227f..2ef2ccca92baf 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.cxx @@ -28,7 +28,7 @@ #include #endif -typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int32_t*); using namespace GPUCA_NAMESPACE::gpu; @@ -38,7 +38,7 @@ GPUDisplayFrontendX11::GPUDisplayFrontendX11() mFrontendName = "X11"; } -int GPUDisplayFrontendX11::GetKey(int key) +int32_t GPUDisplayFrontendX11::GetKey(int32_t key) { if (key == 65453) { return ('-'); @@ -139,16 +139,16 @@ int GPUDisplayFrontendX11::GetKey(int key) return 0; } -void GPUDisplayFrontendX11::GetKey(XEvent& event, int& keyOut, int& keyPressOut) +void GPUDisplayFrontendX11::GetKey(XEvent& event, int32_t& keyOut, int32_t& keyPressOut) { char tmpString[9]; KeySym sym; if (XLookupString(&event.xkey, tmpString, 8, &sym, nullptr) == 0) { tmpString[0] = 0; } - int specialKey = GetKey(sym); - int localeKey = (unsigned char)tmpString[0]; - // GPUInfo("Key: keycode %d -> sym %d (%c) key %d (%c) special %d (%c)", (int)event.xkey.keycode, (int)sym, (char)sym, (int)localeKey, (char)localeKey, (int)specialKey, (char)specialKey); + int32_t specialKey = GetKey(sym); + int32_t localeKey = (uint8_t)tmpString[0]; + // GPUInfo("Key: keycode %d -> sym %d (%c) key %d (%c) special %d (%c)", (int32_t)event.xkey.keycode, (int32_t)sym, (char)sym, (int32_t)localeKey, (char)localeKey, (int32_t)specialKey, (char)specialKey); if (specialKey) { keyOut = keyPressOut = specialKey; @@ -182,15 +182,15 @@ void GPUDisplayFrontendX11::OpenGLPrint(const char* s, float x, float y, float r #endif } -int GPUDisplayFrontendX11::FrontendMain() +int32_t GPUDisplayFrontendX11::FrontendMain() { XSetWindowAttributes windowAttributes; XVisualInfo* visualInfo = nullptr; XEvent event; Colormap colorMap; GLXContext glxContext = nullptr; - int errorBase; - int eventBase; + int32_t errorBase; + int32_t eventBase; // Open a connection to the X server mDisplay = XOpenDisplay(nullptr); @@ -215,13 +215,13 @@ int GPUDisplayFrontendX11::FrontendMain() } // Require MSAA, double buffering, and Depth buffer - int attribs[] = {GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, True, - // GLX_SAMPLE_BUFFERS , 1, //Disable MSAA here, we do it by rendering to offscreenbuffer - // GLX_SAMPLES , MSAA_SAMPLES, - None}; + int32_t attribs[] = {GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, True, + // GLX_SAMPLE_BUFFERS , 1, //Disable MSAA here, we do it by rendering to offscreenbuffer + // GLX_SAMPLES , MSAA_SAMPLES, + None}; GLXFBConfig fbconfig = nullptr; - int fbcount; + int32_t fbcount; GLXFBConfig* fbc = glXChooseFBConfig(mDisplay, DefaultScreen(mDisplay), attribs, &fbcount); if (fbc == nullptr || fbcount == 0) { GPUError("Failed to get MSAA GLXFBConfig"); @@ -240,7 +240,7 @@ int GPUDisplayFrontendX11::FrontendMain() // Create an OpenGL rendering context glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); if (glXCreateContextAttribsARB) { - int context_attribs[] = { + int32_t context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, GL_MIN_VERSION_MAJOR, GLX_CONTEXT_MINOR_VERSION_ARB, GL_MIN_VERSION_MINOR, GLX_CONTEXT_PROFILE_MASK_ARB, mBackend->CoreProfile() ? GLX_CONTEXT_CORE_PROFILE_BIT_ARB : GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, @@ -291,8 +291,8 @@ int GPUDisplayFrontendX11::FrontendMain() GPUError("XLoadQueryFont failed."); return (-1); } else { - int first = font_info->min_char_or_byte2; - int last = font_info->max_char_or_byte2; + int32_t first = font_info->min_char_or_byte2; + int32_t last = font_info->max_char_or_byte2; glXUseXFont(font_info->fid, first, last - first + 1, mFontBase + first); } } @@ -309,7 +309,7 @@ int GPUDisplayFrontendX11::FrontendMain() XMapWindow(mDisplay, mWindow); XFlush(mDisplay); - int x11_fd = ConnectionNumber(mDisplay); + int32_t x11_fd = ConnectionNumber(mDisplay); // Enable vsync if (backend()->backendType() == GPUDisplayBackend::TYPE_OPENGL && vsync_supported) { @@ -331,10 +331,10 @@ int GPUDisplayFrontendX11::FrontendMain() std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); while (1) { - int num_ready_fds; + int32_t num_ready_fds; struct timeval tv; fd_set in_fds; - int waitCount = 0; + int32_t waitCount = 0; do { FD_ZERO(&in_fds); FD_SET(x11_fd, &in_fds); @@ -399,7 +399,7 @@ int GPUDisplayFrontendX11::FrontendMain() } case KeyPress: { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(event, handleKey, keyPress); mKeysShift[keyPress] = mKeys[KEY_SHIFT]; mKeys[keyPress] = true; @@ -408,7 +408,7 @@ int GPUDisplayFrontendX11::FrontendMain() } case KeyRelease: { - int handleKey = 0, keyPress = 0; + int32_t handleKey = 0, keyPress = 0; GetKey(event, handleKey, keyPress); mKeys[keyPress] = false; mKeysShift[keyPress] = false; @@ -514,11 +514,11 @@ void GPUDisplayFrontendX11::ToggleMaximized(bool set) void GPUDisplayFrontendX11::SetVSync(bool enable) { if (backend()->backendType() == GPUDisplayBackend::TYPE_OPENGL && vsync_supported) { - mGlXSwapIntervalEXT(mDisplay, glXGetCurrentDrawable(), (int)enable); + mGlXSwapIntervalEXT(mDisplay, glXGetCurrentDrawable(), (int32_t)enable); } } -int GPUDisplayFrontendX11::StartDisplay() +int32_t GPUDisplayFrontendX11::StartDisplay() { static pthread_t hThread; if (pthread_create(&hThread, nullptr, FrontendThreadWrapper, this)) { @@ -528,11 +528,11 @@ int GPUDisplayFrontendX11::StartDisplay() return (0); } -void GPUDisplayFrontendX11::getSize(int& width, int& height) +void GPUDisplayFrontendX11::getSize(int32_t& width, int32_t& height) { Window root_return; - int x_return, y_return; - unsigned int width_return, height_return, border_width_return, depth_return; + int32_t x_return, y_return; + uint32_t width_return, height_return, border_width_return, depth_return; if (XGetGeometry(mDisplay, mWindow, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return) == 0) { throw std::runtime_error("Cannot query X11 window geometry"); } @@ -540,7 +540,7 @@ void GPUDisplayFrontendX11::getSize(int& width, int& height) height = height_return; } -int GPUDisplayFrontendX11::getVulkanSurface(void* instance, void* surface) +int32_t GPUDisplayFrontendX11::getVulkanSurface(void* instance, void* surface) { #ifdef GPUCA_BUILD_EVENT_DISPLAY_VULKAN VkXlibSurfaceCreateInfoKHR info{}; @@ -554,7 +554,7 @@ int GPUDisplayFrontendX11::getVulkanSurface(void* instance, void* surface) #endif } -unsigned int GPUDisplayFrontendX11::getReqVulkanExtensions(const char**& p) +uint32_t GPUDisplayFrontendX11::getReqVulkanExtensions(const char**& p) { static const char* exts[] = {"VK_KHR_surface", "VK_KHR_xlib_surface"}; p = exts; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h index e53961db97399..16920ce77460e 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendX11.h @@ -29,20 +29,20 @@ class GPUDisplayFrontendX11 : public GPUDisplayFrontend GPUDisplayFrontendX11(); ~GPUDisplayFrontendX11() override = default; - int StartDisplay() override; + int32_t StartDisplay() override; void DisplayExit() override; void SwitchFullscreen(bool set) override; void ToggleMaximized(bool set) override; void SetVSync(bool enable) override; void OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton = true) override; - void getSize(int& width, int& height) override; - int getVulkanSurface(void* instance, void* surface) override; - unsigned int getReqVulkanExtensions(const char**& p) override; + void getSize(int32_t& width, int32_t& height) override; + int32_t getVulkanSurface(void* instance, void* surface) override; + uint32_t getReqVulkanExtensions(const char**& p) override; private: - int FrontendMain() override; - int GetKey(int key); - void GetKey(XEvent& event, int& keyOut, int& keyPressOut); + int32_t FrontendMain() override; + int32_t GetKey(int32_t key); + void GetKey(XEvent& event, int32_t& keyOut, int32_t& keyPressOut); pthread_mutex_t mSemLockExit = PTHREAD_MUTEX_INITIALIZER; volatile bool mDisplayRunning = false; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx index 000019dbd9446..a5ba968f9e50d 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.cxx @@ -76,7 +76,7 @@ void GPUDisplayGUIWrapper::UpdateTimer() void GPUDisplayGUIWrapper::guiThread() { - static int tmp_argc = 1; + static int32_t tmp_argc = 1; static const char* tmp_argv[2] = {"GPU CA Standalone Event Display GUI", NULL}; mO->app.reset(new QApplication(tmp_argc, (char**)tmp_argv)); while (!mO->terminate) { @@ -116,7 +116,7 @@ void GPUDisplayGUIWrapper::guiThread() mO->app.reset(nullptr); } -int GPUDisplayGUIWrapper::start() +int32_t GPUDisplayGUIWrapper::start() { if (!mO->started) { { @@ -134,7 +134,7 @@ int GPUDisplayGUIWrapper::start() return 0; } -int GPUDisplayGUIWrapper::stop() +int32_t GPUDisplayGUIWrapper::stop() { if (mO->started) { mO->stop = true; @@ -148,7 +148,7 @@ int GPUDisplayGUIWrapper::stop() return 0; } -int GPUDisplayGUIWrapper::focus() +int32_t GPUDisplayGUIWrapper::focus() { if (mO->started) { } diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h index 855e949ac409c..ef632c6f2d54b 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h +++ b/GPU/GPUTracking/display/frontend/GPUDisplayGUIWrapper.h @@ -30,9 +30,9 @@ class GPUDisplayGUIWrapper bool isRunning() const; void UpdateTimer(); - int start(); - int stop(); - int focus(); + int32_t start(); + int32_t stop(); + int32_t focus(); private: std::unique_ptr mO; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx index 16f76468c663a..1842c276a580c 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx @@ -71,12 +71,12 @@ const char* HelpText[] = { void GPUDisplay::PrintHelp() { mInfoHelpTimer.ResetStart(); - for (unsigned int i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) { + for (uint32_t i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) { GPUInfo("%s", HelpText[i]); } } -void GPUDisplay::HandleKey(unsigned char key) +void GPUDisplay::HandleKey(uint8_t key) { GPUSettingsDisplayHeavy oldCfgH = mCfgH; GPUSettingsDisplayLight oldCfgL = mCfgL; @@ -152,10 +152,10 @@ void GPUDisplay::HandleKey(unsigned char key) } } else if (key == 'F') { mCfgR.fullScreen ^= 1; - SetInfo("Toggling full screen (%d)", (int)mCfgR.fullScreen); + SetInfo("Toggling full screen (%d)", (int32_t)mCfgR.fullScreen); } else if (key == '_') { mCfgR.maximized ^= 1; - SetInfo("Toggling Maximized window (%d)", (int)mCfgR.maximized); + SetInfo("Toggling Maximized window (%d)", (int32_t)mCfgR.maximized); } else if (key == 'R') { mCfgR.maxFPSRate ^= 1; SetInfo("FPS rate %s", mCfgR.maxFPSRate ? "not limited" : "limited"); @@ -313,40 +313,40 @@ void GPUDisplay::HandleKey(unsigned char key) } else if (key == mFrontend->KEY_F1) { if (mFrontend->mKeysShift[mFrontend->KEY_F1]) { mCfgH.drawTPCTracks ^= 1; - SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int)mCfgH.drawTPCTracks, (int)mCfgH.drawTRDTracks, (int)mCfgH.drawTOFTracks, (int)mCfgH.drawITSTracks); + SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks); } else { mCfgL.drawTPC ^= 1; - SetInfo("Showing TPC Clusters: %d", (int)mCfgL.drawTPC); + SetInfo("Showing TPC Clusters: %d", (int32_t)mCfgL.drawTPC); } } else if (key == mFrontend->KEY_F2) { if (mFrontend->mKeysShift[mFrontend->KEY_F2]) { mCfgH.drawTRDTracks ^= 1; - SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int)mCfgH.drawTPCTracks, (int)mCfgH.drawTRDTracks, (int)mCfgH.drawTOFTracks, (int)mCfgH.drawITSTracks); + SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks); } else { mCfgL.drawTRD ^= 1; - SetInfo("Showing TRD Tracklets: %d", (int)mCfgL.drawTRD); + SetInfo("Showing TRD Tracklets: %d", (int32_t)mCfgL.drawTRD); } } else if (key == mFrontend->KEY_F3) { if (mFrontend->mKeysShift[mFrontend->KEY_F3]) { mCfgH.drawTOFTracks ^= 1; - SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int)mCfgH.drawTPCTracks, (int)mCfgH.drawTRDTracks, (int)mCfgH.drawTOFTracks, (int)mCfgH.drawITSTracks); + SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks); } else { mCfgL.drawTOF ^= 1; - SetInfo("Showing TOF Hits: %d", (int)mCfgL.drawTOF); + SetInfo("Showing TOF Hits: %d", (int32_t)mCfgL.drawTOF); } } else if (key == mFrontend->KEY_F4) { if (mFrontend->mKeysShift[mFrontend->KEY_F4]) { mCfgH.drawITSTracks ^= 1; - SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int)mCfgH.drawTPCTracks, (int)mCfgH.drawTRDTracks, (int)mCfgH.drawTOFTracks, (int)mCfgH.drawITSTracks); + SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks); } else { mCfgL.drawITS ^= 1; - SetInfo("Showing ITS Clusters: %d", (int)mCfgL.drawITS); + SetInfo("Showing ITS Clusters: %d", (int32_t)mCfgL.drawITS); } } else if (key == mFrontend->KEY_F12 && mFrontend->mKeysShift[mFrontend->KEY_F12]) { mCfgH.drawTracksAndFilter ^= 1; SetInfo("Track filter: %s", mCfgH.drawTracksAndFilter ? "AND" : "OR"); } else if (key == 't') { - static int nScreenshot = 1; + static int32_t nScreenshot = 1; char fname[32]; snprintf(fname, 32, "screenshot%d.bmp", nScreenshot++); mRequestScreenshot = true; @@ -373,7 +373,7 @@ void GPUDisplay::HandleKey(unsigned char key) SetInfo("Interpolating visualization settings during Animation %s", mAnimationChangeConfig ? "enabled" : "disabled"); } else if (key == 'Y') { setAnimationPoint(); - SetInfo("Added Animation point (%d points, %6.2f seconds)", (int)mAnimateVectors[0].size(), mAnimateVectors[0].back()); + SetInfo("Added Animation point (%d points, %6.2f seconds)", (int32_t)mAnimateVectors[0].size(), mAnimateVectors[0].back()); } else if (key == 'X') { resetAnimation(); SetInfo("Reset Animation points", 1); @@ -398,7 +398,7 @@ void GPUDisplay::HandleKey(unsigned char key) } else if (key == 'o') { FILE* ftmp = fopen("glpos.tmp", "w+b"); if (ftmp) { - int retval = fwrite(&mViewMatrix, sizeof(mViewMatrix), 1, ftmp); + int32_t retval = fwrite(&mViewMatrix, sizeof(mViewMatrix), 1, ftmp); if (retval != 1) { GPUError("Error writing position to file"); } else { @@ -412,7 +412,7 @@ void GPUDisplay::HandleKey(unsigned char key) } else if (key == 'p') { FILE* ftmp = fopen("glpos.tmp", "rb"); if (ftmp) { - int retval = fread(&mViewMatrix, 1, sizeof(mViewMatrix), ftmp); + int32_t retval = fread(&mViewMatrix, 1, sizeof(mViewMatrix), ftmp); if (retval == sizeof(mViewMatrix)) { GPUInfo("Position read from file"); } else { @@ -427,9 +427,9 @@ void GPUDisplay::HandleKey(unsigned char key) FILE* ftmp = fopen("glanimation.tmp", "w+b"); if (ftmp) { fwrite(&mCfgL, sizeof(mCfgL), 1, ftmp); - int size = mAnimateVectors[0].size(); + int32_t size = mAnimateVectors[0].size(); fwrite(&size, sizeof(size), 1, ftmp); - for (int i = 0; i < 9; i++) { + for (int32_t i = 0; i < 9; i++) { fwrite(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp); } fwrite(mAnimateConfig.data(), sizeof(mAnimateConfig[0]), size, ftmp); @@ -441,10 +441,10 @@ void GPUDisplay::HandleKey(unsigned char key) } else if (key == 'P') { FILE* ftmp = fopen("glanimation.tmp", "rb"); if (ftmp) { - int retval = fread(&mCfgL, sizeof(mCfgL), 1, ftmp); - int size; + int32_t retval = fread(&mCfgL, sizeof(mCfgL), 1, ftmp); + int32_t size; retval += fread(&size, sizeof(size), 1, ftmp); - for (int i = 0; i < 9; i++) { + for (int32_t i = 0; i < 9; i++) { mAnimateVectors[i].resize(size); retval += fread(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp); } @@ -514,12 +514,12 @@ void GPUDisplay::HandleKey(unsigned char key) } } -void GPUDisplay::HandleSendKey(int key) +void GPUDisplay::HandleSendKey(int32_t key) { // GPUError("key %d '%c'", key, (char) key); bool shifted = key >= 'A' && key <= 'Z'; - int press = key; + int32_t press = key; if (press >= 'a' && press <= 'z') { press += 'A' - 'a'; } @@ -531,7 +531,7 @@ void GPUDisplay::HandleSendKey(int key) void GPUDisplay::PrintGLHelpText(float colorValue) { - for (unsigned int i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) { + for (uint32_t i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) { OpenGLPrint(HelpText[i], 40.f, 35 + std::max(20, mDrawTextFontSize + 4) * (1 + i), colorValue, colorValue, colorValue, mInfoHelpTimer.GetCurrentElapsedTime() >= 5 ? (6 - mInfoHelpTimer.GetCurrentElapsedTime()) : 1, false); } } diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx index 8d023fb70cb16..77b7181a3a377 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayAnimation.cxx @@ -35,7 +35,7 @@ void GPUDisplay::setAnimationPoint() mAnimateVectors[2].emplace_back(anglePhi); mAnimateVectors[3].emplace_back(angleTheta); } else { - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { mAnimateVectors[i + 1].emplace_back(mXYZ[i]); } // Cartesian @@ -44,7 +44,7 @@ void GPUDisplay::setAnimationPoint() mAnimateVectors[4].emplace_back(r); if (mCfgL.animationMode & 1) // Euler-angles { - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { float newangle = mAngle[i]; if (mAnimateVectors[0].size()) { mAnimationCloseAngle(newangle, mAnimateVectors[i + 5].back()); @@ -58,13 +58,13 @@ void GPUDisplay::setAnimationPoint() if (mAnimateVectors[0].size()) { mAnimateCloseQuaternion(v, mAnimateVectors[5].back(), mAnimateVectors[6].back(), mAnimateVectors[7].back(), mAnimateVectors[8].back()); } - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { mAnimateVectors[i + 5].emplace_back(v[i]); } } float delay = 0.f; if (mAnimateVectors[0].size()) { - delay = mAnimateVectors[0].back() + ((int)(mAnimationDelay * 20)) / 20.f; + delay = mAnimateVectors[0].back() + ((int32_t)(mAnimationDelay * 20)) / 20.f; } mAnimateVectors[0].emplace_back(delay); mAnimateConfig.emplace_back(mCfgL); @@ -72,7 +72,7 @@ void GPUDisplay::setAnimationPoint() void GPUDisplay::resetAnimation() { - for (int i = 0; i < 9; i++) { + for (int32_t i = 0; i < 9; i++) { mAnimateVectors[i].clear(); } mAnimateConfig.clear(); @@ -84,7 +84,7 @@ void GPUDisplay::removeAnimationPoint() if (mAnimateVectors[0].size() == 0) { return; } - for (int i = 0; i < 9; i++) { + for (int32_t i = 0; i < 9; i++) { mAnimateVectors[i].pop_back(); } mAnimateConfig.pop_back(); @@ -92,7 +92,7 @@ void GPUDisplay::removeAnimationPoint() void GPUDisplay::startAnimation() { - for (int i = 0; i < 8; i++) { + for (int32_t i = 0; i < 8; i++) { mAnimationSplines[i].create(mAnimateVectors[0], mAnimateVectors[i + 1]); } mAnimationTimer.ResetStart(); @@ -101,7 +101,7 @@ void GPUDisplay::startAnimation() mAnimationLastBase = 0; } -int GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix) +int32_t GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix) { float time = animateTime; if (mAnimate && time < 0) { @@ -125,12 +125,12 @@ int GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4 return 0; } float vals[8]; - for (int i = 0; i < 8; i++) { + for (int32_t i = 0; i < 8; i++) { vals[i] = mAnimationSplines[i].evaluate(time); } if (mAnimationChangeConfig && animateTime < 0) { - int base = 0; - int k = mAnimateVectors[0].size() - 1; + int32_t base = 0; + int32_t k = mAnimateVectors[0].size() - 1; while (base < k && time > mAnimateVectors[0][base]) { base++; } @@ -162,7 +162,7 @@ int GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4 if (mag < 0.0001f) { vals[7] = 1; } else { - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { vals[4 + i] /= mag; } } @@ -184,7 +184,7 @@ int GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4 r = 1; } r = vals[3] / r; - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { vals[i] *= r; } } diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx index ad1fd33cab686..16166baa9a91c 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayBackendOpenGLMagneticField.cxx @@ -49,17 +49,17 @@ using namespace GPUCA_NAMESPACE::gpu; #ifdef GPUCA_BUILD_EVENT_DISPLAY_OPENGL -#define CHKERR(cmd) \ - do { \ - (cmd); \ - GLenum err = glGetError(); \ - while (err != GL_NO_ERROR) { \ - GPUError("OpenGL Error %d: %s (%s: %d)", (int)err, (const char*)gluErrorString(err), __FILE__, __LINE__); \ - throw std::runtime_error("OpenGL Failure"); \ - } \ +#define CHKERR(cmd) \ + do { \ + (cmd); \ + GLenum err = glGetError(); \ + while (err != GL_NO_ERROR) { \ + GPUError("OpenGL Error %d: %s (%s: %d)", (int32_t)err, (const char*)gluErrorString(err), __FILE__, __LINE__); \ + throw std::runtime_error("OpenGL Failure"); \ + } \ } while (false) -int GPUDisplayBackendOpenGL::InitMagFieldVisualization() +int32_t GPUDisplayBackendOpenGL::InitMagFieldVisualization() { #ifndef GPUCA_NO_FMT mMagneticFieldVisualization = std::make_unique(); @@ -144,13 +144,13 @@ int GPUDisplayBackendOpenGL::InitMagFieldVisualization() return 0; } -unsigned int GPUDisplayBackendOpenGL::drawField() +uint32_t GPUDisplayBackendOpenGL::drawField() { if (!mMagneticFieldVisualization) { return InitMagFieldVisualization(); // next frame will fill MVP matrix } - if (mMagneticFieldVisualization->mFieldLineSeedPoints.size() != (unsigned int)mDisplay->cfgL().bFieldLinesCount) { + if (mMagneticFieldVisualization->mFieldLineSeedPoints.size() != (uint32_t)mDisplay->cfgL().bFieldLinesCount) { mMagneticFieldVisualization->generateSeedPoints(mDisplay->cfgL().bFieldLinesCount); CHKERR(glNamedBufferData(VBO_field, mMagneticFieldVisualization->mFieldLineSeedPoints.size() * sizeof(GPUDisplayMagneticField::vtx), mMagneticFieldVisualization->mFieldLineSeedPoints.data(), GL_STATIC_DRAW)); } @@ -196,10 +196,10 @@ void GPUDisplayBackendOpenGL::ExitMagFieldVisualization() } #else // GPUCA_BUILD_EVENT_DISPLAY_OPENGL -int GPUDisplayBackendOpenGL::InitMagFieldVisualization() +int32_t GPUDisplayBackendOpenGL::InitMagFieldVisualization() { return 0; } -unsigned int GPUDisplayBackendOpenGL::drawField() { return 0; } +uint32_t GPUDisplayBackendOpenGL::drawField() { return 0; } void GPUDisplayBackendOpenGL::ExitMagFieldVisualization() {} #endif // GPUCA_BUILD_EVENT_DISPLAY_OPENGL diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc b/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc index 75093ab191804..2994af86980d8 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc +++ b/GPU/GPUTracking/display/helpers/GPUDisplayColors.inc @@ -162,11 +162,11 @@ inline void GPUDisplay::SetColorMarked() } ActivateColor(); } -inline void GPUDisplay::SetCollisionColor(int col) +inline void GPUDisplay::SetCollisionColor(int32_t col) { - int red = (col * 2) % 5; - int blue = (2 + col * 3) % 7; - int green = (4 + col * 5) % 6; + int32_t red = (col * 2) % 5; + int32_t blue = (2 + col * 3) % 7; + int32_t green = (4 + col * 5) % 6; if (mCfgL.invertColors && red == 4 && blue == 5 && green == 6) { red = 0; } diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx index a41be9d9e278a..cd73cc0b9b34f 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx @@ -23,7 +23,7 @@ using namespace GPUCA_NAMESPACE::gpu; -int GPUDisplay::getNumThreads() +int32_t GPUDisplay::getNumThreads() { if (mChain) { return mChain->GetProcessingSettings().ompThreads; diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx index d3a2a4d584460..3df61bfc81110 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayInterpolation.cxx @@ -27,9 +27,9 @@ void GPUDisplay::opengl_spline::create(const vecpod& x, const vecpod %f", i, x[i], y[i]); } } @@ -39,36 +39,36 @@ void GPUDisplay::opengl_spline::create(const vecpod& x, const vecpod h(k + 1), alpha(k + 1), l(k + 1), mu(k + 1), z(k + 1); - for (int i = 0; i <= k; i++) { + for (int32_t i = 0; i <= k; i++) { ma[i] = y[i]; } - for (int i = 0; i < k; i++) { + for (int32_t i = 0; i < k; i++) { h[i] = x[i + 1] - x[i]; } - for (int i = 1; i < k; i++) { + for (int32_t i = 1; i < k; i++) { alpha[i] = 3.f / h[i] * (ma[i + 1] - ma[i]) - 3.f / h[i - 1] * (ma[i] - ma[i - 1]); } l[0] = l[k] = 1; mu[0] = z[0] = z[k] = mc[k] = 0; - for (int i = 1; i < k; i++) { + for (int32_t i = 1; i < k; i++) { l[i] = 2.f * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / l[i]; z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i]; } - for (int i = k - 1; i >= 0; i--) { + for (int32_t i = k - 1; i >= 0; i--) { mc[i] = z[i] - mu[i] * mc[i + 1]; mb[i] = (ma[i + 1] - ma[i]) / h[i] - h[i] / 3.f * (mc[i + 1] + 2.f * mc[i]); md[i] = (mc[i + 1] - mc[i]) / (3.f * h[i]); } - for (int i = 0; i <= k; i++) { + for (int32_t i = 0; i <= k; i++) { mx[i] = x[i]; } } float GPUDisplay::opengl_spline::evaluate(float x) { - int base = 0; - const int k = mx.size() - 1; + int32_t base = 0; + const int32_t k = mx.size() - 1; if (k < 0) { return (0); } diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx index 357274e2decfc..352f029ab3648 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.cxx @@ -47,9 +47,9 @@ void GPUDisplayMagneticField::generateSeedPoints(std::size_t count) std::mt19937 rng(0xDEADBEEF); // TODO: fetch these values from somewhere? - std::uniform_int_distribution generator_x(-512, 512); - std::uniform_int_distribution generator_y(-512, 512); - std::uniform_int_distribution generator_z(-455 - 1312, -455 + 1312); + std::uniform_int_distribution generator_x(-512, 512); + std::uniform_int_distribution generator_y(-512, 512); + std::uniform_int_distribution generator_z(-455 - 1312, -455 + 1312); mFieldLineSeedPoints.clear(); @@ -131,7 +131,7 @@ std::tuple loadParams(std::i } #ifndef GPUCA_O2_LIB -int GPUDisplayMagneticField::initializeUniforms() +int32_t GPUDisplayMagneticField::initializeUniforms() { mSolenoidSegments = std::make_unique(); mDipoleSegments = std::make_unique(); @@ -177,7 +177,7 @@ int GPUDisplayMagneticField::initializeUniforms() #endif #if !defined(GPUCA_NO_ROOT) && defined(GPUCA_O2_LIB) -int GPUDisplayMagneticField::initializeUniforms() +int32_t GPUDisplayMagneticField::initializeUniforms() { mRenderConstantsUniform = std::make_unique(); @@ -198,7 +198,7 @@ int GPUDisplayMagneticField::initializeUniforms() return initializeUniformsFromField(field); } -int GPUDisplayMagneticField::initializeUniformsFromField(o2::field::MagneticField* field) +int32_t GPUDisplayMagneticField::initializeUniformsFromField(o2::field::MagneticField* field) { const auto chebMap = field->getMeasuredMap(); @@ -279,8 +279,8 @@ int GPUDisplayMagneticField::initializeUniformsFromField(o2::field::MagneticFiel const auto getParameterSolenoid = [chebMap](Int_t i) { return chebMap->getParameterSolenoid(i); }; const auto getParameterDipole = [chebMap](Int_t i) { return chebMap->getParameterDipole(i); }; - auto countArraySizes = [](int numberOfParametrization, auto& getParameter) { - int TotalRows = 0, TotalColumns = 0, TotalCoefficients = 0; + auto countArraySizes = [](int32_t numberOfParametrization, auto& getParameter) { + int32_t TotalRows = 0, TotalColumns = 0, TotalCoefficients = 0; UShort_t MaxChebyshevOrder = 0; for (auto i = 0; i < numberOfParametrization; ++i) { @@ -389,8 +389,8 @@ int GPUDisplayMagneticField::initializeUniformsFromField(o2::field::MagneticFiel mDipoleSegments = std::make_unique(); loadSegments(dipoleTableInfo, *mDipoleSegments); - auto initParametrization = [](int numberOfParametrization, auto& getParameter, auto& parametrizationUniform) { - int ColsAtRowOffset = 0, CofsAtRowOffset = 0, CofsAtColOffset = 0, Coeffs = 0; + auto initParametrization = [](int32_t numberOfParametrization, auto& getParameter, auto& parametrizationUniform) { + int32_t ColsAtRowOffset = 0, CofsAtRowOffset = 0, CofsAtColOffset = 0, Coeffs = 0; for (auto i = 0; i < numberOfParametrization; ++i) { const auto param = getParameter(i); diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h index 3ec9682b6b6b3..f8461e4c036f4 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h +++ b/GPU/GPUTracking/display/helpers/GPUDisplayMagneticField.h @@ -51,7 +51,7 @@ class GPUDisplayMagneticField static constexpr std::size_t MAX_CHEBYSHEV_ORDER = 32; struct RenderConstantsUniform { - unsigned int StepCount; + uint32_t StepCount; float StepSize; }; @@ -61,21 +61,21 @@ class GPUDisplayMagneticField float MaxZ; float MultiplicativeFactor; - int ZSegments; + int32_t ZSegments; float SegDim1[MAX_DIM1_SEGMENTS]; - int BegSegDim2[MAX_DIM1_SEGMENTS]; - int NSegDim2[MAX_DIM1_SEGMENTS]; + int32_t BegSegDim2[MAX_DIM1_SEGMENTS]; + int32_t NSegDim2[MAX_DIM1_SEGMENTS]; float SegDim2[MAX_DIM2_SEGMENTS]; - int BegSegDim3[MAX_DIM2_SEGMENTS]; - int NSegDim3[MAX_DIM2_SEGMENTS]; + int32_t BegSegDim3[MAX_DIM2_SEGMENTS]; + int32_t NSegDim3[MAX_DIM2_SEGMENTS]; float SegDim3[MAX_DIM3_SEGMENTS]; - int SegID[MAX_DIM3_SEGMENTS]; + int32_t SegID[MAX_DIM3_SEGMENTS]; }; template @@ -85,15 +85,15 @@ class GPUDisplayMagneticField float BMin[MAX_PARAMETERIZATIONS]; float BMax[MAX_PARAMETERIZATIONS]; - int NRows[MAX_PARAMETERIZATIONS]; - int ColsAtRowOffset[MAX_PARAMETERIZATIONS]; - int CofsAtRowOffset[MAX_PARAMETERIZATIONS]; + int32_t NRows[MAX_PARAMETERIZATIONS]; + int32_t ColsAtRowOffset[MAX_PARAMETERIZATIONS]; + int32_t CofsAtRowOffset[MAX_PARAMETERIZATIONS]; - int NColsAtRow[MAX_ROWS]; - int CofsAtColOffset[MAX_ROWS]; + int32_t NColsAtRow[MAX_ROWS]; + int32_t CofsAtColOffset[MAX_ROWS]; - int NCofsAtCol[MAX_COLUMNS]; - int AtColCoefOffset[MAX_COLUMNS]; + int32_t NCofsAtCol[MAX_COLUMNS]; + int32_t AtColCoefOffset[MAX_COLUMNS]; float Coeffs[MAX_COEFFICIENTS]; }; @@ -110,9 +110,9 @@ class GPUDisplayMagneticField vtx(float a, float b, float c) : x(a), y(b), z(c) {} }; - int initializeUniforms(); + int32_t initializeUniforms(); #ifdef GPUCA_O2_LIB - int initializeUniformsFromField(o2::field::MagneticField* field); + int32_t initializeUniformsFromField(o2::field::MagneticField* field); #endif void generateSeedPoints(std::size_t count); diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx index cb81b485bc6dd..4d99c3aa38cfc 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayROOT.cxx @@ -25,7 +25,7 @@ using namespace GPUCA_NAMESPACE::gpu; #include "TSystem.h" #include "TMethodCall.h" -int GPUDisplay::buildTrackFilter() +int32_t GPUDisplay::buildTrackFilter() { if (!mCfgH.trackFilter) { return 0; @@ -54,7 +54,7 @@ int GPUDisplay::buildTrackFilter() #else -int GPUDisplay::buildTrackFilter() +int32_t GPUDisplay::buildTrackFilter() { } diff --git a/GPU/GPUTracking/display/helpers/bitmapfile.h b/GPU/GPUTracking/display/helpers/bitmapfile.h index 274993633e36e..ead2b80045cc6 100644 --- a/GPU/GPUTracking/display/helpers/bitmapfile.h +++ b/GPU/GPUTracking/display/helpers/bitmapfile.h @@ -13,24 +13,24 @@ /// \author David Rohr struct BITMAPFILEHEADER { - unsigned short bfType; - unsigned int bfSize; - unsigned int bfReserved; - unsigned int bfOffBits; + uint16_t bfType; + uint32_t bfSize; + uint32_t bfReserved; + uint32_t bfOffBits; } __attribute__((packed)); struct BITMAPINFOHEADER { - unsigned int biSize; - unsigned int biWidth; - unsigned int biHeight; - unsigned short biPlanes; - unsigned short biBitCount; - unsigned int biCompression; - unsigned int biSizeImage; - unsigned int biXPelsPerMeter; - unsigned int biYPelsPerMeter; - unsigned int biClrUsed; - unsigned int biClrImportant; + uint32_t biSize; + uint32_t biWidth; + uint32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + uint32_t biXPelsPerMeter; + uint32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; } __attribute__((packed)); enum BI_Compression { BI_RGB = 0x0000, diff --git a/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx b/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx index 3f564f5bc8e5b..d8210979efa64 100644 --- a/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx +++ b/GPU/GPUTracking/display/helpers/field-uniform-exporter.cxx @@ -24,7 +24,7 @@ namespace bpo = boost::program_options; using namespace GPUCA_NAMESPACE::gpu; template -void saveSegments(std::ofstream& file, int NSegDim1, int NSegDim2, int NSegDim3, GPUDisplayMagneticField::SegmentsUniform& segments) +void saveSegments(std::ofstream& file, int32_t NSegDim1, int32_t NSegDim2, int32_t NSegDim3, GPUDisplayMagneticField::SegmentsUniform& segments) { file.write(reinterpret_cast(&segments.MinZ), sizeof(segments.MinZ)); file.write(reinterpret_cast(&segments.MaxZ), sizeof(segments.MaxZ)); @@ -51,7 +51,7 @@ void saveSegments(std::ofstream& file, int NSegDim1, int NSegDim2, int NSegDim3, } template -void saveParams(std::ofstream& file, int numberOfParametrization, int Nrows, int Ncolums, int Ncoeffs, GPUDisplayMagneticField::ParametrizationUniform& param) +void saveParams(std::ofstream& file, int32_t numberOfParametrization, int32_t Nrows, int32_t Ncolums, int32_t Ncoeffs, GPUDisplayMagneticField::ParametrizationUniform& param) { file.write(reinterpret_cast(&numberOfParametrization), sizeof(std::int32_t)); @@ -66,20 +66,20 @@ void saveParams(std::ofstream& file, int numberOfParametrization, int Nrows, int file.write(reinterpret_cast(&Nrows), sizeof(std::int32_t)); - file.write(reinterpret_cast(param.NColsAtRow), Nrows * sizeof(int)); - file.write(reinterpret_cast(param.CofsAtColOffset), Nrows * sizeof(int)); + file.write(reinterpret_cast(param.NColsAtRow), Nrows * sizeof(int32_t)); + file.write(reinterpret_cast(param.CofsAtColOffset), Nrows * sizeof(int32_t)); - file.write(reinterpret_cast(&Ncolums), sizeof(int)); + file.write(reinterpret_cast(&Ncolums), sizeof(int32_t)); - file.write(reinterpret_cast(param.NCofsAtCol), Ncolums * sizeof(int)); - file.write(reinterpret_cast(param.AtColCoefOffset), Ncolums * sizeof(int)); + file.write(reinterpret_cast(param.NCofsAtCol), Ncolums * sizeof(int32_t)); + file.write(reinterpret_cast(param.AtColCoefOffset), Ncolums * sizeof(int32_t)); - file.write(reinterpret_cast(&Ncoeffs), sizeof(int)); + file.write(reinterpret_cast(&Ncoeffs), sizeof(int32_t)); file.write(reinterpret_cast(param.Coeffs), Ncoeffs * sizeof(float)); } -int main(int argc, char** argv) +int32_t main(int argc, char** argv) { bpo::options_description options("Field Uniform exporter options"); diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx index 0b0eed697de2d..18b93a7826ffd 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -47,9 +47,9 @@ using namespace GPUCA_NAMESPACE::gpu; #define SEPERATE_GLOBAL_TRACKS_LIMIT (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT) const GPUTRDGeometry* GPUDisplay::trdGeometry() { return (GPUTRDGeometry*)mCalib->trdGeometry; } -const GPUTPCTracker& GPUDisplay::sliceTracker(int iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } +const GPUTPCTracker& GPUDisplay::sliceTracker(int32_t iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } -inline void GPUDisplay::insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last) +inline void GPUDisplay::insertVertexList(std::pair*, vecpod*>& vBuf, size_t first, size_t last) { if (first == last) { return; @@ -57,13 +57,13 @@ inline void GPUDisplay::insertVertexList(std::pair*, vecpodemplace_back(first); vBuf.second->emplace_back(last - first); } -inline void GPUDisplay::insertVertexList(int iSlice, size_t first, size_t last) +inline void GPUDisplay::insertVertexList(int32_t iSlice, size_t first, size_t last) { - std::pair*, vecpod*> vBuf(mVertexBufferStart + iSlice, mVertexBufferCount + iSlice); + std::pair*, vecpod*> vBuf(mVertexBufferStart + iSlice, mVertexBufferCount + iSlice); insertVertexList(vBuf, first, last); } -inline void GPUDisplay::drawPointLinestrip(int iSlice, int cid, int id, int id_limit) +inline void GPUDisplay::drawPointLinestrip(int32_t iSlice, int32_t cid, int32_t id, int32_t id_limit) { mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); if (mGlobalPos[cid].w < id_limit) { @@ -71,14 +71,14 @@ inline void GPUDisplay::drawPointLinestrip(int iSlice, int cid, int id, int id_l } } -GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int iSlice, int select, int iCol) +GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int32_t iSlice, int32_t select, int32_t iCol) { size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); if (iCol == 0) { - for (unsigned int i = 0; i < mIOPtrs->nTRDTracklets; i++) { - int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); + for (uint32_t i = 0; i < mIOPtrs->nTRDTracklets; i++) { + int32_t iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); bool draw = iSlice == iSec && mGlobalPosTRD[i].w == select; if (draw) { mVertexBuffer[iSlice].emplace_back(mGlobalPosTRD[i].x, mGlobalPosTRD[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[i].z); @@ -91,13 +91,13 @@ GPUDisplay::vboList GPUDisplay::DrawSpacePointsTRD(int iSlice, int select, int i return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int iSlice, int select, int iCol) +GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int32_t iSlice, int32_t select, int32_t iCol) { size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); if (iCol == 0 && iSlice == 0) { - for (unsigned int i = 0; i < mIOPtrs->nTOFClusters; i++) { + for (uint32_t i = 0; i < mIOPtrs->nTOFClusters; i++) { mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[i].x, mGlobalPosTOF[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[i].z); } } @@ -106,13 +106,13 @@ GPUDisplay::vboList GPUDisplay::DrawSpacePointsTOF(int iSlice, int select, int i return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int iSlice, int select, int iCol) +GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int32_t iSlice, int32_t select, int32_t iCol) { size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); if (iCol == 0 && iSlice == 0 && mIOPtrs->itsClusters) { - for (unsigned int i = 0; i < mIOPtrs->nItsClusters; i++) { + for (uint32_t i = 0; i < mIOPtrs->nItsClusters; i++) { mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[i].x, mGlobalPosITS[i].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[i].z); } } @@ -121,16 +121,16 @@ GPUDisplay::vboList GPUDisplay::DrawSpacePointsITS(int iSlice, int select, int i return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned int iCol) +GPUDisplay::vboList GPUDisplay::DrawClusters(int32_t iSlice, int32_t select, uint32_t iCol) { size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); if (mOverlayTFClusters.size() > 0 || iCol == 0 || mNCollissions) { - const int firstCluster = (mOverlayTFClusters.size() > 1 && iCol > 0) ? mOverlayTFClusters[iCol - 1][iSlice] : 0; - const int lastCluster = (mOverlayTFClusters.size() > 1 && iCol + 1 < mOverlayTFClusters.size()) ? mOverlayTFClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); + const int32_t firstCluster = (mOverlayTFClusters.size() > 1 && iCol > 0) ? mOverlayTFClusters[iCol - 1][iSlice] : 0; + const int32_t lastCluster = (mOverlayTFClusters.size() > 1 && iCol + 1 < mOverlayTFClusters.size()) ? mOverlayTFClusters[iCol][iSlice] : (mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] : 0); const bool checkClusterCollision = mQA && mNCollissions && mOverlayTFClusters.size() == 0 && mIOPtrs->clustersNative && mIOPtrs->clustersNative->clustersMCTruth; - for (int cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { - const int cid = GET_CID(iSlice, cidInSlice); + for (int32_t cidInSlice = firstCluster; cidInSlice < lastCluster; cidInSlice++) { + const int32_t cid = GET_CID(iSlice, cidInSlice); #ifdef GPUCA_TPC_GEOMETRY_O2 if (checkClusterCollision) { const auto& labels = mIOPtrs->clustersNative->clustersMCTruth->getLabels(cid); @@ -147,7 +147,7 @@ GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned in bool draw = mGlobalPos[cid].w == select; if (mCfgH.markAdjacentClusters) { - const int attach = mIOPtrs->mergedTrackHitAttachment[cid]; + const int32_t attach = mIOPtrs->mergedTrackHitAttachment[cid]; if (attach) { if (mCfgH.markAdjacentClusters >= 32) { if (mQA && mQA->clusterRemovable(attach, mCfgH.markAdjacentClusters == 33)) { @@ -168,7 +168,7 @@ GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned in } } } else if (mCfgH.markClusters) { - short flags; + int16_t flags; if (mParam->par.earlyTpcTransform) { flags = mIOPtrs->clusterData[iSlice][cidInSlice].flags; } else { @@ -189,23 +189,23 @@ GPUDisplay::vboList GPUDisplay::DrawClusters(int iSlice, int select, unsigned in return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int id, bool dodown) +GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int32_t id, bool dodown) { - int iSlice = tracker.ISlice(); + int32_t iSlice = tracker.ISlice(); if (mCfgH.clustersOnly) { return (vboList(0, 0, iSlice)); } size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { const GPUTPCRow& row = tracker.Data().Row(i); if (i < GPUCA_ROW_COUNT - 2) { const GPUTPCRow& rowUp = tracker.Data().Row(i + 2); - for (int j = 0; j < row.NHits(); j++) { + for (int32_t j = 0; j < row.NHits(); j++) { if (tracker.Data().HitLinkUpData(row, j) != CALINK_INVAL) { - const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); - const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowUp, tracker.Data().HitLinkUpData(row, j))); + const int32_t cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); + const int32_t cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowUp, tracker.Data().HitLinkUpData(row, j))); drawPointLinestrip(iSlice, cid1, id); drawPointLinestrip(iSlice, cid2, id); } @@ -214,10 +214,10 @@ GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int id, if (dodown && i >= 2) { const GPUTPCRow& rowDown = tracker.Data().Row(i - 2); - for (int j = 0; j < row.NHits(); j++) { + for (int32_t j = 0; j < row.NHits(); j++) { if (tracker.Data().HitLinkDownData(row, j) != CALINK_INVAL) { - const int cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); - const int cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowDown, tracker.Data().HitLinkDownData(row, j))); + const int32_t cid1 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, j)); + const int32_t cid2 = GET_CID(iSlice, tracker.Data().ClusterDataIndex(rowDown, tracker.Data().HitLinkDownData(row, j))); drawPointLinestrip(iSlice, cid1, id); drawPointLinestrip(iSlice, cid2, id); } @@ -230,19 +230,19 @@ GPUDisplay::vboList GPUDisplay::DrawLinks(const GPUTPCTracker& tracker, int id, GPUDisplay::vboList GPUDisplay::DrawSeeds(const GPUTPCTracker& tracker) { - int iSlice = tracker.ISlice(); + int32_t iSlice = tracker.ISlice(); if (mCfgH.clustersOnly) { return (vboList(0, 0, iSlice)); } size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < *tracker.NStartHits(); i++) { + for (uint32_t i = 0; i < *tracker.NStartHits(); i++) { const GPUTPCHitId& hit = tracker.TrackletStartHit(i); size_t startCountInner = mVertexBuffer[iSlice].size(); - int ir = hit.RowIndex(); + int32_t ir = hit.RowIndex(); calink ih = hit.HitIndex(); do { const GPUTPCRow& row = tracker.Data().Row(ir); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, ih)); + const int32_t cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, ih)); drawPointLinestrip(iSlice, cid, tSEED); ir += 2; ih = tracker.Data().HitLinkUpData(row, ih); @@ -254,20 +254,20 @@ GPUDisplay::vboList GPUDisplay::DrawSeeds(const GPUTPCTracker& tracker) GPUDisplay::vboList GPUDisplay::DrawTracklets(const GPUTPCTracker& tracker) { - int iSlice = tracker.ISlice(); + int32_t iSlice = tracker.ISlice(); if (mCfgH.clustersOnly) { return (vboList(0, 0, iSlice)); } size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < *tracker.NTracklets(); i++) { + for (uint32_t i = 0; i < *tracker.NTracklets(); i++) { const GPUTPCTracklet& tracklet = tracker.Tracklet(i); size_t startCountInner = mVertexBuffer[iSlice].size(); float4 oldpos; - for (int j = tracklet.FirstRow(); j <= tracklet.LastRow(); j++) { + for (int32_t j = tracklet.FirstRow(); j <= tracklet.LastRow(); j++) { const calink rowHit = tracker.TrackletRowHits()[tracklet.FirstHit() + (j - tracklet.FirstRow())]; if (rowHit != CALINK_INVAL && rowHit != CALINK_DEAD_CHANNEL) { const GPUTPCRow& row = tracker.Data().Row(j); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, rowHit)); + const int32_t cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, rowHit)); oldpos = mGlobalPos[cid]; drawPointLinestrip(iSlice, cid, tTRACKLET); } @@ -277,20 +277,20 @@ GPUDisplay::vboList GPUDisplay::DrawTracklets(const GPUTPCTracker& tracker) return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int global) +GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int32_t global) { - int iSlice = tracker.ISlice(); + int32_t iSlice = tracker.ISlice(); if (mCfgH.clustersOnly) { return (vboList(0, 0, iSlice)); } size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = (global ? tracker.CommonMemory()->nLocalTracks : 0); i < (global ? *tracker.NTracks() : tracker.CommonMemory()->nLocalTracks); i++) { + for (uint32_t i = (global ? tracker.CommonMemory()->nLocalTracks : 0); i < (global ? *tracker.NTracks() : tracker.CommonMemory()->nLocalTracks); i++) { GPUTPCTrack& track = tracker.Tracks()[i]; size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int j = 0; j < track.NHits(); j++) { + for (int32_t j = 0; j < track.NHits(); j++) { const GPUTPCHitId& hit = tracker.TrackHits()[track.FirstHitID() + j]; const GPUTPCRow& row = tracker.Data().Row(hit.RowIndex()); - const int cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, hit.HitIndex())); + const int32_t cid = GET_CID(iSlice, tracker.Data().ClusterDataIndex(row, hit.HitIndex())); drawPointLinestrip(iSlice, cid, tSLICETRACK + global); } insertVertexList(iSlice, startCountInner, mVertexBuffer[iSlice].size()); @@ -298,12 +298,12 @@ GPUDisplay::vboList GPUDisplay::DrawTracks(const GPUTPCTracker& tracker, int glo return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -void GPUDisplay::DrawTrackITS(int trackId, int iSlice) +void GPUDisplay::DrawTrackITS(int32_t trackId, int32_t iSlice) { #ifdef GPUCA_HAVE_O2HEADERS const auto& trk = mIOPtrs->itsTracks[trackId]; - for (int k = 0; k < trk.getNClusters(); k++) { - int cid = mIOPtrs->itsTrackClusIdx[trk.getFirstClusterEntry() + k]; + for (int32_t k = 0; k < trk.getNClusters(); k++) { + int32_t cid = mIOPtrs->itsTrackClusIdx[trk.getFirstClusterEntry() + k]; mVertexBuffer[iSlice].emplace_back(mGlobalPosITS[cid].x, mGlobalPosITS[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosITS[cid].z); mGlobalPosITS[cid].w = tITSATTACHED; } @@ -312,9 +312,9 @@ void GPUDisplay::DrawTrackITS(int trackId, int iSlice) GPUDisplay::vboList GPUDisplay::DrawFinalITS() { - const int iSlice = 0; + const int32_t iSlice = 0; size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int i = 0; i < mIOPtrs->nItsTracks; i++) { + for (uint32_t i = 0; i < mIOPtrs->nItsTracks; i++) { if (mITSStandaloneTracks[i]) { size_t startCountInner = mVertexBuffer[iSlice].size(); DrawTrackITS(i, iSlice); @@ -325,24 +325,24 @@ GPUDisplay::vboList GPUDisplay::DrawFinalITS() } template -void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer) +void GPUDisplay::DrawFinal(int32_t iSlice, int32_t /*iCol*/, GPUTPCGMPropagator* prop, std::array, 2>& trackList, threadVertexBuffer& threadBuffer) { auto& vBuf = threadBuffer.vBuf; auto& buffer = threadBuffer.buffer; - unsigned int nTracks = std::max(trackList[0].size(), trackList[1].size()); + uint32_t nTracks = std::max(trackList[0].size(), trackList[1].size()); if (mCfgH.clustersOnly) { nTracks = 0; } - for (unsigned int ii = 0; ii < nTracks; ii++) { - int i = 0; + for (uint32_t ii = 0; ii < nTracks; ii++) { + int32_t i = 0; const T* track = nullptr; - int lastCluster = -1; + int32_t lastCluster = -1; while (true) { if (ii >= trackList[0].size()) { break; } i = trackList[0][ii]; - int nClusters; + int32_t nClusters; if constexpr (std::is_same_v) { track = &mIOPtrs->mergedTracks[i]; nClusters = track->NClusters(); @@ -375,7 +375,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s // Print TOF part of track if constexpr (std::is_same_v) { if (mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1 && mIOPtrs->nTOFClusters) { - int cid = mIOPtrs->tpcLinkTOF[i]; + int32_t cid = mIOPtrs->tpcLinkTOF[i]; drawing = true; mVertexBuffer[iSlice].emplace_back(mGlobalPosTOF[cid].x, mGlobalPosTOF[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[cid].z); mGlobalPosTOF[cid].w = tTOFATTACHED; @@ -384,8 +384,8 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s // Print TRD part of track auto tmpDoTRDTracklets = [&](const auto& trk) { - for (int k = 5; k >= 0; k--) { - int cid = trk.getTrackletIndex(k); + for (int32_t k = 5; k >= 0; k--) { + int32_t cid = trk.getTrackletIndex(k); if (cid < 0) { continue; } @@ -396,7 +396,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } }; if (std::is_same_v || (!mIOPtrs->tpcLinkTRD && mIOPtrs->trdTracksO2)) { - if (mChain && ((int)mConfig.showTPCTracksFromO2Format == (int)mChain->GetProcessingSettings().trdTrackModelO2) && mTRDTrackIds[i] != -1 && mIOPtrs->nTRDTracklets) { + if (mChain && ((int32_t)mConfig.showTPCTracksFromO2Format == (int32_t)mChain->GetProcessingSettings().trdTrackModelO2) && mTRDTrackIds[i] != -1 && mIOPtrs->nTRDTracklets) { if (mIOPtrs->trdTracksO2) { #ifdef GPUCA_HAVE_O2HEADERS tmpDoTRDTracklets(mIOPtrs->trdTracksO2[mTRDTrackIds[i]]); @@ -416,19 +416,19 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } // Print TPC part of track - for (int k = 0; k < nClusters; k++) { + for (int32_t k = 0; k < nClusters; k++) { if constexpr (std::is_same_v) { if (mCfgH.hideRejectedClusters && (mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject)) { continue; } } - int cid; + int32_t cid; if constexpr (std::is_same_v) { cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].num; } else { cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, k, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; } - int w = mGlobalPos[cid].w; + int32_t w = mGlobalPos[cid].w; if (drawing) { drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); } @@ -472,7 +472,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } // Propagate track paramters / plot MC tracks - for (int iMC = 0; iMC < 2; iMC++) { + for (int32_t iMC = 0; iMC < 2; iMC++) { if (iMC) { if (ii >= trackList[1].size()) { continue; @@ -488,7 +488,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int inFlyDirection = 0; inFlyDirection < 2; inFlyDirection++) { + for (int32_t inFlyDirection = 0; inFlyDirection < 2; inFlyDirection++) { GPUTPCGMPhysicalTrackModel trkParam; float ZOffset = 0; float x = 0; @@ -574,7 +574,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s } float alpha = alphaOrg; vecpod& useBuffer = iMC && inFlyDirection == 0 ? buffer : mVertexBuffer[iSlice]; - int nPoints = 0; + int32_t nPoints = 0; while (nPoints++ < 5000) { if ((inFlyDirection == 0 && x < 0) || (inFlyDirection && x * x + trkParam.Y() * trkParam.Y() > (iMC ? (450 * 450) : (300 * 300)))) { @@ -618,7 +618,7 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s if (inFlyDirection == 0) { if (iMC) { - for (int k = (int)buffer.size() - 1; k >= 0; k--) { + for (int32_t k = (int32_t)buffer.size() - 1; k >= 0; k--) { mVertexBuffer[iSlice].emplace_back(buffer[k]); } } else { @@ -634,12 +634,12 @@ void GPUDisplay::DrawFinal(int iSlice, int /*iCol*/, GPUTPCGMPropagator* prop, s GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) { - int iSlice = tracker.ISlice(); + int32_t iSlice = tracker.ISlice(); size_t startCount = mVertexBufferStart[iSlice].size(); size_t startCountInner = mVertexBuffer[iSlice].size(); - for (int i = 0; i < GPUCA_ROW_COUNT; i++) { + for (int32_t i = 0; i < GPUCA_ROW_COUNT; i++) { const GPUTPCRow& row = tracker.Data().Row(i); - for (int j = 0; j <= (signed)row.Grid().Ny(); j++) { + for (int32_t j = 0; j <= (signed)row.Grid().Ny(); j++) { float z1 = row.Grid().ZMin(); float z2 = row.Grid().ZMax(); float x = row.X() + mCfgH.xAdd; @@ -657,7 +657,7 @@ GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) mVertexBuffer[iSlice].emplace_back(xx1 * GL_SCALE_FACTOR, yy1 * GL_SCALE_FACTOR * mYFactor, zz1 * GL_SCALE_FACTOR); mVertexBuffer[iSlice].emplace_back(xx2 * GL_SCALE_FACTOR, yy2 * GL_SCALE_FACTOR * mYFactor, zz2 * GL_SCALE_FACTOR); } - for (int j = 0; j <= (signed)row.Grid().Nz(); j++) { + for (int32_t j = 0; j <= (signed)row.Grid().Nz(); j++) { float y1 = row.Grid().YMin(); float y2 = row.Grid().YMax(); float x = row.X() + mCfgH.xAdd; @@ -680,7 +680,7 @@ GPUDisplay::vboList GPUDisplay::DrawGrid(const GPUTPCTracker& tracker) return (vboList(startCount, mVertexBufferStart[iSlice].size() - startCount, iSlice)); } -GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) +GPUDisplay::vboList GPUDisplay::DrawGridTRD(int32_t sector) { // TODO: tilted pads ignored at the moment size_t startCount = mVertexBufferStart[sector].size(); @@ -688,20 +688,20 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) #ifdef GPUCA_HAVE_O2HEADERS auto* geo = trdGeometry(); if (geo) { - int trdsector = NSLICES / 2 - 1 - sector; + int32_t trdsector = NSLICES / 2 - 1 - sector; float alpha = geo->GetAlpha() / 2.f + geo->GetAlpha() * trdsector; if (trdsector >= 9) { alpha -= 2 * CAMath::Pi(); } - for (int iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; ++iLy) { - for (int iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; ++iStack) { - int iDet = geo->GetDetector(iLy, iStack, trdsector); + for (int32_t iLy = 0; iLy < GPUTRDTracker::EGPUTRDTracker::kNLayers; ++iLy) { + for (int32_t iStack = 0; iStack < GPUTRDTracker::EGPUTRDTracker::kNStacks; ++iStack) { + int32_t iDet = geo->GetDetector(iLy, iStack, trdsector); auto matrix = geo->GetClusterMatrix(iDet); if (!matrix) { continue; } auto pp = geo->GetPadPlane(iDet); - for (int i = 0; i < pp->GetNrows(); ++i) { + for (int32_t i = 0; i < pp->GetNrows(); ++i) { float xyzLoc1[3]; float xyzLoc2[3]; float xyzGlb1[3]; @@ -721,7 +721,7 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) mVertexBuffer[sector].emplace_back(xyzGlb1[0] * GL_SCALE_FACTOR, xyzGlb1[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb1[2] * GL_SCALE_FACTOR); mVertexBuffer[sector].emplace_back(xyzGlb2[0] * GL_SCALE_FACTOR, xyzGlb2[1] * GL_SCALE_FACTOR * mYFactor, xyzGlb2[2] * GL_SCALE_FACTOR); } - for (int j = 0; j < pp->GetNcols(); ++j) { + for (int32_t j = 0; j < pp->GetNcols(); ++j) { float xyzLoc1[3]; float xyzLoc2[3]; float xyzGlb1[3]; @@ -751,38 +751,38 @@ GPUDisplay::vboList GPUDisplay::DrawGridTRD(int sector) size_t GPUDisplay::DrawGLScene_updateVertexList() { - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { mVertexBuffer[i].clear(); mVertexBufferStart[i].clear(); mVertexBufferCount[i].clear(); } - for (int i = 0; i < mCurrentClusters; i++) { + for (int32_t i = 0; i < mCurrentClusters; i++) { mGlobalPos[i].w = tCLUSTER; } - for (int i = 0; i < mCurrentSpacePointsTRD; i++) { + for (int32_t i = 0; i < mCurrentSpacePointsTRD; i++) { mGlobalPosTRD[i].w = tTRDCLUSTER; } - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = 0; i < N_POINTS_TYPE; i++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t i = 0; i < N_POINTS_TYPE; i++) { mGlDLPoints[iSlice][i].resize(mNCollissions); } - for (int i = 0; i < N_FINAL_TYPE; i++) { + for (int32_t i = 0; i < N_FINAL_TYPE; i++) { mGlDLFinal[iSlice].resize(mNCollissions); } } GPUCA_OPENMP(parallel num_threads(getNumThreads())) { #ifdef WITH_OPENMP - int numThread = omp_get_thread_num(); - int numThreads = omp_get_num_threads(); + int32_t numThread = omp_get_thread_num(); + int32_t numThreads = omp_get_num_threads(); #else - int numThread = 0, numThreads = 1; + int32_t numThread = 0, numThreads = 1; #endif if (mChain && (mChain->GetRecoSteps() & GPUDataTypes::RecoStep::TPCSliceTracking)) { GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { GPUTPCTracker& tracker = (GPUTPCTracker&)sliceTracker(iSlice); tracker.SetPointersDataLinks(tracker.LinkTmpMemory()); mGlDLLines[iSlice][tINITLINK] = DrawLinks(tracker, tINITLINK, true); @@ -791,7 +791,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() GPUCA_OPENMP(barrier) GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { const GPUTPCTracker& tracker = sliceTracker(iSlice); mGlDLLines[iSlice][tLINK] = DrawLinks(tracker, tLINK); @@ -806,25 +806,25 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() GPUCA_OPENMP(barrier) GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { const GPUTPCTracker& tracker = sliceTracker(iSlice); mGlDLLines[iSlice][tGLOBALTRACK] = DrawTracks(tracker, 1); } GPUCA_OPENMP(barrier) } mThreadTracks[numThread].resize(mNCollissions); - for (int i = 0; i < mNCollissions; i++) { - for (int j = 0; j < NSLICES; j++) { - for (int k = 0; k < 2; k++) { + for (int32_t i = 0; i < mNCollissions; i++) { + for (int32_t j = 0; j < NSLICES; j++) { + for (int32_t k = 0; k < 2; k++) { mThreadTracks[numThread][i][j][k].clear(); } } } if (mConfig.showTPCTracksFromO2Format) { #ifdef GPUCA_TPC_GEOMETRY_O2 - unsigned int col = 0; + uint32_t col = 0; GPUCA_OPENMP(for) - for (unsigned int i = 0; i < mIOPtrs->nOutputTracksTPCO2; i++) { + for (uint32_t i = 0; i < mIOPtrs->nOutputTracksTPCO2; i++) { uint8_t sector, row; if (mIOPtrs->clustersNative) { mIOPtrs->outputTracksTPCO2[i].getCluster(mIOPtrs->outputClusRefsTPCO2, 0, *mIOPtrs->clustersNative, sector, row); @@ -839,7 +839,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() #endif } else { GPUCA_OPENMP(for) - for (unsigned int i = 0; i < mIOPtrs->nMergedTracks; i++) { + for (uint32_t i = 0; i < mIOPtrs->nMergedTracks; i++) { const GPUTPCGMMergedTrack* track = &mIOPtrs->mergedTracks[i]; if (track->NClusters() == 0) { continue; @@ -847,8 +847,8 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() if (mCfgH.hideRejectedTracks && !track->OK()) { continue; } - int slice = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].slice; - unsigned int col = 0; + int32_t slice = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + track->NClusters() - 1].slice; + uint32_t col = 0; if (mQA) { const auto& label = mQA->GetMCTrackLabel(i); #ifdef GPUCA_TPC_GEOMETRY_O2 @@ -862,9 +862,9 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() mThreadTracks[numThread][col][slice][0].emplace_back(i); } } - for (unsigned int col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) { + for (uint32_t col = 0; col < mIOPtrs->nMCInfosTPCCol; col++) { GPUCA_OPENMP(for) - for (unsigned int i = mIOPtrs->mcInfosTPCCol[col].first; i < mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num; i++) { + for (uint32_t i = mIOPtrs->mcInfosTPCCol[col].first; i < mIOPtrs->mcInfosTPCCol[col].first + mIOPtrs->mcInfosTPCCol[col].num; i++) { const GPUTPCMCInfo& mc = mIOPtrs->mcInfosTPC[i]; if (mc.charge == 0.f) { continue; @@ -877,7 +877,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() if (alpha < 0) { alpha += 2 * CAMath::Pi(); } - int slice = alpha / (2 * CAMath::Pi()) * 18; + int32_t slice = alpha / (2 * CAMath::Pi()) * 18; if (mc.z < 0) { slice += 18; } @@ -892,10 +892,10 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() prop.SetPolynomialField(&mParam->polynomialField); GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iCol = 0; iCol < mNCollissions; iCol++) { mThreadBuffers[numThread].clear(); - for (int iSet = 0; iSet < numThreads; iSet++) { + for (int32_t iSet = 0; iSet < numThreads; iSet++) { #ifdef GPUCA_HAVE_O2HEADERS if (mConfig.showTPCTracksFromO2Format) { DrawFinal(iSlice, iCol, &prop, mThreadTracks[iSet][iCol][iSlice], mThreadBuffers[numThread]); @@ -906,9 +906,9 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() } } vboList* list = &mGlDLFinal[iSlice][iCol][0]; - for (int i = 0; i < N_FINAL_TYPE; i++) { + for (int32_t i = 0; i < N_FINAL_TYPE; i++) { size_t startCount = mVertexBufferStart[iSlice].size(); - for (unsigned int j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) { + for (uint32_t j = 0; j < mThreadBuffers[numThread].start[i].size(); j++) { mVertexBufferStart[iSlice].emplace_back(mThreadBuffers[numThread].start[i][j]); mVertexBufferCount[iSlice].emplace_back(mThreadBuffers[numThread].count[i][j]); } @@ -919,9 +919,9 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() GPUCA_OPENMP(barrier) GPUCA_OPENMP(for) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = 0; i < N_POINTS_TYPE_TPC; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t i = 0; i < N_POINTS_TYPE_TPC; i++) { + for (int32_t iCol = 0; iCol < mNCollissions; iCol++) { mGlDLPoints[iSlice][i][iCol] = DrawClusters(iSlice, i, iCol); } } @@ -931,26 +931,26 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() mGlDLFinalITS = DrawFinalITS(); - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t i = N_POINTS_TYPE_TPC; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i++) { + for (int32_t iCol = 0; iCol < mNCollissions; iCol++) { mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTRD(iSlice, i, iCol); } } } - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i++) { + for (int32_t iCol = 0; iCol < mNCollissions; iCol++) { mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsTOF(iSlice, i, iCol); } } break; // TODO: Only slice 0 filled for now } - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - for (int i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF + N_POINTS_TYPE_ITS; i++) { - for (int iCol = 0; iCol < mNCollissions; iCol++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t i = N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF; i < N_POINTS_TYPE_TPC + N_POINTS_TYPE_TRD + N_POINTS_TYPE_TOF + N_POINTS_TYPE_ITS; i++) { + for (int32_t iCol = 0; iCol < mNCollissions; iCol++) { mGlDLPoints[iSlice][i][iCol] = DrawSpacePointsITS(iSlice, i, iCol); } } @@ -959,7 +959,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() mUpdateVertexLists = 0; size_t totalVertizes = 0; - for (int i = 0; i < NSLICES; i++) { + for (int32_t i = 0; i < NSLICES; i++) { totalVertizes += mVertexBuffer[i].size(); } if (totalVertizes > 0xFFFFFFFF) { @@ -970,8 +970,8 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() if (!mUseMultiVBO) { size_t totalYet = mVertexBuffer[0].size(); mVertexBuffer[0].resize(totalVertizes); - for (int i = 1; i < GPUCA_NSLICES; i++) { - for (unsigned int j = 0; j < mVertexBufferStart[i].size(); j++) { + for (int32_t i = 1; i < GPUCA_NSLICES; i++) { + for (uint32_t j = 0; j < mVertexBufferStart[i].size(); j++) { mVertexBufferStart[i][j] += totalYet; } memcpy(&mVertexBuffer[0][totalYet], &mVertexBuffer[i][0], mVertexBuffer[i].size() * sizeof(mVertexBuffer[i][0])); @@ -980,7 +980,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() } } mBackend->loadDataToGPU(totalVertizes); - for (int i = 0; i < (mUseMultiVBO ? GPUCA_NSLICES : 1); i++) { + for (int32_t i = 0; i < (mUseMultiVBO ? GPUCA_NSLICES : 1); i++) { mVertexBuffer[i].clear(); } return totalVertizes; diff --git a/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx index b1e6dfe21fb97..072119f7d528f 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayImportEvent.cxx @@ -44,7 +44,7 @@ void GPUDisplay::DrawGLScene_updateEventData() mCurrentClusters = mIOPtrs->clustersNative->nClustersTotal; } else { mCurrentClusters = 0; - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { mCurrentClusters += mIOPtrs->nClusterData[iSlice]; } } @@ -77,18 +77,18 @@ void GPUDisplay::DrawGLScene_updateEventData() mGlobalPosTOF = mGlobalPosPtrTOF.get(); } - unsigned int nTpcMergedTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; + uint32_t nTpcMergedTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; if ((size_t)nTpcMergedTracks > mTRDTrackIds.size()) { mTRDTrackIds.resize(nTpcMergedTracks); } if (mIOPtrs->nItsTracks > mITSStandaloneTracks.size()) { mITSStandaloneTracks.resize(mIOPtrs->nItsTracks); } - for (unsigned int i = 0; i < nTpcMergedTracks; i++) { + for (uint32_t i = 0; i < nTpcMergedTracks; i++) { mTRDTrackIds[i] = -1; } auto tmpDoTRDTracklets = [&](auto* trdTracks) { - for (unsigned int i = 0; i < mIOPtrs->nTRDTracks; i++) { + for (uint32_t i = 0; i < mIOPtrs->nTRDTracks; i++) { if (trdTracks[i].getNtracklets()) { mTRDTrackIds[trdTracks[i].getRefGlobalTrackIdRaw()] = i; } @@ -104,7 +104,7 @@ void GPUDisplay::DrawGLScene_updateEventData() if (mIOPtrs->nItsTracks) { std::fill(mITSStandaloneTracks.begin(), mITSStandaloneTracks.end(), true); if (mIOPtrs->tpcLinkITS) { - for (unsigned int i = 0; i < nTpcMergedTracks; i++) { + for (uint32_t i = 0; i < nTpcMergedTracks; i++) { if (mIOPtrs->tpcLinkITS[i] != -1) { mITSStandaloneTracks[mIOPtrs->tpcLinkITS[i]] = false; } @@ -113,18 +113,18 @@ void GPUDisplay::DrawGLScene_updateEventData() } if (mCfgH.trackFilter) { - unsigned int nTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; + uint32_t nTracks = mConfig.showTPCTracksFromO2Format ? mIOPtrs->nOutputTracksTPCO2 : mIOPtrs->nMergedTracks; mTrackFilter.resize(nTracks); std::fill(mTrackFilter.begin(), mTrackFilter.end(), true); if (buildTrackFilter()) { SetInfo("Error running track filter from %s", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str()); } else { - unsigned int nFiltered = 0; - for (unsigned int i = 0; i < mTrackFilter.size(); i++) { + uint32_t nFiltered = 0; + for (uint32_t i = 0; i < mTrackFilter.size(); i++) { nFiltered += !mTrackFilter[i]; } if (mUpdateTrackFilter) { - SetInfo("Applied track filter %s - filtered %u / %u", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str(), nFiltered, (unsigned int)mTrackFilter.size()); + SetInfo("Applied track filter %s - filtered %u / %u", mConfig.filterMacros[mCfgH.trackFilter - 1].c_str(), nFiltered, (uint32_t)mTrackFilter.size()); } } } @@ -132,19 +132,19 @@ void GPUDisplay::DrawGLScene_updateEventData() mMaxClusterZ = 0; GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) - for (int iSlice = 0; iSlice < NSLICES; iSlice++) { - int row = 0; - unsigned int nCls = mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] - : 0; - for (unsigned int i = 0; i < nCls; i++) { - int cid; + for (int32_t iSlice = 0; iSlice < NSLICES; iSlice++) { + int32_t row = 0; + uint32_t nCls = mParam->par.earlyTpcTransform ? mIOPtrs->nClusterData[iSlice] : mIOPtrs->clustersNative ? mIOPtrs->clustersNative->nClustersSector[iSlice] + : 0; + for (uint32_t i = 0; i < nCls; i++) { + int32_t cid; if (mParam->par.earlyTpcTransform) { const auto& cl = mIOPtrs->clusterData[iSlice][i]; cid = cl.id; row = cl.row; } else { cid = mIOPtrs->clustersNative->clusterOffset[iSlice][0] + i; - while (row < GPUCA_ROW_COUNT - 1 && mIOPtrs->clustersNative->clusterOffset[iSlice][row + 1] <= (unsigned int)cid) { + while (row < GPUCA_ROW_COUNT - 1 && mIOPtrs->clustersNative->clusterOffset[iSlice][row + 1] <= (uint32_t)cid) { row++; } } @@ -176,11 +176,11 @@ void GPUDisplay::DrawGLScene_updateEventData() } } - int trdTriggerRecord = -1; + int32_t trdTriggerRecord = -1; float trdZoffset = 0; GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ) firstprivate(trdTriggerRecord, trdZoffset)) - for (int i = 0; i < mCurrentSpacePointsTRD; i++) { - while (mParam->par.continuousTracking && trdTriggerRecord < (int)mIOPtrs->nTRDTriggerRecords - 1 && mIOPtrs->trdTrackletIdxFirst[trdTriggerRecord + 1] <= i) { + for (int32_t i = 0; i < mCurrentSpacePointsTRD; i++) { + while (mParam->par.continuousTracking && trdTriggerRecord < (int32_t)mIOPtrs->nTRDTriggerRecords - 1 && mIOPtrs->trdTrackletIdxFirst[trdTriggerRecord + 1] <= i) { trdTriggerRecord++; #ifdef GPUCA_HAVE_O2HEADERS float trdTime = mIOPtrs->trdTriggerTimes[trdTriggerRecord] * 1e3 / o2::constants::lhc::LHCBunchSpacingNS / o2::tpc::constants::LHCBCPERTIMEBIN; @@ -188,7 +188,7 @@ void GPUDisplay::DrawGLScene_updateEventData() #endif } const auto& sp = mIOPtrs->trdSpacePoints[i]; - int iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); + int32_t iSec = trdGeometry()->GetSector(mIOPtrs->trdTracklets[i].GetDetector()); float4* ptr = &mGlobalPosTRD[i]; mParam->Slice2Global(iSec, sp.getX() + mCfgH.xAdd, sp.getY(), sp.getZ(), &ptr->x, &ptr->y, &ptr->z); ptr->z += ptr->z > 0 ? trdZoffset : -trdZoffset; @@ -212,7 +212,7 @@ void GPUDisplay::DrawGLScene_updateEventData() } GPUCA_OPENMP(parallel for num_threads(getNumThreads()) reduction(max : mMaxClusterZ)) - for (int i = 0; i < mCurrentClustersTOF; i++) { + for (int32_t i = 0; i < mCurrentClustersTOF; i++) { #ifdef GPUCA_HAVE_O2HEADERS float4* ptr = &mGlobalPosTOF[i]; mParam->Slice2Global(mIOPtrs->tofClusters[i].getSector(), mIOPtrs->tofClusters[i].getX() + mCfgH.xAdd, mIOPtrs->tofClusters[i].getY(), mIOPtrs->tofClusters[i].getZ(), &ptr->x, &ptr->y, &ptr->z); @@ -241,8 +241,8 @@ void GPUDisplay::DrawGLScene_updateEventData() itsROFhalfLen = alpParams.roFrameLengthInBC / (float)o2::tpc::constants::LHCBCPERTIMEBIN / 2; } #endif - int i = 0; - for (unsigned int j = 0; j < mIOPtrs->nItsClusterROF; j++) { + int32_t i = 0; + for (uint32_t j = 0; j < mIOPtrs->nItsClusterROF; j++) { float ZOffset = 0; if (mParam->par.continuousTracking) { o2::InteractionRecord startIR = o2::InteractionRecord(0, mIOPtrs->settingsTF && mIOPtrs->settingsTF->hasTfStartOrbit ? mIOPtrs->settingsTF->tfStartOrbit : 0); @@ -252,7 +252,7 @@ void GPUDisplay::DrawGLScene_updateEventData() if (i != mIOPtrs->itsClusterROF[j].getFirstEntry()) { throw std::runtime_error("Inconsistent ITS data, number of clusters does not match ROF content"); } - for (int k = 0; k < mIOPtrs->itsClusterROF[j].getNEntries(); k++) { + for (int32_t k = 0; k < mIOPtrs->itsClusterROF[j].getNEntries(); k++) { float4* ptr = &mGlobalPosITS[i]; const auto& cl = mIOPtrs->itsClusters[i]; auto* itsGeo = o2::its::GeometryTGeo::Instance(); diff --git a/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h b/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h index 9f365d59ecc5b..5dd99fab38160 100644 --- a/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h +++ b/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h @@ -135,19 +135,19 @@ layout(std430, binding = 1) restrict readonly buffer sol_segment_ssbo { float MaxZ; float MultiplicativeFactor; - int ZSegments; + int32_t ZSegments; float SegZSol[SOL_Z_SEGS]; - int BegSegPSol[SOL_Z_SEGS]; - int NSegPSol[SOL_Z_SEGS]; + int32_t BegSegPSol[SOL_Z_SEGS]; + int32_t NSegPSol[SOL_Z_SEGS]; float SegPSol[SOL_P_SEGS]; - int BegSegRSol[SOL_P_SEGS]; - int NSegRSol[SOL_P_SEGS]; + int32_t BegSegRSol[SOL_P_SEGS]; + int32_t NSegRSol[SOL_P_SEGS]; float SegRSol[SOL_R_SEGS]; - int SegIDSol[SOL_R_SEGS]; + int32_t SegIDSol[SOL_R_SEGS]; } sol_segment; layout(std430, binding = 2) restrict readonly buffer dip_segment_ssbo { @@ -155,19 +155,19 @@ layout(std430, binding = 2) restrict readonly buffer dip_segment_ssbo { float MaxZ; float MultiplicativeFactor; - int ZSegments; + int32_t ZSegments; float SegZDip[DIP_Z_SEGS]; - int BegSegYDip[DIP_Z_SEGS]; - int NSegYDip[DIP_Z_SEGS]; + int32_t BegSegYDip[DIP_Z_SEGS]; + int32_t NSegYDip[DIP_Z_SEGS]; float SegYDip[DIP_Y_SEGS]; - int BegSegXDip[DIP_Y_SEGS]; - int NSegXDip[DIP_Y_SEGS]; + int32_t BegSegXDip[DIP_Y_SEGS]; + int32_t NSegXDip[DIP_Y_SEGS]; float SegXDip[DIP_X_SEGS]; - int SegIDDip[DIP_X_SEGS]; + int32_t SegIDDip[DIP_X_SEGS]; } dip_segment; layout(std430, binding = 3) restrict readonly buffer sol_params_ssbo { @@ -175,15 +175,15 @@ layout(std430, binding = 3) restrict readonly buffer sol_params_ssbo { float BScales[DIMENSIONS*SOL_PARAMS]; float BMin[DIMENSIONS*SOL_PARAMS]; float BMax[DIMENSIONS*SOL_PARAMS]; - int NRows[DIMENSIONS*SOL_PARAMS]; - int ColsAtRowOffset[DIMENSIONS*SOL_PARAMS]; - int CofsAtRowOffset[DIMENSIONS*SOL_PARAMS]; + int32_t NRows[DIMENSIONS*SOL_PARAMS]; + int32_t ColsAtRowOffset[DIMENSIONS*SOL_PARAMS]; + int32_t CofsAtRowOffset[DIMENSIONS*SOL_PARAMS]; - int NColsAtRow[SOL_ROWS]; - int CofsAtColOffset[SOL_ROWS]; + int32_t NColsAtRow[SOL_ROWS]; + int32_t CofsAtColOffset[SOL_ROWS]; - int NCofsAtCol[SOL_COLUMNS]; - int AtColCoefOffset[SOL_COLUMNS]; + int32_t NCofsAtCol[SOL_COLUMNS]; + int32_t AtColCoefOffset[SOL_COLUMNS]; float Coeffs[SOL_COEFFS]; } sol_params; @@ -193,15 +193,15 @@ layout(std430, binding = 4) restrict readonly buffer dip_params_ssbo { float BScales[DIMENSIONS*DIP_PARAMS]; float BMin[DIMENSIONS*DIP_PARAMS]; float BMax[DIMENSIONS*DIP_PARAMS]; - int NRows[DIMENSIONS*DIP_PARAMS]; - int ColsAtRowOffset[DIMENSIONS*DIP_PARAMS]; - int CofsAtRowOffset[DIMENSIONS*DIP_PARAMS]; + int32_t NRows[DIMENSIONS*DIP_PARAMS]; + int32_t ColsAtRowOffset[DIMENSIONS*DIP_PARAMS]; + int32_t CofsAtRowOffset[DIMENSIONS*DIP_PARAMS]; - int NColsAtRow[DIP_ROWS]; - int CofsAtColOffset[DIP_ROWS]; + int32_t NColsAtRow[DIP_ROWS]; + int32_t CofsAtColOffset[DIP_ROWS]; - int NCofsAtCol[DIP_COLUMNS]; - int AtColCoefOffset[DIP_COLUMNS]; + int32_t NCofsAtCol[DIP_COLUMNS]; + int32_t AtColCoefOffset[DIP_COLUMNS]; float Coeffs[DIP_COEFFS]; } dip_params; @@ -213,18 +213,18 @@ vec3 CarttoCyl(vec3 pos) { return vec3(length(pos.xy), atan(pos.y, pos.x), pos.z); } -int findSolSegment(vec3 pos) { - int rid,pid,zid; +int32_t findSolSegment(vec3 pos) { + int32_t rid,pid,zid; for(zid=0; zid < sol_segment.ZSegments; zid++) if(pos.z=0;i--) { + for (int32_t i=ncf;i>=0;i--) { b.zy = b.yx; b.x = arr[i]; b.x = dot(t1, b); @@ -287,7 +287,7 @@ float cheb1DArray(float x, float arr[MAX_CHEB_ORDER], int ncf) { return dot(t, b); } -float cheb1DParamsSol(float x, int coeff_offset, int ncf) { +float cheb1DParamsSol(float x, int32_t coeff_offset, int32_t ncf) { if(ncf <= 0) return 0.0f; const float x2 = 2*x; @@ -297,7 +297,7 @@ float cheb1DParamsSol(float x, int coeff_offset, int ncf) { const vec3 t1 = vec3(1, x2, -1); - for (int i=ncf;i>=0;i--) { + for (int32_t i=ncf;i>=0;i--) { b.zy = b.yx; b.x = sol_params.Coeffs[coeff_offset + i]; b.x = dot(t1, b); @@ -307,7 +307,7 @@ float cheb1DParamsSol(float x, int coeff_offset, int ncf) { return dot(t, b); } -float cheb1DParamsDip(float x, int coeff_offset, int ncf) { +float cheb1DParamsDip(float x, int32_t coeff_offset, int32_t ncf) { if(ncf <= 0) return 0.0f; const float x2 = 2*x; @@ -317,7 +317,7 @@ float cheb1DParamsDip(float x, int coeff_offset, int ncf) { const vec3 t1 = vec3(1, x2, -1); - for (int i=ncf;i>=0;i--) { + for (int32_t i=ncf;i>=0;i--) { b.zy = b.yx; b.x = dip_params.Coeffs[coeff_offset + i]; b.x = dot(t1, b); @@ -331,8 +331,8 @@ bool IsBetween(vec3 sMin, vec3 val, vec3 sMax) { return all(lessThanEqual(sMin, val)) && all(lessThanEqual(val, sMax)); } -bool IsInsideSol(int segID, vec3 rphiz) { - const int index = DIMENSIONS*segID; +bool IsInsideSol(int32_t segID, vec3 rphiz) { + const int32_t index = DIMENSIONS*segID; const vec3 seg_min = vec3(sol_params.BMin[index+0], sol_params.BMin[index+1], sol_params.BMin[index+2]); const vec3 seg_max = vec3(sol_params.BMax[index+0], sol_params.BMax[index+1], sol_params.BMax[index+2]); @@ -340,8 +340,8 @@ bool IsInsideSol(int segID, vec3 rphiz) { return IsBetween(seg_min, rphiz, seg_max); } -bool IsInsideDip(int segID, vec3 pos) { - const int index = DIMENSIONS*segID; +bool IsInsideDip(int32_t segID, vec3 pos) { + const int32_t index = DIMENSIONS*segID; const vec3 seg_min = vec3(dip_params.BMin[index+0], dip_params.BMin[index+1], dip_params.BMin[index+2]); const vec3 seg_max = vec3(dip_params.BMax[index+0], dip_params.BMax[index+1], dip_params.BMax[index+2]); @@ -349,21 +349,21 @@ bool IsInsideDip(int segID, vec3 pos) { return IsBetween(seg_min, pos, seg_max); } -float Eval3DSol(int segID, int dim, vec3 internal) { - const int index = DIMENSIONS*segID; - const int n_rows = sol_params.NRows[index+dim]; - const int cols_at_row_offset = sol_params.ColsAtRowOffset[index+dim]; - const int coeffs_at_row_offset = sol_params.CofsAtRowOffset[index+dim]; +float Eval3DSol(int32_t segID, int32_t dim, vec3 internal) { + const int32_t index = DIMENSIONS*segID; + const int32_t n_rows = sol_params.NRows[index+dim]; + const int32_t cols_at_row_offset = sol_params.ColsAtRowOffset[index+dim]; + const int32_t coeffs_at_row_offset = sol_params.CofsAtRowOffset[index+dim]; - for(int row = 0; row < n_rows; row++) { - const int n_cols = sol_params.NColsAtRow[cols_at_row_offset+row]; - const int coeff_at_col_offset = sol_params.CofsAtColOffset[cols_at_row_offset+row]; + for(int32_t row = 0; row < n_rows; row++) { + const int32_t n_cols = sol_params.NColsAtRow[cols_at_row_offset+row]; + const int32_t coeff_at_col_offset = sol_params.CofsAtColOffset[cols_at_row_offset+row]; - for(int col = 0; col < n_cols; col++) { - const int n_coeffs = sol_params.NCofsAtCol[coeff_at_col_offset+col]; - const int per_col_coeff_offset = sol_params.AtColCoefOffset[coeff_at_col_offset+col]; + for(int32_t col = 0; col < n_cols; col++) { + const int32_t n_coeffs = sol_params.NCofsAtCol[coeff_at_col_offset+col]; + const int32_t per_col_coeff_offset = sol_params.AtColCoefOffset[coeff_at_col_offset+col]; - const int coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset; + const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset; tmpCfs1[col] = cheb1DParamsSol(internal.z, coeffs_offset,n_coeffs); } @@ -373,26 +373,26 @@ float Eval3DSol(int segID, int dim, vec3 internal) { return cheb1DArray(internal.x, tmpCfs0, n_rows); } -vec3 EvalSol(int segID, vec3 rphiz) { +vec3 EvalSol(int32_t segID, vec3 rphiz) { const vec3 internal = mapToInternalSol(segID, rphiz); return vec3(Eval3DSol(segID, 0, internal), Eval3DSol(segID, 1, internal), Eval3DSol(segID, 2, internal)); } -float Eval3DDip(int segID, int dim, vec3 internal) { - const int index = DIMENSIONS*segID; - const int n_rows = dip_params.NRows[index+dim]; - const int cols_at_row_offset = dip_params.ColsAtRowOffset[index+dim]; - const int coeffs_at_row_offset = dip_params.CofsAtRowOffset[index+dim]; +float Eval3DDip(int32_t segID, int32_t dim, vec3 internal) { + const int32_t index = DIMENSIONS*segID; + const int32_t n_rows = dip_params.NRows[index+dim]; + const int32_t cols_at_row_offset = dip_params.ColsAtRowOffset[index+dim]; + const int32_t coeffs_at_row_offset = dip_params.CofsAtRowOffset[index+dim]; - for(int row = 0; row < n_rows; row++) { - const int n_cols = dip_params.NColsAtRow[cols_at_row_offset+row]; - const int coeff_at_col_offset = dip_params.CofsAtColOffset[cols_at_row_offset+row]; + for(int32_t row = 0; row < n_rows; row++) { + const int32_t n_cols = dip_params.NColsAtRow[cols_at_row_offset+row]; + const int32_t coeff_at_col_offset = dip_params.CofsAtColOffset[cols_at_row_offset+row]; - for(int col = 0; col < n_cols; col++) { - const int n_coeffs = dip_params.NCofsAtCol[coeff_at_col_offset+col]; - const int per_col_coeff_offset = dip_params.AtColCoefOffset[coeff_at_col_offset+col]; + for(int32_t col = 0; col < n_cols; col++) { + const int32_t n_coeffs = dip_params.NCofsAtCol[coeff_at_col_offset+col]; + const int32_t per_col_coeff_offset = dip_params.AtColCoefOffset[coeff_at_col_offset+col]; - const int coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset; + const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset; tmpCfs1[col] = cheb1DParamsDip(internal.z, coeffs_offset, n_coeffs); } @@ -402,7 +402,7 @@ float Eval3DDip(int segID, int dim, vec3 internal) { return cheb1DArray(internal.x, tmpCfs0, n_rows); } -vec3 EvalDip(int segID, vec3 pos) { +vec3 EvalDip(int32_t segID, vec3 pos) { const vec3 internal = mapToInternalDip(segID, pos); return vec3(Eval3DDip(segID, 0, internal), Eval3DDip(segID, 1, internal), Eval3DDip(segID, 2, internal)); } @@ -421,14 +421,14 @@ vec3 MachineField(vec3 pos) { vec3 SolDipField(vec3 pos) { if(pos.z > sol_segment.MinZ) { const vec3 rphiz = CarttoCyl(pos); - const int segID = findSolSegment(rphiz); + const int32_t segID = findSolSegment(rphiz); if(segID >=0 && IsInsideSol(segID, rphiz)) { const vec3 brphiz = EvalSol(segID, rphiz); return CyltoCartCylB(rphiz, brphiz) * sol_segment.MultiplicativeFactor; } } - const int segID = findDipSegment(pos); + const int32_t segID = findDipSegment(pos); if(segID >= 0 && IsInsideDip(segID, pos)) { return EvalDip(segID, pos) * dip_segment.MultiplicativeFactor; } diff --git a/GPU/GPUTracking/kernels.cmake b/GPU/GPUTracking/kernels.cmake index 1789e8f6b46c4..b0aed5aba1166 100644 --- a/GPU/GPUTracking/kernels.cmake +++ b/GPU/GPUTracking/kernels.cmake @@ -40,39 +40,39 @@ o2_gpu_add_kernel("GPUTPCStartHitsSorter" "= TPCTRAC o2_gpu_add_kernel("GPUTPCTrackletConstructor, singleSlice" "= TPCTRACKER" LB_OCL1 single) o2_gpu_add_kernel("GPUTPCTrackletConstructor, allSlices" "= TPCTRACKER" LB_OCL1 single) o2_gpu_add_kernel("GPUTPCTrackletSelector" "= TPCTRACKER" LB_OCL1 both) -o2_gpu_add_kernel("GPUMemClean16" "GPUGeneralKernels" NO_OCL1 "simple, REG, (GPUCA_THREAD_COUNT, 1)" void* ptr "unsigned long" size) -o2_gpu_add_kernel("GPUitoa" "GPUGeneralKernels" NO_OCL1 "simple, REG, (GPUCA_THREAD_COUNT, 1)" int* ptr "unsigned long" size) -o2_gpu_add_kernel("GPUTPCGlobalTrackingCopyNumbers" "GPUTPCGlobalTracking TPCTRACKER" NO_OCL1 single int n) +o2_gpu_add_kernel("GPUMemClean16" "GPUGeneralKernels" NO_OCL1 "simple, REG, (GPUCA_THREAD_COUNT, 1)" void* ptr "uint64_t" size) +o2_gpu_add_kernel("GPUitoa" "GPUGeneralKernels" NO_OCL1 "simple, REG, (GPUCA_THREAD_COUNT, 1)" int32_t* ptr "uint64_t" size) +o2_gpu_add_kernel("GPUTPCGlobalTrackingCopyNumbers" "GPUTPCGlobalTracking TPCTRACKER" NO_OCL1 single int32_t n) o2_gpu_add_kernel("GPUTPCGlobalTracking" "= TPCTRACKER TPCTRACKLETCONS" LB single) o2_gpu_add_kernel("GPUTPCCreateSliceData" "= TPCTRACKER TPCSLICEDATA" LB single) o2_gpu_add_kernel("GPUTPCSectorDebugSortKernels, hitData" "= TPCTRACKER" NO single) o2_gpu_add_kernel("GPUTPCSectorDebugSortKernels, startHits" "= TPCTRACKER" NO single) o2_gpu_add_kernel("GPUTPCSectorDebugSortKernels, sliceTracks" "= TPCTRACKER" NO single) -o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, clearIds" "= TPCMERGER" NO single char parameter) -o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, sectorTracks" "= TPCMERGER" NO single char parameter) -o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, globalTracks1" "= TPCMERGER" NO single char parameter) -o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, globalTracks2" "= TPCMERGER" NO single char parameter) -o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, borderTracks" "= TPCMERGER" NO single char parameter) +o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, clearIds" "= TPCMERGER" NO single int8_t parameter) +o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, sectorTracks" "= TPCMERGER" NO single int8_t parameter) +o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, globalTracks1" "= TPCMERGER" NO single int8_t parameter) +o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, globalTracks2" "= TPCMERGER" NO single int8_t parameter) +o2_gpu_add_kernel("GPUTPCGlobalDebugSortKernels, borderTracks" "= TPCMERGER" NO single int8_t parameter) o2_gpu_add_kernel("GPUTPCCreateOccupancyMap, fill" "= TPCOCCUPANCY" LB simple GPUTPCClusterOccupancyMapBin* map) -o2_gpu_add_kernel("GPUTPCCreateOccupancyMap, fold" "= TPCOCCUPANCY" LB simple GPUTPCClusterOccupancyMapBin* map "unsigned int*" output) -o2_gpu_add_kernel("GPUTPCGMMergerTrackFit" "GPUTPCGMMergerGPU TPCMERGER TPCTRACKER MATLUT TPCDEDX" LB simple int mode) +o2_gpu_add_kernel("GPUTPCCreateOccupancyMap, fold" "= TPCOCCUPANCY" LB simple GPUTPCClusterOccupancyMapBin* map "uint32_t*" output) +o2_gpu_add_kernel("GPUTPCGMMergerTrackFit" "GPUTPCGMMergerGPU TPCMERGER TPCTRACKER MATLUT TPCDEDX" LB simple int32_t mode) o2_gpu_add_kernel("GPUTPCGMMergerFollowLoopers" "GPUTPCGMMergerGPU TPCMERGER TPCTRACKER MATLUT" LB simple) -o2_gpu_add_kernel("GPUTPCGMMergerUnpackResetIds" "GPUTPCGMMergerGPU TPCMERGER" LB simple int iSlice) -o2_gpu_add_kernel("GPUTPCGMMergerSliceRefit" "GPUTPCGMMergerGPU TPCMERGER MATLUT" LB simple int iSlice) -o2_gpu_add_kernel("GPUTPCGMMergerUnpackGlobal" "GPUTPCGMMergerGPU TPCMERGER" LB simple int iSlice) -o2_gpu_add_kernel("GPUTPCGMMergerUnpackSaveNumber" "GPUTPCGMMergerGPU TPCMERGER" NO simple int id) +o2_gpu_add_kernel("GPUTPCGMMergerUnpackResetIds" "GPUTPCGMMergerGPU TPCMERGER" LB simple int32_t iSlice) +o2_gpu_add_kernel("GPUTPCGMMergerSliceRefit" "GPUTPCGMMergerGPU TPCMERGER MATLUT" LB simple int32_t iSlice) +o2_gpu_add_kernel("GPUTPCGMMergerUnpackGlobal" "GPUTPCGMMergerGPU TPCMERGER" LB simple int32_t iSlice) +o2_gpu_add_kernel("GPUTPCGMMergerUnpackSaveNumber" "GPUTPCGMMergerGPU TPCMERGER" NO simple int32_t id) o2_gpu_add_kernel("GPUTPCGMMergerResolve, step0" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerResolve, step1" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerResolve, step2" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerResolve, step3" "GPUTPCGMMergerGPU TPCMERGER" LB simple) -o2_gpu_add_kernel("GPUTPCGMMergerResolve, step4" "GPUTPCGMMergerGPU TPCMERGER" LB simple char useOrigTrackParam char mergeAll) -o2_gpu_add_kernel("GPUTPCGMMergerClearLinks" "GPUTPCGMMergerGPU TPCMERGER" LB simple char output) +o2_gpu_add_kernel("GPUTPCGMMergerResolve, step4" "GPUTPCGMMergerGPU TPCMERGER" LB simple int8_t useOrigTrackParam int8_t mergeAll) +o2_gpu_add_kernel("GPUTPCGMMergerClearLinks" "GPUTPCGMMergerGPU TPCMERGER" LB simple int8_t output) o2_gpu_add_kernel("GPUTPCGMMergerMergeWithinPrepare" "GPUTPCGMMergerGPU TPCMERGER" LB simple) -o2_gpu_add_kernel("GPUTPCGMMergerMergeSlicesPrepare" "GPUTPCGMMergerGPU TPCMERGER" LB simple int border0 int border1 char useOrigTrackParam) -o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step0" "GPUTPCGMMergerGPU TPCMERGER" LB simple int iSlice char withinSlice char mergeMode) -o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step1" "GPUTPCGMMergerGPU TPCMERGER" NO simple int iSlice char withinSlice char mergeMode) -o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step2" "GPUTPCGMMergerGPU TPCMERGER" LB simple int iSlice char withinSlice char mergeMode) -o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, variant" "GPUTPCGMMergerGPU TPCMERGER" NO simple gputpcgmmergertypes::GPUTPCGMBorderRange* range int N int cmpMax) +o2_gpu_add_kernel("GPUTPCGMMergerMergeSlicesPrepare" "GPUTPCGMMergerGPU TPCMERGER" LB simple int32_t border0 int32_t border1 int8_t useOrigTrackParam) +o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step0" "GPUTPCGMMergerGPU TPCMERGER" LB simple int32_t iSlice int8_t withinSlice int8_t mergeMode) +o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step1" "GPUTPCGMMergerGPU TPCMERGER" NO simple int32_t iSlice int8_t withinSlice int8_t mergeMode) +o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, step2" "GPUTPCGMMergerGPU TPCMERGER" LB simple int32_t iSlice int8_t withinSlice int8_t mergeMode) +o2_gpu_add_kernel("GPUTPCGMMergerMergeBorders, variant" "GPUTPCGMMergerGPU TPCMERGER" NO simple gputpcgmmergertypes::GPUTPCGMBorderRange* range int32_t N int32_t cmpMax) o2_gpu_add_kernel("GPUTPCGMMergerMergeCE" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerLinkGlobalTracks" "GPUTPCGMMergerGPU TPCMERGER" LB simple) o2_gpu_add_kernel("GPUTPCGMMergerCollect" "GPUTPCGMMergerGPU TPCMERGER" LB simple) @@ -105,28 +105,28 @@ o2_gpu_add_kernel("GPUTPCCompressionGatherKernels, buffered32" "GPUTPCCom o2_gpu_add_kernel("GPUTPCCompressionGatherKernels, buffered64" "GPUTPCCompressionKernels" LB simple) o2_gpu_add_kernel("GPUTPCCompressionGatherKernels, buffered128" "GPUTPCCompressionKernels" LB simple) o2_gpu_add_kernel("GPUTPCCompressionGatherKernels, multiBlock" "GPUTPCCompressionKernels" LB simple) -o2_gpu_add_kernel("GPUTPCDecompressionKernels, step0attached" "= TPCDECOMPRESSION" LB simple int trackStart int trackEnd) -o2_gpu_add_kernel("GPUTPCDecompressionKernels, step1unattached" "= TPCDECOMPRESSION" LB simple int sliceStart int nSlices) +o2_gpu_add_kernel("GPUTPCDecompressionKernels, step0attached" "= TPCDECOMPRESSION" LB simple int32_t trackStart int32_t trackEnd) +o2_gpu_add_kernel("GPUTPCDecompressionKernels, step1unattached" "= TPCDECOMPRESSION" LB simple int32_t sliceStart int32_t nSlices) o2_gpu_add_kernel("GPUTPCDecompressionUtilKernels, sortPerSectorRow" "GPUTPCDecompressionKernels" LB simple) o2_gpu_add_kernel("GPUTPCCFCheckPadBaseline" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, fillIndexMap" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, fillFromDigits" "= TPCCLUSTERFINDER" LB single) -o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, findFragmentStart" "= TPCCLUSTERFINDER" LB single char setPositions) +o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, findFragmentStart" "= TPCCLUSTERFINDER" LB single int8_t setPositions) o2_gpu_add_kernel("GPUTPCCFPeakFinder" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFNoiseSuppression, noiseSuppression" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFNoiseSuppression, updatePeaks" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFDeconvolution" "= TPCCLUSTERFINDER" LB single) -o2_gpu_add_kernel("GPUTPCCFClusterizer" "= TPCCLUSTERFINDER" LB single char onlyMC) +o2_gpu_add_kernel("GPUTPCCFClusterizer" "= TPCCLUSTERFINDER" LB single int8_t onlyMC) o2_gpu_add_kernel("GPUTPCCFMCLabelFlattener, setRowOffsets" "= TPCCLUSTERFINDER" NO single) o2_gpu_add_kernel("GPUTPCCFMCLabelFlattener, flatten" "= TPCCLUSTERFINDER" NO single GPUTPCLinearLabels* out) -o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanStart" "= TPCCLUSTERFINDER" LB single int iBuf int stage) -o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanUp" "= TPCCLUSTERFINDER" LB single int iBuf int nElems) -o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanTop" "= TPCCLUSTERFINDER" LB single int iBuf int nElems) -o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanDown" "= TPCCLUSTERFINDER" LB single int iBuf "unsigned int" offset int nElems) -o2_gpu_add_kernel("GPUTPCCFStreamCompaction, compactDigits" "= TPCCLUSTERFINDER" LB single int iBuf int stage ChargePos* in ChargePos* out) -o2_gpu_add_kernel("GPUTPCCFDecodeZS" "= TPCCLUSTERFINDER" LB single int firstHBF) -o2_gpu_add_kernel("GPUTPCCFDecodeZSLink" "GPUTPCCFDecodeZS" LB single int firstHBF) -o2_gpu_add_kernel("GPUTPCCFDecodeZSDenseLink" "GPUTPCCFDecodeZS" LB single int firstHBF) +o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanStart" "= TPCCLUSTERFINDER" LB single int32_t iBuf int32_t stage) +o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanUp" "= TPCCLUSTERFINDER" LB single int32_t iBuf int32_t nElems) +o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanTop" "= TPCCLUSTERFINDER" LB single int32_t iBuf int32_t nElems) +o2_gpu_add_kernel("GPUTPCCFStreamCompaction, scanDown" "= TPCCLUSTERFINDER" LB single int32_t iBuf "uint32_t" offset int32_t nElems) +o2_gpu_add_kernel("GPUTPCCFStreamCompaction, compactDigits" "= TPCCLUSTERFINDER" LB single int32_t iBuf int32_t stage ChargePos* in ChargePos* out) +o2_gpu_add_kernel("GPUTPCCFDecodeZS" "= TPCCLUSTERFINDER" LB single int32_t firstHBF) +o2_gpu_add_kernel("GPUTPCCFDecodeZSLink" "GPUTPCCFDecodeZS" LB single int32_t firstHBF) +o2_gpu_add_kernel("GPUTPCCFDecodeZSDenseLink" "GPUTPCCFDecodeZS" LB single int32_t firstHBF) o2_gpu_add_kernel("GPUTPCCFGather" "=" LB single o2::tpc::ClusterNative* dest) o2_gpu_add_kernel("GPUTrackingRefitKernel, mode0asGPU" "= GLOBALREFIT " LB simple) o2_gpu_add_kernel("GPUTrackingRefitKernel, mode1asTrackParCov" "= GLOBALREFIT " LB simple) diff --git a/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.cxx b/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.cxx index 05e8d4af0b187..4cac2612e4cb2 100644 --- a/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.cxx +++ b/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.cxx @@ -99,34 +99,34 @@ void AliHLT3DTrackParam::TransportToDS(double Bz, double DS, double* T0) {0, 0, 0, 0, 0, 1, }}; // clang-format on - for (int i = 0; i < 6; i++) { + for (int32_t i = 0; i < 6; i++) { mParam[i] = T0[i]; - for (int j = 0; j < 6; j++) { + for (int32_t j = 0; j < 6; j++) { mParam[i] += mJ[i][j] * d[j]; } } double mA[6][6]; - for (int k = 0, i = 0; i < 6; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 6; i++) { + for (int32_t j = 0; j <= i; j++, k++) { mA[i][j] = mA[j][i] = fCov[k]; } } double mJC[6][6]; - for (int i = 0; i < 6; i++) { - for (int j = 0; j < 6; j++) { + for (int32_t i = 0; i < 6; i++) { + for (int32_t j = 0; j < 6; j++) { mJC[i][j] = 0; - for (int k = 0; k < 6; k++) { + for (int32_t k = 0; k < 6; k++) { mJC[i][j] += mJ[i][k] * mA[k][j]; } } } - for (int k = 0, i = 0; i < 6; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 6; i++) { + for (int32_t j = 0; j <= i; j++, k++) { fCov[k] = 0; - for (int l = 0; l < 6; l++) { + for (int32_t l = 0; l < 6; l++) { fCov[k] += mJC[i][l] * mJ[j][l]; } } @@ -139,7 +139,7 @@ void AliHLT3DTrackParam::InitializeCovarianceMatrix() { //* Initialization of covariance matrix - for (int i = 0; i < 21; i++) { + for (int32_t i = 0; i < 21; i++) { fCov[i] = 0; } fSignQ = 0; @@ -341,26 +341,26 @@ void AliHLT3DTrackParam::RotateCoordinateSystem(double alpha) // clang-format on double mA[6][6]; - for (int k = 0, i = 0; i < 6; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 6; i++) { + for (int32_t j = 0; j <= i; j++, k++) { mA[i][j] = mA[j][i] = fCov[k]; } } double mJC[6][6]; - for (int i = 0; i < 6; i++) { - for (int j = 0; j < 6; j++) { + for (int32_t i = 0; i < 6; i++) { + for (int32_t j = 0; j < 6; j++) { mJC[i][j] = 0; - for (int k = 0; k < 6; k++) { + for (int32_t k = 0; k < 6; k++) { mJC[i][j] += mJ[i][k] * mA[k][j]; } } } - for (int k = 0, i = 0; i < 6; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 6; i++) { + for (int32_t j = 0; j <= i; j++, k++) { fCov[k] = 0; - for (int l = 0; l < 6; l++) { + for (int32_t l = 0; l < 6; l++) { fCov[k] += mJC[i][l] * mJ[j][l]; } } @@ -398,26 +398,26 @@ void AliHLT3DTrackParam::Get5Parameters(double alpha, double T[6], double C[15]) // clang-format on double mA[6][6]; - for (int k = 0, i = 0; i < 6; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 6; i++) { + for (int32_t j = 0; j <= i; j++, k++) { mA[i][j] = mA[j][i] = t.fCov[k]; } } double mJC[5][6]; - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 6; j++) { + for (int32_t i = 0; i < 5; i++) { + for (int32_t j = 0; j < 6; j++) { mJC[i][j] = 0; - for (int k = 0; k < 6; k++) { + for (int32_t k = 0; k < 6; k++) { mJC[i][j] += mJ[i][k] * mA[k][j]; } } } - for (int k = 0, i = 0; i < 5; i++) { - for (int j = 0; j <= i; j++, k++) { + for (int32_t k = 0, i = 0; i < 5; i++) { + for (int32_t j = 0; j <= i; j++, k++) { C[k] = 0; - for (int l = 0; l < 6; l++) { + for (int32_t l = 0; l < 6; l++) { C[k] += mJC[i][l] * mJ[j][l]; } } diff --git a/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.h b/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.h index f9cc54f95a2e8..a762f22eb46dd 100644 --- a/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.h +++ b/GPU/GPUTracking/oldFiles/AliHLT3DTrackParam.h @@ -48,12 +48,12 @@ class AliHLT3DTrackParam : public TObject double GetPy() const { return mParam[4]; } double GetPz() const { return mParam[5]; } double GetChi2() const { return fChi2; } - int GetNDF() const { return fNDF; } - int GetCharge() const { return fSignQ; } + int32_t GetNDF() const { return fNDF; } + int32_t GetCharge() const { return fSignQ; } - double GetParameter(int i) const { return mParam[i]; } - double GetCovariance(int i) const { return fCov[i]; } - double GetCovariance(int i, int j) const { return fCov[(j <= i) ? i * (i + 1) / 2 + j : j * (j + 1) / 2 + i]; } + double GetParameter(int32_t i) const { return mParam[i]; } + double GetCovariance(int32_t i) const { return fCov[i]; } + double GetCovariance(int32_t i, int32_t j) const { return fCov[(j <= i) ? i * (i + 1) / 2 + j : j * (j + 1) / 2 + i]; } //* //* Accessors @@ -68,8 +68,8 @@ class AliHLT3DTrackParam : public TObject double Py() const { return mParam[4]; } double Pz() const { return mParam[5]; } double Chi2() const { return fChi2; } - int NDF() const { return fNDF; } - int Charge() const { return fSignQ; } + int32_t NDF() const { return fNDF; } + int32_t Charge() const { return fSignQ; } //* Accessors with calculations( &value, &estimated sigma ) //* error flag returned (0 means no error during calculations) @@ -78,8 +78,8 @@ class AliHLT3DTrackParam : public TObject //* MODIFIERS //* - void SetParam(int i, double v) { mParam[i] = v; } - void SetCov(int i, double v) { fCov[i] = v; } + void SetParam(int32_t i, double v) { mParam[i] = v; } + void SetCov(int32_t i, double v) { fCov[i] = v; } void SetX(double v) { mParam[0] = v; } void SetY(double v) { mParam[1] = v; } void SetZ(double v) { mParam[2] = v; } @@ -87,8 +87,8 @@ class AliHLT3DTrackParam : public TObject void SetPy(double v) { mParam[4] = v; } void SetPz(double v) { mParam[5] = v; } void SetChi2(double v) { fChi2 = v; } - void SetNDF(int v) { fNDF = v; } - void SetCharge(int v) { fSignQ = v; } + void SetNDF(int32_t v) { fNDF = v; } + void SetCharge(int32_t v) { fSignQ = v; } //* //* UTILITIES @@ -128,8 +128,8 @@ class AliHLT3DTrackParam : public TObject double mParam[6]; // Parameters ( x, y, z, px, py, pz ): 3-position and 3-momentum double fCov[21]; // Covariance matrix double fChi2; // Chi^2 - int fNDF; // Number of Degrees of Freedom - int fSignQ; // Charge + int32_t fNDF; // Number of Degrees of Freedom + int32_t fSignQ; // Charge ClassDef(AliHLT3DTrackParam, 1); }; diff --git a/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.cxx b/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.cxx index be329aafc8bd4..efecae4fc9b47 100644 --- a/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.cxx +++ b/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.cxx @@ -40,7 +40,7 @@ GPUTPCGMOfflineFitter::GPUTPCGMOfflineFitter() : fCAParam() {} GPUTPCGMOfflineFitter::~GPUTPCGMOfflineFitter() {} -void GPUTPCGMOfflineFitter::Initialize(const GPUParam& hltParam, Long_t TimeStamp, bool isMC) +void GPUTPCGMOfflineFitter::Initialize(const GPUParam& hltParam, long TimeStamp, bool isMC) { // @@ -80,7 +80,7 @@ void GPUTPCGMOfflineFitter::RefitTrack(GPUTPCGMMergedTrack& track, const GPUTPCG return; } - int nTrackHits = track.NClusters(); + int32_t nTrackHits = track.NClusters(); cout << "call FitOffline .. " << endl; bool ok = FitOffline(field, track, clusters + track.FirstClusterRef(), nTrackHits); cout << ".. end of call FitOffline " << endl; @@ -98,7 +98,7 @@ void GPUTPCGMOfflineFitter::RefitTrack(GPUTPCGMMergedTrack& track, const GPUTPCG track.Alpha() = Alpha; { - int ind = track.FirstClusterRef(); + int32_t ind = track.FirstClusterRef(); float alphaa = fCAParam.Alpha(clusters[ind].slice); float xx = clusters[ind].fX; float yy = clusters[ind].fY; @@ -111,7 +111,7 @@ void GPUTPCGMOfflineFitter::RefitTrack(GPUTPCGMMergedTrack& track, const GPUTPCG } } -int GPUTPCGMOfflineFitter::CreateTPCclusterMI(const GPUTPCGMMergedTrackHit& h, AliTPCclusterMI& c) +int32_t GPUTPCGMOfflineFitter::CreateTPCclusterMI(const GPUTPCGMMergedTrackHit& h, AliTPCclusterMI& c) { // Create AliTPCclusterMI for the HLT hit @@ -127,15 +127,15 @@ int GPUTPCGMOfflineFitter::CreateTPCclusterMI(const GPUTPCGMMergedTrackHit& h, A c.SetX(h.fX); c.SetY(h.fY); c.SetZ(h.fZ); - int index = (((sector << 8) + row) << 16) + 0; + int32_t index = (((sector << 8) + row) << 16) + 0; return index; } -bool GPUTPCGMOfflineFitter::FitOffline(const GPUTPCGMPolynomialField* field, GPUTPCGMMergedTrack& gmtrack, GPUTPCGMMergedTrackHit* clusters, int& N) +bool GPUTPCGMOfflineFitter::FitOffline(const GPUTPCGMPolynomialField* field, GPUTPCGMMergedTrack& gmtrack, GPUTPCGMMergedTrackHit* clusters, int32_t& N) { const float maxSinPhi = GPUCA_MAX_SIN_PHI; - int maxN = N; + int32_t maxN = N; float covYYUpd = 0.; float lastUpdateX = -1.; @@ -157,14 +157,14 @@ bool GPUTPCGMOfflineFitter::FitOffline(const GPUTPCGMPolynomialField* field, GPU lastUpdateX = -1; // find last leg - int ihitStart = 0; - for (int ihit = 0; ihit < maxN; ihit++) { + int32_t ihitStart = 0; + for (int32_t ihit = 0; ihit < maxN; ihit++) { if (clusters[ihit].leg != clusters[ihitStart].leg) { ihitStart = ihit; } } - for (int ihit = ihitStart; ihit < maxN; ihit++) { + for (int32_t ihit = ihitStart; ihit < maxN; ihit++) { if (clusters[ihit].fState < 0) { continue; // hit is excluded from fit } @@ -215,14 +215,14 @@ bool GPUTPCGMOfflineFitter::FitOffline(const GPUTPCGMPolynomialField* field, GPU seed.SetClusterPointer(iRow, &cluster); seed.SetCurrentClusterIndex1(tpcindex); - int retVal; + int32_t retVal; float threshold = 3. + (lastUpdateX >= 0 ? (fabsf(seed.GetX() - lastUpdateX) / 2) : 0.); if (N > 2 && (fabsf(yy - seed.GetY()) > threshold || fabsf(zz - seed.GetZ()) > threshold)) { retVal = 2; } else { Int_t err = !(AliTPCtracker::FollowToNext(seed, iRow)); - const int err2 = N > 0 && CAMath::Abs(seed.GetSnp()) >= maxSinForUpdate; + const int32_t err2 = N > 0 && CAMath::Abs(seed.GetSnp()) >= maxSinForUpdate; if (err || err2) { if (markNonFittedClusters) { if (N > 0 && (fabsf(yy - seed.GetY()) > 3 || fabsf(zz - seed.GetZ()) > 3)) { @@ -275,9 +275,9 @@ bool GPUTPCGMOfflineFitter::FitOffline(const GPUTPCGMPolynomialField* field, GPU prop.SetMaxSinPhi(maxSinPhi); prop.SetToyMCEventsFlag(fCAParam.ToyMCEventsFlag()); - for (int k = 0; k < 3; k++) // max 3 attempts + for (int32_t k = 0; k < 3; k++) // max 3 attempts { - int err = prop.PropagateToXAlpha(fCAParam.GetTrackReferenceX(), Alpha, 0); + int32_t err = prop.PropagateToXAlpha(fCAParam.GetTrackReferenceX(), Alpha, 0); t.ConstrainSinPhi(); if (fabsf(t.GetY()) <= t.GetX() * tan(kSectAngle / 2.f)) { break; diff --git a/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.h b/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.h index b6e5056a24389..8daf8102a8d20 100644 --- a/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.h +++ b/GPU/GPUTracking/oldFiles/GPUTPCGMOfflineFitter.h @@ -31,13 +31,13 @@ class GPUTPCGMOfflineFitter : public AliTPCtracker GPUTPCGMOfflineFitter(); ~GPUTPCGMOfflineFitter(); - void Initialize(const GPUParam& hltParam, Long_t TimeStamp, bool isMC); + void Initialize(const GPUParam& hltParam, long TimeStamp, bool isMC); void RefitTrack(GPUTPCGMMergedTrack& track, const GPUTPCGMPolynomialField* field, GPUTPCGMMergedTrackHit* clusters); - int CreateTPCclusterMI(const GPUTPCGMMergedTrackHit& h, AliTPCclusterMI& c); + int32_t CreateTPCclusterMI(const GPUTPCGMMergedTrackHit& h, AliTPCclusterMI& c); - bool FitOffline(const GPUTPCGMPolynomialField* field, GPUTPCGMMergedTrack& gmtrack, GPUTPCGMMergedTrackHit* clusters, int& N); + bool FitOffline(const GPUTPCGMPolynomialField* field, GPUTPCGMMergedTrack& gmtrack, GPUTPCGMMergedTrackHit* clusters, int32_t& N); private: GPUParam fCAParam; diff --git a/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h b/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h index b860714d5ca18..be283433061e3 100644 --- a/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h +++ b/GPU/GPUTracking/oldFiles/GPUTPCMCPoint.h @@ -33,8 +33,8 @@ class GPUTPCMCPoint float Sy() const { return fSy; } float Sz() const { return fSz; } float Time() const { return fTime; } - int ISlice() const { return mISlice; } - int TrackID() const { return fTrackID; } + int32_t ISlice() const { return mISlice; } + int32_t TrackID() const { return fTrackID; } void SetX(float v) { fX = v; } void SetY(float v) { fY = v; } @@ -43,8 +43,8 @@ class GPUTPCMCPoint void SetSy(float v) { fSy = v; } void SetSz(float v) { fSz = v; } void SetTime(float v) { fTime = v; } - void SetISlice(int v) { mISlice = v; } - void SetTrackID(int v) { fTrackID = v; } + void SetISlice(int32_t v) { mISlice = v; } + void SetTrackID(int32_t v) { fTrackID = v; } static bool Compare(const GPUTPCMCPoint& p1, const GPUTPCMCPoint& p2) { @@ -57,7 +57,7 @@ class GPUTPCMCPoint return (p1.Sx() < p2.Sx()); } - static bool CompareSlice(const GPUTPCMCPoint& p, int slice) { return (p.ISlice() < slice); } + static bool CompareSlice(const GPUTPCMCPoint& p, int32_t slice) { return (p.ISlice() < slice); } static bool CompareX(const GPUTPCMCPoint& p, float X) { return (p.Sx() < X); } @@ -69,8 +69,8 @@ class GPUTPCMCPoint float fSy; //* slice Y position float fSz; //* slice Z position float fTime; //* time - int mISlice; //* slice number - int fTrackID; //* mc track number + int32_t mISlice; //* slice number + int32_t fTrackID; //* mc track number }; #endif // GPUTPCMCPOINT_H diff --git a/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx index 2a5736ec6f7cc..12a52e0e04b4f 100644 --- a/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx +++ b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.cxx @@ -20,7 +20,7 @@ GPUTPCMCTrack::GPUTPCMCTrack() : fPDG(0), fP(0), fPt(0), mNHits(0), fNMCPoints(0), fFirstMCPointID(0), fNReconstructed(0), fSet(0), fNTurns(0) { //* Default constructor - for (int i = 0; i < 7; i++) { + for (int32_t i = 0; i < 7; i++) { fPar[i] = 0; fTPCPar[i] = 0; } @@ -30,10 +30,10 @@ GPUTPCMCTrack::GPUTPCMCTrack(const TParticle* part) : fPDG(0), fP(0), fPt(0), mN { //* Constructor from TParticle - for (int i = 0; i < 7; i++) { + for (int32_t i = 0; i < 7; i++) { fPar[i] = 0; } - for (int i = 0; i < 7; i++) { + for (int32_t i = 0; i < 7; i++) { fTPCPar[i] = 0; } fP = 0; @@ -68,7 +68,7 @@ void GPUTPCMCTrack::SetTPCPar(float X, float Y, float Z, float Px, float Py, flo { //* Set parameters at TPC entrance - for (int i = 0; i < 7; i++) { + for (int32_t i = 0; i < 7; i++) { fTPCPar[i] = 0; } diff --git a/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h index 7cd39b242de40..9f2e4da6ada54 100644 --- a/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h +++ b/GPU/GPUTracking/oldFiles/GPUTPCMCTrack.h @@ -31,42 +31,42 @@ class GPUTPCMCTrack void SetTPCPar(float X, float Y, float Z, float Px, float Py, float Pz); - int PDG() const { return fPDG; } + int32_t PDG() const { return fPDG; } const double* Par() const { return fPar; } const double* TPCPar() const { return fTPCPar; } double P() const { return fP; } double Pt() const { return fPt; } - int NHits() const { return mNHits; } - int NMCPoints() const { return fNMCPoints; } - int FirstMCPointID() const { return fFirstMCPointID; } - int NReconstructed() const { return fNReconstructed; } - int Set() const { return fSet; } - int NTurns() const { return fNTurns; } + int32_t NHits() const { return mNHits; } + int32_t NMCPoints() const { return fNMCPoints; } + int32_t FirstMCPointID() const { return fFirstMCPointID; } + int32_t NReconstructed() const { return fNReconstructed; } + int32_t Set() const { return fSet; } + int32_t NTurns() const { return fNTurns; } void SetP(float v) { fP = v; } void SetPt(float v) { fPt = v; } - void SetPDG(int v) { fPDG = v; } - void SetPar(int i, double v) { fPar[i] = v; } - void SetTPCPar(int i, double v) { fTPCPar[i] = v; } - void SetNHits(int v) { mNHits = v; } - void SetNMCPoints(int v) { fNMCPoints = v; } - void SetFirstMCPointID(int v) { fFirstMCPointID = v; } - void SetNReconstructed(int v) { fNReconstructed = v; } - void SetSet(int v) { fSet = v; } - void SetNTurns(int v) { fNTurns = v; } + void SetPDG(int32_t v) { fPDG = v; } + void SetPar(int32_t i, double v) { fPar[i] = v; } + void SetTPCPar(int32_t i, double v) { fTPCPar[i] = v; } + void SetNHits(int32_t v) { mNHits = v; } + void SetNMCPoints(int32_t v) { fNMCPoints = v; } + void SetFirstMCPointID(int32_t v) { fFirstMCPointID = v; } + void SetNReconstructed(int32_t v) { fNReconstructed = v; } + void SetSet(int32_t v) { fSet = v; } + void SetNTurns(int32_t v) { fNTurns = v; } protected: - int fPDG; //* particle pdg code + int32_t fPDG; //* particle pdg code double fPar[7]; //* x,y,z,ex,ey,ez,q/p double fTPCPar[7]; //* x,y,z,ex,ey,ez,q/p at TPC entrance (x=y=0 means no information) double fP, fPt; //* momentum and transverse momentum - int mNHits; //* N TPC clusters - int fNMCPoints; //* N MC points - int fFirstMCPointID; //* id of the first MC point in the points array - int fNReconstructed; //* how many times is reconstructed - int fSet; //* set of tracks 0-OutSet, 1-ExtraSet, 2-RefSet - int fNTurns; //* N of turns in the current sector + int32_t mNHits; //* N TPC clusters + int32_t fNMCPoints; //* N MC points + int32_t fFirstMCPointID; //* id of the first MC point in the points array + int32_t fNReconstructed; //* how many times is reconstructed + int32_t fSet; //* set of tracks 0-OutSet, 1-ExtraSet, 2-RefSet + int32_t fNTurns; //* N of turns in the current sector }; #endif // GPUTPCMCTrack diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index dce1104303668..7ef907838ccf4 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -82,9 +82,9 @@ using namespace GPUCA_NAMESPACE::gpu; #ifdef GPUCA_MERGER_BY_MC_LABEL #define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() \ if (!unattached && mTrackMCLabels[id].isValid()) { \ - int mcLabel = mTrackMCLabels[id].getTrackID(); \ - int mcEvent = mTrackMCLabels[id].getEventID(); \ - int mcSource = mTrackMCLabels[id].getSourceID(); \ + int32_t mcLabel = mTrackMCLabels[id].getTrackID(); \ + int32_t mcEvent = mTrackMCLabels[id].getEventID(); \ + int32_t mcSource = mTrackMCLabels[id].getSourceID(); \ if (mTrackMCLabelsReverse[mMCEventOffset[mcSource] + mcEvent][mcLabel] != id) { \ attach &= (~gputpcgmmergertypes::attachGoodLeg); \ } \ @@ -99,7 +99,7 @@ using namespace GPUCA_NAMESPACE::gpu; bool lowPt = false; \ bool mev200 = false; \ bool mergedLooper = false; \ - int id = attach & gputpcgmmergertypes::attachTrackMask; \ + int32_t id = attach & gputpcgmmergertypes::attachTrackMask; \ if (!unattached) { \ qpt = fabsf(mTracking->mIOPtrs.mergedTracks[id].GetParam().GetQPt()); \ lowPt = qpt * mTracking->GetParam().qptB5Scaler > mTracking->GetParam().rec.tpc.rejectQPtB5; \ @@ -161,7 +161,7 @@ static constexpr float FINDABLE_WEIGHT_CLS = 70; static constexpr bool CLUST_HIST_INT_SUM = false; -static constexpr const int COLORCOUNT = 12; +static constexpr const int32_t COLORCOUNT = 12; static const constexpr char* EFF_TYPES[4] = {"Rec", "Clone", "Fake", "All"}; static const constexpr char* FINDABLE_NAMES[2] = {"", "Findable"}; @@ -182,23 +182,23 @@ static const constexpr char* CLUSTER_NAMES[GPUQA::N_CLS_HIST] = {"Correctly atta static const constexpr char* CLUSTER_TITLES[GPUQA::N_CLS_TYPE] = {"Clusters Pt Distribution / Attachment", "Clusters Pt Distribution / Attachment (relative to all clusters)", "Clusters Pt Distribution / Attachment (integrated)"}; static const constexpr char* CLUSTER_NAMES_SHORT[GPUQA::N_CLS_HIST] = {"Attached", "Fake", "AttachAdjacent", "FakeAdjacent", "FoundTracks", "Physics", "Protected", "All"}; static const constexpr char* CLUSTER_TYPES[GPUQA::N_CLS_TYPE] = {"", "Ratio", "Integral"}; -static const constexpr int COLORS_HEX[COLORCOUNT] = {0xB03030, 0x00A000, 0x0000C0, 0x9400D3, 0x19BBBF, 0xF25900, 0x7F7F7F, 0xFFD700, 0x07F707, 0x07F7F7, 0xF08080, 0x000000}; +static const constexpr int32_t COLORS_HEX[COLORCOUNT] = {0xB03030, 0x00A000, 0x0000C0, 0x9400D3, 0x19BBBF, 0xF25900, 0x7F7F7F, 0xFFD700, 0x07F707, 0x07F7F7, 0xF08080, 0x000000}; -static const constexpr int CONFIG_DASHED_MARKERS = 0; +static const constexpr int32_t CONFIG_DASHED_MARKERS = 0; static const constexpr float AXES_MIN[5] = {-Y_MAX, -Z_MAX, 0.f, -ETA_MAX, PT_MIN}; static const constexpr float AXES_MAX[5] = {Y_MAX, Z_MAX, 2.f * M_PI, ETA_MAX, PT_MAX}; -static const constexpr int AXIS_BINS[5] = {51, 51, 144, 31, 50}; -static const constexpr int RES_AXIS_BINS[] = {1017, 113}; // Consecutive bin sizes, histograms are binned down until the maximum entry is 50, each bin size should evenly divide its predecessor. +static const constexpr int32_t AXIS_BINS[5] = {51, 51, 144, 31, 50}; +static const constexpr int32_t RES_AXIS_BINS[] = {1017, 113}; // Consecutive bin sizes, histograms are binned down until the maximum entry is 50, each bin size should evenly divide its predecessor. static const constexpr float RES_AXES[5] = {1., 1., 0.03, 0.03, 1.0}; static const constexpr float RES_AXES_NATIVE[5] = {1., 1., 0.1, 0.1, 5.0}; static const constexpr float PULL_AXIS = 10.f; std::vector GPUQA::mColors; -int GPUQA::initColors() +int32_t GPUQA::initColors() { mColors.reserve(COLORCOUNT); - for (int i = 0; i < COLORCOUNT; i++) { + for (int32_t i = 0; i < COLORCOUNT; i++) { float f1 = (float)((COLORS_HEX[i] >> 16) & 0xFF) / (float)0xFF; float f2 = (float)((COLORS_HEX[i] >> 8) & 0xFF) / (float)0xFF; float f3 = (float)((COLORS_HEX[i] >> 0) & 0xFF) / (float)0xFF; @@ -210,57 +210,57 @@ static constexpr Color_t defaultColorNums[COLORCOUNT] = {kRed, kBlue, kGreen, kM #define TRACK_EXPECTED_REFERENCE_X_DEFAULT 81 #ifdef GPUCA_TPC_GEOMETRY_O2 -static inline int GPUQA_O2_ConvertFakeLabel(int label) { return label >= 0x7FFFFFFE ? -1 : label; } -inline unsigned int GPUQA::GetNMCCollissions() const { return mMCInfosCol.size(); } -inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mMCInfosCol[iCol].num; } -inline unsigned int GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].num; } -inline unsigned int GPUQA::GetNMCLabels() const { return mClNative->clustersMCTruth ? mClNative->clustersMCTruth->getIndexedSize() : 0; } -inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mMCInfos[mMCInfosCol[iCol].first + iTrk]; } +static inline int32_t GPUQA_O2_ConvertFakeLabel(int32_t label) { return label >= 0x7FFFFFFE ? -1 : label; } +inline uint32_t GPUQA::GetNMCCollissions() const { return mMCInfosCol.size(); } +inline uint32_t GPUQA::GetNMCTracks(int32_t iCol) const { return mMCInfosCol[iCol].num; } +inline uint32_t GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].num; } +inline uint32_t GPUQA::GetNMCLabels() const { return mClNative->clustersMCTruth ? mClNative->clustersMCTruth->getIndexedSize() : 0; } +inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(uint32_t iTrk, uint32_t iCol) { return mMCInfos[mMCInfosCol[iCol].first + iTrk]; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return mMCInfos[mMCInfosCol[mMCEventOffset[label.getSourceID()] + label.getEventID()].first + label.getTrackID()]; } -inline GPUQA::mcLabels_t GPUQA::GetMCLabel(unsigned int i) { return mClNative->clustersMCTruth->getLabels(i); } -inline int GPUQA::GetMCLabelNID(const mcLabels_t& label) { return label.size(); } -inline int GPUQA::GetMCLabelNID(unsigned int i) { return mClNative->clustersMCTruth->getLabels(i).size(); } -inline GPUQA::mcLabel_t GPUQA::GetMCLabel(unsigned int i, unsigned int j) { return mClNative->clustersMCTruth->getLabels(i)[j]; } -inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(mClNative->clustersMCTruth->getLabels(i)[j].getTrackID()); } -inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return GPUQA_O2_ConvertFakeLabel(label[j].getTrackID()); } -inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return GPUQA_O2_ConvertFakeLabel(label.getTrackID()); } -inline unsigned int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mMCEventOffset[mClNative->clustersMCTruth->getLabels(i)[j].getSourceID()] + mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } +inline GPUQA::mcLabels_t GPUQA::GetMCLabel(uint32_t i) { return mClNative->clustersMCTruth->getLabels(i); } +inline int32_t GPUQA::GetMCLabelNID(const mcLabels_t& label) { return label.size(); } +inline int32_t GPUQA::GetMCLabelNID(uint32_t i) { return mClNative->clustersMCTruth->getLabels(i).size(); } +inline GPUQA::mcLabel_t GPUQA::GetMCLabel(uint32_t i, uint32_t j) { return mClNative->clustersMCTruth->getLabels(i)[j]; } +inline int32_t GPUQA::GetMCLabelID(uint32_t i, uint32_t j) { return GPUQA_O2_ConvertFakeLabel(mClNative->clustersMCTruth->getLabels(i)[j].getTrackID()); } +inline int32_t GPUQA::GetMCLabelID(const mcLabels_t& label, uint32_t j) { return GPUQA_O2_ConvertFakeLabel(label[j].getTrackID()); } +inline int32_t GPUQA::GetMCLabelID(const mcLabel_t& label) { return GPUQA_O2_ConvertFakeLabel(label.getTrackID()); } +inline uint32_t GPUQA::GetMCLabelCol(uint32_t i, uint32_t j) { return mMCEventOffset[mClNative->clustersMCTruth->getLabels(i)[j].getSourceID()] + mClNative->clustersMCTruth->getLabels(i)[j].getEventID(); } inline const auto& GPUQA::GetClusterLabels() { return mClNative->clustersMCTruth; } -inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } -inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return 1; } +inline float GPUQA::GetMCLabelWeight(uint32_t i, uint32_t j) { return 1; } +inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, uint32_t j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return 1; } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && mClNative && mClNative->clustersMCTruth && mMCInfos.size(); } -unsigned int GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return !label.isValid() ? 0 : (mMCEventOffset[label.getSourceID()] + label.getEventID()); } -GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? MCCompLabel() : mTrackMCLabels[trackId]; } +uint32_t GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return !label.isValid() ? 0 : (mMCEventOffset[label.getSourceID()] + label.getEventID()); } +GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(uint32_t trackId) const { return trackId >= mTrackMCLabels.size() ? MCCompLabel() : mTrackMCLabels[trackId]; } #define TRACK_EXPECTED_REFERENCE_X 78 #else inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) {} inline bool GPUQA::mcLabelI_t::operator==(const GPUQA::mcLabel_t& l) { return AbsLabelID(track) == l.fMCID; } -inline unsigned int GPUQA::GetNMCCollissions() const { return 1; } -inline unsigned int GPUQA::GetNMCTracks(int iCol) const { return mTracking->mIOPtrs.nMCInfosTPC; } -inline unsigned int GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mTracking->mIOPtrs.nMCInfosTPC; } -inline unsigned int GPUQA::GetNMCLabels() const { return mTracking->mIOPtrs.nMCLabelsTPC; } -inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(unsigned int iTrk, unsigned int iCol) { return mTracking->mIOPtrs.mcInfosTPC[AbsLabelID(iTrk)]; } +inline uint32_t GPUQA::GetNMCCollissions() const { return 1; } +inline uint32_t GPUQA::GetNMCTracks(int32_t iCol) const { return mTracking->mIOPtrs.nMCInfosTPC; } +inline uint32_t GPUQA::GetNMCTracks(const mcLabelI_t& label) const { return mTracking->mIOPtrs.nMCInfosTPC; } +inline uint32_t GPUQA::GetNMCLabels() const { return mTracking->mIOPtrs.nMCLabelsTPC; } +inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(uint32_t iTrk, uint32_t iCol) { return mTracking->mIOPtrs.mcInfosTPC[AbsLabelID(iTrk)]; } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabel_t& label) { return GetMCTrack(label.fMCID, 0); } inline const GPUQA::mcInfo_t& GPUQA::GetMCTrack(const mcLabelI_t& label) { return GetMCTrack(label.track, 0); } -inline const GPUQA::mcLabels_t& GPUQA::GetMCLabel(unsigned int i) { return mTracking->mIOPtrs.mcLabelsTPC[i]; } -inline const GPUQA::mcLabel_t& GPUQA::GetMCLabel(unsigned int i, unsigned int j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j]; } -inline int GPUQA::GetMCLabelNID(const mcLabels_t& label) { return 3; } -inline int GPUQA::GetMCLabelNID(unsigned int i) { return 3; } -inline int GPUQA::GetMCLabelID(unsigned int i, unsigned int j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fMCID; } -inline int GPUQA::GetMCLabelID(const mcLabels_t& label, unsigned int j) { return label.fClusterID[j].fMCID; } -inline int GPUQA::GetMCLabelID(const mcLabel_t& label) { return label.fMCID; } -inline unsigned int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return 0; } +inline const GPUQA::mcLabels_t& GPUQA::GetMCLabel(uint32_t i) { return mTracking->mIOPtrs.mcLabelsTPC[i]; } +inline const GPUQA::mcLabel_t& GPUQA::GetMCLabel(uint32_t i, uint32_t j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j]; } +inline int32_t GPUQA::GetMCLabelNID(const mcLabels_t& label) { return 3; } +inline int32_t GPUQA::GetMCLabelNID(uint32_t i) { return 3; } +inline int32_t GPUQA::GetMCLabelID(uint32_t i, uint32_t j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fMCID; } +inline int32_t GPUQA::GetMCLabelID(const mcLabels_t& label, uint32_t j) { return label.fClusterID[j].fMCID; } +inline int32_t GPUQA::GetMCLabelID(const mcLabel_t& label) { return label.fMCID; } +inline uint32_t GPUQA::GetMCLabelCol(uint32_t i, uint32_t j) { return 0; } inline const auto& GPUQA::GetClusterLabels() { return mTracking->mIOPtrs.mcLabelsTPC; } -inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fWeight; } -inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return label.fClusterID[j].fWeight; } +inline float GPUQA::GetMCLabelWeight(uint32_t i, uint32_t j) { return mTracking->mIOPtrs.mcLabelsTPC[i].fClusterID[j].fWeight; } +inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, uint32_t j) { return label.fClusterID[j].fWeight; } inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return label.fWeight; } -inline int GPUQA::FakeLabelID(int id) { return id < 0 ? id : (-2 - id); } -inline int GPUQA::AbsLabelID(int id) { return id >= 0 ? id : (-id - 2); } +inline int32_t GPUQA::FakeLabelID(int32_t id) { return id < 0 ? id : (-2 - id); } +inline int32_t GPUQA::AbsLabelID(int32_t id) { return id >= 0 ? id : (-id - 2); } inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && GetNMCLabels() && GetNMCTracks(0); } -unsigned int GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return 0; } -GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(unsigned int trackId) const { return trackId >= mTrackMCLabels.size() ? mcLabelI_t() : mTrackMCLabels[trackId]; } +uint32_t GPUQA::GetMCLabelCol(const mcLabel_t& label) const { return 0; } +GPUQA::mcLabelI_t GPUQA::GetMCTrackLabel(uint32_t trackId) const { return trackId >= mTrackMCLabels.size() ? mcLabelI_t() : mTrackMCLabels[trackId]; } #define TRACK_EXPECTED_REFERENCE_X TRACK_EXPECTED_REFERENCE_X_DEFAULT #endif template @@ -350,7 +350,7 @@ GPUQA::~GPUQA() clearGarbagageCollector(); // Needed to guarantee correct order for ROOT ownership } -bool GPUQA::clusterRemovable(int attach, bool prot) const +bool GPUQA::clusterRemovable(int32_t attach, bool prot) const { CHECK_CLUSTER_STATE_NOCOUNT(); if (prot) { @@ -378,7 +378,7 @@ void GPUQA::SetLegend(TLegend* l) l->SetFillColor(0); } -double* GPUQA::CreateLogAxis(int nbins, float xmin, float xmax) +double* GPUQA::CreateLogAxis(int32_t nbins, float xmin, float xmax) { float logxmin = std::log10(xmin); float logxmax = std::log10(xmax); @@ -387,7 +387,7 @@ double* GPUQA::CreateLogAxis(int nbins, float xmin, float xmax) double* xbins = new double[nbins + 1]; xbins[0] = xmin; - for (int i = 1; i <= nbins; i++) { + for (int32_t i = 1; i <= nbins; i++) { xbins[i] = std::pow(10, logxmin + i * binwidth); } return xbins; @@ -426,21 +426,21 @@ void GPUQA::doPerfFigure(float x, float y, float size) t->DrawLatex(x, y - 0.01 - size, str_perf_figure_2); } -void GPUQA::SetMCTrackRange(int min, int max) +void GPUQA::SetMCTrackRange(int32_t min, int32_t max) { mMCTrackMin = min; mMCTrackMax = max; } -int GPUQA::InitQACreateHistograms() +int32_t GPUQA::InitQACreateHistograms() { char name[2048], fname[1024]; if (mQATasks & taskTrackingEff) { // Create Efficiency Histograms - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 2; j++) { - for (int k = 0; k < 2; k++) { - for (int l = 0; l < 5; l++) { + for (int32_t i = 0; i < 4; i++) { + for (int32_t j = 0; j < 2; j++) { + for (int32_t k = 0; k < 2; k++) { + for (int32_t l = 0; l < 5; l++) { snprintf(name, 2048, "%s%s%s%sVs%s", "tracks", EFF_TYPES[i], FINDABLE_NAMES[j], PRIM_NAMES[k], VSPARAMETER_NAMES[l]); if (l == 4) { std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], k == 0 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4])}; @@ -461,8 +461,8 @@ int GPUQA::InitQACreateHistograms() // Create Resolution Histograms if (mQATasks & taskTrackingRes) { - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 5; j++) { + for (int32_t i = 0; i < 5; i++) { + for (int32_t j = 0; j < 5; j++) { snprintf(name, 2048, "rms_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); snprintf(fname, 1024, "mean_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); if (j == 4) { @@ -475,7 +475,7 @@ int GPUQA::InitQACreateHistograms() } snprintf(name, 2048, "res_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); const float* axis = mConfig.nativeFitResolutions ? RES_AXES_NATIVE : RES_AXES; - const int nbins = i == 4 && mConfig.nativeFitResolutions ? (10 * RES_AXIS_BINS[0]) : RES_AXIS_BINS[0]; + const int32_t nbins = i == 4 && mConfig.nativeFitResolutions ? (10 * RES_AXIS_BINS[0]) : RES_AXIS_BINS[0]; if (j == 4) { std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], mConfig.resPrimaries == 1 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4])}; createHist(mRes2[i][j], name, name, nbins, -axis[i], axis[i], AXIS_BINS[j], binsPt.get()); @@ -488,8 +488,8 @@ int GPUQA::InitQACreateHistograms() // Create Pull Histograms if (mQATasks & taskTrackingResPull) { - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 5; j++) { + for (int32_t i = 0; i < 5; i++) { + for (int32_t j = 0; j < 5; j++) { snprintf(name, 2048, "pull_rms_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); snprintf(fname, 1024, "pull_mean_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); if (j == 4) { @@ -513,9 +513,9 @@ int GPUQA::InitQACreateHistograms() // Create Cluster Histograms if (mQATasks & taskClusterAttach) { - for (int i = 0; i < N_CLS_TYPE * N_CLS_HIST - 1; i++) { - int ioffset = i >= (2 * N_CLS_HIST - 1) ? (2 * N_CLS_HIST - 1) : i >= N_CLS_HIST ? N_CLS_HIST : 0; - int itype = i >= (2 * N_CLS_HIST - 1) ? 2 : i >= N_CLS_HIST ? 1 : 0; + for (int32_t i = 0; i < N_CLS_TYPE * N_CLS_HIST - 1; i++) { + int32_t ioffset = i >= (2 * N_CLS_HIST - 1) ? (2 * N_CLS_HIST - 1) : i >= N_CLS_HIST ? N_CLS_HIST : 0; + int32_t itype = i >= (2 * N_CLS_HIST - 1) ? 2 : i >= N_CLS_HIST ? 1 : 0; snprintf(name, 2048, "clusters%s%s", CLUSTER_NAMES_SHORT[i - ioffset], CLUSTER_TYPES[itype]); std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], PT_MIN_CLUST, PT_MAX)}; createHist(mClusters[i], name, name, AXIS_BINS[4], binsPt.get()); @@ -533,28 +533,28 @@ int GPUQA::InitQACreateHistograms() } if ((mQATasks & taskClusterCounts) && mConfig.clusterRejectionHistograms) { - int num = DoClusterCounts(nullptr, 2); + int32_t num = DoClusterCounts(nullptr, 2); mHistClusterCount.resize(num); DoClusterCounts(nullptr, 1); } - for (unsigned int i = 0; i < mHist1D->size(); i++) { + for (uint32_t i = 0; i < mHist1D->size(); i++) { *mHist1D_pos[i] = &(*mHist1D)[i]; } - for (unsigned int i = 0; i < mHist2D->size(); i++) { + for (uint32_t i = 0; i < mHist2D->size(); i++) { *mHist2D_pos[i] = &(*mHist2D)[i]; } - for (unsigned int i = 0; i < mHist1Dd->size(); i++) { + for (uint32_t i = 0; i < mHist1Dd->size(); i++) { *mHist1Dd_pos[i] = &(*mHist1Dd)[i]; } - for (unsigned int i = 0; i < mHistGraph->size(); i++) { + for (uint32_t i = 0; i < mHistGraph->size(); i++) { *mHistGraph_pos[i] = &(*mHistGraph)[i]; } return 0; } -int GPUQA::loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3, std::vector& i4, int tasks) +int32_t GPUQA::loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3, std::vector& i4, int32_t tasks) { if (tasks == -1) { tasks = taskDefaultPostprocess; @@ -588,7 +588,7 @@ void GPUQA::DumpO2MCData(const char* filename) const if (fp == nullptr) { return; } - unsigned int n = mMCInfos.size(); + uint32_t n = mMCInfos.size(); fwrite(&n, sizeof(n), 1, fp); fwrite(mMCInfos.data(), sizeof(mMCInfos[0]), n, fp); n = mMCInfosCol.size(); @@ -600,14 +600,14 @@ void GPUQA::DumpO2MCData(const char* filename) const fclose(fp); } -int GPUQA::ReadO2MCData(const char* filename) +int32_t GPUQA::ReadO2MCData(const char* filename) { FILE* fp = fopen(filename, "rb"); if (fp == nullptr) { return 1; } - unsigned int n; - unsigned int x; + uint32_t n; + uint32_t x; if ((x = fread(&n, sizeof(n), 1, fp)) != 1) { fclose(fp); return 1; @@ -665,23 +665,23 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) static constexpr float PRIM_MAX_T = 0.01f; o2::steer::MCKinematicsReader mcReader("collisioncontext.root"); - std::vector refId; + std::vector refId; auto dc = o2::steer::DigitizationContext::loadFromFile("collisioncontext.root"); auto evrec = dc->getEventRecords(); - unsigned int nSimSources = mcReader.getNSources(); + uint32_t nSimSources = mcReader.getNSources(); mMCEventOffset.resize(nSimSources); - unsigned int nSimTotalEvents = 0; - unsigned int nSimTotalTracks = 0; - for (unsigned int i = 0; i < nSimSources; i++) { + uint32_t nSimTotalEvents = 0; + uint32_t nSimTotalTracks = 0; + for (uint32_t i = 0; i < nSimSources; i++) { mMCEventOffset[i] = nSimTotalEvents; nSimTotalEvents += mcReader.getNEvents(i); } mMCInfosCol.resize(nSimTotalEvents); - for (int iSim = 0; iSim < mcReader.getNSources(); iSim++) { - for (int i = 0; i < mcReader.getNEvents(iSim); i++) { + for (int32_t iSim = 0; iSim < mcReader.getNSources(); iSim++) { + for (int32_t i = 0; i < mcReader.getNEvents(iSim); i++) { auto ir = evrec[i]; auto ir0 = o2::raw::HBFUtils::Instance().getFirstIRofTF(ir); float timebin = (float)ir.differenceInBC(ir0) / o2::tpc::constants::LHCBCPERTIMEBIN; @@ -691,9 +691,9 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) refId.resize(tracks.size()); std::fill(refId.begin(), refId.end(), -1); - for (unsigned int j = 0; j < trackRefs.size(); j++) { + for (uint32_t j = 0; j < trackRefs.size(); j++) { if (trackRefs[j].getDetectorId() == o2::detectors::DetID::TPC) { - int trkId = trackRefs[j].getTrackID(); + int32_t trkId = trackRefs[j].getTrackID(); if (refId[trkId] == -1) { refId[trkId] = j; } @@ -702,7 +702,7 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) mMCInfosCol[mMCEventOffset[iSim] + i].first = mMCInfos.size(); mMCInfosCol[mMCEventOffset[iSim] + i].num = tracks.size(); mMCInfos.resize(mMCInfos.size() + tracks.size()); - for (unsigned int j = 0; j < tracks.size(); j++) { + for (uint32_t j = 0; j < tracks.size(); j++) { auto& info = mMCInfos[mMCInfosCol[mMCEventOffset[iSim] + i].first + j]; const auto& trk = tracks[j]; TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(trk.GetPdgCode()); @@ -727,7 +727,7 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) info.prim = trk.T() < PRIM_MAX_T; info.primDaughters = 0; if (trk.getFirstDaughterTrackId() != -1) { - for (int k = trk.getFirstDaughterTrackId(); k <= trk.getLastDaughterTrackId(); k++) { + for (int32_t k = trk.getFirstDaughterTrackId(); k <= trk.getLastDaughterTrackId(); k++) { if (tracks[k].T() < PRIM_MAX_T) { info.primDaughters = 1; break; @@ -763,7 +763,7 @@ void GPUQA::InitO2MCData(GPUTrackingInOutPointers* updateIOPtr) #endif } -int GPUQA::InitQA(int tasks) +int32_t GPUQA::InitQA(int32_t tasks) { if (mQAInitialized) { throw std::runtime_error("QA already initialized"); @@ -804,14 +804,14 @@ int GPUQA::InitQA(int tasks) #endif if (mConfig.matchMCLabels.size()) { - unsigned int nFiles = mConfig.matchMCLabels.size(); + uint32_t nFiles = mConfig.matchMCLabels.size(); std::vector> files; - std::vector>*> labelsBuffer(nFiles); - std::vector>*> effBuffer(nFiles); - for (unsigned int i = 0; i < nFiles; i++) { + std::vector>*> labelsBuffer(nFiles); + std::vector>*> effBuffer(nFiles); + for (uint32_t i = 0; i < nFiles; i++) { files.emplace_back(std::make_unique(mConfig.matchMCLabels[i].c_str())); - labelsBuffer[i] = (std::vector>*)files[i]->Get("mcLabelBuffer"); - effBuffer[i] = (std::vector>*)files[i]->Get("mcEffBuffer"); + labelsBuffer[i] = (std::vector>*)files[i]->Get("mcLabelBuffer"); + effBuffer[i] = (std::vector>*)files[i]->Get("mcEffBuffer"); if (labelsBuffer[i] == nullptr || effBuffer[i] == nullptr) { GPUError("Error opening / reading from labels file %u/%s: %p %p", i, mConfig.matchMCLabels[i].c_str(), (void*)labelsBuffer[i], (void*)effBuffer[i]); exit(1); @@ -820,11 +820,11 @@ int GPUQA::InitQA(int tasks) mGoodTracks.resize(labelsBuffer[0]->size()); mGoodHits.resize(labelsBuffer[0]->size()); - for (unsigned int iEvent = 0; iEvent < labelsBuffer[0]->size(); iEvent++) { + for (uint32_t iEvent = 0; iEvent < labelsBuffer[0]->size(); iEvent++) { std::vector labelsOK((*effBuffer[0])[iEvent].size()); - for (unsigned int k = 0; k < (*effBuffer[0])[iEvent].size(); k++) { + for (uint32_t k = 0; k < (*effBuffer[0])[iEvent].size(); k++) { labelsOK[k] = false; - for (unsigned int l = 0; l < nFiles; l++) { + for (uint32_t l = 0; l < nFiles; l++) { if ((*effBuffer[0])[iEvent][k] != (*effBuffer[l])[iEvent][k]) { labelsOK[k] = true; break; @@ -832,7 +832,7 @@ int GPUQA::InitQA(int tasks) } } mGoodTracks[iEvent].resize((*labelsBuffer[0])[iEvent].size()); - for (unsigned int k = 0; k < (*labelsBuffer[0])[iEvent].size(); k++) { + for (uint32_t k = 0; k < (*labelsBuffer[0])[iEvent].size(); k++) { if ((*labelsBuffer[0])[iEvent][k] == MC_LABEL_INVALID) { continue; } @@ -850,7 +850,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx throw std::runtime_error("QA not initialized"); } if (mTracking && mTracking->GetProcessingSettings().debugLevel >= 2) { - GPUInfo("Running QA - Mask %d, Efficiency %d, Resolution %d, Pulls %d, Cluster Attachment %d, Track Statistics %d, Cluster Counts %d", mQATasks, (int)(mQATasks & taskTrackingEff), (int)(mQATasks & taskTrackingRes), (int)(mQATasks & taskTrackingResPull), (int)(mQATasks & taskClusterAttach), (int)(mQATasks & taskTrackStatistics), (int)(mQATasks & taskClusterCounts)); + GPUInfo("Running QA - Mask %d, Efficiency %d, Resolution %d, Pulls %d, Cluster Attachment %d, Track Statistics %d, Cluster Counts %d", mQATasks, (int32_t)(mQATasks & taskTrackingEff), (int32_t)(mQATasks & taskTrackingRes), (int32_t)(mQATasks & taskTrackingResPull), (int32_t)(mQATasks & taskClusterAttach), (int32_t)(mQATasks & taskTrackStatistics), (int32_t)(mQATasks & taskClusterCounts)); } if (!clNative && mTracking) { clNative = mTracking->mIOPtrs.clustersNative; @@ -858,7 +858,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClNative = clNative; #ifdef GPUCA_TPC_GEOMETRY_O2 - unsigned int nSimEvents = GetNMCCollissions(); + uint32_t nSimEvents = GetNMCCollissions(); if (mTrackMCLabelsReverse.size() < nSimEvents) { mTrackMCLabelsReverse.resize(nSimEvents); } @@ -874,7 +874,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx #endif // Initialize Arrays - unsigned int nReconstructedTracks = 0; + uint32_t nReconstructedTracks = 0; if (tracksExternal) { #ifdef GPUCA_O2_LIB nReconstructedTracks = tracksExternal->size(); @@ -883,7 +883,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx nReconstructedTracks = mTracking->mIOPtrs.nMergedTracks; } mTrackMCLabels.resize(nReconstructedTracks); - for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { + for (uint32_t iCol = 0; iCol < GetNMCCollissions(); iCol++) { mTrackMCLabelsReverse[iCol].resize(GetNMCTracks(iCol)); mRecTracks[iCol].resize(GetNMCTracks(iCol)); mFakeTracks[iCol].resize(GetNMCTracks(iCol)); @@ -920,7 +920,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx timer.Start(); if (tracksExternal) { #ifdef GPUCA_O2_LIB - for (unsigned int i = 0; i < tracksExternal->size(); i++) { + for (uint32_t i = 0; i < tracksExternal->size(); i++) { mTrackMCLabels[i] = (*tracksExtMC)[i]; } #endif @@ -929,25 +929,25 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx #if QA_DEBUG == 0 GPUCA_OPENMP(parallel for firstprivate(acc)) #endif - for (unsigned int i = 0; i < nReconstructedTracks; i++) { + for (uint32_t i = 0; i < nReconstructedTracks; i++) { acc.reset(); - int nClusters = 0; + int32_t nClusters = 0; const GPUTPCGMMergedTrack& track = mTracking->mIOPtrs.mergedTracks[i]; std::vector labels; - for (unsigned int k = 0; k < track.NClusters(); k++) { + for (uint32_t k = 0; k < track.NClusters(); k++) { if (mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } nClusters++; - unsigned int hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; + uint32_t hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; if (hitId >= GetNMCLabels()) { GPUError("Invalid hit id %u > %d (nClusters %d)", hitId, GetNMCLabels(), mTracking->mIOPtrs.clustersNative ? mTracking->mIOPtrs.clustersNative->nClustersTotal : 0); throw std::runtime_error("qa error"); } acc.addLabel(hitId); - for (int j = 0; j < GetMCLabelNID(hitId); j++) { - if (GetMCLabelID(hitId, j) >= (int)GetNMCTracks(GetMCLabelCol(hitId, j))) { - GPUError("Invalid label %d > %d (hit %d, label %d, col %d)", GetMCLabelID(hitId, j), GetNMCTracks(GetMCLabelCol(hitId, j)), hitId, j, (int)GetMCLabelCol(hitId, j)); + for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { + if (GetMCLabelID(hitId, j) >= (int32_t)GetNMCTracks(GetMCLabelCol(hitId, j))) { + GPUError("Invalid label %d > %d (hit %d, label %d, col %d)", GetMCLabelID(hitId, j), GetNMCTracks(GetMCLabelCol(hitId, j)), hitId, j, (int32_t)GetMCLabelCol(hitId, j)); throw std::runtime_error("qa error"); } if (GetMCLabelID(hitId, j) >= 0) { @@ -959,12 +959,12 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } float maxweight, sumweight; - int maxcount; + int32_t maxcount; auto maxLabel = acc.computeLabel(&maxweight, &sumweight, &maxcount); mTrackMCLabels[i] = maxLabel; - if (QA_DEBUG && track.OK() && GetNMCTracks(maxLabel) > (unsigned int)maxLabel.getTrackID()) { + if (QA_DEBUG && track.OK() && GetNMCTracks(maxLabel) > (uint32_t)maxLabel.getTrackID()) { const mcInfo_t& mc = GetMCTrack(maxLabel); - GPUInfo("Track %d label %d (fake %d) weight %f clusters %d (fitted %d) (%f%% %f%%) Pt %f", i, maxLabel.getTrackID(), (int)(maxLabel.isFake()), maxweight, nClusters, track.NClustersFitted(), 100.f * maxweight / sumweight, 100.f * (float)maxcount / (float)nClusters, + GPUInfo("Track %d label %d (fake %d) weight %f clusters %d (fitted %d) (%f%% %f%%) Pt %f", i, maxLabel.getTrackID(), (int32_t)(maxLabel.isFake()), maxweight, nClusters, track.NClustersFitted(), 100.f * maxweight / sumweight, 100.f * (float)maxcount / (float)nClusters, std::sqrt(mc.pX * mc.pX + mc.pY * mc.pY)); } } @@ -973,7 +973,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx GPUInfo("QA Time: Assign Track Labels:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } - for (unsigned int i = 0; i < nReconstructedTracks; i++) { + for (uint32_t i = 0; i < nReconstructedTracks; i++) { const GPUTPCGMMergedTrack* track = mTracking ? &mTracking->mIOPtrs.mergedTracks[i] : nullptr; mcLabelI_t label = mTrackMCLabels[i]; if (mQATasks & taskClusterAttach) { @@ -982,7 +982,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx continue; } if (!mTrackMCLabels[i].isValid()) { - for (unsigned int k = 0; k < track->NClusters(); k++) { + for (uint32_t k = 0; k < track->NClusters(); k++) { if (mTracking->mIOPtrs.mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } @@ -991,13 +991,13 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx continue; } if (mMCTrackMin == -1 || (label.getTrackID() >= mMCTrackMin && label.getTrackID() < mMCTrackMax)) { - for (unsigned int k = 0; k < track->NClusters(); k++) { + for (uint32_t k = 0; k < track->NClusters(); k++) { if (mTracking->mIOPtrs.mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } - int hitId = mTracking->mIOPtrs.mergedTrackHits[track->FirstClusterRef() + k].num; + int32_t hitId = mTracking->mIOPtrs.mergedTrackHits[track->FirstClusterRef() + k].num; bool correct = false; - for (int j = 0; j < GetMCLabelNID(hitId); j++) { + for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { if (label == GetMCLabel(hitId, j)) { correct = true; break; @@ -1017,7 +1017,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } else if (tracksExternal || !track->MergedLooper()) { GetMCTrackObj(mRecTracks, label)++; if (mMCTrackMin == -1 || (label.getTrackID() >= mMCTrackMin && label.getTrackID() < mMCTrackMax)) { - int& revLabel = GetMCTrackObj(mTrackMCLabelsReverse, label); + int32_t& revLabel = GetMCTrackObj(mTrackMCLabelsReverse, label); if (tracksExternal) { #ifdef GPUCA_O2_LIB if (revLabel == -1 || fabsf((*tracksExternal)[i].getZ()) < fabsf((*tracksExternal)[revLabel].getZ())) { @@ -1045,14 +1045,14 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } if ((mQATasks & taskClusterAttach) && mTracking->mIOPtrs.mergedTrackHitAttachment) { // fill cluster adjacent status - for (unsigned int i = 0; i < GetNMCLabels(); i++) { + for (uint32_t i = 0; i < GetNMCLabels(); i++) { if (mClusterParam[i].attached == 0 && mClusterParam[i].fakeAttached == 0) { - int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; if (attach & gputpcgmmergertypes::attachFlagMask) { - int track = attach & gputpcgmmergertypes::attachTrackMask; + int32_t track = attach & gputpcgmmergertypes::attachTrackMask; mcLabelI_t trackL = mTrackMCLabels[track]; bool fake = true; - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { // GPUInfo("Attach %x Track %d / %d:%d", attach, track, j, GetMCLabelID(i, j)); if (trackL == GetMCLabel(i, j)) { fake = false; @@ -1072,10 +1072,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (mConfig.matchMCLabels.size()) { mGoodHits[mNEvents - 1].resize(GetNMCLabels()); std::vector allowMCLabels(GetNMCTracks(0)); - for (unsigned int k = 0; k < GetNMCTracks(0); k++) { + for (uint32_t k = 0; k < GetNMCTracks(0); k++) { allowMCLabels[k] = false; } - for (unsigned int i = 0; i < nReconstructedTracks; i++) { + for (uint32_t i = 0; i < nReconstructedTracks; i++) { if (!mGoodTracks[mNEvents - 1][i]) { continue; } @@ -1090,19 +1090,19 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } const GPUTPCGMMergedTrack& track = mTracking->mIOPtrs.mergedTracks[i]; - for (unsigned int j = 0; j < track.NClusters(); j++) { - int hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + j].num; + for (uint32_t j = 0; j < track.NClusters(); j++) { + int32_t hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + j].num; if (GetMCLabelNID(hitId)) { - int mcID = GetMCLabelID(hitId, 0); + int32_t mcID = GetMCLabelID(hitId, 0); if (mcID >= 0) { allowMCLabels[mcID] = true; } } } } - for (unsigned int i = 0; i < GetNMCLabels(); i++) { - for (int j = 0; j < GetMCLabelNID(i); j++) { - int mcID = GetMCLabelID(i, j); + for (uint32_t i = 0; i < GetNMCLabels(); i++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { + int32_t mcID = GetMCLabelID(i, j); if (mcID >= 0 && allowMCLabels[mcID]) { mGoodHits[mNEvents - 1][i] = true; } @@ -1118,19 +1118,19 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } // Recompute fNWeightCls (might have changed after merging events into timeframes) - for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { - for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { + for (uint32_t iCol = 0; iCol < GetNMCCollissions(); iCol++) { + for (uint32_t i = 0; i < GetNMCTracks(iCol); i++) { mMCParam[iCol][i].nWeightCls = 0.; } } - for (unsigned int i = 0; i < GetNMCLabels(); i++) { + for (uint32_t i = 0; i < GetNMCLabels(); i++) { float weightTotal = 0.f; - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { if (GetMCLabelID(i, j) >= 0) { weightTotal += GetMCLabelWeight(i, j); } } - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { if (GetMCLabelID(i, j) >= 0) { GetMCTrackObj(mMCParam, GetMCLabel(i, j)).nWeightCls += GetMCLabelWeight(i, j) / weightTotal; } @@ -1142,8 +1142,8 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx // Compute MC Track Parameters for MC Tracks GPUCA_OPENMP(parallel for) - for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { - for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { + for (uint32_t iCol = 0; iCol < GetNMCCollissions(); iCol++) { + for (uint32_t i = 0; i < GetNMCTracks(iCol); i++) { const mcInfo_t& info = GetMCTrack(i, iCol); additionalMCParameters& mc2 = mMCParam[iCol][i]; mc2.pt = std::sqrt(info.pX * info.pX + info.pY * info.pY); @@ -1156,7 +1156,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mc2.eta = -std::log(std::tan(0.5 * mc2.theta)); } if (mConfig.writeMCLabels) { - std::vector& effBuffer = mcEffBuffer[mNEvents - 1]; + std::vector& effBuffer = mcEffBuffer[mNEvents - 1]; effBuffer[i] = mRecTracks[iCol][i] * 1000 + mFakeTracks[iCol][i]; } } @@ -1167,9 +1167,9 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx // Fill Efficiency Histograms if (mQATasks & taskTrackingEff) { - for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { - for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { - if ((mMCTrackMin != -1 && (int)i < mMCTrackMin) || (mMCTrackMax != -1 && (int)i >= mMCTrackMax)) { + for (uint32_t iCol = 0; iCol < GetNMCCollissions(); iCol++) { + for (uint32_t i = 0; i < GetNMCTracks(iCol); i++) { + if ((mMCTrackMin != -1 && (int32_t)i < mMCTrackMin) || (mMCTrackMax != -1 && (int32_t)i >= mMCTrackMax)) { continue; } const mcInfo_t& info = GetMCTrack(i, iCol); @@ -1187,7 +1187,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (mc2.nWeightCls < MIN_WEIGHT_CLS) { continue; } - int findable = mc2.nWeightCls >= FINDABLE_WEIGHT_CLS; + int32_t findable = mc2.nWeightCls >= FINDABLE_WEIGHT_CLS; if (info.pid < 0) { continue; } @@ -1221,18 +1221,18 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx effdump.Fill(alpha, localX, localY, info.z, mcphi, mceta, mcpt, mRecTracks[iCol][i], mFakeTracks[iCol][i], findable, info.prim); } - for (int j = 0; j < 4; j++) { - for (int k = 0; k < 2; k++) { + for (int32_t j = 0; j < 4; j++) { + for (int32_t k = 0; k < 2; k++) { if (k == 0 && findable == 0) { continue; } - int val = (j == 0) ? (mRecTracks[iCol][i] ? 1 : 0) : (j == 1) ? (mRecTracks[iCol][i] ? mRecTracks[iCol][i] - 1 : 0) : (j == 2) ? mFakeTracks[iCol][i] : 1; + int32_t val = (j == 0) ? (mRecTracks[iCol][i] ? 1 : 0) : (j == 1) ? (mRecTracks[iCol][i] ? mRecTracks[iCol][i] - 1 : 0) : (j == 2) ? mFakeTracks[iCol][i] : 1; if (val == 0) { continue; } - for (int l = 0; l < 5; l++) { + for (int32_t l = 0; l < 5; l++) { if (info.prim && mcpt < PT_MIN_PRIM) { continue; } @@ -1263,9 +1263,9 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx prop.SetMaterialTPC(); prop.SetPolynomialField(&mParam->polynomialField); - for (unsigned int i = 0; i < mTrackMCLabels.size(); i++) { + for (uint32_t i = 0; i < mTrackMCLabels.size(); i++) { if (mConfig.writeMCLabels) { - std::vector& labelBuffer = mcLabelBuffer[mNEvents - 1]; + std::vector& labelBuffer = mcLabelBuffer[mNEvents - 1]; labelBuffer[i] = mTrackMCLabels[i].getTrackID(); } if (mTrackMCLabels[i].isFake()) { @@ -1311,19 +1311,19 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } else if (mConfig.resPrimaries == 2 && mc1.prim) { continue; } - if (GetMCTrackObj(mTrackMCLabelsReverse, mTrackMCLabels[i]) != (int)i) { + if (GetMCTrackObj(mTrackMCLabelsReverse, mTrackMCLabels[i]) != (int32_t)i) { continue; } GPUTPCGMTrackParam param; float alpha = 0.f; - int side; + int32_t side; if (tracksExternal) { #ifdef GPUCA_O2_LIB - for (int k = 0; k < 5; k++) { + for (int32_t k = 0; k < 5; k++) { param.Par()[k] = (*tracksExternal)[i].getParams()[k]; } - for (int k = 0; k < 15; k++) { + for (int32_t k = 0; k < 15; k++) { param.Cov()[k] = (*tracksExternal)[i].getCov()[k]; } param.X() = (*tracksExternal)[i].getX(); @@ -1407,8 +1407,8 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx float resval[5] = {deltaY, deltaZ, mConfig.nativeFitResolutions ? deltaPhiNative : deltaPhi, mConfig.nativeFitResolutions ? deltaLambdaNative : deltaLambda, mConfig.nativeFitResolutions ? deltaPtNative : deltaPt}; float pullval[5] = {deltaY / std::sqrt(param.GetErr2Y()), deltaZ / std::sqrt(param.GetErr2Z()), deltaPhiNative / std::sqrt(param.GetErr2SinPhi()), deltaLambdaNative / std::sqrt(param.GetErr2DzDs()), deltaPtNative / std::sqrt(param.GetErr2QPt())}; - for (int j = 0; j < 5; j++) { - for (int k = 0; k < 5; k++) { + for (int32_t j = 0; j < 5; j++) { + for (int32_t k = 0; k < 5; k++) { if (k != 3 && fabsf(mc2.eta) > ETA_MAX2) { continue; } @@ -1431,28 +1431,28 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (mQATasks & taskClusterAttach) { // Fill cluster histograms - for (unsigned int iTrk = 0; iTrk < nReconstructedTracks; iTrk++) { + for (uint32_t iTrk = 0; iTrk < nReconstructedTracks; iTrk++) { const GPUTPCGMMergedTrack& track = mTracking->mIOPtrs.mergedTracks[iTrk]; if (!track.OK()) { continue; } if (!mTrackMCLabels[iTrk].isValid()) { - for (unsigned int k = 0; k < track.NClusters(); k++) { + for (uint32_t k = 0; k < track.NClusters(); k++) { if (mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } - int hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; + int32_t hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; float totalWeight = 0.; - for (int j = 0; j < GetMCLabelNID(hitId); j++) { + for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { if (GetMCLabelID(hitId, j) >= 0 && GetMCTrackObj(mMCParam, GetMCLabel(hitId, j)).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { totalWeight += GetMCLabelWeight(hitId, j); } } - int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; CHECK_CLUSTER_STATE_NOCOUNT(); if (totalWeight > 0) { float weight = 1.f / (totalWeight * (mClusterParam[hitId].attached + mClusterParam[hitId].fakeAttached)); - for (int j = 0; j < GetMCLabelNID(hitId); j++) { + for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { mcLabelI_t label = GetMCLabel(hitId, j); if (!label.isFake() && GetMCTrackObj(mMCParam, label).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { float pt = GetMCTrackObj(mMCParam, label).pt; @@ -1493,18 +1493,18 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (mMCTrackMin != -1 && (label.getTrackID() < mMCTrackMin || label.getTrackID() >= mMCTrackMax)) { continue; } - for (unsigned int k = 0; k < track.NClusters(); k++) { + for (uint32_t k = 0; k < track.NClusters(); k++) { if (mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject) { continue; } - int hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; + int32_t hitId = mTracking->mIOPtrs.mergedTrackHits[track.FirstClusterRef() + k].num; float pt = GetMCTrackObj(mMCParam, label).pt; if (pt < PT_MIN_CLUST) { pt = PT_MIN_CLUST; } float weight = 1.f / (mClusterParam[hitId].attached + mClusterParam[hitId].fakeAttached); bool correct = false; - for (int j = 0; j < GetMCLabelNID(hitId); j++) { + for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { if (label == GetMCLabel(hitId, j)) { correct = true; break; @@ -1518,7 +1518,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } mClusters[CL_att_adj]->Fill(pt, weight); mClusters[CL_all]->Fill(pt, weight); - int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; CHECK_CLUSTER_STATE_NOCOUNT(); if (protect || physics) { mClusters[CL_prot]->Fill(pt, weight); @@ -1528,20 +1528,20 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } } - for (unsigned int i = 0; i < GetNMCLabels(); i++) { + for (uint32_t i = 0; i < GetNMCLabels(); i++) { if ((mMCTrackMin != -1 && GetMCLabelID(i, 0) < mMCTrackMin) || (mMCTrackMax != -1 && GetMCLabelID(i, 0) >= mMCTrackMax)) { continue; } if (mClusterParam[i].attached || mClusterParam[i].fakeAttached) { continue; } - int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; CHECK_CLUSTER_STATE_NOCOUNT(); if (mClusterParam[i].adjacent) { - int label = mTracking->mIOPtrs.mergedTrackHitAttachment[i] & gputpcgmmergertypes::attachTrackMask; + int32_t label = mTracking->mIOPtrs.mergedTrackHitAttachment[i] & gputpcgmmergertypes::attachTrackMask; if (!mTrackMCLabels[label].isValid()) { float totalWeight = 0.; - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { mcLabelI_t labelT = GetMCLabel(i, j); if (!labelT.isFake() && GetMCTrackObj(mMCParam, labelT).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { totalWeight += GetMCLabelWeight(i, j); @@ -1549,7 +1549,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } float weight = 1.f / totalWeight; if (totalWeight > 0) { - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { mcLabelI_t labelT = GetMCLabel(i, j); if (!labelT.isFake() && GetMCTrackObj(mMCParam, labelT).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { float pt = GetMCTrackObj(mMCParam, labelT).pt; @@ -1599,14 +1599,14 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } else { float totalWeight = 0.; - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { mcLabelI_t labelT = GetMCLabel(i, j); if (!labelT.isFake() && GetMCTrackObj(mMCParam, labelT).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { totalWeight += GetMCLabelWeight(i, j); } } if (totalWeight > 0) { - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { mcLabelI_t label = GetMCLabel(i, j); if (!label.isFake() && GetMCTrackObj(mMCParam, label).pt > GPUCA_MIN_TRACK_PTB5_DEFAULT) { float pt = GetMCTrackObj(mMCParam, label).pt; @@ -1661,7 +1661,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (mQATasks & taskTrackStatistics) { // Fill track statistic histograms - for (unsigned int i = 0; i < nReconstructedTracks; i++) { + for (uint32_t i = 0; i < nReconstructedTracks; i++) { const GPUTPCGMMergedTrack& track = mTracking->mIOPtrs.mergedTracks[i]; if (!track.OK()) { continue; @@ -1670,9 +1670,9 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mNCl->Fill(track.NClustersFitted()); } if (mClNative && mTracking && mTracking->GetTPCTransformHelper()) { - for (unsigned int i = 0; i < GPUChainTracking::NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - for (unsigned int k = 0; k < mClNative->nClusters[i][j]; k++) { + for (uint32_t i = 0; i < GPUChainTracking::NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t k = 0; k < mClNative->nClusters[i][j]; k++) { const auto& cl = mClNative->clusters[i][j][k]; float x, y, z; GPUTPCConvertImpl::convert(*mTracking->GetTPCTransformHelper()->getCorrMap(), mTracking->GetParam(), i, j, cl.getPad(), cl.getTime(), x, y, z); @@ -1688,16 +1688,16 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } - unsigned int nCl = clNative ? clNative->nClustersTotal : mTracking->GetTPCMerger().NMaxClusters(); + uint32_t nCl = clNative ? clNative->nClustersTotal : mTracking->GetTPCMerger().NMaxClusters(); mClusterCounts.nTotal += nCl; if (mQATasks & taskClusterCounts) { - for (unsigned int i = 0; i < nCl; i++) { - int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; + for (uint32_t i = 0; i < nCl; i++) { + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; CHECK_CLUSTER_STATE(); if (mcAvail) { float totalWeight = 0, weight400 = 0, weight40 = 0; - for (int j = 0; j < GetMCLabelNID(i); j++) { + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { const auto& label = GetMCLabel(i, j); if (GetMCLabelID(label) >= 0) { totalWeight += GetMCLabelWeight(label); @@ -1712,18 +1712,18 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (totalWeight > 0 && 10.f * weight400 >= totalWeight) { if (!unattached && !protect && !physics) { mClusterCounts.nFakeRemove400++; - int totalFake = weight400 < 0.9f * totalWeight; + int32_t totalFake = weight400 < 0.9f * totalWeight; if (totalFake) { mClusterCounts.nFullFakeRemove400++; } - /*printf("Fake removal (%d): Hit %7d, attached %d lowPt %d looper %d tube200 %d highIncl %d tube %d bad %d recPt %7.2f recLabel %6d", totalFake, i, (int) (mClusterParam[i].attached || mClusterParam[i].fakeAttached), - (int) lowPt, (int) ((attach & gputpcgmmergertypes::attachGoodLeg) == 0), (int) ((attach & gputpcgmmergertypes::attachTube) && mev200), - (int) ((attach & gputpcgmmergertypes::attachHighIncl) != 0), (int) ((attach & gputpcgmmergertypes::attachTube) != 0), (int) ((attach & gputpcgmmergertypes::attachGood) == 0), + /*printf("Fake removal (%d): Hit %7d, attached %d lowPt %d looper %d tube200 %d highIncl %d tube %d bad %d recPt %7.2f recLabel %6d", totalFake, i, (int32_t) (mClusterParam[i].attached || mClusterParam[i].fakeAttached), + (int32_t) lowPt, (int32_t) ((attach & gputpcgmmergertypes::attachGoodLeg) == 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) && mev200), + (int32_t) ((attach & gputpcgmmergertypes::attachHighIncl) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachGood) == 0), fabsf(qpt) > 0 ? 1.f / qpt : 0.f, id); - for (int j = 0;j < GetMCLabelNID(i);j++) + for (int32_t j = 0;j < GetMCLabelNID(i);j++) { //if (GetMCLabelID(i, j) < 0) break; - printf(" - label%d %6d weight %5d", j, GetMCLabelID(i, j), (int) GetMCLabelWeight(i, j)); + printf(" - label%d %6d weight %5d", j, GetMCLabelID(i, j), (int32_t) GetMCLabelWeight(i, j)); if (GetMCLabelID(i, j) >= 0) printf(" - pt %7.2f", mMCParam[GetMCLabelID(i, j)].pt); else printf(" "); } @@ -1764,20 +1764,20 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx if (!clNative || !mTracking || !mTracking->mIOPtrs.mergedTrackHitAttachment || !mTracking->mIOPtrs.mergedTracks) { throw std::runtime_error("Cannot dump non o2::tpc::clusterNative clusters, need also hit attachmend and GPU tracks"); } - unsigned int clid = 0; - for (unsigned int i = 0; i < GPUChainTracking::NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - for (unsigned int k = 0; k < mClNative->nClusters[i][j]; k++) { + uint32_t clid = 0; + for (uint32_t i = 0; i < GPUChainTracking::NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + for (uint32_t k = 0; k < mClNative->nClusters[i][j]; k++) { const auto& cl = mClNative->clusters[i][j][k]; - unsigned int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[clid]; + uint32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[clid]; float x = 0, y = 0, z = 0; if (attach & gputpcgmmergertypes::attachFlagMask) { - unsigned int track = attach & gputpcgmmergertypes::attachTrackMask; + uint32_t track = attach & gputpcgmmergertypes::attachTrackMask; const auto& trk = mTracking->mIOPtrs.mergedTracks[track]; mTracking->GetTPCTransformHelper()->Transform(i, j, cl.getPad(), cl.getTime(), x, y, z, trk.GetParam().GetTZOffset()); mTracking->GetParam().Slice2Global(i, x, y, z, &x, &y, &z); } - unsigned int extState = mTracking->mIOPtrs.mergedTrackHitStates ? mTracking->mIOPtrs.mergedTrackHitStates[clid] : 0; + uint32_t extState = mTracking->mIOPtrs.mergedTrackHitStates ? mTracking->mIOPtrs.mergedTrackHitStates[clid] : 0; if (mConfig.dumpToROOT >= 2) { GPUTPCGMMergedTrack trk; @@ -1785,9 +1785,9 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx memset((void*)&trk, 0, sizeof(trk)); memset((void*)&trkHit, 0, sizeof(trkHit)); if (attach & gputpcgmmergertypes::attachFlagMask) { - unsigned int track = attach & gputpcgmmergertypes::attachTrackMask; + uint32_t track = attach & gputpcgmmergertypes::attachTrackMask; trk = mTracking->mIOPtrs.mergedTracks[track]; - for (unsigned int l = 0; l < trk.NClusters(); l++) { + for (uint32_t l = 0; l < trk.NClusters(); l++) { const auto& tmp = mTracking->mIOPtrs.mergedTrackHits[trk.FirstClusterRef() + l]; if (tmp.num == clid) { trkHit = tmp; @@ -1795,10 +1795,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } } - static auto cldump = GPUROOTDump::getNew("cluster", "track", "trackHit", "attach", "extState", "x", "y", "z", "sector", "row", "nEv", "clusterTree"); + static auto cldump = GPUROOTDump::getNew("cluster", "track", "trackHit", "attach", "extState", "x", "y", "z", "sector", "row", "nEv", "clusterTree"); cldump.Fill(cl, trk, trkHit, attach, extState, x, y, z, i, j, mNEvents - 1); } else { - static auto cldump = GPUROOTDump::getNew("cluster", "attach", "extState", "x", "y", "z", "sector", "row", "nEv", "clusterTree"); + static auto cldump = GPUROOTDump::getNew("cluster", "attach", "extState", "x", "y", "z", "sector", "row", "nEv", "clusterTree"); cldump.Fill(cl, attach, extState, x, y, z, i, j, mNEvents - 1); } clid++; @@ -1806,16 +1806,16 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } - static auto trkdump = GPUROOTDump::getNew("nEv", "track", "tracksTree"); - for (unsigned int i = 0; i < mTracking->mIOPtrs.nMergedTracks; i++) { + static auto trkdump = GPUROOTDump::getNew("nEv", "track", "tracksTree"); + for (uint32_t i = 0; i < mTracking->mIOPtrs.nMergedTracks; i++) { if (mTracking->mIOPtrs.mergedTracks[i].OK()) { trkdump.Fill(mNEvents - 1, mTracking->mIOPtrs.mergedTracks[i]); } } if (mTracking && mTracking->GetProcessingSettings().createO2Output) { - static auto o2trkdump = GPUROOTDump::getNew("nEv", "track", "tracksO2Tree"); - for (unsigned int i = 0; i < mTracking->mIOPtrs.nOutputTracksTPCO2; i++) { + static auto o2trkdump = GPUROOTDump::getNew("nEv", "track", "tracksO2Tree"); + for (uint32_t i = 0; i < mTracking->mIOPtrs.nOutputTracksTPCO2; i++) { o2trkdump.Fill(mNEvents - 1, mTracking->mIOPtrs.outputTracksTPCO2[i]); } } @@ -1824,9 +1824,9 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mTrackingScratchBuffer.shrink_to_fit(); } -void GPUQA::GetName(char* fname, int k) +void GPUQA::GetName(char* fname, int32_t k) { - const int nNewInput = mConfig.inputHistogramsOnly ? 0 : 1; + const int32_t nNewInput = mConfig.inputHistogramsOnly ? 0 : 1; if (k || mConfig.inputHistogramsOnly || mConfig.name.size()) { if (!(mConfig.inputHistogramsOnly || k)) { snprintf(fname, 1024, "%s - ", mConfig.name.c_str()); @@ -1845,7 +1845,7 @@ void GPUQA::GetName(char* fname, int k) } template -T* GPUQA::GetHist(T*& ee, std::vector>& tin, int k, int nNewInput) +T* GPUQA::GetHist(T*& ee, std::vector>& tin, int32_t k, int32_t nNewInput) { T* e = ee; if ((mConfig.inputHistogramsOnly || k) && (e = dynamic_cast(tin[k - nNewInput]->Get(e->GetName()))) == nullptr) { @@ -1884,7 +1884,7 @@ void GPUQA::resetHists() mClusterCounts = counts_t(); } -int GPUQA::DrawQAHistograms(TObjArray* qcout) +int32_t GPUQA::DrawQAHistograms(TObjArray* qcout) { const auto oldRootIgnoreLevel = gErrorIgnoreLevel; gErrorIgnoreLevel = kWarning; @@ -1898,21 +1898,21 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) std::vector colorNums(COLORCOUNT); if (!qcout) { - static int initColorsInitialized = initColors(); + static int32_t initColorsInitialized = initColors(); (void)initColorsInitialized; } - for (int i = 0; i < COLORCOUNT; i++) { + for (int32_t i = 0; i < COLORCOUNT; i++) { colorNums[i] = qcout ? defaultColorNums[i] : mColors[i]->GetNumber(); } bool mcAvail = mcPresent(); char name[2048], fname[1024]; - const int nNewInput = mConfig.inputHistogramsOnly ? 0 : 1; - const int ConfigNumInputs = nNewInput + mConfig.compareInputs.size(); + const int32_t nNewInput = mConfig.inputHistogramsOnly ? 0 : 1; + const int32_t ConfigNumInputs = nNewInput + mConfig.compareInputs.size(); std::vector> tin; - for (unsigned int i = 0; i < mConfig.compareInputs.size(); i++) { + for (uint32_t i = 0; i < mConfig.compareInputs.size(); i++) { tin.emplace_back(std::make_unique(mConfig.compareInputs[i].c_str())); } std::unique_ptr tout = nullptr; @@ -1922,7 +1922,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) if (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) { float legendSpacingString = 0.025; - for (int i = 0; i < ConfigNumInputs; i++) { + for (int32_t i = 0; i < ConfigNumInputs; i++) { GetName(fname, i); if (strlen(fname) * 0.006 > legendSpacingString) { legendSpacingString = strlen(fname) * 0.006; @@ -1931,8 +1931,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) // Create Canvas / Pads for Efficiency Histograms if (mQATasks & taskTrackingEff) { - for (int ii = 0; ii < 6; ii++) { - int i = ii == 5 ? 4 : ii; + for (int32_t ii = 0; ii < 6; ii++) { + int32_t i = ii == 5 ? 4 : ii; snprintf(fname, 1024, "eff_vs_%s_layout", VSPARAMETER_NAMES[ii]); snprintf(name, 2048, "Efficiency versus %s", VSPARAMETER_NAMES[i]); mCEff[ii] = createGarbageCollected(fname, name, 0, 0, 700, 700. * 2. / 3.); @@ -1957,8 +1957,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) // Create Canvas / Pads for Resolution Histograms if (mQATasks & taskTrackingRes) { - for (int ii = 0; ii < 7; ii++) { - int i = ii == 5 ? 4 : ii; + for (int32_t ii = 0; ii < 7; ii++) { + int32_t i = ii == 5 ? 4 : ii; if (ii == 6) { snprintf(fname, 1024, "res_integral_layout"); snprintf(name, 2048, "Integral Resolution"); @@ -1998,8 +1998,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) // Create Canvas / Pads for Pull Histograms if (mQATasks & taskTrackingResPull) { - for (int ii = 0; ii < 7; ii++) { - int i = ii == 5 ? 4 : ii; + for (int32_t ii = 0; ii < 7; ii++) { + int32_t i = ii == 5 ? 4 : ii; if (ii == 6) { snprintf(fname, 1024, "pull_integral_layout"); @@ -2040,7 +2040,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) // Create Canvas for Cluster Histos if (mQATasks & taskClusterAttach) { - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { snprintf(fname, 1024, "clusters_%s_layout", CLUSTER_TYPES[i]); mCClust[i] = createGarbageCollected(fname, CLUSTER_TITLES[i], 0, 0, 700, 700. * 2. / 3.); mCClust[i]->cd(); @@ -2076,27 +2076,27 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } if (mConfig.enableLocalOutput && !mConfig.inputHistogramsOnly && (mQATasks & taskTrackingEff) && mcPresent()) { - GPUInfo("QA Stats: Eff: Tracks Prim %d (Eta %d, Pt %d) %f%% (%f%%) Sec %d (Eta %d, Pt %d) %f%% (%f%%) - Res: Tracks %d (Eta %d, Pt %d)", (int)mEff[3][1][0][0]->GetEntries(), (int)mEff[3][1][0][3]->GetEntries(), (int)mEff[3][1][0][4]->GetEntries(), - mEff[0][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][0][0]->GetSumOfWeights()), mEff[0][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][0][0]->GetSumOfWeights()), (int)mEff[3][1][1][0]->GetEntries(), (int)mEff[3][1][1][3]->GetEntries(), - (int)mEff[3][1][1][4]->GetEntries(), mEff[0][0][1][0]->GetSumOfWeights() / std::max(1., mEff[3][0][1][0]->GetSumOfWeights()), mEff[0][1][1][0]->GetSumOfWeights() / std::max(1., mEff[3][1][1][0]->GetSumOfWeights()), (int)mRes2[0][0]->GetEntries(), - (int)mRes2[0][3]->GetEntries(), (int)mRes2[0][4]->GetEntries()); + GPUInfo("QA Stats: Eff: Tracks Prim %d (Eta %d, Pt %d) %f%% (%f%%) Sec %d (Eta %d, Pt %d) %f%% (%f%%) - Res: Tracks %d (Eta %d, Pt %d)", (int32_t)mEff[3][1][0][0]->GetEntries(), (int32_t)mEff[3][1][0][3]->GetEntries(), (int32_t)mEff[3][1][0][4]->GetEntries(), + mEff[0][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][0][0]->GetSumOfWeights()), mEff[0][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][0][0]->GetSumOfWeights()), (int32_t)mEff[3][1][1][0]->GetEntries(), (int32_t)mEff[3][1][1][3]->GetEntries(), + (int32_t)mEff[3][1][1][4]->GetEntries(), mEff[0][0][1][0]->GetSumOfWeights() / std::max(1., mEff[3][0][1][0]->GetSumOfWeights()), mEff[0][1][1][0]->GetSumOfWeights() / std::max(1., mEff[3][1][1][0]->GetSumOfWeights()), (int32_t)mRes2[0][0]->GetEntries(), + (int32_t)mRes2[0][3]->GetEntries(), (int32_t)mRes2[0][4]->GetEntries()); } - int flagShowVsPtLog = (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) ? 1 : 0; + int32_t flagShowVsPtLog = (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) ? 1 : 0; if (mQATasks & taskTrackingEff) { // Process / Draw Efficiency Histograms - for (int ii = 0; ii < 5 + flagShowVsPtLog; ii++) { - int i = ii == 5 ? 4 : ii; - for (int k = 0; k < ConfigNumInputs; k++) { - for (int j = 0; j < 4; j++) { + for (int32_t ii = 0; ii < 5 + flagShowVsPtLog; ii++) { + int32_t i = ii == 5 ? 4 : ii; + for (int32_t k = 0; k < ConfigNumInputs; k++) { + for (int32_t j = 0; j < 4; j++) { if (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) { mPEff[ii][j]->cd(); if (ii == 5) { mPEff[ii][j]->SetLogx(); } } - for (int l = 0; l < 3; l++) { + for (int32_t l = 0; l < 3; l++) { if (k == 0 && mConfig.inputHistogramsOnly == 0 && ii != 5) { if (l == 0) { // Divide eff, compute all for fake/clone @@ -2185,15 +2185,15 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) TH1D *resIntegral[5] = {}, *pullIntegral[5] = {}; TCanvas* cfit = nullptr; std::unique_ptr customGaus = std::make_unique("G", "[0]*exp(-(x-[1])*(x-[1])/(2.*[2]*[2]))"); - for (int p = 0; p < 2; p++) { + for (int32_t p = 0; p < 2; p++) { if ((p == 0 && (mQATasks & taskTrackingRes) == 0) || (p == 1 && (mQATasks & taskTrackingResPull) == 0)) { continue; } - for (int ii = 0; ii < 5 + flagShowVsPtLog; ii++) { + for (int32_t ii = 0; ii < 5 + flagShowVsPtLog; ii++) { TCanvas* can = p ? mCPull[ii] : mCRes[ii]; TLegend* leg = p ? mLPull[ii] : mLRes[ii]; - int i = ii == 5 ? 4 : ii; - for (int j = 0; j < 5; j++) { + int32_t i = ii == 5 ? 4 : ii; + for (int32_t j = 0; j < 5; j++) { TH2F* src = p ? mPull2[j][i] : mRes2[j][i]; TH1F** dst = p ? mPull[j][i] : mRes[j][i]; TH1D*& dstIntegral = p ? pullIntegral[j] : resIntegral[j]; @@ -2206,15 +2206,15 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) cfit->cd(); TAxis* axis = src->GetYaxis(); - int nBins = axis->GetNbins(); - int integ = 1; - for (int bin = 1; bin <= nBins; bin++) { - int bin0 = std::max(bin - integ, 0); - int bin1 = std::min(bin + integ, nBins); + int32_t nBins = axis->GetNbins(); + int32_t integ = 1; + for (int32_t bin = 1; bin <= nBins; bin++) { + int32_t bin0 = std::max(bin - integ, 0); + int32_t bin1 = std::min(bin + integ, nBins); std::unique_ptr proj{src->ProjectionX("proj", bin0, bin1)}; proj->ClearUnderflowAndOverflow(); if (proj->GetEntries()) { - unsigned int rebin = 1; + uint32_t rebin = 1; while (proj->GetMaximum() < 50 && rebin < sizeof(RES_AXIS_BINS) / sizeof(RES_AXIS_BINS[0])) { proj->Rebin(RES_AXIS_BINS[rebin - 1] / RES_AXIS_BINS[rebin]); rebin++; @@ -2229,7 +2229,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) proj->GetXaxis()->SetRange(0, 0); proj->GetXaxis()->SetRangeUser(std::max(proj->GetXaxis()->GetXmin(), proj->GetMean() - 3. * proj->GetRMS()), std::min(proj->GetXaxis()->GetXmax(), proj->GetMean() + 3. * proj->GetRMS())); bool forceLogLike = proj->GetMaximum() < 20; - for (int k = forceLogLike ? 2 : 0; k < 3; k++) { + for (int32_t k = forceLogLike ? 2 : 0; k < 3; k++) { proj->Fit("gaus", forceLogLike || k == 2 ? "sQl" : k ? "sQww" : "sQ"); TF1* fitFunc = proj->GetFunction("gaus"); @@ -2250,7 +2250,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) const bool fail3 = dst[0]->GetBinContent(bin) > 3.f * proj->GetRMS() || dst[0]->GetBinError(bin) > 1 || dst[1]->GetBinError(bin) > 1; const bool fail4 = fitFunc->GetParameter(0) < proj->GetMaximum() / 5.; const bool fail = fail1 || fail2 || fail3 || fail4; - // if (p == 0 && ii == 4 && j == 2) DrawHisto(proj, Form("Hist_bin_%d-%d_vs_%d____%d_%d___%f-%f___%f-%f___%d.pdf", p, j, ii, bin, k, dst[0]->GetBinContent(bin), proj->GetRMS(), dst[1]->GetBinContent(bin), proj->GetMean(), (int) fail), ""); + // if (p == 0 && ii == 4 && j == 2) DrawHisto(proj, Form("Hist_bin_%d-%d_vs_%d____%d_%d___%f-%f___%f-%f___%d.pdf", p, j, ii, bin, k, dst[0]->GetBinContent(bin), proj->GetRMS(), dst[1]->GetBinContent(bin), proj->GetMean(), (int32_t) fail), ""); if (!fail) { break; @@ -2271,7 +2271,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } if (ii == 0) { dstIntegral = src->ProjectionX(mConfig.nativeFitResolutions ? PARAMETER_NAMES_NATIVE[j] : PARAMETER_NAMES[j], 0, nBins + 1); - unsigned int rebin = 1; + uint32_t rebin = 1; while (dstIntegral->GetMaximum() < 50 && rebin < sizeof(RES_AXIS_BINS) / sizeof(RES_AXIS_BINS[0])) { dstIntegral->Rebin(RES_AXIS_BINS[rebin - 1] / RES_AXIS_BINS[rebin]); rebin++; @@ -2290,12 +2290,12 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) if (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) { pad->cd(); } - int numColor = 0; + int32_t numColor = 0; float tmpMax = -1000.; float tmpMin = 1000.; - for (int l = 0; l < 2; l++) { - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t l = 0; l < 2; l++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1F* e = dst[l]; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2332,8 +2332,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) tmpMax += tmpSpan * 0.13 * ConfigNumInputs; } - for (int k = 0; k < ConfigNumInputs; k++) { - for (int l = 0; l < 2; l++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { + for (int32_t l = 0; l < 2; l++) { TH1F* e = dst[l]; if (!mConfig.inputHistogramsOnly && k == 0) { snprintf(name, 2048, p ? "%s Pull" : "%s Resolution", p || mConfig.nativeFitResolutions ? PARAMETER_NAMES_NATIVE[j] : PARAMETER_NAMES[j]); @@ -2419,15 +2419,15 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } // Process Integral Resolution Histogreams - for (int p = 0; p < 2; p++) { + for (int32_t p = 0; p < 2; p++) { if ((p == 0 && (mQATasks & taskTrackingRes) == 0) || (p == 1 && (mQATasks & taskTrackingResPull) == 0)) { continue; } TCanvas* can = p ? mCPull[6] : mCRes[6]; - for (int i = 0; i < 5; i++) { + for (int32_t i = 0; i < 5; i++) { TPad* pad = p ? mPPull[6][i] : mPRes[6][i]; TH1D* hist = p ? pullIntegral[i] : resIntegral[i]; - int numColor = 0; + int32_t numColor = 0; if (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) { pad->cd(); } @@ -2439,7 +2439,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } float tmpMax = 0; - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1D* e = hist; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2450,7 +2450,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } } - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1D* e = hist; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2489,25 +2489,25 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } } - unsigned long attachClusterCounts[N_CLS_HIST]; + uint64_t attachClusterCounts[N_CLS_HIST]; if (mQATasks & taskClusterAttach) { // Process Cluster Attachment Histograms if (mConfig.inputHistogramsOnly == 0) { - for (int i = N_CLS_HIST; i < N_CLS_TYPE * N_CLS_HIST - 1; i++) { + for (int32_t i = N_CLS_HIST; i < N_CLS_TYPE * N_CLS_HIST - 1; i++) { mClusters[i]->Sumw2(true); } double totalVal = 0; if (!CLUST_HIST_INT_SUM) { - for (int j = 0; j < mClusters[N_CLS_HIST - 1]->GetXaxis()->GetNbins() + 2; j++) { + for (int32_t j = 0; j < mClusters[N_CLS_HIST - 1]->GetXaxis()->GetNbins() + 2; j++) { totalVal += mClusters[N_CLS_HIST - 1]->GetBinContent(j); } } if (totalVal == 0.) { totalVal = 1.; } - for (int i = 0; i < N_CLS_HIST; i++) { + for (int32_t i = 0; i < N_CLS_HIST; i++) { double val = 0; - for (int j = 0; j < mClusters[i]->GetXaxis()->GetNbins() + 2; j++) { + for (int32_t j = 0; j < mClusters[i]->GetXaxis()->GetNbins() + 2; j++) { val += mClusters[i]->GetBinContent(j); mClusters[2 * N_CLS_HIST - 1 + i]->SetBinContent(j, val / totalVal); } @@ -2515,13 +2515,13 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } if (!CLUST_HIST_INT_SUM) { - for (int i = 0; i < N_CLS_HIST; i++) { + for (int32_t i = 0; i < N_CLS_HIST; i++) { mClusters[2 * N_CLS_HIST - 1 + i]->SetMaximum(1.02); mClusters[2 * N_CLS_HIST - 1 + i]->SetMinimum(-0.02); } } - for (int i = 0; i < N_CLS_HIST - 1; i++) { + for (int32_t i = 0; i < N_CLS_HIST - 1; i++) { auto oldLevel = gErrorIgnoreLevel; gErrorIgnoreLevel = kError; mClusters[N_CLS_HIST + i]->Divide(mClusters[i], mClusters[N_CLS_HIST - 1], 1, 1, "B"); @@ -2532,8 +2532,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } float tmpMax[2] = {0, 0}, tmpMin[2] = {0, 0}; - for (int l = 0; l <= CLUST_HIST_INT_SUM; l++) { - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t l = 0; l <= CLUST_HIST_INT_SUM; l++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1* e = mClusters[l ? (N_CLS_TYPE * N_CLS_HIST - 2) : (N_CLS_HIST - 1)]; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2550,8 +2550,8 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) tmpMin[l] = e->GetMinimum(); } } - for (int k = 0; k < ConfigNumInputs; k++) { - for (int i = 0; i < N_CLS_HIST; i++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { + for (int32_t i = 0; i < N_CLS_HIST; i++) { TH1* e = mClusters[l ? (2 * N_CLS_HIST - 1 + i) : i]; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2562,16 +2562,16 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } } - for (int i = 0; i < N_CLS_TYPE; i++) { + for (int32_t i = 0; i < N_CLS_TYPE; i++) { if (mConfig.enableLocalOutput || mConfig.shipToQCAsCanvas) { mPClust[i]->cd(); mPClust[i]->SetLogx(); } - int begin = i == 2 ? (2 * N_CLS_HIST - 1) : i == 1 ? N_CLS_HIST : 0; - int end = i == 2 ? (3 * N_CLS_HIST - 1) : i == 1 ? (2 * N_CLS_HIST - 1) : N_CLS_HIST; - int numColor = 0; - for (int k = 0; k < ConfigNumInputs; k++) { - for (int j = end - 1; j >= begin; j--) { + int32_t begin = i == 2 ? (2 * N_CLS_HIST - 1) : i == 1 ? N_CLS_HIST : 0; + int32_t end = i == 2 ? (3 * N_CLS_HIST - 1) : i == 1 ? (2 * N_CLS_HIST - 1) : N_CLS_HIST; + int32_t numColor = 0; + for (int32_t k = 0; k < ConfigNumInputs; k++) { + for (int32_t j = end - 1; j >= begin; j--) { TH1* e = mClusters[j]; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2646,7 +2646,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) DoClusterCounts(attachClusterCounts); } if ((qcout || tout) && (mQATasks & taskClusterCounts) && mConfig.clusterRejectionHistograms) { - for (unsigned int i = 0; i < mHistClusterCount.size(); i++) { + for (uint32_t i = 0; i < mHistClusterCount.size(); i++) { if (tout) { mHistClusterCount[i]->Write(); } @@ -2659,7 +2659,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) if (mQATasks & taskTrackStatistics) { // Process track statistic histograms float tmpMax = 0.; - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1F* e = mTracks; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2671,7 +2671,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } mPTracks->cd(); mPTracks->SetLogx(); - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1F* e = mTracks; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2703,7 +2703,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } tmpMax = 0.; - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1F* e = mNCl; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2714,7 +2714,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } } mPNCl->cd(); - for (int k = 0; k < ConfigNumInputs; k++) { + for (int32_t k = 0; k < ConfigNumInputs; k++) { TH1F* e = mNCl; if (GetHist(e, tin, k, nNewInput) == nullptr) { continue; @@ -2756,7 +2756,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) } if (tout && !mConfig.inputHistogramsOnly && mConfig.writeMCLabels) { - gInterpreter->GenerateDictionary("vector>", ""); + gInterpreter->GenerateDictionary("vector>", ""); tout->WriteObject(&mcEffBuffer, "mcEffBuffer"); tout->WriteObject(&mcLabelBuffer, "mcLabelBuffer"); remove("AutoDict_vector_vector_int__.cxx"); @@ -2768,7 +2768,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) if (tout) { tout->Close(); } - for (unsigned int i = 0; i < mConfig.compareInputs.size(); i++) { + for (uint32_t i = 0; i < mConfig.compareInputs.size(); i++) { tin[i]->Close(); } if (!qcout) { @@ -2779,7 +2779,7 @@ int GPUQA::DrawQAHistograms(TObjArray* qcout) return (0); } -void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned long n, unsigned long normalization) +void GPUQA::PrintClusterCount(int32_t mode, int32_t& num, const char* name, uint64_t n, uint64_t normalization) { if (mode == 2) { // do nothing, just count num @@ -2787,7 +2787,7 @@ void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned lon char name2[128]; snprintf(name2, 128, "clusterCount%d_", num); char* ptr = name2 + strlen(name2); - for (unsigned int i = 0; i < strlen(name); i++) { + for (uint32_t i = 0; i < strlen(name); i++) { if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') || (name[i] >= '0' && name[i] <= '9')) { *(ptr++) = name[i]; } @@ -2806,11 +2806,11 @@ void GPUQA::PrintClusterCount(int mode, int& num, const char* name, unsigned lon num++; } -int GPUQA::DoClusterCounts(unsigned long* attachClusterCounts, int mode) +int32_t GPUQA::DoClusterCounts(uint64_t* attachClusterCounts, int32_t mode) { - int num = 0; + int32_t num = 0; if (mcPresent() && (mQATasks & taskClusterAttach) && attachClusterCounts) { - for (int i = 0; i < N_CLS_HIST; i++) { + for (int32_t i = 0; i < N_CLS_HIST; i++) { PrintClusterCount(mode, num, CLUSTER_NAMES[i], attachClusterCounts[i], mClusterCounts.nTotal); } PrintClusterCount(mode, num, "Unattached", attachClusterCounts[N_CLS_HIST - 1] - attachClusterCounts[CL_att_adj], mClusterCounts.nTotal); diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index fbeedc8b1ff45..b3175d9fd32c7 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -29,7 +29,7 @@ class TH1D; class TObjArray; class TColor; class TGraphAsymmErrors; -typedef short int Color_t; +typedef int16_t Color_t; #if !defined(GPUCA_BUILD_QA) || defined(GPUCA_GPUCODE) @@ -42,18 +42,18 @@ class GPUQA public: GPUQA(void* chain) {} ~GPUQA() = default; - typedef int mcLabelI_t; - int InitQA(int tasks = 0) { return 1; } + typedef int32_t mcLabelI_t; + int32_t InitQA(int32_t tasks = 0) { return 1; } void RunQA(bool matchOnly = false) {} - int DrawQAHistograms() { return 1; } - void SetMCTrackRange(int min, int max) {} - bool SuppressTrack(int iTrack) const { return false; } - bool SuppressHit(int iHit) const { return false; } - int HitAttachStatus(int iHit) const { return false; } - mcLabelI_t GetMCTrackLabel(unsigned int trackId) const { return -1; } - bool clusterRemovable(int attach, bool prot) const { return false; } + int32_t DrawQAHistograms() { return 1; } + void SetMCTrackRange(int32_t min, int32_t max) {} + bool SuppressTrack(int32_t iTrack) const { return false; } + bool SuppressHit(int32_t iHit) const { return false; } + int32_t HitAttachStatus(int32_t iHit) const { return false; } + mcLabelI_t GetMCTrackLabel(uint32_t trackId) const { return -1; } + bool clusterRemovable(int32_t attach, bool prot) const { return false; } void DumpO2MCData(const char* filename) const {} - int ReadO2MCData(const char* filename) { return 1; } + int32_t ReadO2MCData(const char* filename) { return 1; } void* AllocateScratchBuffer(size_t nBytes) { return nullptr; } static bool QAAvailable() { return false; } static bool IsInitialized() { return false; } @@ -113,20 +113,20 @@ class GPUQA #endif void UpdateParam(const GPUParam* param) { mParam = param; } - int InitQA(int tasks = -1); + int32_t InitQA(int32_t tasks = -1); void RunQA(bool matchOnly = false, const std::vector* tracksExternal = nullptr, const std::vector* tracksExtMC = nullptr, const o2::tpc::ClusterNativeAccess* clNative = nullptr); - int DrawQAHistograms(TObjArray* qcout = nullptr); + int32_t DrawQAHistograms(TObjArray* qcout = nullptr); void DrawQAHistogramsCleanup(); // Needed after call to DrawQAHistograms with qcout != nullptr when GPUSettingsQA.shipToQCAsCanvas = true to clean up the Canvases etc. - void SetMCTrackRange(int min, int max); - bool SuppressTrack(int iTrack) const; - bool SuppressHit(int iHit) const; - int HitAttachStatus(int iHit) const; - mcLabelI_t GetMCTrackLabel(unsigned int trackId) const; - unsigned int GetMCLabelCol(const mcLabel_t& label) const; - bool clusterRemovable(int attach, bool prot) const; + void SetMCTrackRange(int32_t min, int32_t max); + bool SuppressTrack(int32_t iTrack) const; + bool SuppressHit(int32_t iHit) const; + int32_t HitAttachStatus(int32_t iHit) const; + mcLabelI_t GetMCTrackLabel(uint32_t trackId) const; + uint32_t GetMCLabelCol(const mcLabel_t& label) const; + bool clusterRemovable(int32_t attach, bool prot) const; void InitO2MCData(GPUTrackingInOutPointers* updateIOPtr = nullptr); void DumpO2MCData(const char* filename) const; - int ReadO2MCData(const char* filename); + int32_t ReadO2MCData(const char* filename); static bool QAAvailable() { return true; } bool IsInitialized() { return mQAInitialized; } void UpdateChain(GPUChainTracking* chain) { mTracking = chain; } @@ -136,13 +136,13 @@ class GPUQA const std::vector& getHistograms1Dd() const { return *mHist1Dd; } const std::vector& getGraphs() const { return *mHistGraph; } void resetHists(); - int loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3, std::vector& i4, int tasks = -1); + int32_t loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3, std::vector& i4, int32_t tasks = -1); void* AllocateScratchBuffer(size_t nBytes); - static constexpr int N_CLS_HIST = 8; - static constexpr int N_CLS_TYPE = 3; + static constexpr int32_t N_CLS_HIST = 8; + static constexpr int32_t N_CLS_TYPE = 3; - static constexpr int MC_LABEL_INVALID = -1e9; + static constexpr int32_t MC_LABEL_INVALID = -1e9; enum QA_TASKS { taskTrackingEff = 1, @@ -162,35 +162,35 @@ class GPUQA }; struct additionalClusterParameters { - int attached, fakeAttached, adjacent, fakeAdjacent; + int32_t attached, fakeAttached, adjacent, fakeAdjacent; float pt; }; - int InitQACreateHistograms(); - int DoClusterCounts(unsigned long* attachClusterCounts, int mode = 0); - void PrintClusterCount(int mode, int& num, const char* name, unsigned long n, unsigned long normalization); + int32_t InitQACreateHistograms(); + int32_t DoClusterCounts(uint64_t* attachClusterCounts, int32_t mode = 0); + void PrintClusterCount(int32_t mode, int32_t& num, const char* name, uint64_t n, uint64_t normalization); void CopyO2MCtoIOPtr(GPUTrackingInOutPointers* ptr); template void SetAxisSize(T* e); void SetLegend(TLegend* l); - double* CreateLogAxis(int nbins, float xmin, float xmax); + double* CreateLogAxis(int32_t nbins, float xmin, float xmax); void ChangePadTitleSize(TPad* p, float size); void DrawHisto(TH1* histo, char* filename, char* options); void doPerfFigure(float x, float y, float size); - void GetName(char* fname, int k); + void GetName(char* fname, int32_t k); template - T* GetHist(T*& ee, std::vector>& tin, int k, int nNewInput); + T* GetHist(T*& ee, std::vector>& tin, int32_t k, int32_t nNewInput); using mcInfo_t = GPUTPCMCInfo; #ifdef GPUCA_TPC_GEOMETRY_O2 - mcLabels_t GetMCLabel(unsigned int i); - mcLabel_t GetMCLabel(unsigned int i, unsigned int j); + mcLabels_t GetMCLabel(uint32_t i); + mcLabel_t GetMCLabel(uint32_t i, uint32_t j); #else struct mcLabelI_t { - int getTrackID() const { return AbsLabelID(track); } - int getEventID() const { return 0; } - int getSourceID() const { return 0; } - long getTrackEventSourceID() const { return getTrackID(); } + int32_t getTrackID() const { return AbsLabelID(track); } + int32_t getEventID() const { return 0; } + int32_t getSourceID() const { return 0; } + int64_t getTrackEventSourceID() const { return getTrackID(); } bool isFake() const { return track < 0; } bool isValid() const { return track != MC_LABEL_INVALID; } void invalidate() { track = MC_LABEL_INVALID; } @@ -200,31 +200,31 @@ class GPUQA bool operator!=(const mcLabel_t& l) { return !(*this == l); } mcLabelI_t() = default; mcLabelI_t(const mcLabel_t& l); - int track = MC_LABEL_INVALID; + int32_t track = MC_LABEL_INVALID; }; - const mcLabels_t& GetMCLabel(unsigned int i); - const mcLabel_t& GetMCLabel(unsigned int i, unsigned int j); + const mcLabels_t& GetMCLabel(uint32_t i); + const mcLabel_t& GetMCLabel(uint32_t i, uint32_t j); const mcInfo_t& GetMCTrack(const mcLabelI_t& label); - static int FakeLabelID(const int id); - static int AbsLabelID(const int id); + static int32_t FakeLabelID(const int32_t id); + static int32_t AbsLabelID(const int32_t id); #endif template auto& GetMCTrackObj(T& obj, const mcLabelI_t& l); - unsigned int GetNMCCollissions() const; - unsigned int GetNMCTracks(int iCol) const; - unsigned int GetNMCTracks(const mcLabelI_t& label) const; - unsigned int GetNMCLabels() const; - const mcInfo_t& GetMCTrack(unsigned int iTrk, unsigned int iCol); + uint32_t GetNMCCollissions() const; + uint32_t GetNMCTracks(int32_t iCol) const; + uint32_t GetNMCTracks(const mcLabelI_t& label) const; + uint32_t GetNMCLabels() const; + const mcInfo_t& GetMCTrack(uint32_t iTrk, uint32_t iCol); const mcInfo_t& GetMCTrack(const mcLabel_t& label); - int GetMCLabelNID(const mcLabels_t& label); - int GetMCLabelNID(unsigned int i); - int GetMCLabelID(unsigned int i, unsigned int j); - unsigned int GetMCLabelCol(unsigned int i, unsigned int j); - static int GetMCLabelID(const mcLabels_t& label, unsigned int j); - static int GetMCLabelID(const mcLabel_t& label); - float GetMCLabelWeight(unsigned int i, unsigned int j); - float GetMCLabelWeight(const mcLabels_t& label, unsigned int j); + int32_t GetMCLabelNID(const mcLabels_t& label); + int32_t GetMCLabelNID(uint32_t i); + int32_t GetMCLabelID(uint32_t i, uint32_t j); + uint32_t GetMCLabelCol(uint32_t i, uint32_t j); + static int32_t GetMCLabelID(const mcLabels_t& label, uint32_t j); + static int32_t GetMCLabelID(const mcLabel_t& label); + float GetMCLabelWeight(uint32_t i, uint32_t j); + float GetMCLabelWeight(const mcLabels_t& label, uint32_t j); float GetMCLabelWeight(const mcLabel_t& label); const auto& GetClusterLabels(); bool mcPresent(); @@ -240,23 +240,23 @@ class GPUQA std::vector mTrackMCLabels; #ifdef GPUCA_TPC_GEOMETRY_O2 - std::vector> mTrackMCLabelsReverse; - std::vector> mRecTracks; - std::vector> mFakeTracks; + std::vector> mTrackMCLabelsReverse; + std::vector> mRecTracks; + std::vector> mFakeTracks; std::vector> mMCParam; #else - std::vector mTrackMCLabelsReverse[1]; - std::vector mRecTracks[1]; - std::vector mFakeTracks[1]; + std::vector mTrackMCLabelsReverse[1]; + std::vector mRecTracks[1]; + std::vector mFakeTracks[1]; std::vector mMCParam[1]; #endif std::vector mMCInfos; std::vector mMCInfosCol; - std::vector mMCNEvents; - std::vector mMCEventOffset; + std::vector mMCNEvents; + std::vector mMCEventOffset; std::vector mClusterParam; - int mNTotalFakes = 0; + int32_t mNTotalFakes = 0; TH1F* mEff[4][2][2][5]; // eff,clone,fake,all - findable - secondaries - y,z,phi,eta,pt - work,result TGraphAsymmErrors* mEffResult[4][2][2][5]; @@ -290,7 +290,7 @@ class GPUQA TLegend* mLClust[N_CLS_TYPE]; struct counts_t { - long nRejected = 0, nTube = 0, nTube200 = 0, nLoopers = 0, nLowPt = 0, n200MeV = 0, nPhysics = 0, nProt = 0, nUnattached = 0, nTotal = 0, nHighIncl = 0, nAbove400 = 0, nFakeRemove400 = 0, nFullFakeRemove400 = 0, nBelow40 = 0, nFakeProtect40 = 0, nMergedLooper = 0; + int64_t nRejected = 0, nTube = 0, nTube200 = 0, nLoopers = 0, nLowPt = 0, n200MeV = 0, nPhysics = 0, nProt = 0, nUnattached = 0, nTotal = 0, nHighIncl = 0, nAbove400 = 0, nFakeRemove400 = 0, nFullFakeRemove400 = 0, nBelow40 = 0, nFakeProtect40 = 0, nMergedLooper = 0; double nUnaccessible = 0; } mClusterCounts; @@ -329,28 +329,28 @@ class GPUQA T* createGarbageCollected(Args... args); void clearGarbagageCollector(); - int mNEvents = 0; + int32_t mNEvents = 0; bool mQAInitialized = false; bool mO2MCDataLoaded = false; - int mQATasks = 0; - std::vector> mcEffBuffer; - std::vector> mcLabelBuffer; + int32_t mQATasks = 0; + std::vector> mcEffBuffer; + std::vector> mcLabelBuffer; std::vector> mGoodTracks; std::vector> mGoodHits; - std::vector mTrackingScratchBuffer; + std::vector mTrackingScratchBuffer; static std::vector mColors; - static int initColors(); + static int32_t initColors(); - int mMCTrackMin = -1, mMCTrackMax = -1; + int32_t mMCTrackMin = -1, mMCTrackMax = -1; const o2::tpc::ClusterNativeAccess* mClNative = nullptr; }; -inline bool GPUQA::SuppressTrack(int iTrack) const { return (mConfig.matchMCLabels.size() && !mGoodTracks[mNEvents][iTrack]); } -inline bool GPUQA::SuppressHit(int iHit) const { return (mConfig.matchMCLabels.size() && !mGoodHits[mNEvents - 1][iHit]); } -inline int GPUQA::HitAttachStatus(int iHit) const { return (mClusterParam.size() && mClusterParam[iHit].fakeAttached ? (mClusterParam[iHit].attached ? 1 : 2) : 0); } +inline bool GPUQA::SuppressTrack(int32_t iTrack) const { return (mConfig.matchMCLabels.size() && !mGoodTracks[mNEvents][iTrack]); } +inline bool GPUQA::SuppressHit(int32_t iHit) const { return (mConfig.matchMCLabels.size() && !mGoodHits[mNEvents - 1][iHit]); } +inline int32_t GPUQA::HitAttachStatus(int32_t iHit) const { return (mClusterParam.size() && mClusterParam[iHit].fakeAttached ? (mClusterParam[iHit].attached ? 1 : 2) : 0); } } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/qa/GPUQAHelper.h b/GPU/GPUTracking/qa/GPUQAHelper.h index e33b298a437b6..92da6bbac94e8 100644 --- a/GPU/GPUTracking/qa/GPUQAHelper.h +++ b/GPU/GPUTracking/qa/GPUQAHelper.h @@ -46,17 +46,17 @@ class GPUTPCTrkLbl mNCl = 0; mTotalWeight = 0.f; } - inline void addLabel(unsigned int elementId) + inline void addLabel(uint32_t elementId) { if constexpr (std::is_same::value) { - for (unsigned int i = 0; i < sizeof(mClusterLabels[elementId]) / sizeof(mClusterLabels[elementId].fClusterID[0]); i++) { + for (uint32_t i = 0; i < sizeof(mClusterLabels[elementId]) / sizeof(mClusterLabels[elementId].fClusterID[0]); i++) { const auto& element = mClusterLabels[elementId].fClusterID[i]; if (element.fMCID >= 0) { if constexpr (WEIGHT) { mTotalWeight += element.fWeight; } bool found = false; - for (unsigned int l = 0; l < mLabels.size(); l++) { + for (uint32_t l = 0; l < mLabels.size(); l++) { if (mLabels[l].first.fMCID == element.fMCID) { mLabels[l].second++; if constexpr (WEIGHT) { @@ -74,7 +74,7 @@ class GPUTPCTrkLbl } else { for (const auto& element : mClusterLabels->getLabels(elementId)) { bool found = false; - for (unsigned int l = 0; l < mLabels.size(); l++) { + for (uint32_t l = 0; l < mLabels.size(); l++) { if (mLabels[l].first == element) { mLabels[l].second++; found = true; @@ -88,13 +88,13 @@ class GPUTPCTrkLbl } mNCl++; } - inline U computeLabel(float* labelWeight = nullptr, float* totalWeight = nullptr, int* maxCount = nullptr) + inline U computeLabel(float* labelWeight = nullptr, float* totalWeight = nullptr, int32_t* maxCount = nullptr) { if (mLabels.size() == 0) { return U(); //default constructor creates NotSet label } else { - unsigned int bestLabelNum = 0, bestLabelCount = 0; - for (unsigned int j = 0; j < mLabels.size(); j++) { + uint32_t bestLabelNum = 0, bestLabelCount = 0; + for (uint32_t j = 0; j < mLabels.size(); j++) { if (mLabels[j].second > bestLabelCount) { bestLabelNum = j; bestLabelCount = mLabels[j].second; @@ -120,15 +120,15 @@ class GPUTPCTrkLbl private: const S* mClusterLabels; - std::vector> mLabels; + std::vector> mLabels; const float mTrackMCMaxFake; - unsigned int mNCl = 0; + uint32_t mNCl = 0; float mTotalWeight = 0.f; }; } // namespace internal struct GPUTPCTrkLbl_ret { - long id = -1; + int64_t id = -1; GPUTPCTrkLbl_ret() = default; template GPUTPCTrkLbl_ret(T){}; diff --git a/GPU/GPUTracking/qa/genEvents.cxx b/GPU/GPUTracking/qa/genEvents.cxx index 280a1eb025479..20c9b7bec096c 100644 --- a/GPU/GPUTracking/qa/genEvents.cxx +++ b/GPU/GPUTracking/qa/genEvents.cxx @@ -47,7 +47,7 @@ namespace GPUCA_NAMESPACE::gpu extern GPUSettingsStandalone configStandalone; } -int genEvents::GetSlice(double GlobalPhi) +int32_t genEvents::GetSlice(double GlobalPhi) { double phi = GlobalPhi; // std::cout<<" GetSlice: phi = "<Divide(3, 2); - int ipad = 1; - for (int j = 0; j < 2; j++) { - for (int i = 0; i < 3; i++) { + int32_t ipad = 1; + for (int32_t j = 0; j < 2; j++) { + for (int32_t i = 0; i < 3; i++) { c->cd(ipad++); - int k = i; + int32_t k = i; if (i == 1) { k = 2; } @@ -149,16 +149,16 @@ void genEvents::FinishEventGenerator() } } -int genEvents::GenerateEvent(const GPUParam& param, char* filename) +int32_t genEvents::GenerateEvent(const GPUParam& param, char* filename) { mRec->ClearIOPointers(); - static int iEvent = -1; + static int32_t iEvent = -1; iEvent++; if (iEvent == 0) { gRandom->SetSeed(configStandalone.seed); } - int nTracks = configStandalone.EG.numberOfTracks; // Number of MC tracks, must be at least as large as the largest fMCID assigned above + int32_t nTracks = configStandalone.EG.numberOfTracks; // Number of MC tracks, must be at least as large as the largest fMCID assigned above cout << "NTracks " << nTracks << endl; std::vector mcInfo(nTracks); memset(mcInfo.data(), 0, nTracks * sizeof(mcInfo[0])); @@ -176,11 +176,11 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) // Bz*=o2::gpu::gpu_common_constants::kCLight; std::vector vClusters; - int clusterId = 0; // Here we count up the cluster ids we fill (must be unique). + int32_t clusterId = 0; // Here we count up the cluster ids we fill (must be unique). // gRandom->SetSeed(0); - // unsigned int seed = gRandom->GetSeed(); + // uint32_t seed = gRandom->GetSeed(); - for (int itr = 0; itr < nTracks; itr++) { + for (int32_t itr = 0; itr < nTracks; itr++) { // std::cout<<"Track "<SetSeed(seed); @@ -206,7 +206,7 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) double pt = .08 * std::pow(10, gRandom->Uniform(0, 2.2)); double q = 1.; - int iSlice = GetSlice(phi); + int32_t iSlice = GetSlice(phi); phi = phi - GetSliceAngle(iSlice); // std::cout<<"phi = "<=50 ) break; //SG!!! float xRow = param.tpcGeometry.Row2X(iRow); // transport to row - int err = 0; - for (int itry = 0; itry < 1; itry++) { + int32_t err = 0; + for (int32_t itry = 0; itry < 1; itry++) { float B[3]; prop.GetBxByBz(GetSliceAngle(iSlice), t.GetX(), t.GetY(), t.GetZ(), B); float dLp = 0; @@ -242,7 +242,7 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) break; } // rotate track coordinate system to current sector - int isNewSlice = RecalculateSlice(t, iSlice); + int32_t isNewSlice = RecalculateSlice(t, iSlice); if (!isNewSlice) { break; } else { @@ -276,7 +276,7 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) GenCluster c; float sigmaY = 0.3; float sigmaZ = 0.5; - const int rowType = iRow < 64 ? 0 : iRow < 128 ? 2 : 1; + const int32_t rowType = iRow < 64 ? 0 : iRow < 128 ? 2 : 1; t.UpdateValues(); param.GetClusterErrors2(iSlice, rowType, t.GetZ(), t.GetSinPhi(), t.GetDzDs(), -1.f, 0.f, 0.f, sigmaY, sigmaZ); sigmaY = std::sqrt(sigmaY); @@ -295,16 +295,16 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) c.id = clusterId++; vClusters.push_back(c); } // iRow - } // itr + } // itr std::vector labels; std::unique_ptr clSlices[GPUChainTracking::NSLICES]; - for (int iSector = 0; iSector < (int)GPUChainTracking::NSLICES; iSector++) // HLT Sector numbering, sectors go from 0 to 35, all spanning all rows from 0 to 158. + for (int32_t iSector = 0; iSector < (int32_t)GPUChainTracking::NSLICES; iSector++) // HLT Sector numbering, sectors go from 0 to 35, all spanning all rows from 0 to 158. { - int nNumberOfHits = 0; - for (unsigned int i = 0; i < vClusters.size(); i++) { + int32_t nNumberOfHits = 0; + for (uint32_t i = 0; i < vClusters.size(); i++) { if (vClusters[i].sector == iSector) { nNumberOfHits++; } @@ -314,8 +314,8 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) GPUTPCClusterData* clusters = new GPUTPCClusterData[nNumberOfHits]; clSlices[iSector].reset(clusters); - int icl = 0; - for (unsigned int i = 0; i < vClusters.size(); i++) { + int32_t icl = 0; + for (uint32_t i = 0; i < vClusters.size(); i++) { GenCluster& c = vClusters[i]; if (c.sector == iSector) { clusters[icl].id = c.id; @@ -326,7 +326,7 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) clusters[icl].amp = 100; // Arbitrary amplitude icl++; AliHLTTPCClusterMCLabel clusterLabel; - for (int j = 0; j < 3; j++) { + for (int32_t j = 0; j < 3; j++) { clusterLabel.fClusterID[j].fMCID = -1; clusterLabel.fClusterID[j].fWeight = 0; } @@ -345,7 +345,7 @@ int genEvents::GenerateEvent(const GPUParam& param, char* filename) mRec->mIOPtrs.nMCInfosTPC = mcInfo.size(); mRec->mIOPtrs.mcInfosTPC = mcInfo.data(); - static const GPUTPCMCInfoCol mcColInfo = {0, (unsigned int)mcInfo.size()}; + static const GPUTPCMCInfoCol mcColInfo = {0, (uint32_t)mcInfo.size()}; mRec->mIOPtrs.mcInfosTPCCol = &mcColInfo; mRec->mIOPtrs.nMCInfosTPCCol = 1; @@ -365,7 +365,7 @@ void genEvents::RunEventGenerator(GPUChainTracking* rec) gen->InitEventGenerator(); - for (int i = 0; i < (configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents); i++) { + for (int32_t i = 0; i < (configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents); i++) { GPUInfo("Generating event %d/%d", i, configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents); snprintf(dirname, 256, "events/%s/" GPUCA_EVDUMP_FILE ".%d.dump", configStandalone.eventsDir, i); gen->GenerateEvent(rec->GetParam(), dirname); diff --git a/GPU/GPUTracking/qa/genEvents.h b/GPU/GPUTracking/qa/genEvents.h index b2ed2426ea439..943fa1e787674 100644 --- a/GPU/GPUTracking/qa/genEvents.h +++ b/GPU/GPUTracking/qa/genEvents.h @@ -30,7 +30,7 @@ class genEvents public: genEvents(GPUChainTracking* rec) {} void InitEventGenerator() {} - int GenerateEvent(const GPUParam& sliceParam, char* filename) { return 1; } + int32_t GenerateEvent(const GPUParam& sliceParam, char* filename) { return 1; } void FinishEventGenerator() {} static void RunEventGenerator(GPUChainTracking* rec){}; @@ -43,28 +43,28 @@ class genEvents public: genEvents(GPUChainTracking* rec) : mRec(rec) {} void InitEventGenerator(); - int GenerateEvent(const GPUParam& sliceParam, char* filename); + int32_t GenerateEvent(const GPUParam& sliceParam, char* filename); void FinishEventGenerator(); static void RunEventGenerator(GPUChainTracking* rec); private: - int GetSlice(double GlobalPhi); - int GetDSlice(double LocalPhi); - double GetSliceAngle(int iSlice); - int RecalculateSlice(GPUTPCGMPhysicalTrackModel& t, int& iSlice); + int32_t GetSlice(double GlobalPhi); + int32_t GetDSlice(double LocalPhi); + double GetSliceAngle(int32_t iSlice); + int32_t RecalculateSlice(GPUTPCGMPhysicalTrackModel& t, int32_t& iSlice); double GetGaus(double sigma); TH1F* mClusterError[3][2] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}}; struct GenCluster { - int sector; - int row; - int mcID; + int32_t sector; + int32_t row; + int32_t mcID; float x; float y; float z; - unsigned int id; + uint32_t id; }; const double mTwoPi = 2 * M_PI; diff --git a/GPU/GPUTracking/utils/linux_helpers.h b/GPU/GPUTracking/utils/linux_helpers.h index b9b17a3ab3be6..9de9f49d8207d 100644 --- a/GPU/GPUTracking/utils/linux_helpers.h +++ b/GPU/GPUTracking/utils/linux_helpers.h @@ -19,31 +19,31 @@ #include #include -static inline int getch() +static inline int32_t getch() { static struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); - int retVal = getchar(); + int32_t retVal = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); return (retVal); } -static inline int kbhit() +static inline int32_t kbhit() { termios term; tcgetattr(0, &term); termios term2 = term; term2.c_lflag &= ~ICANON; tcsetattr(0, TCSANOW, &term2); - int byteswaiting; + int32_t byteswaiting; ioctl(0, FIONREAD, &byteswaiting); tcsetattr(0, TCSANOW, &term); return byteswaiting > 0; } -static void inline Sleep(int msecs) { usleep(msecs * 1000); } +static void inline Sleep(int32_t msecs) { usleep(msecs * 1000); } #endif diff --git a/GPU/GPUTracking/utils/makefile_opencl_compiler.cxx b/GPU/GPUTracking/utils/makefile_opencl_compiler.cxx index a94509cf94db0..f6400cc3369e0 100644 --- a/GPU/GPUTracking/utils/makefile_opencl_compiler.cxx +++ b/GPU/GPUTracking/utils/makefile_opencl_compiler.cxx @@ -31,7 +31,7 @@ #define DEFAULT_OPENCL_COMPILER_OPTIONS "" #define DEFAULT_OUTPUT_FILE "opencl.out" -int main(int argc, char** argv) +int32_t main(int argc, char** argv) { const char* output_file = DEFAULT_OUTPUT_FILE; std::string compiler_options = DEFAULT_OPENCL_COMPILER_OPTIONS; @@ -39,7 +39,7 @@ int main(int argc, char** argv) printf("Passing command line options:\n"); bool add_option = false; - for (int i = 1; i < argc; i++) { + for (int32_t i = 1; i < argc; i++) { if (add_option) { compiler_options += " "; compiler_options += argv[i]; @@ -79,7 +79,7 @@ int main(int argc, char** argv) bool found = false; _makefiles_opencl_platform_info pinfo; - for (unsigned int i_platform = 0; i_platform < num_platforms; i_platform++) { + for (uint32_t i_platform = 0; i_platform < num_platforms; i_platform++) { clGetPlatformInfo(platforms[i_platform], CL_PLATFORM_PROFILE, 64, pinfo.platform_profile, nullptr); clGetPlatformInfo(platforms[i_platform], CL_PLATFORM_VERSION, 64, pinfo.platform_version, nullptr); clGetPlatformInfo(platforms[i_platform], CL_PLATFORM_NAME, 64, pinfo.platform_name, nullptr); @@ -114,7 +114,7 @@ int main(int argc, char** argv) cl_uint freq, shaders; printf("Available OPENCL devices:\n"); - for (unsigned int i = 0; i < pinfo.count; i++) { + for (uint32_t i = 0; i < pinfo.count; i++) { printf("Examining device %u\n", i); clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 64, dinfo.device_name, nullptr); @@ -123,7 +123,7 @@ int main(int argc, char** argv) clGetDeviceInfo(devices[i], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(freq), &freq, nullptr); clGetDeviceInfo(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(shaders), &shaders, nullptr); clGetDeviceInfo(devices[i], CL_DEVICE_ADDRESS_BITS, sizeof(dinfo.nbits), &dinfo.nbits, nullptr); - printf("Found Device %u : %s %s (Frequency %d, Shaders %d, %d bit)\n", i, dinfo.device_vendor, dinfo.device_name, (int)freq, (int)shaders, (int)dinfo.nbits); + printf("Found Device %u : %s %s (Frequency %d, Shaders %d, %d bit)\n", i, dinfo.device_vendor, dinfo.device_name, (int32_t)freq, (int32_t)shaders, (int32_t)dinfo.nbits); } if (files.size() == 0) { @@ -134,7 +134,7 @@ int main(int argc, char** argv) if (buffers == nullptr) { quit("Memory allocation error\n"); } - for (unsigned int i = 0; i < files.size(); i++) { + for (uint32_t i = 0; i < files.size(); i++) { printf("Reading source file %s\n", files[i]); FILE* fp = fopen(files[i], "rb"); if (fp == nullptr) { @@ -177,11 +177,11 @@ int main(int argc, char** argv) if (ocl_error != CL_SUCCESS) { fprintf(stderr, "OpenCL Error while building program: %d (Compiler options: %s)\n", ocl_error, compiler_options.c_str()); fprintf(stderr, "OpenCL Kernel:\n\n"); - for (unsigned int i = 0; i < files.size(); i++) { + for (uint32_t i = 0; i < files.size(); i++) { printf("%s\n\n", buffers[i]); } - for (unsigned int i = 0; i < pinfo.count; i++) { + for (uint32_t i = 0; i < pinfo.count; i++) { cl_build_status status; clGetProgramBuildInfo(program, devices[i], CL_PROGRAM_BUILD_STATUS, sizeof(status), &status, nullptr); if (status == CL_BUILD_ERROR) { @@ -197,7 +197,7 @@ int main(int argc, char** argv) } } } - for (unsigned int i = 0; i < files.size(); i++) { + for (uint32_t i = 0; i < files.size(); i++) { free(buffers[i]); } free(buffers); @@ -215,8 +215,8 @@ int main(int argc, char** argv) if (binary_buffers == nullptr) { quit("Memory allocation error"); } - for (unsigned int i = 0; i < pinfo.count; i++) { - printf("Binary size for device %d: %d\n", i, (int)binary_sizes[i]); + for (uint32_t i = 0; i < pinfo.count; i++) { + printf("Binary size for device %d: %d\n", i, (int32_t)binary_sizes[i]); binary_buffers[i] = (char*)malloc(binary_sizes[i]); memset(binary_buffers[i], 0, binary_sizes[i]); if (binary_buffers[i] == nullptr) { @@ -238,7 +238,7 @@ int main(int argc, char** argv) const char* magic_bytes = "QOCLPB"; fwrite(magic_bytes, 1, strlen(magic_bytes) + 1, fp); fwrite(&pinfo, 1, sizeof(pinfo), fp); - for (unsigned int i = 0; i < pinfo.count; i++) { + for (uint32_t i = 0; i < pinfo.count; i++) { clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 64, dinfo.device_name, nullptr); clGetDeviceInfo(devices[i], CL_DEVICE_VENDOR, 64, dinfo.device_vendor, nullptr); dinfo.binary_size = binary_sizes[i]; @@ -248,7 +248,7 @@ int main(int argc, char** argv) fclose(fp); printf("All done, cleaning up remaining buffers\n"); - for (unsigned int i = 0; i < pinfo.count; i++) { + for (uint32_t i = 0; i < pinfo.count; i++) { free(binary_buffers[i]); } free(binary_sizes); diff --git a/GPU/GPUTracking/utils/opencl_obtain_program.h b/GPU/GPUTracking/utils/opencl_obtain_program.h index b1e8e8dea7308..6c10ca9d47de1 100644 --- a/GPU/GPUTracking/utils/opencl_obtain_program.h +++ b/GPU/GPUTracking/utils/opencl_obtain_program.h @@ -19,7 +19,7 @@ #include #include "opencl_compiler_structs.h" -static int _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint num_devices, cl_device_id* devices, cl_program* program, char* binaries) +static int32_t _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint num_devices, cl_device_id* devices, cl_program* program, char* binaries) { const char* magic_bytes = "QOCLPB"; if (strncmp(magic_bytes, binaries, strlen(magic_bytes)) != 0) { @@ -39,7 +39,7 @@ static int _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint n std::vector program_sizes(pinfo->count); std::vector program_binaries(pinfo->count); - for (unsigned int i = 0; i < pinfo->count; i++) { + for (uint32_t i = 0; i < pinfo->count; i++) { char device_name[64], device_vendor[64]; cl_uint nbits; clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 64, device_name, nullptr); @@ -55,7 +55,7 @@ static int _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint n return (1); } current_ptr += sizeof(_makefiles_opencl_device_info); - // printf("Device %d: %s %s (size %ld)\n", i, dinfo->device_vendor, dinfo->device_name, (long) dinfo->binary_size); + // printf("Device %d: %s %s (size %ld)\n", i, dinfo->device_vendor, dinfo->device_name, (int64_t) dinfo->binary_size); program_sizes[i] = dinfo->binary_size; program_binaries[i] = current_ptr; current_ptr += dinfo->binary_size; @@ -63,14 +63,14 @@ static int _makefiles_opencl_obtain_program_helper(cl_context context, cl_uint n cl_int return_status[pinfo->count]; cl_int ocl_error; - *program = clCreateProgramWithBinary(context, num_devices, devices, program_sizes.data(), (const unsigned char**)program_binaries.data(), return_status, &ocl_error); + *program = clCreateProgramWithBinary(context, num_devices, devices, program_sizes.data(), (const uint8_t**)program_binaries.data(), return_status, &ocl_error); if (ocl_error != CL_SUCCESS) { printf("Error loading program\n"); return (1); } - for (unsigned int i = 0; i < pinfo->count; i++) { + for (uint32_t i = 0; i < pinfo->count; i++) { if (return_status[i] != CL_SUCCESS) { printf("Error loading program for device %d\n", i); clReleaseProgram(*program); diff --git a/GPU/GPUTracking/utils/pthread_mutex_win32_wrapper.h b/GPU/GPUTracking/utils/pthread_mutex_win32_wrapper.h index e61b1fd69d0cd..7d22c5ffd8431 100644 --- a/GPU/GPUTracking/utils/pthread_mutex_win32_wrapper.h +++ b/GPU/GPUTracking/utils/pthread_mutex_win32_wrapper.h @@ -29,20 +29,20 @@ typedef HANDLE sem_t; #define EAGAIN WAIT_TIMEOUT #endif -static inline int pthread_mutex_init(pthread_mutex_t* mutex, const void* attr) +static inline int32_t pthread_mutex_init(pthread_mutex_t* mutex, const void* attr) { *mutex = CreateSemaphore(nullptr, 1, 1, nullptr); // printf("INIT %d\n", *mutex); return ((*mutex) == nullptr); } -static inline int pthread_mutex_lock(pthread_mutex_t* mutex) +static inline int32_t pthread_mutex_lock(pthread_mutex_t* mutex) { // printf("LOCK %d\n", *mutex); return (WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED); } -static inline int pthread_mutex_trylock(pthread_mutex_t* mutex) +static inline int32_t pthread_mutex_trylock(pthread_mutex_t* mutex) { DWORD retVal = WaitForSingleObject(*mutex, 0); if (retVal == WAIT_TIMEOUT) { @@ -55,19 +55,19 @@ static inline int pthread_mutex_trylock(pthread_mutex_t* mutex) return (1); } -static inline int pthread_mutex_unlock(pthread_mutex_t* mutex) +static inline int32_t pthread_mutex_unlock(pthread_mutex_t* mutex) { // printf("UNLOCK %d\n", *mutex); return (ReleaseSemaphore(*mutex, 1, nullptr) == 0); } -static inline int pthread_mutex_destroy(pthread_mutex_t* mutex) { return (CloseHandle(*mutex) == 0); } +static inline int32_t pthread_mutex_destroy(pthread_mutex_t* mutex) { return (CloseHandle(*mutex) == 0); } -static inline int pthread_create(pthread_t* thread, const void* attr, void* (*start_routine)(void*), void* arg) { return ((*thread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, nullptr)) == 0); } +static inline int32_t pthread_create(pthread_t* thread, const void* attr, void* (*start_routine)(void*), void* arg) { return ((*thread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, nullptr)) == 0); } -static inline int pthread_exit(void* ret) { ExitThread((DWORD)(size_t)ret); } +static inline int32_t pthread_exit(void* ret) { ExitThread((DWORD)(size_t)ret); } -static inline int pthread_join(pthread_t thread, void** retval) +static inline int32_t pthread_join(pthread_t thread, void** retval) { static DWORD ExitCode; while (GetExitCodeThread(thread, &ExitCode) == STILL_ACTIVE) { @@ -79,17 +79,17 @@ static inline int pthread_join(pthread_t thread, void** retval) return (0); } -static inline int sem_init(sem_t* sem, int pshared, unsigned int value) +static inline int32_t sem_init(sem_t* sem, int32_t pshared, uint32_t value) { *sem = CreateSemaphore(nullptr, value, 1024, nullptr); return ((*sem) == nullptr); } -static inline int sem_destroy(sem_t* sem) { return (CloseHandle(*sem) == 0); } +static inline int32_t sem_destroy(sem_t* sem) { return (CloseHandle(*sem) == 0); } -static inline int sem_wait(sem_t* sem) { return (WaitForSingleObject(*sem, INFINITE) == WAIT_FAILED); } +static inline int32_t sem_wait(sem_t* sem) { return (WaitForSingleObject(*sem, INFINITE) == WAIT_FAILED); } -static inline int sem_trywait(sem_t* sem) +static inline int32_t sem_trywait(sem_t* sem) { DWORD retVal = WaitForSingleObject(*sem, 0); if (retVal == WAIT_TIMEOUT) { @@ -101,17 +101,17 @@ static inline int sem_trywait(sem_t* sem) return (-1); } -static inline int sem_post(sem_t* sem) { return (ReleaseSemaphore(*sem, 1, nullptr) == 0); } +static inline int32_t sem_post(sem_t* sem) { return (ReleaseSemaphore(*sem, 1, nullptr) == 0); } #ifdef CMODULES_PTHREAD_BARRIERS typedef SYNCHRONIZATION_BARRIER pthread_barrier_t; -static inline int pthread_barrier_destroy(pthread_barrier_t* b) { return (DeleteSynchronizationBarrier(b) == 0); } +static inline int32_t pthread_barrier_destroy(pthread_barrier_t* b) { return (DeleteSynchronizationBarrier(b) == 0); } -static inline int pthread_barrier_init(pthread_barrier_t* b, void* attr, unsigned count) { return (InitializeSynchronizationBarrier(b, count, -1) == 0); } +static inline int32_t pthread_barrier_init(pthread_barrier_t* b, void* attr, unsigned count) { return (InitializeSynchronizationBarrier(b, count, -1) == 0); } -static inline int pthread_barrier_wait(pthread_barrier_t* b) +static inline int32_t pthread_barrier_wait(pthread_barrier_t* b) { EnterSynchronizationBarrier(b, 0); return (0); diff --git a/GPU/GPUTracking/utils/qconfig.cxx b/GPU/GPUTracking/utils/qconfig.cxx index 1ce2395a4dad8..aadd4622a1497 100644 --- a/GPU/GPUTracking/utils/qconfig.cxx +++ b/GPU/GPUTracking/utils/qconfig.cxx @@ -20,7 +20,6 @@ #include #include #include -#include #include "qconfig.h" #include "qconfig_helpers.h" @@ -59,7 +58,7 @@ QCONFIG_SETTING_TEMPLATE(max) QCONFIG_SETTING_TEMPLATE(set) QCONFIG_SETTING_TEMPLATE(def) -static inline const char* getOptName(const char** argv, int i) +static inline const char* getOptName(const char** argv, int32_t i) { while (i > 1 && argv[i][0] != '-') { i--; @@ -81,11 +80,11 @@ struct qConfigSettings { }; template -static int qAddOptionType(qConfigSettings& settings, T& ref, int& i, const char** argv, const int argc, T def); +static int32_t qAddOptionType(qConfigSettings& settings, T& ref, int32_t& i, const char** argv, const int argc, T def); template static void qAddOptionMessage(qConfigSettings& settings, T& ref); template -static int qAddOptionMinMax(qConfigSettings& settings, T& ref, const char* arg); +static int32_t qAddOptionMinMax(qConfigSettings& settings, T& ref, const char* arg); template struct qSettingsType { @@ -93,24 +92,24 @@ struct qSettingsType { }; template struct qSettingsType> { - typedef int settingsType; + typedef int32_t settingsType; }; template struct qConfigTypeSpecialized { - static inline int qAddOptionMain(qConfigSettings& settings, T& ref, int& i, const char** argv, const int argc, T def); + static inline int32_t qAddOptionMain(qConfigSettings& settings, T& ref, int32_t& i, const char** argv, const int argc, T def); }; template struct qConfigTypeSpecialized> { - static inline int qAddOptionMain(qConfigSettings>::settingsType>& settings, std::tuple& ref, int& i, const char** argv, const int argc, std::tuple& def); + static inline int32_t qAddOptionMain(qConfigSettings>::settingsType>& settings, std::tuple& ref, int32_t& i, const char** argv, const int argc, std::tuple& def); }; // Main processing function for arguments template -inline int qConfigTypeSpecialized::qAddOptionMain(qConfigSettings& settings, T& ref, int& i, const char** argv, const int argc, T def) +inline int32_t qConfigTypeSpecialized::qAddOptionMain(qConfigSettings& settings, T& ref, int32_t& i, const char** argv, const int argc, T def) { - int retVal = 0; - int iOrg = i; + int32_t retVal = 0; + int32_t iOrg = i; if (settings.doSet) { ref = settings.set; } else if ((retVal = qAddOptionType(settings, ref, i, argv, argc, def))) { @@ -123,18 +122,18 @@ inline int qConfigTypeSpecialized::qAddOptionMain(qConfigSettings& setting return (0); } template -static inline int qAddOptionMainTupleElem(qConfigSettings::settingsType> settingsTup, T& ref, int& i, const char** argv, const int argc) +static inline int32_t qAddOptionMainTupleElem(qConfigSettings::settingsType> settingsTup, T& ref, int32_t& i, const char** argv, const int argc) { T def = T(); qConfigSettings settings = settingsTup; return (qAddOptionType(settings, ref, i, argv, argc, def)); } -template ::value> +template ::value> struct qAddOptionMainTupleStruct { - static inline int qAddOptionMainTuple(qConfigSettings::settingsType> settings, T& tup, int& i, const char** argv, const int argc) + static inline int32_t qAddOptionMainTuple(qConfigSettings::settingsType> settings, T& tup, int32_t& i, const char** argv, const int argc) { auto& ref = std::get(tup); - int retVal = qAddOptionMainTupleElem(settings, ref, i, argv, argc); + int32_t retVal = qAddOptionMainTupleElem(settings, ref, i, argv, argc); if (retVal) { if (retVal == qcrArgMissing && index != 0) { printf("Invalid number of arguments for option %s\n", getOptName(argv, i)); @@ -145,12 +144,12 @@ struct qAddOptionMainTupleStruct { return (qAddOptionMainTupleStruct::qAddOptionMainTuple(settings, tup, i, argv, argc)); } }; -template +template struct qAddOptionMainTupleStruct { - static inline int qAddOptionMainTuple(qConfigSettings::settingsType> /*settings*/, T& /*tup*/, int& /*i*/, const char** /*argv*/, const int /*argc*/) { return 0; } + static inline int32_t qAddOptionMainTuple(qConfigSettings::settingsType> /*settings*/, T& /*tup*/, int32_t& /*i*/, const char** /*argv*/, const int32_t /*argc*/) { return 0; } }; template -inline int qConfigTypeSpecialized>::qAddOptionMain(qConfigSettings>::settingsType>& settings, std::tuple& ref, int& i, const char** argv, const int argc, std::tuple& /*def*/) +inline int32_t qConfigTypeSpecialized>::qAddOptionMain(qConfigSettings>::settingsType>& settings, std::tuple& ref, int32_t& i, const char** argv, const int argc, std::tuple& /*def*/) { return (qAddOptionMainTupleStruct>::qAddOptionMainTuple(settings, ref, i, argv, argc)); } @@ -191,22 +190,22 @@ struct qConfigType { } template - static inline int qAddOption(T& ref, int& i, const char** argv, const int argc, T def, const char* /*help*/, Args&&... args) + static inline int32_t qAddOption(T& ref, int32_t& i, const char** argv, const int argc, T def, const char* /*help*/, Args&&... args) { auto settings = qConfigGetSettings(args...); return qConfigTypeSpecialized::qAddOptionMain(settings, ref, i, argv, argc, def); } template - static inline int qAddOptionVec(std::vector& ref, int& i, const char** argv, const int argc, const char* /*help*/, Args&&... args) + static inline int32_t qAddOptionVec(std::vector& ref, int32_t& i, const char** argv, const int argc, const char* /*help*/, Args&&... args) { auto settings = qConfigGetSettings(args...); - int iFirst = i, iLast; + int32_t iFirst = i, iLast; do { iLast = i; T tmp = T(), def = T(); settings.allowEmpty = (i != iFirst); - int retVal = qConfigTypeSpecialized::qAddOptionMain(settings, tmp, i, argv, argc, def); + int32_t retVal = qConfigTypeSpecialized::qAddOptionMain(settings, tmp, i, argv, argc, def); if (retVal) { return (retVal != qcrArgMissing || i == iFirst ? retVal : 0); } @@ -218,15 +217,15 @@ struct qConfigType { } template - static inline int qAddOptionArray(T* ref, int count, int& i, const char** argv, const int argc, const char* /*help*/, Args&&... args) + static inline int32_t qAddOptionArray(T* ref, int32_t count, int32_t& i, const char** argv, const int argc, const char* /*help*/, Args&&... args) { auto settings = qConfigGetSettings(args...); - int iFirst = i, iLast; + int32_t iFirst = i, iLast; do { iLast = i; T tmp = T(), def = T(); settings.allowEmpty = (i != iFirst); - int retVal = qConfigTypeSpecialized::qAddOptionMain(settings, tmp, i, argv, argc, def); + int32_t retVal = qConfigTypeSpecialized::qAddOptionMain(settings, tmp, i, argv, argc, def); if (retVal) { return (retVal != qcrArgMissing || i == iFirst ? retVal : 0); } @@ -242,13 +241,13 @@ struct qConfigType { } template - static inline void qConfigHelpOption(const char* name, const char* type, const char* def, const char* optname, char optnameshort, const char* preopt, char preoptshort, int optionType, const char* help, Args&&... args) + static inline void qConfigHelpOption(const char* name, const char* type, const char* def, const char* optname, char optnameshort, const char* preopt, char preoptshort, int32_t optionType, const char* help, Args&&... args) { auto settings = qConfigGetSettings(args...); const bool boolType = optionType != 1 && std::is_same::value; const char* arguments = settings.doSet ? " (" : (settings.doDefault || optionType == 1 || boolType) ? " [arg] (" : optionType == 2 ? " [...] (" : " arg ("; char argBuffer[4] = {0}; - unsigned int argBufferPos = 0; + uint32_t argBufferPos = 0; if (optnameshort && preoptshort) { argBuffer[argBufferPos++] = '-'; } @@ -298,7 +297,7 @@ struct qConfigType { } }; -static inline const char* getArg(int& i, const char** argv, const int argc, bool allowOption = false) +static inline const char* getArg(int32_t& i, const char** argv, const int argc, bool allowOption = false) { if (i + 1 < argc && argv[i + 1][0] && ((allowOption && argv[i + 1][0] == '-' && argv[i + 1][1] != '-') || argv[i + 1][0] != '-')) { return (argv[++i]); @@ -307,7 +306,7 @@ static inline const char* getArg(int& i, const char** argv, const int argc, bool } template -static inline int qAddOptionGeneric(qConfigSettings& settings, T& ref, int& i, const char** argv, const int argc, T def, std::function func, bool allowDefault = false) +static inline int32_t qAddOptionGeneric(qConfigSettings& settings, T& ref, int32_t& i, const char** argv, const int argc, T def, std::function func, bool allowDefault = false) { const char* arg = getArg(i, argv, argc, !allowDefault); if (arg) { @@ -325,7 +324,7 @@ static inline int qAddOptionGeneric(qConfigSettings& settings, T& ref, int& i // Handling of all supported types template <> -inline int qAddOptionType(qConfigSettings& settings, bool& ref, int& i, const char** argv, const int argc, bool /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, bool& ref, int32_t& i, const char** argv, const int argc, bool /*def*/) { return qAddOptionGeneric( settings, ref, i, argv, argc, settings.doDefault ? settings.set : true, [](const char* a) -> bool { @@ -334,79 +333,79 @@ inline int qAddOptionType(qConfigSettings& settings, bool& ref, int& true); } template <> -inline int qAddOptionType(qConfigSettings& settings, signed char& ref, int& i, const char** argv, const int argc, signed char /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, int8_t& ref, int32_t& i, const char** argv, const int argc, int8_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> signed char { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> int8_t { return atoi(a); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, unsigned char& ref, int& i, const char** argv, const int argc, unsigned char /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, uint8_t& ref, int32_t& i, const char** argv, const int argc, uint8_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> unsigned char { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> uint8_t { return atoi(a); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, int& ref, int& i, const char** argv, const int argc, int /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, int32_t& ref, int32_t& i, const char** argv, const int argc, int32_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> int { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> int32_t { return atoi(a); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, unsigned int& ref, int& i, const char** argv, const int argc, unsigned int /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, uint32_t& ref, int32_t& i, const char** argv, const int argc, uint32_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> unsigned int { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> uint32_t { return strtoul(a, nullptr, 0); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, short& ref, int& i, const char** argv, const int argc, short /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, int16_t& ref, int32_t& i, const char** argv, const int argc, int16_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> short { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> int16_t { return atoi(a); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, unsigned short& ref, int& i, const char** argv, const int argc, unsigned short /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, uint16_t& ref, int32_t& i, const char** argv, const int argc, uint16_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> unsigned short { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> uint16_t { return strtoul(a, nullptr, 0); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, long& ref, int& i, const char** argv, const int argc, long /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, int64_t& ref, int32_t& i, const char** argv, const int argc, int64_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> long { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> int64_t { return strtoll(a, nullptr, 0); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, unsigned long& ref, int& i, const char** argv, const int argc, unsigned long /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, uint64_t& ref, int32_t& i, const char** argv, const int argc, uint64_t /*def*/) { - return qAddOptionGeneric( - settings, ref, i, argv, argc, settings.set, [](const char* a) -> unsigned long { + return qAddOptionGeneric( + settings, ref, i, argv, argc, settings.set, [](const char* a) -> uint64_t { return strtoull(a, nullptr, 0); }, settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, float& ref, int& i, const char** argv, const int argc, float /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, float& ref, int32_t& i, const char** argv, const int argc, float /*def*/) { return qAddOptionGeneric( settings, ref, i, argv, argc, settings.set, [](const char* a) -> float { @@ -415,7 +414,7 @@ inline int qAddOptionType(qConfigSettings& settings, float& ref, i settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, double& ref, int& i, const char** argv, const int argc, double /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, double& ref, int32_t& i, const char** argv, const int argc, double /*def*/) { return qAddOptionGeneric( settings, ref, i, argv, argc, settings.set, [](const char* a) -> double { @@ -424,7 +423,7 @@ inline int qAddOptionType(qConfigSettings& settings, double& ref settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, const char*& ref, int& i, const char** argv, const int argc, const char* /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, const char*& ref, int32_t& i, const char** argv, const int argc, const char* /*def*/) { return qAddOptionGeneric( settings, ref, i, argv, argc, settings.set, [](const char* a) -> const char* { @@ -433,7 +432,7 @@ inline int qAddOptionType(qConfigSettings& settings, c settings.doDefault); } template <> -inline int qAddOptionType(qConfigSettings& settings, std::string& ref, int& i, const char** argv, const int argc, std::string /*def*/) +inline int32_t qAddOptionType(qConfigSettings& settings, std::string& ref, int32_t& i, const char** argv, const int argc, std::string /*def*/) { return qAddOptionGeneric( settings, ref, i, argv, argc, settings.set, [](const char* a) -> std::string { @@ -444,7 +443,7 @@ inline int qAddOptionType(qConfigSettings& settings, s // Checks and messages for additional settings template -static inline int qAddOptionMinMax(qConfigSettings& settings, T& ref, const char* arg) +static inline int32_t qAddOptionMinMax(qConfigSettings& settings, T& ref, const char* arg) { if (settings.checkMin && ref < settings.min) { std::cout << "Invalid setting for " << arg << ": minimum threshold exceeded (" << ref << " < " << settings.min << ")!\n"; @@ -457,7 +456,7 @@ static inline int qAddOptionMinMax(qConfigSettings& settings, T& ref, const c return (0); } template <> -inline int qAddOptionMinMax(qConfigSettings& /*settings*/, bool& /*ref*/, const char* /*arg*/) +inline int32_t qAddOptionMinMax(qConfigSettings& /*settings*/, bool& /*ref*/, const char* /*arg*/) { return (0); } @@ -472,7 +471,7 @@ inline void qAddOptionMessage(qConfigSettings& settings, T& ref) } } -static inline void qConfigHelp(const char* subConfig = nullptr, int followSub = 0) +static inline void qConfigHelp(const char* subConfig = nullptr, int32_t followSub = 0) { if (followSub < 2) { printf("Usage Info:"); @@ -486,9 +485,9 @@ static inline void qConfigHelp(const char* subConfig = nullptr, int followSub = } // Create parser for configuration -static inline int qConfigParse(int argc, const char** argv, const char* /*filename*/) +static inline int32_t qConfigParse(int argc, const char** argv, const char* /*filename*/) { - for (int i = 1; i < argc; i++) { + for (int32_t i = 1; i < argc; i++) { const char* thisoption = argv[i]; repeat: bool found = false; @@ -511,7 +510,7 @@ std::vector> qprint_global; } // end namespace qConfig // Main parse function called from outside -int qConfigParse(int argc, const char** argv, const char* filename) { return (qConfig::qConfigParse(argc, argv, filename)); } +int32_t qConfigParse(int argc, const char** argv, const char* filename) { return (qConfig::qConfigParse(argc, argv, filename)); } void qConfigPrint() { diff --git a/GPU/GPUTracking/utils/qconfig.h b/GPU/GPUTracking/utils/qconfig.h index 855df80e3b53a..d19ad370acc7d 100644 --- a/GPU/GPUTracking/utils/qconfig.h +++ b/GPU/GPUTracking/utils/qconfig.h @@ -14,7 +14,11 @@ #ifndef QCONFIG_H_GENERAL #define QCONFIG_H_GENERAL -extern int qConfigParse(int argc, const char** argv, const char* filename = nullptr); +#ifndef GPUCA_GPUCODE_DEVICE +#include +#endif + +extern int32_t qConfigParse(int argc, const char** argv, const char* filename = nullptr); extern void qConfigPrint(); namespace qConfig { @@ -44,40 +48,40 @@ enum qConfigRetVal { qcrOK = 0, (preoptshort == 0 && thisoption[1] == optnameshort && thisoption[2] == 0) || (thisoption[1] == '-' && strlen(preopt) == 0 && strcmp(&thisoption[2], name) == 0) || \ (preoptshort != 0 && thisoption[1] == preoptshort && thisoption[2] == optnameshort && thisoption[3] == 0) || (thisoption[1] == '-' && strlen(preopt) && strncmp(&thisoption[2], preopt, strlen(preopt)) == 0 && strcmp(&thisoption[2 + strlen(preopt)], name) == 0))) -#define AddOption(name, type, default, optname, optnameshort, ...) \ - else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ - { \ - int retVal = qConfigType::qAddOption(tmp.name, i, argv, argc, default, __VA_ARGS__); \ - if (retVal) { \ - return (retVal); \ - } \ +#define AddOption(name, type, default, optname, optnameshort, ...) \ + else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ + { \ + int32_t retVal = qConfigType::qAddOption(tmp.name, i, argv, argc, default, __VA_ARGS__); \ + if (retVal) { \ + return (retVal); \ + } \ } -#define AddOptionSet(name, type, value, optname, optnameshort, ...) \ - else if (QCONFIG_COMPARE(optname, "", optnameshort)) \ - { \ - int retVal = qConfigType::qAddOption(tmp.name, i, nullptr, 0, value, __VA_ARGS__, set(value)); \ - if (retVal) { \ - return (retVal); \ - } \ +#define AddOptionSet(name, type, value, optname, optnameshort, ...) \ + else if (QCONFIG_COMPARE(optname, "", optnameshort)) \ + { \ + int32_t retVal = qConfigType::qAddOption(tmp.name, i, nullptr, 0, value, __VA_ARGS__, set(value)); \ + if (retVal) { \ + return (retVal); \ + } \ } -#define AddOptionVec(name, type, optname, optnameshort, ...) \ - else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ - { \ - int retVal = qConfigType::qAddOptionVec(tmp.name, i, argv, argc, __VA_ARGS__); \ - if (retVal) { \ - return (retVal); \ - } \ +#define AddOptionVec(name, type, optname, optnameshort, ...) \ + else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ + { \ + int32_t retVal = qConfigType::qAddOptionVec(tmp.name, i, argv, argc, __VA_ARGS__); \ + if (retVal) { \ + return (retVal); \ + } \ } -#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) \ - else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ - { \ - int retVal = qConfigType::qAddOptionArray(tmp.name, count, i, argv, argc, __VA_ARGS__); \ - if (retVal) { \ - return (retVal); \ - } \ +#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) \ + else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \ + { \ + int32_t retVal = qConfigType::qAddOptionArray(tmp.name, count, i, argv, argc, __VA_ARGS__); \ + if (retVal) { \ + return (retVal); \ + } \ } #define AddSubConfig(name, instance) @@ -140,14 +144,14 @@ enum qConfigRetVal { qcrOK = 0, } \ } -#define AddShortcut(cmd, cmdshort, forward, help, ...) \ - else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \ - { \ - const char* options[] = {"", __VA_ARGS__, nullptr}; \ - const int nOptions = sizeof(options) / sizeof(options[0]) - 1; \ - qConfigParse(nOptions, options, nullptr); \ - thisoption = forward; \ - goto repeat; \ +#define AddShortcut(cmd, cmdshort, forward, help, ...) \ + else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \ + { \ + const char* options[] = {"", __VA_ARGS__, nullptr}; \ + const int32_t nOptions = sizeof(options) / sizeof(options[0]) - 1; \ + qConfigParse(nOptions, options, nullptr); \ + thisoption = forward; \ + goto repeat; \ } // End QCONFIG_PARSE @@ -189,21 +193,21 @@ enum qConfigRetVal { qcrOK = 0, #define AddOption(name, type, default, optname, optnameshort, ...) std::cout << "\t" << blockName << qon_mxstr(name) << ": " << qConfig::print_type(qconfig_tmp_object.name) << "\n"; #define AddVariable(name, type, default) std::cout << "\t" << blockName << qon_mxstr(name) << ": " << qConfig::print_type(qconfig_tmp_object.name) << "\n"; #define AddOptionSet(name, type, value, optname, optnameshort, ...) -#define AddOptionVec(name, type, optname, optnameshort, ...) \ - { \ - std::cout << "\t" << blockName << qon_mxstr(name) << "[]: "; \ - for (unsigned int i = 0; i < qconfig_tmp_object.name.size(); i++) { \ - if (i) { \ - std::cout << ", "; \ - } \ - std::cout << qConfig::print_type(qconfig_tmp_object.name[i]); \ - } \ - std::cout << "\n"; \ +#define AddOptionVec(name, type, optname, optnameshort, ...) \ + { \ + std::cout << "\t" << blockName << qon_mxstr(name) << "[]: "; \ + for (uint32_t i = 0; i < qconfig_tmp_object.name.size(); i++) { \ + if (i) { \ + std::cout << ", "; \ + } \ + std::cout << qConfig::print_type(qconfig_tmp_object.name[i]); \ + } \ + std::cout << "\n"; \ } #define AddOptionArray(name, type, count, default, optname, optnameshort, ...) \ { \ std::cout << "\t" << blockName << qon_mxstr(name) << "[" << count << "]: " << qConfig::print_type(qconfig_tmp_object.name[0]); \ - for (int i = 1; i < count; i++) { \ + for (int32_t i = 1; i < count; i++) { \ std::cout << ", " << qConfig::print_type(qconfig_tmp_object.name[i]); \ } \ std::cout << "\n"; \ @@ -257,7 +261,7 @@ enum qConfigRetVal { qcrOK = 0, #define AddOptionArrayRTC(name, type, count, default, optname, optnameshort, help, ...) \ if (useConstexpr) { \ out << "static constexpr " << qon_mxstr(type) << " " << qon_mxstr(name) << "[" << count << "] = {" << qConfig::print_type(std::get(tSrc)->name[0]); \ - for (int i = 1; i < count; i++) { \ + for (int32_t i = 1; i < count; i++) { \ out << ", " << qConfig::print_type(std::get(tSrc)->name[i]); \ } \ out << "};\n"; \ diff --git a/GPU/GPUTracking/utils/qconfig_helpers.h b/GPU/GPUTracking/utils/qconfig_helpers.h index a873e618b05c6..e721f08ccfa90 100644 --- a/GPU/GPUTracking/utils/qconfig_helpers.h +++ b/GPU/GPUTracking/utils/qconfig_helpers.h @@ -42,12 +42,12 @@ inline std::string print_type(char val) return std::to_string(val); }; template <> -inline std::string print_type(signed char val) +inline std::string print_type(int8_t val) { return std::to_string(val); }; template <> -inline std::string print_type(unsigned char val) +inline std::string print_type(uint8_t val) { return std::to_string(val); }; diff --git a/GPU/GPUTracking/utils/qsem.cxx b/GPU/GPUTracking/utils/qsem.cxx index 3109a6c2608f0..220dbc859a205 100644 --- a/GPU/GPUTracking/utils/qsem.cxx +++ b/GPU/GPUTracking/utils/qsem.cxx @@ -21,7 +21,7 @@ #define STD_OUT stdout #endif -qSem::qSem(int num) +qSem::qSem(int32_t num) { max = num; if (sem_init(&sem, 0, num)) { @@ -36,27 +36,27 @@ qSem::~qSem() } } -int qSem::Lock() +int32_t qSem::Lock() { - int retVal; + int32_t retVal; if ((retVal = sem_wait(&sem))) { fprintf(STD_OUT, "Error locking semaphore"); } return (retVal); } -int qSem::Unlock() +int32_t qSem::Unlock() { - int retVal; + int32_t retVal; if ((retVal = sem_post(&sem))) { fprintf(STD_OUT, "Error unlocking semaphire"); } return (retVal); } -int qSem::Trylock() +int32_t qSem::Trylock() { - int retVal = sem_trywait(&sem); + int32_t retVal = sem_trywait(&sem); if (retVal) { if (errno == EAGAIN) { return (EBUSY); @@ -67,9 +67,9 @@ int qSem::Trylock() } #ifndef _WIN32 -int qSem::Query() +int32_t qSem::Query() { - int value; + int32_t value; if (sem_getvalue(&sem, &value) != 0) { value = -1; } diff --git a/GPU/GPUTracking/utils/qsem.h b/GPU/GPUTracking/utils/qsem.h index 08d3bcfeaa50f..9ea48b6ab3075 100644 --- a/GPU/GPUTracking/utils/qsem.h +++ b/GPU/GPUTracking/utils/qsem.h @@ -24,16 +24,16 @@ class qSem { public: - qSem(int num = 1); + qSem(int32_t num = 1); ~qSem(); - int Lock(); - int Unlock(); - int Trylock(); - int Query(); + int32_t Lock(); + int32_t Unlock(); + int32_t Trylock(); + int32_t Query(); private: - int max; + int32_t max; sem_t sem; }; diff --git a/GPU/GPUTracking/utils/strtag.h b/GPU/GPUTracking/utils/strtag.h index 00a84fc680d33..69e79de004779 100644 --- a/GPU/GPUTracking/utils/strtag.h +++ b/GPU/GPUTracking/utils/strtag.h @@ -18,17 +18,18 @@ #include #include -template +template #if defined(__cplusplus) && __cplusplus >= 201402L constexpr #endif -T qStr2Tag(const char* str) + T + qStr2Tag(const char* str) { if (strlen(str) != sizeof(T)) { throw std::runtime_error("Invalid tag length"); } T tmp; - for (unsigned int i = 0; i < sizeof(T); i++) { + for (uint32_t i = 0; i < sizeof(T); i++) { ((char*)&tmp)[i] = str[i]; } return tmp; diff --git a/GPU/GPUTracking/utils/threadserver.h b/GPU/GPUTracking/utils/threadserver.h index 0e3204993a484..606531f46f201 100644 --- a/GPU/GPUTracking/utils/threadserver.h +++ b/GPU/GPUTracking/utils/threadserver.h @@ -39,7 +39,7 @@ class qThreadParam public: qThreadParam() { - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { threadMutex[i].Lock(); } terminate = false; @@ -48,7 +48,7 @@ class qThreadParam ~qThreadParam() { - for (int i = 0; i < 2; i++) { + for (int32_t i = 0; i < 2; i++) { threadMutex[i].Unlock(); } } @@ -60,10 +60,10 @@ class qThreadParam return (!terminate); } - int threadNum; + int32_t threadNum; protected: - int pinCPU; + int32_t pinCPU; qSem threadMutex[2]; volatile bool terminate; }; @@ -87,13 +87,13 @@ class qThreadCls { public: qThreadCls() { started = false; }; - qThreadCls(S* pCls, void (S::*pFunc)(T*), int threadNum = 0, int pinCPU = -1) : threadParam() + qThreadCls(S* pCls, void (S::*pFunc)(T*), int32_t threadNum = 0, int32_t pinCPU = -1) : threadParam() { started = false; SpawnThread(pCls, pFunc, threadNum, pinCPU); } - void SpawnThread(S* pCls, void (S::*pFunc)(T*), int threadNum = 0, int pinCPU = -1, bool wait = true) + void SpawnThread(S* pCls, void (S::*pFunc)(T*), int32_t threadNum = 0, int32_t pinCPU = -1, bool wait = true) { qThreadParamCls& XthreadParam = *((qThreadParamCls*)&this->threadParam); @@ -167,14 +167,14 @@ class qThreadClsArray pArray = nullptr; nThreadsRunning = 0; } - qThreadClsArray(int n, S* pCls, void (S::*pFunc)(T*), int threadNumOffset = 0, int* pinCPU = nullptr) + qThreadClsArray(int32_t n, S* pCls, void (S::*pFunc)(T*), int32_t threadNumOffset = 0, int32_t* pinCPU = nullptr) { pArray = nullptr; nThreadsRunning = 0; SetNumberOfThreads(n, pCls, pFunc, threadNumOffset, pinCPU); } - void SetNumberOfThreads(int n, S* pCls, void (S::*pFunc)(T*), int threadNumOffset = 0, int* pinCPU = nullptr) + void SetNumberOfThreads(int32_t n, S* pCls, void (S::*pFunc)(T*), int32_t threadNumOffset = 0, int32_t* pinCPU = nullptr) { if (nThreadsRunning) { fprintf(STD_OUT, "Threads already started\n"); @@ -182,10 +182,10 @@ class qThreadClsArray } pArray = new qThreadCls[n]; nThreadsRunning = n; - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { pArray[i].SpawnThread(pCls, pFunc, threadNumOffset + i, pinCPU == nullptr ? -1 : pinCPU[i], false); } - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { pArray[i].WaitForSpawn(); } } @@ -205,21 +205,21 @@ class qThreadClsArray void Start() { - for (int i = 0; i < nThreadsRunning; i++) { + for (int32_t i = 0; i < nThreadsRunning; i++) { pArray[i].Start(); } } void Sync() { - for (int i = 0; i < nThreadsRunning; i++) { + for (int32_t i = 0; i < nThreadsRunning; i++) { pArray[i].Sync(); } } private: qThreadCls* pArray; - int nThreadsRunning; + int32_t nThreadsRunning; }; #endif diff --git a/GPU/GPUTracking/utils/timer.h b/GPU/GPUTracking/utils/timer.h index 3816f49f3024d..6365a63263cfe 100644 --- a/GPU/GPUTracking/utils/timer.h +++ b/GPU/GPUTracking/utils/timer.h @@ -15,6 +15,8 @@ #ifndef QONMODULE_TIMER_H #define QONMODULE_TIMER_H +#include + class HighResTimer { public: @@ -28,13 +30,13 @@ class HighResTimer double GetElapsedTime(); double GetCurrentElapsedTime(bool reset = false); void StopAndStart(HighResTimer& startTimer); - int IsRunning() { return running; } + int32_t IsRunning() { return running; } void AddTime(double t); private: double ElapsedTime = 0.; double StartTime = 0.; - int running = 0; + int32_t running = 0; static double GetFrequency(); static double GetTime(); diff --git a/GPU/GPUbenchmark/Shared/Kernels.h b/GPU/GPUbenchmark/Shared/Kernels.h index 900b683f24219..6fed2c2eb753d 100644 --- a/GPU/GPUbenchmark/Shared/Kernels.h +++ b/GPU/GPUbenchmark/Shared/Kernels.h @@ -43,28 +43,28 @@ class GPUbenchmark final template float runSequential(void (*kernel)(chunk_t*, size_t, T...), std::pair& chunkRanges, - int nLaunches, - int dimGrid, - int dimBlock, + int32_t nLaunches, + int32_t dimGrid, + int32_t dimBlock, T&... args); // Multi-streams asynchronous executions template std::vector runConcurrent(void (*kernel)(chunk_t*, size_t, T...), std::vector>& chunkRanges, - int nLaunches, - int dimStreams, - int nBlocks, - int nThreads, + int32_t nLaunches, + int32_t dimStreams, + int32_t nBlocks, + int32_t nThreads, T&... args); // Single stream executions on all chunks at a time by same kernel template float runDistributed(void (*kernel)(chunk_t**, size_t*, T...), std::vector>& chunkRanges, - int nLaunches, + int32_t nLaunches, size_t nBlocks, - int nThreads, + int32_t nThreads, T&... args); // Main interface diff --git a/GPU/GPUbenchmark/Shared/Utils.h b/GPU/GPUbenchmark/Shared/Utils.h index 97d6788eb01de..fc3345a704b65 100644 --- a/GPU/GPUbenchmark/Shared/Utils.h +++ b/GPU/GPUbenchmark/Shared/Utils.h @@ -137,14 +137,14 @@ inline std::ostream& operator<<(std::ostream& os, KernelConfig config) template inline std::string getType() { - if (typeid(T).name() == typeid(char).name()) { - return std::string{"char"}; + if (typeid(T).name() == typeid(int8_t).name()) { + return std::string{"int8_t"}; } if (typeid(T).name() == typeid(size_t).name()) { - return std::string{"unsigned_long"}; + return std::string{"uint64_t"}; } - if (typeid(T).name() == typeid(int).name()) { - return std::string{"int"}; + if (typeid(T).name() == typeid(int32_t).name()) { + return std::string{"int32_t"}; } if (typeid(T).name() == typeid(int4).name()) { return std::string{"int4"}; @@ -169,7 +169,7 @@ inline chunk_t* getCustomPtr(chunk_t* scratchPtr, float startGB) return reinterpret_cast(reinterpret_cast(scratchPtr) + (static_cast(GB * startGB) & 0xFFFFFFFFFFFFF000)); } -inline float computeThroughput(Test test, float result, float chunkSizeGB, int ntests) +inline float computeThroughput(Test test, float result, float chunkSizeGB, int32_t ntests) { // https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html // Eff_bandwidth (GB/s) = (B_r + B_w) / (~1e9 * Time (s)) @@ -178,7 +178,7 @@ inline float computeThroughput(Test test, float result, float chunkSizeGB, int n } template -inline size_t getBufferCapacity(float chunkSizeGB, int prime) +inline size_t getBufferCapacity(float chunkSizeGB, int32_t prime) { auto chunkCapacity = (static_cast(GB * chunkSizeGB) & 0xFFFFFFFFFFFFF000) / sizeof(chunk_t); if (!prime) { @@ -188,13 +188,13 @@ inline size_t getBufferCapacity(float chunkSizeGB, int prime) } } -inline bool is_prime(const int n) +inline bool is_prime(const int32_t n) { bool isPrime = true; if (n == 0 || n == 1) { isPrime = false; } else { - for (int i = 2; i <= sqrt(n); ++i) { + for (int32_t i = 2; i <= sqrt(n); ++i) { if (n % i == 0) { isPrime = false; break; @@ -212,40 +212,40 @@ namespace benchmark struct benchmarkOpts { benchmarkOpts() = default; - int deviceId = 0; + int32_t deviceId = 0; std::vector tests = {Test::Read, Test::Write, Test::Copy}; std::vector modes = {Mode::Sequential, Mode::Concurrent}; std::vector pools = {KernelConfig::Single, KernelConfig::Multi}; - std::vector dtypes = {"char", "int", "ulong"}; + std::vector dtypes = {"int8_t", "int32_t", "uint64_t"}; std::vector> testChunks; float chunkReservedGB = 1.f; float threadPoolFraction = 1.f; float freeMemoryFractionToAllocate = 0.95f; - int numThreads = -1; - int numBlocks = -1; - int kernelLaunches = 1; - int nTests = 1; + int32_t numThreads = -1; + int32_t numBlocks = -1; + int32_t kernelLaunches = 1; + int32_t nTests = 1; bool raw = false; - int streams = 8; - int prime = 0; + int32_t streams = 8; + int32_t prime = 0; std::string outFileName = "benchmark_result"; bool dumpChunks = false; }; template struct gpuState { - int getMaxChunks() + int32_t getMaxChunks() { return (double)scratchSize / (chunkReservedGB * GB); } - int getNKernelLaunches() { return iterations; } - int getStreamsPoolSize() { return streams; } + int32_t getNKernelLaunches() { return iterations; } + int32_t getStreamsPoolSize() { return streams; } // Configuration size_t nMaxThreadsPerDimension; - int iterations; - int streams; + int32_t iterations; + int32_t streams; float chunkReservedGB; // Size of each partition (GB) diff --git a/GPU/GPUbenchmark/cuda/Kernels.cu b/GPU/GPUbenchmark/cuda/Kernels.cu index ba6abd84f662d..75799e4aa8c96 100644 --- a/GPU/GPUbenchmark/cuda/Kernels.cu +++ b/GPU/GPUbenchmark/cuda/Kernels.cu @@ -131,7 +131,7 @@ template __global__ void rand_read_k( chunk_t* chunkPtr, size_t chunkSize, - int prime) + int32_t prime) { chunk_t sink{0}; for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < chunkSize; i += blockDim.x * gridDim.x) { @@ -145,7 +145,7 @@ template __global__ void rand_write_k( chunk_t* chunkPtr, size_t chunkSize, - int prime) + int32_t prime) { for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < chunkSize; i += blockDim.x * gridDim.x) { chunkPtr[(i * prime) % chunkSize] = 0; @@ -156,7 +156,7 @@ template <> __global__ void rand_write_k( int4* chunkPtr, size_t chunkSize, - int prime) + int32_t prime) { for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < chunkSize; i += blockDim.x * gridDim.x) { chunkPtr[(i * prime) % chunkSize] = {0, 1, 0, 0}; @@ -168,7 +168,7 @@ template __global__ void rand_copy_k( chunk_t* chunkPtr, size_t chunkSize, - int prime) + int32_t prime) { size_t offset = chunkSize / 2; for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < offset; i += blockDim.x * gridDim.x) { @@ -235,7 +235,7 @@ template __global__ void rand_read_dist_k( chunk_t** block_ptr, size_t* block_size, - int prime) + int32_t prime) { chunk_t sink{0}; chunk_t* ptr = block_ptr[blockIdx.x]; @@ -251,7 +251,7 @@ template __global__ void rand_write_dist_k( chunk_t** block_ptr, size_t* block_size, - int prime) + int32_t prime) { chunk_t* ptr = block_ptr[blockIdx.x]; size_t n = block_size[blockIdx.x]; @@ -264,7 +264,7 @@ template <> __global__ void rand_write_dist_k( int4** block_ptr, size_t* block_size, - int prime) + int32_t prime) { int4* ptr = block_ptr[blockIdx.x]; size_t n = block_size[blockIdx.x]; @@ -278,7 +278,7 @@ template __global__ void rand_copy_dist_k( chunk_t** block_ptr, size_t* block_size, - int prime) + int32_t prime) { chunk_t* ptr = block_ptr[blockIdx.x]; size_t n = block_size[blockIdx.x]; @@ -289,9 +289,9 @@ __global__ void rand_copy_dist_k( } } // namespace gpu -void printDeviceProp(int deviceId) +void printDeviceProp(int32_t deviceId) { - const int w1 = 34; + const int32_t w1 = 34; std::cout << std::left; std::cout << std::setw(w1) << "--------------------------------------------------------------------------------" @@ -379,11 +379,11 @@ void printDeviceProp(int deviceId) std::cout << std::setw(w1) << "asicRevision: " << props.asicRevision << std::endl; #endif - int deviceCnt; + int32_t deviceCnt; GPUCHECK(cudaGetDeviceCount(&deviceCnt)); std::cout << std::setw(w1) << "peers: "; - for (int i = 0; i < deviceCnt; i++) { - int isPeer; + for (int32_t i = 0; i < deviceCnt; i++) { + int32_t isPeer; GPUCHECK(cudaDeviceCanAccessPeer(&isPeer, i, deviceId)); if (isPeer) { std::cout << "device#" << i << " "; @@ -391,8 +391,8 @@ void printDeviceProp(int deviceId) } std::cout << std::endl; std::cout << std::setw(w1) << "non-peers: "; - for (int i = 0; i < deviceCnt; i++) { - int isPeer; + for (int32_t i = 0; i < deviceCnt; i++) { + int32_t isPeer; GPUCHECK(cudaDeviceCanAccessPeer(&isPeer, i, deviceId)); if (!isPeer) { std::cout << "device#" << i << " "; @@ -413,9 +413,9 @@ template template float GPUbenchmark::runSequential(void (*kernel)(chunk_t*, size_t, T...), std::pair& chunk, - int nLaunches, - int nBlocks, - int nThreads, + int32_t nLaunches, + int32_t nBlocks, + int32_t nThreads, T&... args) // run for each chunk { float milliseconds{0.f}; @@ -451,10 +451,10 @@ template template std::vector GPUbenchmark::runConcurrent(void (*kernel)(chunk_t*, size_t, T...), std::vector>& chunkRanges, - int nLaunches, - int dimStreams, - int nBlocks, - int nThreads, + int32_t nLaunches, + int32_t dimStreams, + int32_t nBlocks, + int32_t nThreads, T&... args) { auto nChunks = chunkRanges.size(); @@ -512,9 +512,9 @@ template template float GPUbenchmark::runDistributed(void (*kernel)(chunk_t**, size_t*, T...), std::vector>& chunkRanges, - int nLaunches, + int32_t nLaunches, size_t nBlocks, - int nThreads, + int32_t nThreads, T&... args) { std::vector chunkPtrs(chunkRanges.size()); // Pointers to the beginning of each chunk @@ -528,12 +528,12 @@ float GPUbenchmark::runDistributed(void (*kernel)(chunk_t**, size_t*, T chunkPtrs[iChunk] = getCustomPtr(mState.scratchPtr, chunkRanges[iChunk].first); totChunkGB += chunkRanges[iChunk].second; } - int index{0}; + int32_t index{0}; for (size_t iChunk{0}; iChunk < chunkRanges.size(); ++iChunk) { float percFromMem = chunkRanges[iChunk].second / totChunkGB; - int blocksPerChunk = percFromMem * nBlocks; + int32_t blocksPerChunk = percFromMem * nBlocks; totComputedBlocks += blocksPerChunk; - for (int iBlock{0}; iBlock < blocksPerChunk; ++iBlock, ++index) { + for (int32_t iBlock{0}; iBlock < blocksPerChunk; ++iBlock, ++index) { float memPerBlock = chunkRanges[iChunk].second / blocksPerChunk; ptrPerBlocks[index] = getCustomPtr(chunkPtrs[iChunk], iBlock * memPerBlock); perBlockCapacity[index] = getBufferCapacity(memPerBlock, mOptions.prime); @@ -588,10 +588,10 @@ float GPUbenchmark::runDistributed(void (*kernel)(chunk_t**, size_t*, T template void GPUbenchmark::printDevices() { - int deviceCnt; + int32_t deviceCnt; GPUCHECK(cudaGetDeviceCount(&deviceCnt)); - for (int i = 0; i < deviceCnt; i++) { + for (int32_t i = 0; i < deviceCnt; i++) { GPUCHECK(cudaSetDevice(i)); printDeviceProp(i); } @@ -619,7 +619,7 @@ void GPUbenchmark::globalInit() mState.nMultiprocessors = props.multiProcessorCount; mState.nMaxThreadsPerBlock = props.maxThreadsPerMultiProcessor; mState.nMaxThreadsPerDimension = props.maxThreadsDim[0]; - mState.scratchSize = static_cast(mOptions.freeMemoryFractionToAllocate * free); + mState.scratchSize = static_cast(mOptions.freeMemoryFractionToAllocate * free); if (mState.testChunks.empty()) { for (auto j{0}; j < mState.getMaxChunks() * mState.chunkReservedGB; j += mState.chunkReservedGB) { @@ -668,8 +668,8 @@ void GPUbenchmark::runTest(Test test, Mode mode, KernelConfig config) void (*kernel)(chunk_t*, size_t) = &gpu::read_k; // Initialising to a default value void (*kernel_distributed)(chunk_t**, size_t*) = &gpu::read_dist_k; // Initialising to a default value - void (*kernel_rand)(chunk_t*, size_t, int) = &gpu::rand_read_k; // Initialising to a default value - void (*kernel_rand_distributed)(chunk_t**, size_t*, int) = &gpu::rand_read_dist_k; // Initialising to a default value + void (*kernel_rand)(chunk_t*, size_t, int32_t) = &gpu::rand_read_k; // Initialising to a default value + void (*kernel_rand_distributed)(chunk_t**, size_t*, int32_t) = &gpu::rand_read_dist_k; // Initialising to a default value bool is_random{false}; @@ -739,7 +739,7 @@ void GPUbenchmark::runTest(Test test, Mode mode, KernelConfig config) if (!mOptions.raw) { std::cout << " ├ " << mode << " " << test << " " << config << " block(s) (" << measurement + 1 << "/" << mOptions.nTests << "): \n" << " │ - blocks per kernel: " << nBlocks << "/" << dimGrid << "\n" - << " │ - threads per block: " << (int)nThreads << "\n"; + << " │ - threads per block: " << (int32_t)nThreads << "\n"; } if (mode == Mode::Sequential) { if (!mOptions.raw) { @@ -885,9 +885,9 @@ void GPUbenchmark::run() globalFinalize(); } -template class GPUbenchmark; +template class GPUbenchmark; template class GPUbenchmark; -template class GPUbenchmark; +template class GPUbenchmark; template class GPUbenchmark; } // namespace benchmark diff --git a/GPU/GPUbenchmark/cuda/benchmark.cu b/GPU/GPUbenchmark/cuda/benchmark.cu index 5cd87b5307ea4..db404295c143e 100644 --- a/GPU/GPUbenchmark/cuda/benchmark.cu +++ b/GPU/GPUbenchmark/cuda/benchmark.cu @@ -25,21 +25,21 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) "arbitrary,a", bpo::value>()->multitoken()->default_value(std::vector{""}, ""), "Custom selected chunks syntax

:. P is starting GB, S is the size in GB.")( "blockPool,b", bpo::value>()->multitoken()->default_value(std::vector{"sb", "mb", "ab"}, "sb mb ab cb"), "Block pool strategy: single, multi, all or manual blocks.")( "chunkSize,c", bpo::value()->default_value(1.f), "Size of scratch partitions (GB).")( - "device,d", bpo::value()->default_value(0), "Id of the device to run test on, EPN targeted.")( + "device,d", bpo::value()->default_value(0), "Id of the device to run test on, EPN targeted.")( "threadPool,e", bpo::value()->default_value(1.f), "Fraction of blockDim.x to use (aka: rounded fraction of thread pool).")( "freeMemFraction,f", bpo::value()->default_value(0.95f), "Fraction of free memory to be allocated (min: 0.f, max: 1.f).")( - "blocks,g", bpo::value()->default_value(-1), "Number of blocks, manual mode. (g=-1: gridDim.x).")( + "blocks,g", bpo::value()->default_value(-1), "Number of blocks, manual mode. (g=-1: gridDim.x).")( "help,h", "Print help message.")( "inspect,i", "Inspect and dump chunk addresses.")( - "threads,j", bpo::value()->default_value(-1), "Number of threads per block, manual mode. (j=-1: blockDim.x).")( - "kind,k", bpo::value>()->multitoken()->default_value(std::vector{"char", "int", "ulong", "int4"}, "char int ulong int4"), "Test data type to be used.")( - "launches,l", bpo::value()->default_value(10), "Number of iterations in reading kernels.")( + "threads,j", bpo::value()->default_value(-1), "Number of threads per block, manual mode. (j=-1: blockDim.x).")( + "kind,k", bpo::value>()->multitoken()->default_value(std::vector{"int8_t", "int32_t", "uint64_t", "int4"}, "int8_t int32_t uint64_t int4"), "Test data type to be used.")( + "launches,l", bpo::value()->default_value(10), "Number of iterations in reading kernels.")( "mode,m", bpo::value>()->multitoken()->default_value(std::vector{"seq", "con", "dis"}, "seq con dis"), "Mode: sequential, concurrent or distributed.")( - "nruns,n", bpo::value()->default_value(1), "Number of times each test is run.")( + "nruns,n", bpo::value()->default_value(1), "Number of times each test is run.")( "outfile,o", bpo::value()->default_value("benchmark_result"), "Output file name to store results.")( - "prime,p", bpo::value()->default_value(0), "Prime number to be used for the test.")( + "prime,p", bpo::value()->default_value(0), "Prime number to be used for the test.")( "raw,r", "Display raw output.")( - "streams,s", bpo::value()->default_value(8), "Size of the pool of streams available for concurrent tests.")( + "streams,s", bpo::value()->default_value(8), "Size of the pool of streams available for concurrent tests.")( "test,t", bpo::value>()->multitoken()->default_value(std::vector{"read", "write", "copy", "rread", "rwrite", "rcopy"}, "read write copy rread rwrite rcopy"), "Tests to be performed.")( "version,v", "Print version.")( "extra,x", "Print extra info for each available device."); @@ -57,7 +57,7 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) if (vm.count("extra")) { o2::benchmark::benchmarkOpts opts; - o2::benchmark::GPUbenchmark bm_dummy{opts}; + o2::benchmark::GPUbenchmark bm_dummy{opts}; bm_dummy.printDevices(); return false; } @@ -79,16 +79,16 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) return false; } - conf.deviceId = vm["device"].as(); + conf.deviceId = vm["device"].as(); conf.freeMemoryFractionToAllocate = vm["freeMemFraction"].as(); conf.threadPoolFraction = vm["threadPool"].as(); - conf.numThreads = vm["threads"].as(); - conf.numBlocks = vm["blocks"].as(); + conf.numThreads = vm["threads"].as(); + conf.numBlocks = vm["blocks"].as(); conf.chunkReservedGB = vm["chunkSize"].as(); - conf.kernelLaunches = vm["launches"].as(); - conf.nTests = vm["nruns"].as(); - conf.streams = vm["streams"].as(); - conf.prime = vm["prime"].as(); + conf.kernelLaunches = vm["launches"].as(); + conf.nTests = vm["nruns"].as(); + conf.streams = vm["streams"].as(); + conf.prime = vm["prime"].as(); if ((conf.prime > 0 && !is_prime(conf.prime))) { std::cerr << "Invalid prime number: " << conf.prime << std::endl; exit(1); @@ -103,19 +103,19 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) } else if (test == "copy") { conf.tests.push_back(Test::Copy); } else if (test == "rread") { - if (!vm["prime"].as()) { + if (!vm["prime"].as()) { std::cerr << "Prime number must be specified for rread test." << std::endl; exit(1); } conf.tests.push_back(Test::RandomRead); } else if (test == "rwrite") { - if (!vm["prime"].as()) { + if (!vm["prime"].as()) { std::cerr << "Prime number must be specified for rwrite test." << std::endl; exit(1); } conf.tests.push_back(Test::RandomWrite); } else if (test == "rcopy") { - if (!vm["prime"].as()) { + if (!vm["prime"].as()) { std::cerr << "Prime number must be specified for rcopy test." << std::endl; exit(1); } @@ -149,7 +149,7 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) } else if (pool == "ab") { conf.pools.push_back(KernelConfig::All); } else if (pool == "cb") { - if (vm["blocks"].as() < 0) { + if (vm["blocks"].as() < 0) { std::cerr << "Manual pool setting requires --blocks or -g to be passed." << std::endl; exit(1); } @@ -174,7 +174,7 @@ bool parseArgs(o2::benchmark::benchmarkOpts& conf, int argc, const char* argv[]) return true; } -int main(int argc, const char* argv[]) +int32_t main(int argc, const char* argv[]) { std::cout << "Started benchmark with pid: " << getpid() << std::endl; o2::benchmark::benchmarkOpts opts; @@ -184,13 +184,13 @@ int main(int argc, const char* argv[]) } for (auto& dtype : opts.dtypes) { - if (dtype == "char") { - o2::benchmark::GPUbenchmark bm_char{opts}; + if (dtype == "int8_t") { + o2::benchmark::GPUbenchmark bm_char{opts}; bm_char.run(); - } else if (dtype == "int") { - o2::benchmark::GPUbenchmark bm_int{opts}; + } else if (dtype == "int32_t") { + o2::benchmark::GPUbenchmark bm_int{opts}; bm_int.run(); - } else if (dtype == "ulong") { + } else if (dtype == "uint64_t") { o2::benchmark::GPUbenchmark bm_size_t{opts}; bm_size_t.run(); } else if (dtype == "int4") { diff --git a/GPU/GPUbenchmark/macro/showBenchmarks.C b/GPU/GPUbenchmark/macro/showBenchmarks.C index 4bc177c096c1c..7cb618d63c6de 100644 --- a/GPU/GPUbenchmark/macro/showBenchmarks.C +++ b/GPU/GPUbenchmark/macro/showBenchmarks.C @@ -12,7 +12,7 @@ #include #endif -int nBins{500}; +int32_t nBins{500}; float minHist{0.f}, maxHist{1e4}; void showBenchmarks(const bool times = false, const TString fileName = "0_benchmark_result.root") { @@ -21,7 +21,7 @@ void showBenchmarks(const bool times = false, const TString fileName = "0_benchm std::vector> histograms; std::vector results; std::vector tests = {"read", "write", "copy"}; - std::vector types = {"char", "int", "unsigned_long"}; + std::vector types = {"int8_t", "int32_t", "uint64_t"}; std::vector modes = {"seq", "conc"}; std::vector patterns = {"SB", "MB"}; @@ -50,13 +50,13 @@ void showBenchmarks(const bool times = false, const TString fileName = "0_benchm elapsed->GetEntry(keyPair.second->LoadTree(0)); auto nChunk = measures->size(); histograms.emplace_back(nChunk); - for (int iHist{0}; iHist < (int)nChunk; ++iHist) { + for (int32_t iHist{0}; iHist < (int32_t)nChunk; ++iHist) { histograms.back()[iHist] = new TH1F(Form("Chunk_%d_%s", iHist, keyPair.first.c_str()), Form("Chunk_%d_%s;ms", iHist, keyPair.first.c_str()), 1000, 0, 1e4); } for (size_t iEntry(0); iEntry < (size_t)keyPair.second->GetEntriesFast(); ++iEntry) { auto tentry = keyPair.second->LoadTree(iEntry); elapsed->GetEntry(tentry); - for (int iHist{0}; iHist < (int)nChunk; ++iHist) { + for (int32_t iHist{0}; iHist < (int32_t)nChunk; ++iHist) { histograms.back()[iHist]->Fill((*measures)[iHist]); } } @@ -74,7 +74,7 @@ void showBenchmarks(const bool times = false, const TString fileName = "0_benchm TGraphErrors* g = new TGraphErrors(nChunk, xCoord.data(), yCoord.data(), exCoord.data(), eyCoord.data()); g->GetYaxis()->SetRangeUser(0, 5000); g->GetXaxis()->SetRangeUser(-2.f, nChunk); - g->SetTitle(Form("%s, N_{test}=%d;chunk_id;elapsed (s)", keyPair.first.c_str(), (int)keyPair.second->GetEntriesFast())); + g->SetTitle(Form("%s, N_{test}=%d;chunk_id;elapsed (s)", keyPair.first.c_str(), (int32_t)keyPair.second->GetEntriesFast())); g->SetFillColor(kBlue); g->SetFillStyle(3001); g->Draw("AB"); @@ -87,13 +87,13 @@ void showBenchmarks(const bool times = false, const TString fileName = "0_benchm throughput->GetEntry(keyPair.second->LoadTree(0)); auto nChunk = measures->size(); histograms.emplace_back(nChunk); - for (int iHist{0}; iHist < (int)nChunk; ++iHist) { + for (int32_t iHist{0}; iHist < (int32_t)nChunk; ++iHist) { histograms.back()[iHist] = new TH1F(Form("Chunk_%d_%s", iHist, keyPair.first.c_str()), Form("Chunk_%d_%s;GB/s", iHist, keyPair.first.c_str()), 1000, 0, 1e3); } for (size_t iEntry(0); iEntry < (size_t)keyPair.second->GetEntriesFast(); ++iEntry) { auto tentry = keyPair.second->LoadTree(iEntry); throughput->GetEntry(tentry); - for (int iHist{0}; iHist < (int)nChunk; ++iHist) { + for (int32_t iHist{0}; iHist < (int32_t)nChunk; ++iHist) { histograms.back()[iHist]->Fill((*measures)[iHist]); } } @@ -111,7 +111,7 @@ void showBenchmarks(const bool times = false, const TString fileName = "0_benchm TGraphErrors* g = new TGraphErrors(nChunk, xCoord.data(), yCoord.data(), exCoord.data(), eyCoord.data()); g->GetYaxis()->SetRangeUser(0, 150); g->GetXaxis()->SetRangeUser(-2.f, nChunk); - g->SetTitle(Form("%s, N_{test}=%d;chunk_id;throughput (GB/s)", keyPair.first.c_str(), (int)keyPair.second->GetEntriesFast())); + g->SetTitle(Form("%s, N_{test}=%d;chunk_id;throughput (GB/s)", keyPair.first.c_str(), (int32_t)keyPair.second->GetEntriesFast())); g->SetFillColor(kBlue); g->SetFillStyle(3001); g->Draw("AB"); diff --git a/GPU/TPCFastTransformation/BandMatrixSolver.cxx b/GPU/TPCFastTransformation/BandMatrixSolver.cxx index f02436818fa3b..680216d6e14de 100644 --- a/GPU/TPCFastTransformation/BandMatrixSolver.cxx +++ b/GPU/TPCFastTransformation/BandMatrixSolver.cxx @@ -26,11 +26,11 @@ using namespace GPUCA_NAMESPACE::gpu; templateClassImp(GPUCA_NAMESPACE::gpu::BandMatrixSolver); template <> -int BandMatrixSolver<0>::test(bool prn) +int32_t BandMatrixSolver<0>::test(bool prn) { - constexpr int n = 30; - constexpr int m = 6; - constexpr int d = 3; + constexpr int32_t n = 30; + constexpr int32_t m = 6; + constexpr int32_t d = 3; // std::random_device rd; // Will be used to obtain a seed for the random std::mt19937 gen(1); // Standard mersenne_twister_engine seeded with 1 @@ -38,29 +38,29 @@ int BandMatrixSolver<0>::test(bool prn) double maxDiff = 0.; double maxDiffType1 = 0.; - int nTries = 10000; + int32_t nTries = 10000; auto tmpTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(tmpTime - tmpTime); auto durationMult = duration; - for (int iter = 0; iter < nTries; iter++) { + for (int32_t iter = 0; iter < nTries; iter++) { double x[n][d]; double A[n][n]; double Atype1[n][n]; { - for (int i = 0; i < n; i++) { - for (int j = 0; j < d; j++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t j = 0; j < d; j++) { x[i][j] = 1. * uniform(gen); } } - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { A[i][i] = fabs(2. + uniform(gen)); } - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n; j++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t j = i + 1; j < n; j++) { if (j < i + m) { A[i][j] = A[i][i] * A[j][j] * uniform(gen); } else { @@ -69,14 +69,14 @@ int BandMatrixSolver<0>::test(bool prn) A[j][i] = A[i][j]; } } - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { A[i][i] = A[i][i] * A[i][i]; } } - for (int i = 0; i < n; i++) { - int oddRow = ((i % 2) != 0); - for (int j = i; j < n; j++) { + for (int32_t i = 0; i < n; i++) { + int32_t oddRow = ((i % 2) != 0); + for (int32_t j = i; j < n; j++) { if (j < i + m - oddRow) { Atype1[i][j] = A[i][j]; } else { @@ -88,17 +88,17 @@ int BandMatrixSolver<0>::test(bool prn) if (prn && iter == nTries - 1) { LOG(info) << "Matrix A:"; - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { LOG(info) << ""; - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << A[i][j] << " "; } } LOG(info) << ""; LOG(info) << "\nMatrix A type 1:"; - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { LOG(info) << ""; - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << Atype1[i][j] << " "; } } @@ -106,12 +106,12 @@ int BandMatrixSolver<0>::test(bool prn) } double B[n][d]; - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { B[i][k] = 0.; } - for (int j = 0; j < n; j++) { - for (int k = 0; k < d; k++) { + for (int32_t j = 0; j < n; j++) { + for (int32_t k = 0; k < d; k++) { B[i][k] += x[j][k] * A[i][j]; } } @@ -119,12 +119,12 @@ int BandMatrixSolver<0>::test(bool prn) double Btype1[n][d]; auto startMult = std::chrono::high_resolution_clock::now(); - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { Btype1[i][k] = 0.; } - for (int j = 0; j < n; j++) { - for (int k = 0; k < d; k++) { + for (int32_t j = 0; j < n; j++) { + for (int32_t k = 0; k < d; k++) { Btype1[i][k] += x[j][k] * Atype1[i][j]; } } @@ -138,13 +138,13 @@ int BandMatrixSolver<0>::test(bool prn) band.initWithNaN(); bandType1.initWithNaN(); - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { band.B(i, k) = B[i][k]; bandType1.B(i, k) = Btype1[i][k]; } - int oddRow = ((i % 2) != 0); - for (int j = 0; j < m; j++) { + int32_t oddRow = ((i % 2) != 0); + for (int32_t j = 0; j < m; j++) { if (i + j < n && j < m) { band.A(i, i + j) = A[i][i + j]; } @@ -160,8 +160,8 @@ int BandMatrixSolver<0>::test(bool prn) auto stop = std::chrono::high_resolution_clock::now(); duration += std::chrono::duration_cast(stop - start); - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { double t = fabs(x[i][k] - band.B(i, k)); double t1 = fabs(x[i][k] - bandType1.B(i, k)); if (!std::isfinite(t) || maxDiff < t) { @@ -174,14 +174,14 @@ int BandMatrixSolver<0>::test(bool prn) } } - int ok = (maxDiff < 1.e-6); + int32_t ok = (maxDiff < 1.e-6); if (prn || !ok) { LOG(info) << std::defaultfloat; LOG(info) << "\n\n Band matrix. Overall max diff: " << maxDiff << "\n"; } - int ok1 = (maxDiffType1 < 1.e-6); + int32_t ok1 = (maxDiffType1 < 1.e-6); if (prn || !ok1) { LOG(info) << std::defaultfloat; diff --git a/GPU/TPCFastTransformation/BandMatrixSolver.h b/GPU/TPCFastTransformation/BandMatrixSolver.h index 14d22d4d93862..b548ad60f58e8 100644 --- a/GPU/TPCFastTransformation/BandMatrixSolver.h +++ b/GPU/TPCFastTransformation/BandMatrixSolver.h @@ -51,12 +51,12 @@ namespace gpu /// During calculations, the initial values of mA and mB get lost, so one can call solve() only once. /// The solution X is stored in mB. /// -template +template class BandMatrixSolver { public: /// Consructor - BandMatrixSolver(int N, int Bdim) : mN(N), mBdim(Bdim) + BandMatrixSolver(int32_t N, int32_t Bdim) : mN(N), mBdim(Bdim) { assert(N > 0 && Bdim > 0); mA.resize(mN * BandWidthT, 0.); @@ -72,17 +72,17 @@ class BandMatrixSolver } /// access to A elements - double& A(int i, int j) + double& A(int32_t i, int32_t j) { auto ij = std::minmax(i, j); assert(ij.first >= 0 && ij.second < mN); - int k = ij.second - ij.first; + int32_t k = ij.second - ij.first; assert(k < BandWidthT); return mA[ij.first * BandWidthT + k]; } /// access to B elements - double& B(int i, int j) + double& B(int32_t i, int32_t j) { assert(i >= 0 && i < mN && j >= 0 && j < mBdim); return mB[i * mBdim + j]; @@ -95,21 +95,21 @@ class BandMatrixSolver void solveType1(); /// Test the class functionality. Returns 1 when ok, 0 when not ok - static int test(bool prn = 0) + static int32_t test(bool prn = 0) { return BandMatrixSolver<0>::test(prn); } private: - template + template void triangulateBlock(double AA[], double bb[]); - template + template void dioganalizeBlock(double A[], double b[]); private: - int mN = 0; - int mBdim = 0; + int32_t mN = 0; + int32_t mBdim = 0; std::vector mA; std::vector mB; @@ -119,22 +119,22 @@ class BandMatrixSolver }; template <> -int BandMatrixSolver<0>::test(bool prn); +int32_t BandMatrixSolver<0>::test(bool prn); -template -template +template +template inline void BandMatrixSolver::triangulateBlock(double AA[], double bb[]) { { - int m = BandWidthT; + int32_t m = BandWidthT; double* A = AA; - for (int rows = 0; rows < nRows; rows++) { + for (int32_t rows = 0; rows < nRows; rows++) { double c = 1. / A[0]; A[0] = c; // store 1/a[0][0] double* rowi = A + BandWidthT - 1; - for (int i = 1; i < m; i++) { // row 0+i + for (int32_t i = 1; i < m; i++) { // row 0+i double ai = c * A[i]; // A[0][i] - for (int j = i; j < m; j++) { + for (int32_t j = i; j < m; j++) { rowi[j] -= ai * A[j]; // A[i][j] -= A[0][j]/A[0][0]*A[i][0] } A[i] = ai; // A[0][i] /= A[0][0] @@ -145,13 +145,13 @@ inline void BandMatrixSolver::triangulateBlock(double AA[], double b } } - for (int k = 0; k < mBdim; k++) { - int m = BandWidthT; + for (int32_t k = 0; k < mBdim; k++) { + int32_t m = BandWidthT; double* A = AA; double* b = bb; - for (int rows = 0; rows < nRows; rows++) { + for (int32_t rows = 0; rows < nRows; rows++) { double bk = b[k]; - for (int i = 1; i < m; i++) { + for (int32_t i = 1; i < m; i++) { b[mBdim * i + k] -= A[i] * bk; } b[k] *= A[0]; @@ -162,17 +162,17 @@ inline void BandMatrixSolver::triangulateBlock(double AA[], double b } } -template -template +template +template inline void BandMatrixSolver::dioganalizeBlock(double AA[], double bb[]) { - for (int k = 0; k < mBdim; k++) { - int rows = BandWidthT; + for (int32_t k = 0; k < mBdim; k++) { + int32_t rows = BandWidthT; double* A = AA; double* b = bb; - for (int col = 0; col < nCols; col++) { + for (int32_t col = 0; col < nCols; col++) { double bk = b[k]; - for (int i = 1; i < rows; i++) { + for (int32_t i = 1; i < rows; i++) { b[-i * mBdim + k] -= A[BandWidthT * (-i) + i] * bk; } A -= BandWidthT; @@ -182,16 +182,16 @@ inline void BandMatrixSolver::dioganalizeBlock(double AA[], double b } } -template +template inline void BandMatrixSolver::solve() { /// Solution slover - const int stepA = BandWidthT; - const int stepB = mBdim; + const int32_t stepA = BandWidthT; + const int32_t stepB = mBdim; // Upper Triangulization { - int k = 0; + int32_t k = 0; double* Ak = &mA[0]; double* bk = &mB[0]; for (; k < mN - BandWidthT; k += 1, Ak += stepA, bk += stepB) { // for each row k @@ -203,7 +203,7 @@ inline void BandMatrixSolver::solve() // Diagonalization { - int k = mN - 1; + int32_t k = mN - 1; double* Ak = &mA[BandWidthT * k]; double* bk = &mB[mBdim * k]; for (; k > BandWidthT - 1; k -= 1, Ak -= stepA, bk -= stepB) { // for each row k @@ -214,7 +214,7 @@ inline void BandMatrixSolver::solve() } } -template +template inline void BandMatrixSolver::solveType1() { /// A special solver for a band matrix were every second row has 0 at the end of the band. @@ -232,11 +232,11 @@ inline void BandMatrixSolver::solveType1() /// ( +++*) /// - const int stepA = 2 * BandWidthT; - const int stepB = 2 * mBdim; + const int32_t stepA = 2 * BandWidthT; + const int32_t stepB = 2 * mBdim; // Upper Triangulization { - int k = 0; + int32_t k = 0; double* Ak = &mA[0]; double* bk = &mB[0]; for (; k < mN - BandWidthT; k += 2, Ak += stepA, bk += stepB) { // for each row k @@ -248,7 +248,7 @@ inline void BandMatrixSolver::solveType1() // Diagonalization { - int k = mN - 1; + int32_t k = mN - 1; double* Ak = &mA[BandWidthT * k]; double* bk = &mB[mBdim * k]; for (; k > BandWidthT - 1; k -= 2, Ak -= stepA, bk -= stepB) { // for each row k diff --git a/GPU/TPCFastTransformation/ChebyshevFit1D.cxx b/GPU/TPCFastTransformation/ChebyshevFit1D.cxx index eb77a98ec6c59..011243f5e158f 100644 --- a/GPU/TPCFastTransformation/ChebyshevFit1D.cxx +++ b/GPU/TPCFastTransformation/ChebyshevFit1D.cxx @@ -22,7 +22,7 @@ using namespace GPUCA_NAMESPACE::gpu; -void ChebyshevFit1D::reset(int order, double xMin, double xMax) +void ChebyshevFit1D::reset(int32_t order, double xMin, double xMax) { if (order < 0) { order = 0; @@ -40,13 +40,13 @@ void ChebyshevFit1D::reset(int order, double xMin, double xMax) void ChebyshevFit1D::reset() { - for (int i = 0; i <= mN; i++) { + for (int32_t i = 0; i <= mN; i++) { mB[i] = 0.; mC[i] = 0.; mT[i] = 0.; } - for (int i = 0; i < mN * mN; i++) { + for (int32_t i = 0; i < mN * mN; i++) { mA[i] = 0.; } mM = 0; @@ -56,8 +56,8 @@ void ChebyshevFit1D::print() { LOG(info) << ""; double* Ai = mA.data(); - for (int i = 0; i < mN; i++, Ai += mN) { - for (int j = 0; j < mN; j++) { + for (int32_t i = 0; i < mN; i++, Ai += mN) { + for (int32_t j = 0; j < mN; j++) { LOG(info) << Ai[j] << " "; } LOG(info) << " | " << mB[i]; @@ -66,24 +66,24 @@ void ChebyshevFit1D::print() void ChebyshevFit1D::fit() { - for (int i = 0; i < mN; i++) { - for (int j = 0; j < i; j++) { + for (int32_t i = 0; i < mN; i++) { + for (int32_t j = 0; j < i; j++) { mA[i * mN + j] = mA[j * mN + i]; } } //print(); { double* Ai = mA.data(); - for (int i = 0; i < mN; i++, Ai += mN) { + for (int32_t i = 0; i < mN; i++, Ai += mN) { double a = Ai[i]; if (fabs(a) < 1.e-6) { Ai[i] = 0; continue; } double* Aj = Ai + mN; - for (int j = i + 1; j < mN; j++, Aj += mN) { + for (int32_t j = i + 1; j < mN; j++, Aj += mN) { double c = Aj[i] / a; - for (int k = i + 1; k < mN; k++) { + for (int32_t k = i + 1; k < mN; k++) { Aj[k] -= c * Ai[k]; } mB[j] -= c * mB[i]; @@ -93,16 +93,16 @@ void ChebyshevFit1D::fit() } { double* Ai = mA.data() + (mN - 1) * mN; - for (int i = mN - 1; i >= 0; i--, Ai -= mN) { + for (int32_t i = mN - 1; i >= 0; i--, Ai -= mN) { double s = mB[i]; - for (int k = i + 1; k < mN; k++) { + for (int32_t k = i + 1; k < mN; k++) { s -= mC[k] * Ai[k]; } mC[i] = (fabs(Ai[i]) > 1.e-6) ? (s / Ai[i]) : 0.; } } /* - for (int i = 0; i < mN; i++) { + for (int32_t i = 0; i < mN; i++) { LOG(info) << mC[i] << " "; } LOG(info) ; diff --git a/GPU/TPCFastTransformation/ChebyshevFit1D.h b/GPU/TPCFastTransformation/ChebyshevFit1D.h index ec2cfe0a4bc95..1378563b4d8f3 100644 --- a/GPU/TPCFastTransformation/ChebyshevFit1D.h +++ b/GPU/TPCFastTransformation/ChebyshevFit1D.h @@ -36,14 +36,14 @@ class ChebyshevFit1D reset(0, -1., 1.); } - ChebyshevFit1D(int order, double xMin, double xMax) + ChebyshevFit1D(int32_t order, double xMin, double xMax) { reset(order, xMin, xMax); } ~ChebyshevFit1D() CON_DEFAULT; - void reset(int order, double xMin, double xMax); + void reset(int32_t order, double xMin, double xMax); void reset(); @@ -53,15 +53,15 @@ class ChebyshevFit1D double eval(double x); - int getNmeasurements() const { return mM; } + int32_t getNmeasurements() const { return mM; } const std::vector& getCoefficients() const { return mC; } void print(); private: - int mN = 0; // n coefficients == polynom order + 1 - int mM = 0; // number of measurenents + int32_t mN = 0; // n coefficients == polynom order + 1 + int32_t mM = 0; // number of measurenents double mXmin = -1.; // min of X segment double mXscale = 1; // scaling factor (x-mXmin) to [-1,1] std::vector mA; // fit matiix @@ -76,12 +76,12 @@ inline void ChebyshevFit1D::addMeasurement(double x, double m) mT[0] = 1; mT[1] = x; x *= 2.; - for (int i = 2; i < mN; i++) { + for (int32_t i = 2; i < mN; i++) { mT[i] = x * mT[i - 1] - mT[i - 2]; } double* Ai = mA.data(); - for (int i = 0; i < mN; i++, Ai += mN) { - for (int j = i; j < mN; j++) { + for (int32_t i = 0; i < mN; i++, Ai += mN) { + for (int32_t j = i; j < mN; j++) { Ai[j] += mT[i] * mT[j]; } mB[i] += m * mT[i]; @@ -96,7 +96,7 @@ inline double ChebyshevFit1D::eval(double x) double f0 = 1.; double f1 = x; x *= 2; - for (int i = 2; i < mN; i++) { + for (int32_t i = 2; i < mN; i++) { double f = x * f1 - f0; y += mC[i] * f; f0 = f1; diff --git a/GPU/TPCFastTransformation/CorrectionMapsHelper.h b/GPU/TPCFastTransformation/CorrectionMapsHelper.h index 0e544c3820d8c..e9ee5c793cc3b 100644 --- a/GPU/TPCFastTransformation/CorrectionMapsHelper.h +++ b/GPU/TPCFastTransformation/CorrectionMapsHelper.h @@ -37,22 +37,22 @@ class CorrectionMapsHelper void updateLumiScale(bool report = false); void clear(); - GPUd() void Transform(int slice, int row, float pad, float time, float& x, float& y, float& z, float vertexTime = 0) const + GPUd() void Transform(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float vertexTime = 0) const { mCorrMap->Transform(slice, row, pad, time, x, y, z, vertexTime, mCorrMapRef, mCorrMapMShape, mLumiScale, 1, mLumiScaleMode); } - GPUd() void TransformXYZ(int slice, int row, float& x, float& y, float& z) const + GPUd() void TransformXYZ(int32_t slice, int32_t row, float& x, float& y, float& z) const { mCorrMap->TransformXYZ(slice, row, x, y, z, mCorrMapRef, mCorrMapMShape, mLumiScale, 1, mLumiScaleMode); } - GPUd() void InverseTransformYZtoX(int slice, int row, float y, float z, float& x) const + GPUd() void InverseTransformYZtoX(int32_t slice, int32_t row, float y, float z, float& x) const { mCorrMap->InverseTransformYZtoX(slice, row, y, z, x, mCorrMapRef, mCorrMapMShape, (mScaleInverse ? mLumiScale : 0), (mScaleInverse ? 1 : 0), mLumiScaleMode); } - GPUd() void InverseTransformYZtoNominalYZ(int slice, int row, float y, float z, float& ny, float& nz) const + GPUd() void InverseTransformYZtoNominalYZ(int32_t slice, int32_t row, float y, float z, float& ny, float& nz) const { mCorrMap->InverseTransformYZtoNominalYZ(slice, row, y, z, ny, nz, mCorrMapRef, mCorrMapMShape, (mScaleInverse ? mLumiScale : 0), (mScaleInverse ? 1 : 0), mLumiScaleMode); } @@ -97,7 +97,7 @@ class CorrectionMapsHelper } } - void setLumiScaleMode(int v) + void setLumiScaleMode(int32_t v) { if (v != mLumiScaleMode) { mLumiScaleMode = v; @@ -111,7 +111,7 @@ class CorrectionMapsHelper GPUd() float getMeanLumiRef() const { return mMeanLumiRef; } GPUd() float getLumiScale() const { return mLumiScale; } - GPUd() int getLumiScaleMode() const { return mLumiScaleMode; } + GPUd() int32_t getLumiScaleMode() const { return mLumiScaleMode; } bool isUpdated() const { return mUpdatedFlags != 0; } bool isUpdatedMap() const { return (mUpdatedFlags & UpdateFlags::MapBit) != 0; } @@ -132,8 +132,8 @@ class CorrectionMapsHelper void acknowledgeUpdate() { mUpdatedFlags = 0; } void setLumiCTPAvailable(bool v) { mLumiCTPAvailable = v; } bool getLumiCTPAvailable() const { return mLumiCTPAvailable; } - void setLumiScaleType(int v) { mLumiScaleType = v; } - int getLumiScaleType() const { return mLumiScaleType; } + void setLumiScaleType(int32_t v) { mLumiScaleType = v; } + int32_t getLumiScaleType() const { return mLumiScaleType; } void enableMShapeCorrection(bool v) { mEnableMShape = v; } bool getUseMShapeCorrection() const { return mEnableMShape; } bool canUseCorrections() const { return mMeanLumi >= 0.; } @@ -145,7 +145,7 @@ class CorrectionMapsHelper void setInstCTPLumiOverride(float f) { mInstCTPLumiOverride = f; } float getInstCTPLumiOverride() const { return mInstCTPLumiOverride; } - int getUpdateFlags() const { return mUpdatedFlags; } + int32_t getUpdateFlags() const { return mUpdatedFlags; } bool getScaleInverse() const { return mScaleInverse; } @@ -167,9 +167,9 @@ class CorrectionMapsHelper bool mOwner = false; // is content of pointers owned by the helper bool mLumiCTPAvailable = false; // is CTP Lumi available // these 2 are global options, must be set by the workflow global options - int mLumiScaleType = -1; // use CTP Lumi (1) or TPCScaler (2) for the correction scaling, 0 - no scaling - int mLumiScaleMode = -1; // scaling-mode of the correciton maps - int mUpdatedFlags = 0; + int32_t mLumiScaleType = -1; // use CTP Lumi (1) or TPCScaler (2) for the correction scaling, 0 - no scaling + int32_t mLumiScaleMode = -1; // scaling-mode of the correciton maps + int32_t mUpdatedFlags = 0; float mInstLumiCTP = 0.; // instanteneous luminosity from CTP (a.u) float mInstLumi = 0.; // instanteneous luminosity (a.u) used for TPC corrections scaling float mMeanLumi = 0.; // mean luminosity of the map (a.u) used for TPC corrections scaling diff --git a/GPU/TPCFastTransformation/MultivariatePolynomial.h b/GPU/TPCFastTransformation/MultivariatePolynomial.h index bc980065f6263..77deff08782d5 100644 --- a/GPU/TPCFastTransformation/MultivariatePolynomial.h +++ b/GPU/TPCFastTransformation/MultivariatePolynomial.h @@ -40,7 +40,7 @@ namespace GPUCA_NAMESPACE::gpu /// Dim = 0 && Degree = 0 : the number of dimensions and the degree will be set during runtime /// InteractionOnly: consider only interaction terms: ignore x[0]*x[0]..., x[1]*x[1]*x[2]... etc. terms (same feature as 'interaction_only' in sklearn https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html) /// can be used for N-linear interpolation (https://en.wikipedia.org/wiki/Trilinear_interpolation#Alternative_algorithm) -template +template class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialHelper { public: @@ -48,14 +48,14 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH /// constructor for runtime evaluation of polynomial formula /// \param nDim number of dimensions /// \param degree degree of the polynomial - template ::type = 0> - MultivariatePolynomial(const unsigned int nDim, const unsigned int degree, const bool interactionOnly = false) : MultivariatePolynomialHelper{nDim, degree, interactionOnly}, mNParams{this->getNParameters(degree, nDim, interactionOnly)} + template ::type = 0> + MultivariatePolynomial(const uint32_t nDim, const uint32_t degree, const bool interactionOnly = false) : MultivariatePolynomialHelper{nDim, degree, interactionOnly}, mNParams{this->getNParameters(degree, nDim, interactionOnly)} { construct(); } /// constructor for compile time evaluation of polynomial formula - template ::type = 0> + template ::type = 0> MultivariatePolynomial() : mNParams{this->getNParameters(Degree, Dim, InteractionOnly)} { construct(); @@ -97,7 +97,7 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH #if !defined(GPUCA_GPUCODE) /// \return returns number of parameters of the polynomials - unsigned int getNParams() const { return mNParams; } + uint32_t getNParams() const { return mNParams; } /// set the parameters for the coefficients of the polynomial /// \param params parameter for the coefficients @@ -105,7 +105,7 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH /// \param parameter which will be set /// \val value of the parameter - void setParam(const unsigned int param, const float val) { mParams[param] = val; }; + void setParam(const uint32_t param, const float val) { mParams[param] = val; }; /// \return returns the paramaters of the coefficients const float* getParams() const { return mParams; } @@ -126,7 +126,7 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH /// \param y values which will be fitted of length 'nPoints' /// \param error error of weigths of the points (if empty no weights are applied) /// \param clearPoints perform the fit on new data points - template ::type = 0> + template ::type = 0> void fit(std::vector& x, std::vector& y, std::vector& error, const bool clearPoints) { const auto vec = MultivariatePolynomialHelper::fit(x, y, error, clearPoints); @@ -147,7 +147,7 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH private: using DataTParams = float; ///< data type of the parameters of the polynomials - unsigned int mNParams{}; ///< number of parameters of the polynomial + uint32_t mNParams{}; ///< number of parameters of the polynomial DataTParams* mParams{nullptr}; ///< parameters of the coefficients of the polynomial #if !defined(GPUCA_GPUCODE) @@ -168,7 +168,7 @@ class MultivariatePolynomial : public FlatObject, public MultivariatePolynomialH //================================================================================= #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) -template +template void MultivariatePolynomial::loadFromFile(TFile& inpf, const char* name) { MultivariatePolynomialContainer* polTmp = nullptr; @@ -183,7 +183,7 @@ void MultivariatePolynomial::loadFromFile(TFile& i } } -template +template void MultivariatePolynomial::setFromContainer(const MultivariatePolynomialContainer& container) { if constexpr (Dim > 0 && Degree > 0) { @@ -213,7 +213,7 @@ void MultivariatePolynomial::setFromContainer(cons } } -template +template void MultivariatePolynomial::writeToFile(TFile& outf, const char* name) const { const MultivariatePolynomialContainer cont = getContainer(); @@ -222,7 +222,7 @@ void MultivariatePolynomial::writeToFile(TFile& ou #endif #ifndef GPUCA_GPUCODE -template +template void MultivariatePolynomial::cloneFromObject(const MultivariatePolynomial& obj, char* newFlatBufferPtr) { const char* oldFlatBufferPtr = obj.mFlatBufferPtr; @@ -238,7 +238,7 @@ void MultivariatePolynomial::cloneFromObject(const } } -template +template void MultivariatePolynomial::moveBufferTo(char* newFlatBufferPtr) { char* oldFlatBufferPtr = mFlatBufferPtr; @@ -248,7 +248,7 @@ void MultivariatePolynomial::moveBufferTo(char* ne setActualBufferAddress(currFlatBufferPtr); } -template +template void MultivariatePolynomial::construct() { FlatObject::startConstruction(); @@ -258,21 +258,21 @@ void MultivariatePolynomial::construct() } #endif -template +template void MultivariatePolynomial::destroy() { mParams = nullptr; FlatObject::destroy(); } -template +template void MultivariatePolynomial::setActualBufferAddress(char* actualFlatBufferPtr) { FlatObject::setActualBufferAddress(actualFlatBufferPtr); mParams = reinterpret_cast(mFlatBufferPtr); } -template +template void MultivariatePolynomial::setFutureBufferAddress(char* futureFlatBufferPtr) { mParams = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParams); diff --git a/GPU/TPCFastTransformation/MultivariatePolynomialHelper.cxx b/GPU/TPCFastTransformation/MultivariatePolynomialHelper.cxx index 1e40fcb51359e..80cb691d80fad 100644 --- a/GPU/TPCFastTransformation/MultivariatePolynomialHelper.cxx +++ b/GPU/TPCFastTransformation/MultivariatePolynomialHelper.cxx @@ -51,7 +51,7 @@ std::string MultivariatePolynomialHelper<0, 0, false>::getFormula() const std::string formula = ""; #ifndef GPUCA_NO_FMT const auto terms = getTerms(); - for (int i = 0; i < (int)terms.size() - 1; ++i) { + for (int32_t i = 0; i < (int32_t)terms.size() - 1; ++i) { formula += fmt::format("{} + ", terms[i]); } formula += terms.back(); @@ -62,8 +62,8 @@ std::string MultivariatePolynomialHelper<0, 0, false>::getFormula() const std::vector MultivariatePolynomialHelper<0, 0, false>::getTerms() const { std::vector terms{"par[0]"}; - int indexPar = 1; - for (unsigned int deg = 1; deg <= mDegree; ++deg) { + int32_t indexPar = 1; + for (uint32_t deg = 1; deg <= mDegree; ++deg) { const auto strTmp = combination_with_repetiton>(deg, mDim, nullptr, indexPar, nullptr, mInteractionOnly); terms.insert(terms.end(), strTmp.begin(), strTmp.end()); } @@ -73,7 +73,7 @@ std::vector MultivariatePolynomialHelper<0, 0, false>::getTerms() c TLinearFitter MultivariatePolynomialHelper<0, 0, false>::getTLinearFitter() const { const std::string formula = getTLinearFitterFormula(); - TLinearFitter fitter(int(mDim), formula.data(), ""); + TLinearFitter fitter(int32_t(mDim), formula.data(), ""); return fitter; } @@ -82,10 +82,10 @@ std::vector MultivariatePolynomialHelper<0, 0, false>::fit(TLinearFitter& if (clearPoints) { fitter.ClearPoints(); } - const int nDim = static_cast(x.size() / y.size()); - fitter.AssignData(static_cast(y.size()), nDim, x.data(), y.data(), error.empty() ? nullptr : error.data()); + const int32_t nDim = static_cast(x.size() / y.size()); + fitter.AssignData(static_cast(y.size()), nDim, x.data(), y.data(), error.empty() ? nullptr : error.data()); - const int status = fitter.Eval(); + const int32_t status = fitter.Eval(); if (status != 0) { #ifndef GPUCA_NO_FMT LOGP(info, "Fitting failed with status: {}", status); @@ -96,7 +96,7 @@ std::vector MultivariatePolynomialHelper<0, 0, false>::fit(TLinearFitter& TVectorD params; fitter.GetParameters(params); std::vector paramsFloat; - paramsFloat.reserve(static_cast(params.GetNrows())); + paramsFloat.reserve(static_cast(params.GetNrows())); std::copy(params.GetMatrixArray(), params.GetMatrixArray() + params.GetNrows(), std::back_inserter(paramsFloat)); return paramsFloat; } @@ -108,23 +108,23 @@ std::vector MultivariatePolynomialHelper<0, 0, false>::fit(std::vector -Type MultivariatePolynomialHelper<0, 0, false>::combination_with_repetiton(const unsigned int degree, const unsigned int dim, const float par[], int& indexPar, const float x[], const bool interactionOnly) const +Type MultivariatePolynomialHelper<0, 0, false>::combination_with_repetiton(const uint32_t degree, const uint32_t dim, const float par[], int32_t& indexPar, const float x[], const bool interactionOnly) const { { // each digit represents the currently set dimension - unsigned int pos[FMaxdegree + 1]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint32_t pos[FMaxdegree + 1]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // return value is either the sum of all polynomials or a vector of strings containing the formula for each polynomial Type val(0); for (;;) { // starting on the rightmost digit - for (unsigned int i = degree; i > 0; --i) { + for (uint32_t i = degree; i > 0; --i) { // check if digit of current position is at is max position if (pos[i] == dim) { // increase digit of left position ++pos[i - 1]; // resetting the indices of the digits to the right - for (unsigned int j = i; j <= degree; ++j) { + for (uint32_t j = i; j <= degree; ++j) { pos[j] = pos[i - 1]; } } @@ -174,11 +174,11 @@ Type MultivariatePolynomialHelper<0, 0, false>::combination_with_repetiton(const } } -float MultivariatePolynomialHelper<0, 0, false>::evalPol(const float par[], const float x[], const unsigned int degree, const unsigned int dim, const bool interactionOnly) const +float MultivariatePolynomialHelper<0, 0, false>::evalPol(const float par[], const float x[], const uint32_t degree, const uint32_t dim, const bool interactionOnly) const { float val = par[0]; - int indexPar = 1; - for (unsigned int deg = 1; deg <= degree; ++deg) { + int32_t indexPar = 1; + for (uint32_t deg = 1; deg <= degree; ++deg) { val += combination_with_repetiton(deg, dim, par, indexPar, x, interactionOnly); } return val; diff --git a/GPU/TPCFastTransformation/MultivariatePolynomialHelper.h b/GPU/TPCFastTransformation/MultivariatePolynomialHelper.h index fb5cf7c36288e..e4518efea37c6 100644 --- a/GPU/TPCFastTransformation/MultivariatePolynomialHelper.h +++ b/GPU/TPCFastTransformation/MultivariatePolynomialHelper.h @@ -41,13 +41,13 @@ struct MultivariatePolynomialContainer { /// \param degree degree of the polynomials /// \param nParameters number of parameters /// \param params parmaeters - MultivariatePolynomialContainer(const unsigned int dim, const unsigned int degree, const unsigned int nParameters, const float params[/* nParameters*/], const bool interactionOnly) : mDim{dim}, mDegree{degree}, mParams{params, params + nParameters}, mInteractionOnly{interactionOnly} {}; + MultivariatePolynomialContainer(const uint32_t dim, const uint32_t degree, const uint32_t nParameters, const float params[/* nParameters*/], const bool interactionOnly) : mDim{dim}, mDegree{degree}, mParams{params, params + nParameters}, mInteractionOnly{interactionOnly} {}; /// for ROOT I/O MultivariatePolynomialContainer() = default; - const unsigned int mDim{}; ///< number of dimensions of the polynomial - const unsigned int mDegree{}; ///< degree of the polynomials + const uint32_t mDim{}; ///< number of dimensions of the polynomial + const uint32_t mDegree{}; ///< degree of the polynomials const std::vector mParams{}; ///< parameters of the polynomial const bool mInteractionOnly{}; ///< consider only interaction terms }; @@ -60,12 +60,12 @@ class MultivariatePolynomialParametersHelper /// \returns number of parameters for given dimension and degree of polynomials /// calculates the number of parameters for a multivariate polynomial for given degree: nParameters = (n+d-1 d) -> binomial coefficient /// see: https://mathoverflow.net/questions/225953/number-of-polynomial-terms-for-certain-degree-and-certain-number-of-variables - GPUd() static constexpr unsigned int getNParametersAllTerms(const unsigned int degree, const unsigned int dim) { return (degree == 0) ? binomialCoeff(dim - 1, 0) : binomialCoeff(dim - 1 + degree, degree) + getNParametersAllTerms(degree - 1, dim); } + GPUd() static constexpr uint32_t getNParametersAllTerms(const uint32_t degree, const uint32_t dim) { return (degree == 0) ? binomialCoeff(dim - 1, 0) : binomialCoeff(dim - 1 + degree, degree) + getNParametersAllTerms(degree - 1, dim); } /// \returns the number of parameters for interaction terms only (see: https://en.wikipedia.org/wiki/Combination) - GPUd() static constexpr unsigned int getNParametersInteractionOnly(const unsigned int degree, const unsigned int dim) { return (degree == 0) ? binomialCoeff(dim - 1, 0) : binomialCoeff(dim, degree) + getNParametersInteractionOnly(degree - 1, dim); } + GPUd() static constexpr uint32_t getNParametersInteractionOnly(const uint32_t degree, const uint32_t dim) { return (degree == 0) ? binomialCoeff(dim - 1, 0) : binomialCoeff(dim, degree) + getNParametersInteractionOnly(degree - 1, dim); } - GPUd() static constexpr unsigned int getNParameters(const unsigned int degree, const unsigned int dim, const bool interactionOnly) + GPUd() static constexpr uint32_t getNParameters(const uint32_t degree, const uint32_t dim, const bool interactionOnly) { if (interactionOnly) { return getNParametersInteractionOnly(degree, dim); @@ -77,23 +77,23 @@ class MultivariatePolynomialParametersHelper private: /// calculate factorial of n /// \return returns n! - GPUd() static constexpr unsigned int factorial(const unsigned int n) { return (n == 0) || (n == 1) ? 1 : n * factorial(n - 1); } + GPUd() static constexpr uint32_t factorial(const uint32_t n) { return (n == 0) || (n == 1) ? 1 : n * factorial(n - 1); } /// calculates binomial coefficient /// \return returns (n k) - GPUd() static constexpr unsigned int binomialCoeff(const unsigned int n, const unsigned int k) { return factorial(n) / (factorial(k) * factorial(n - k)); } + GPUd() static constexpr uint32_t binomialCoeff(const uint32_t n, const uint32_t k) { return factorial(n) / (factorial(k) * factorial(n - k)); } }; /// Helper struct for evaluating a multidimensional polynomial using compile time evaluated formula /// Compile time method to extract the formula is obtained from run time method (check combination_with_repetiton() and evalPol()) /// by performing all loops during compile time and replacing the array to keep track of the dimensions for given term (pos[FMaxdegree + 1]) -/// to a simple unsigned int called Pos where each digit represents the dimension for a given term e.g. pos = 2234 -> x[2]*x[2]*x[3]*x[4] +/// to a simple uint32_t called Pos where each digit represents the dimension for a given term e.g. pos = 2234 -> x[2]*x[2]*x[3]*x[4] /// -template +template class MultivariatePolynomialHelper : public MultivariatePolynomialParametersHelper { - static constexpr unsigned short FMaxdim = 10; ///< maximum dimensionality of the polynomials (number of different digits: 0,1,2,3....9 ) - static constexpr unsigned short FMaxdegree = 9; ///< maximum degree of the polynomials (maximum number of digits in unsigned integer - 1) + static constexpr uint16_t FMaxdim = 10; ///< maximum dimensionality of the polynomials (number of different digits: 0,1,2,3....9 ) + static constexpr uint16_t FMaxdegree = 9; ///< maximum degree of the polynomials (maximum number of digits in unsigned integer - 1) #if !defined(GPUCA_GPUCODE) static_assert(Dim <= MultivariatePolynomialHelper::FMaxdim && Degree <= MultivariatePolynomialHelper::FMaxdegree, "Max. number of dimensions or degrees exceeded!"); @@ -106,48 +106,48 @@ class MultivariatePolynomialHelper : public MultivariatePolynomialParametersHelp GPUd() static constexpr float evalPol(GPUgeneric() const float par[/*number of parameters*/], const float x[/*number of dimensions*/]) { return par[0] + loopDegrees<1>(par, x); } /// \return returns number of dimensions of the polynomials - GPUd() static constexpr unsigned int getDim() { return Dim; } + GPUd() static constexpr uint32_t getDim() { return Dim; } /// \return returns the degree of the polynomials - GPUd() static constexpr unsigned int getDegree() { return Degree; } + GPUd() static constexpr uint32_t getDegree() { return Degree; } /// \return returns whether only interaction terms are considered GPUd() static constexpr bool isInteractionOnly() { return InteractionOnly; } private: /// computes power of 10 - GPUd() static constexpr unsigned int pow10(const unsigned int n) { return n == 0 ? 1 : 10 * pow10(n - 1); } + GPUd() static constexpr uint32_t pow10(const uint32_t n) { return n == 0 ? 1 : 10 * pow10(n - 1); } /// helper for modulo to extract the digit in an integer a at position b (can be obtained with pow10(digitposition)): e.g. a=1234 b=pow10(2)=100 -> returns 2 - GPUd() static constexpr unsigned int mod10(const unsigned int a, const unsigned int b) { return (a / b) % 10; } + GPUd() static constexpr uint32_t mod10(const uint32_t a, const uint32_t b) { return (a / b) % 10; } /// resetting digits of pos for given position to refDigit - GPUd() static constexpr unsigned int resetIndices(const unsigned int degreePol, const unsigned int pos, const unsigned int leftDigit, const unsigned int iter, const unsigned int refDigit); + GPUd() static constexpr uint32_t resetIndices(const uint32_t degreePol, const uint32_t pos, const uint32_t leftDigit, const uint32_t iter, const uint32_t refDigit); - GPUd() static constexpr unsigned int getNewPos(const unsigned int degreePol, const unsigned int pos, const unsigned int digitPos); + GPUd() static constexpr uint32_t getNewPos(const uint32_t degreePol, const uint32_t pos, const uint32_t digitPos); /// calculates term e.g. x^3*y /// \tparam DegreePol max degree of the polynomials /// \pos decoded information about the current term e.g. 1233 -> x[1]*x[2]*x[3]*x[3] (otherwise an array could be used) - template - GPUd() static constexpr float prodTerm(const float x[], const unsigned int pos); + template + GPUd() static constexpr float prodTerm(const float x[], const uint32_t pos); /// helper function for checking for interaction terms - template + template static constexpr bool checkInteraction(); /// calculate sum of the terms for given degree -> summation of the par[]*x^4 + par[]*x^3*y + par[]*x^3*z + par[]*x^2*y^2..... terms /// \tparam DegreePol max degree of the polynomials /// \Pos decoded information about the current term e.g. 1233 -> x[1]*x[2]*x[3]*x[3] (otherwise an array could be used) /// \tparam Index index for accessing the parameters - template + template GPUd() static constexpr float sumTerms(GPUgeneric() const float par[], const float x[]); /// loop over the degrees of the polynomials (for formula see https://math.stackexchange.com/questions/1234240/equation-that-defines-multi-dimensional-polynomial) /// \tparam degree iteration of the loop which starts from 1 to the max degree of the polynomial e.g. Iter=4 -> summation of the par[]*x^4 + par[]*x^3*y + par[]*x^3*z + par[]*x^2*y^2..... terms /// \param par parameters of the pokynomial /// \param x input coordinates - template + template GPUd() static constexpr float loopDegrees(GPUgeneric() const float par[], const float x[]); }; @@ -160,7 +160,7 @@ class MultivariatePolynomialHelper<0, 0, false> : public MultivariatePolynomialP /// constructor /// \param nDim dimensionality of the polynomials /// \param degree degree of the polynomials - MultivariatePolynomialHelper(const unsigned int nDim, const unsigned int degree, const bool interactionOnly) : mDim{nDim}, mDegree{degree}, mInteractionOnly{interactionOnly} { assert(mDegree <= FMaxdegree); }; + MultivariatePolynomialHelper(const uint32_t nDim, const uint32_t degree, const bool interactionOnly) : mDim{nDim}, mDegree{degree}, mInteractionOnly{interactionOnly} { assert(mDegree <= FMaxdegree); }; /// default constructor MultivariatePolynomialHelper() CON_DEFAULT; @@ -206,28 +206,28 @@ class MultivariatePolynomialHelper<0, 0, false> : public MultivariatePolynomialP float evalPol(const float par[/*number of parameters*/], const float x[/*number of dimensions*/]) const { return evalPol(par, x, mDegree, mDim, mInteractionOnly); } /// evalutes the polynomial - float evalPol(const float par[], const float x[], const unsigned int degree, const unsigned int dim, const bool interactionOnly) const; + float evalPol(const float par[], const float x[], const uint32_t degree, const uint32_t dim, const bool interactionOnly) const; /// \return returns number of dimensions of the polynomials - unsigned int getDim() const { return mDim; } + uint32_t getDim() const { return mDim; } /// \return returns the degree of the polynomials - unsigned int getDegree() const { return mDegree; } + uint32_t getDegree() const { return mDegree; } /// \return returns whether only interaction terms are considered bool isInteractionOnly() const { return mInteractionOnly; } protected: - unsigned int mDim{}; ///< dimensionality of the polynomial - unsigned int mDegree{}; ///< maximum degree of the polynomial + uint32_t mDim{}; ///< dimensionality of the polynomial + uint32_t mDegree{}; ///< maximum degree of the polynomial bool mInteractionOnly{}; ///< flag if only interaction terms are used private: - static constexpr unsigned short FMaxdegree = 9; ///< maximum degree of the polynomials (can be increased if desired: size of array in combination_with_repetiton: pos[FMaxdegree + 1]) + static constexpr uint16_t FMaxdegree = 9; ///< maximum degree of the polynomials (can be increased if desired: size of array in combination_with_repetiton: pos[FMaxdegree + 1]) /// helper function to get all combinations template - Type combination_with_repetiton(const unsigned int degree, const unsigned int dim, const float par[], int& indexPar, const float x[], const bool interactionOnly) const; + Type combination_with_repetiton(const uint32_t degree, const uint32_t dim, const float par[], int32_t& indexPar, const float x[], const bool interactionOnly) const; }; #endif @@ -235,31 +235,31 @@ class MultivariatePolynomialHelper<0, 0, false> : public MultivariatePolynomialP //============================ inline implementations ============================= //================================================================================= -template -GPUd() constexpr unsigned int MultivariatePolynomialHelper::resetIndices(const unsigned int degreePol, const unsigned int pos, const unsigned int leftDigit, const unsigned int iter, const unsigned int refDigit) +template +GPUd() constexpr uint32_t MultivariatePolynomialHelper::resetIndices(const uint32_t degreePol, const uint32_t pos, const uint32_t leftDigit, const uint32_t iter, const uint32_t refDigit) { if (iter <= degreePol) { - const int powTmp = pow10(leftDigit); - const int rightDigit = mod10(pos, powTmp); - const int posTmp = pos - (rightDigit - refDigit) * powTmp; + const int32_t powTmp = pow10(leftDigit); + const int32_t rightDigit = mod10(pos, powTmp); + const int32_t posTmp = pos - (rightDigit - refDigit) * powTmp; return resetIndices(degreePol, posTmp, leftDigit - 1, iter + 1, refDigit); } return pos; } -template -GPUd() constexpr unsigned int MultivariatePolynomialHelper::getNewPos(const unsigned int degreePol, const unsigned int pos, const unsigned int digitPos) +template +GPUd() constexpr uint32_t MultivariatePolynomialHelper::getNewPos(const uint32_t degreePol, const uint32_t pos, const uint32_t digitPos) { if (degreePol > digitPos) { // check if digit of current position is at is max position if (mod10(pos, pow10(digitPos)) == Dim) { // increase digit of left position - const unsigned int leftDigit = digitPos + 1; - const unsigned int posTmp = pos + pow10(leftDigit); - const unsigned int refDigit = mod10(posTmp, pow10(digitPos + 1)); + const uint32_t leftDigit = digitPos + 1; + const uint32_t posTmp = pos + pow10(leftDigit); + const uint32_t refDigit = mod10(posTmp, pow10(digitPos + 1)); // resetting digits to the right if digit exceeds number of dimensions - const unsigned int posReset = resetIndices(degreePol, posTmp, leftDigit - 1, degreePol - digitPos, refDigit); + const uint32_t posReset = resetIndices(degreePol, posTmp, leftDigit - 1, degreePol - digitPos, refDigit); // check next digit return getNewPos(degreePol, posReset, digitPos + 1); @@ -269,20 +269,20 @@ GPUd() constexpr unsigned int MultivariatePolynomialHelper -template -GPUd() constexpr float MultivariatePolynomialHelper::prodTerm(const float x[], const unsigned int pos) +template +template +GPUd() constexpr float MultivariatePolynomialHelper::prodTerm(const float x[], const uint32_t pos) { if constexpr (DegreePol > 0) { // extract index of the dimension which is decoded in the digit - const unsigned int index = mod10(pos, pow10(DegreePol - 1)); + const uint32_t index = mod10(pos, pow10(DegreePol - 1)); return x[index] * prodTerm(x, pos); } return 1; } -template -template +template +template constexpr bool MultivariatePolynomialHelper::checkInteraction() { if constexpr (DegreePol > 1) { @@ -295,12 +295,12 @@ constexpr bool MultivariatePolynomialHelper::check return false; } -template -template +template +template GPUd() constexpr float MultivariatePolynomialHelper::sumTerms(GPUgeneric() const float par[], const float x[]) { // checking if the current position is reasonable e.g. if the max dimension is x[4]: for Pos=15 -> x[1]*x[5] the position is set to 22 -> x[2]*x[2] - constexpr unsigned int posNew = getNewPos(DegreePol, Pos, 0); + constexpr uint32_t posNew = getNewPos(DegreePol, Pos, 0); if constexpr (mod10(posNew, pow10(DegreePol)) != 1) { // check if all digits in posNew are unequal: For interaction_only terms with x[Dim]*x[Dim]... etc. can be skipped @@ -314,12 +314,12 @@ GPUd() constexpr float MultivariatePolynomialHelper -template +template +template GPUd() constexpr float MultivariatePolynomialHelper::loopDegrees(GPUgeneric() const float par[], const float x[]) { if constexpr (DegreePol <= Degree) { - constexpr unsigned int index{getNParameters(DegreePol - 1, Dim, InteractionOnly)}; // offset of the index for accessing the parameters + constexpr uint32_t index{getNParameters(DegreePol - 1, Dim, InteractionOnly)}; // offset of the index for accessing the parameters return sumTerms(par, x) + loopDegrees(par, x); } return 0; diff --git a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h index 6df5ac8c99cab..6de2bc7afbae8 100644 --- a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h +++ b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h @@ -47,18 +47,18 @@ struct NDPiecewisePolynomialContainer { /// \param xmin minimum coordinates of the grid /// \param xmax maximum coordinates of the grid /// \param nVertices number of vertices: defines number of fits per dimension - NDPiecewisePolynomialContainer(const unsigned int dim, const unsigned int degree, const unsigned int nParameters, const float params[/* nParameters*/], const bool interactionOnly, const float xMin[/* Dim*/], const float xMax[/* Dim*/], const unsigned int nVertices[/* Dim*/]) : mDim{dim}, mDegree{degree}, mParams{params, params + nParameters}, mInteractionOnly{interactionOnly}, mMin{xMin, xMin + dim}, mMax{xMax, xMax + dim}, mN{nVertices, nVertices + dim} {}; + NDPiecewisePolynomialContainer(const uint32_t dim, const uint32_t degree, const uint32_t nParameters, const float params[/* nParameters*/], const bool interactionOnly, const float xMin[/* Dim*/], const float xMax[/* Dim*/], const uint32_t nVertices[/* Dim*/]) : mDim{dim}, mDegree{degree}, mParams{params, params + nParameters}, mInteractionOnly{interactionOnly}, mMin{xMin, xMin + dim}, mMax{xMax, xMax + dim}, mN{nVertices, nVertices + dim} {}; /// for ROOT I/O NDPiecewisePolynomialContainer() = default; - const unsigned int mDim{}; ///< number of dimensions of the polynomial - const unsigned int mDegree{}; ///< degree of the polynomials + const uint32_t mDim{}; ///< number of dimensions of the polynomial + const uint32_t mDegree{}; ///< degree of the polynomials const std::vector mParams{}; ///< parameters of the polynomial const bool mInteractionOnly{}; ///< consider only interaction terms const std::vector mMin{}; ///< min vertices positions of the grid const std::vector mMax{}; ///< max vertices positions of the grid - const std::vector mN{}; ///< number of vertices for each dimension + const std::vector mN{}; ///< number of vertices for each dimension }; #endif @@ -77,7 +77,7 @@ struct NDPiecewisePolynomialContainer { /// \tparam Degree degree of the polynomials /// \tparam InteractionOnly: consider only interaction terms: ignore x[0]*x[0]..., x[1]*x[1]*x[2]... etc. terms (same feature as 'interaction_only' in sklearn https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html) /// can be used for N-linear interpolation (https://en.wikipedia.org/wiki/Trilinear_interpolation#Alternative_algorithm) -template +template class NDPiecewisePolynomials : public FlatObject { public: @@ -86,7 +86,7 @@ class NDPiecewisePolynomials : public FlatObject /// \param min minimum coordinates of the grid /// \param max maximum coordinates of the grid (note: the resulting polynomials can NOT be evaluated at the maximum coordinates: only at min <= X < max) /// \param n number of vertices: defines number of fits per dimension: nFits = n - 1. n should be at least 2 to perform one fit - NDPiecewisePolynomials(const float min[/* Dim */], const float max[/* Dim */], const unsigned int n[/* Dim */]) { init(min, max, n); } + NDPiecewisePolynomials(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]) { init(min, max, n); } #endif #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// constructor construct and object by initializing it from an object stored in a Root file @@ -130,7 +130,7 @@ class NDPiecewisePolynomials : public FlatObject /// \param x coordinates where to interpolate GPUd() float eval(float x[/* Dim */]) const { - int index[Dim]; + int32_t index[Dim]; setIndex(x, index); clamp(x, index); return MultivariatePolynomialHelper::evalPol(getParameters(index), x); @@ -140,7 +140,7 @@ class NDPiecewisePolynomials : public FlatObject /// \param x coordinates where to interpolate (note: the resulting polynomials can NOT be evaluated at the maximum coordinates: only at min <= X < max) GPUd() float evalUnsafe(const float x[/* Dim */]) const { - int index[Dim]; + int32_t index[Dim]; setIndex(x, index); return MultivariatePolynomialHelper::evalPol(getParameters(index), x); } @@ -148,22 +148,22 @@ class NDPiecewisePolynomials : public FlatObject /// evaluate specific polynomial at given index for given coordinate /// \param x coordinates where to interpolate /// \param index index of the polynomial - GPUd() float evalPol(const float x[/* Dim */], const int index[/* Dim */]) const { return MultivariatePolynomialHelper::evalPol(getParameters(index), x); } + GPUd() float evalPol(const float x[/* Dim */], const int32_t index[/* Dim */]) const { return MultivariatePolynomialHelper::evalPol(getParameters(index), x); } /// \return returns min range for given dimension - GPUd() float getXMin(const unsigned int dim) const { return mMin[dim]; } + GPUd() float getXMin(const uint32_t dim) const { return mMin[dim]; } /// \return returns max range for given dimension - GPUd() float getXMax(const unsigned int dim) const { return mMax[dim]; } + GPUd() float getXMax(const uint32_t dim) const { return mMax[dim]; } /// \return returns inverse spacing for given dimension - GPUd() float getInvSpacing(const unsigned int dim) const { return mInvSpacing[dim]; } + GPUd() float getInvSpacing(const uint32_t dim) const { return mInvSpacing[dim]; } /// \return returns number of vertices for given dimension - GPUd() unsigned int getNVertices(const unsigned int dim) const { return mN[dim]; } + GPUd() uint32_t getNVertices(const uint32_t dim) const { return mN[dim]; } /// \return returns number of polynomial fits for given dimension - GPUd() unsigned int getNPolynomials(const unsigned int dim) const { return mN[dim] - 1; } + GPUd() uint32_t getNPolynomials(const uint32_t dim) const { return mN[dim] - 1; } /// \return returns the parameters of the coefficients GPUd() const float* getParams() const { return mParams; } @@ -176,13 +176,13 @@ class NDPiecewisePolynomials : public FlatObject /// \param min minimum coordinates of the grid /// \param max maximum coordinates of the grid (note: the resulting polynomials can NOT be evaluated at the maximum coordinates: only at min <= X < max) /// \param n number of vertices: defines number of fits per dimension: nFits = n - 1. n should be at least 2 to perform one fit - void init(const float min[/* Dim */], const float max[/* Dim */], const unsigned int n[/* Dim */]); + void init(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]); #ifndef GPUCA_STANDALONE /// perform the polynomial fits on the grid /// \param func function which returns for every input x on the defined grid the true value /// \param nAuxiliaryPoints number of points which will be used for the fits (should be at least 2) - void performFits(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */]); + void performFits(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */]); /// perform the polynomial fits on scatter points /// \param x scatter points used to make the fits of size 'y.size() * Dim' as in TLinearFitter @@ -207,10 +207,10 @@ class NDPiecewisePolynomials : public FlatObject /// \param outName name of the output file /// \param treeName name of the tree /// \param recreateFile create new output file or update the output file - void dumpToTree(const unsigned int nSamplingPoints[/* Dim */], const char* outName = "debug.root", const char* treeName = "tree", const bool recreateFile = true) const; + void dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName = "debug.root", const char* treeName = "tree", const bool recreateFile = true) const; /// \return returns total number of polynomial fits - unsigned int getNPolynomials() const; + uint32_t getNPolynomials() const; #endif /// converts the class to a container which can be written to a root file @@ -221,14 +221,14 @@ class NDPiecewisePolynomials : public FlatObject void setFromContainer(const NDPiecewisePolynomialContainer& container); /// \return returns the total number of stored parameters - unsigned int getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); } + uint32_t getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); } #endif /// \return returns number of dimensions of the polynomials - GPUd() static constexpr unsigned int getDim() { return Dim; } + GPUd() static constexpr uint32_t getDim() { return Dim; } /// \return returns the degree of the polynomials - GPUd() static constexpr unsigned int getDegree() { return Degree; } + GPUd() static constexpr uint32_t getDegree() { return Degree; } /// \return returns whether only interaction terms are considered GPUd() static constexpr bool isInteractionOnly() { return InteractionOnly; } @@ -238,37 +238,37 @@ class NDPiecewisePolynomials : public FlatObject float mMin[Dim]{}; ///< min vertices positions of the grid float mMax[Dim]{}; ///< max vertices positions of the grid float mInvSpacing[Dim]{}; ///< inverse spacings of the grid - unsigned int mN[Dim]{}; ///< number of vertices for each dimension + uint32_t mN[Dim]{}; ///< number of vertices for each dimension DataTParams* mParams{nullptr}; ///< storage for the parameters /// \returns vertex number for given position and dimension /// \param x position /// \param dim dimension - GPUd() int getVertex(const float x, const unsigned int dim) const { return ((x - mMin[dim]) * mInvSpacing[dim]); } + GPUd() int32_t getVertex(const float x, const uint32_t dim) const { return ((x - mMin[dim]) * mInvSpacing[dim]); } /// returns terms which are needed to calculate the index for the grid for given dimension /// \param dim dimension - GPUd() unsigned int getTerms(const unsigned int dim) const { return (dim == 0) ? 1 : (mN[dim - 1] - 1) * getTerms(dim - 1); } + GPUd() uint32_t getTerms(const uint32_t dim) const { return (dim == 0) ? 1 : (mN[dim - 1] - 1) * getTerms(dim - 1); } /// returns index for accessing the parameter on the grid /// \param ix index per dimension - GPUd() unsigned int getDataIndex(const int ix[/* Dim */]) const { return getDataIndex(ix) * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); } + GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const { return getDataIndex(ix) * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); } /// helper function to get the index - template - GPUd() unsigned int getDataIndex(const int ix[/* Dim */]) const; + template + GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const; /// \return returns pointer to memory where the parameters for given indices are stored /// \param index indices of polynomials - GPUd() const float* getParameters(const int index[/* Dim */]) const { return &mParams[getDataIndex(index)]; } + GPUd() const float* getParameters(const int32_t index[/* Dim */]) const { return &mParams[getDataIndex(index)]; } /// helper function to fill array containing the indices to where the parameters are stored - template - GPUd() void setIndex(const float x[/* Dim */], int index[/* Dim */]) const; + template + GPUd() void setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const; /// clamp input coordinates to avoid extrapolation - template - GPUd() void clamp(float x[/* Dim */], int index[/* Dim */]) const; + template + GPUd() void clamp(float x[/* Dim */], int32_t index[/* Dim */]) const; #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// perform the actual fit in the grid @@ -278,20 +278,20 @@ class NDPiecewisePolynomials : public FlatObject /// \param fitter TLinearFitter which is used for performing the fits /// \param xCords buffer for x-coordinates /// \param response buffer for y-coordinates - void fitInnerGrid(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */], const int currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response); + void fitInnerGrid(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */], const int32_t currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response); /// heler function to loop over all dimensions - void checkPos(const unsigned int iMax[/* Dim */], int pos[/* Dim */]) const; + void checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const; /// \return returns step width of the inner grid /// \param dim dimension /// \param nAuxiliaryPoints number of Auxiliary points for given dimension - double getStepWidth(const unsigned int dim, const int nAuxiliaryPoints) const { return 1 / (static_cast(mInvSpacing[dim]) * (nAuxiliaryPoints - 1)); } + double getStepWidth(const uint32_t dim, const int32_t nAuxiliaryPoints) const { return 1 / (static_cast(mInvSpacing[dim]) * (nAuxiliaryPoints - 1)); } /// \return returns vertex position for given index and dimension /// \param ix index /// \param dim dimension - double getVertexPosition(const unsigned int ix, const int dim) const { return ix / static_cast(mInvSpacing[dim]) + mMin[dim]; } + double getVertexPosition(const uint32_t ix, const int32_t dim) const { return ix / static_cast(mInvSpacing[dim]) + mMin[dim]; } #endif #if !defined(GPUCA_GPUCODE) @@ -312,7 +312,7 @@ class NDPiecewisePolynomials : public FlatObject //================================================================================= #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) -template +template void NDPiecewisePolynomials::loadFromFile(TFile& inpf, const char* name) { NDPiecewisePolynomialContainer* gridTmp = nullptr; @@ -326,7 +326,7 @@ void NDPiecewisePolynomials::loadFromFile(TFile& i #endif } } -template +template void NDPiecewisePolynomials::setFromContainer(const NDPiecewisePolynomialContainer& container) { if (Dim != container.mDim) { @@ -350,14 +350,14 @@ void NDPiecewisePolynomials::setFromContainer(cons init(container.mMin.data(), container.mMax.data(), container.mN.data()); setParams(container.mParams.data()); } -template +template void NDPiecewisePolynomials::writeToFile(TFile& outf, const char* name) const { const NDPiecewisePolynomialContainer cont = getContainer(); outf.WriteObject(&cont, name); } -template +template void NDPiecewisePolynomials::setDefault() { const auto nParamsPerPol = MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); @@ -371,12 +371,12 @@ void NDPiecewisePolynomials::setDefault() #endif #ifndef GPUCA_GPUCODE -template +template void NDPiecewisePolynomials::cloneFromObject(const NDPiecewisePolynomials& obj, char* newFlatBufferPtr) { const char* oldFlatBufferPtr = obj.mFlatBufferPtr; FlatObject::cloneFromObject(obj, newFlatBufferPtr); - for (unsigned int i = 0; i < Dim; ++i) { + for (uint32_t i = 0; i < Dim; ++i) { mMin[i] = obj.mMin[i]; mMax[i] = obj.mMax[i]; mInvSpacing[i] = obj.mInvSpacing[i]; @@ -387,7 +387,7 @@ void NDPiecewisePolynomials::cloneFromObject(const } } -template +template void NDPiecewisePolynomials::moveBufferTo(char* newFlatBufferPtr) { char* oldFlatBufferPtr = mFlatBufferPtr; @@ -397,7 +397,7 @@ void NDPiecewisePolynomials::moveBufferTo(char* ne setActualBufferAddress(currFlatBufferPtr); } -template +template void NDPiecewisePolynomials::construct() { FlatObject::startConstruction(); @@ -407,30 +407,30 @@ void NDPiecewisePolynomials::construct() } #endif -template +template void NDPiecewisePolynomials::destroy() { mParams = nullptr; FlatObject::destroy(); } -template +template void NDPiecewisePolynomials::setActualBufferAddress(char* actualFlatBufferPtr) { FlatObject::setActualBufferAddress(actualFlatBufferPtr); mParams = reinterpret_cast(mFlatBufferPtr); } -template +template void NDPiecewisePolynomials::setFutureBufferAddress(char* futureFlatBufferPtr) { mParams = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParams); FlatObject::setFutureBufferAddress(futureFlatBufferPtr); } -template -template -GPUdi() unsigned int NDPiecewisePolynomials::getDataIndex(const int ix[/* Dim */]) const +template +template +GPUdi() uint32_t NDPiecewisePolynomials::getDataIndex(const int32_t ix[/* Dim */]) const { if constexpr (DimTmp > 0) { return ix[DimTmp] * getTerms(DimTmp) + getDataIndex(ix); @@ -438,9 +438,9 @@ GPUdi() unsigned int NDPiecewisePolynomials::getDa return ix[DimTmp]; } -template -template -GPUdi() void NDPiecewisePolynomials::setIndex(const float x[/* Dim */], int index[/* Dim */]) const +template +template +GPUdi() void NDPiecewisePolynomials::setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const { index[DimTmp] = getVertex(x[DimTmp], DimTmp); if constexpr (DimTmp > 0) { @@ -449,9 +449,9 @@ GPUdi() void NDPiecewisePolynomials::setIndex(cons return; } -template -template -GPUdi() void NDPiecewisePolynomials::clamp(float x[/* Dim */], int index[/* Dim */]) const +template +template +GPUdi() void NDPiecewisePolynomials::clamp(float x[/* Dim */], int32_t index[/* Dim */]) const { if (index[DimTmp] <= 0) { index[DimTmp] = 0; @@ -461,7 +461,7 @@ GPUdi() void NDPiecewisePolynomials::clamp(float x } } else { - if (index[DimTmp] >= int(mN[DimTmp] - 1)) { + if (index[DimTmp] >= int32_t(mN[DimTmp] - 1)) { index[DimTmp] = mN[DimTmp] - 2; x[DimTmp] = mMax[DimTmp]; } @@ -473,10 +473,10 @@ GPUdi() void NDPiecewisePolynomials::clamp(float x } #ifndef GPUCA_GPUCODE -template -void NDPiecewisePolynomials::init(const float min[], const float max[], const unsigned int n[]) +template +void NDPiecewisePolynomials::init(const float min[], const float max[], const uint32_t n[]) { - for (unsigned int i = 0; i < Dim; ++i) { + for (uint32_t i = 0; i < Dim; ++i) { mMin[i] = min[i]; mMax[i] = max[i]; mN[i] = n[i]; @@ -487,31 +487,31 @@ void NDPiecewisePolynomials::init(const float min[ #endif #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) -template -unsigned int NDPiecewisePolynomials::getNPolynomials() const +template +uint32_t NDPiecewisePolynomials::getNPolynomials() const { - unsigned int nP = getNPolynomials(0); - for (unsigned int i = 1; i < Dim; ++i) { + uint32_t nP = getNPolynomials(0); + for (uint32_t i = 1; i < Dim; ++i) { nP *= getNPolynomials(i); } return nP; } -template -void NDPiecewisePolynomials::checkPos(const unsigned int iMax[/* Dim */], int pos[/* Dim */]) const +template +void NDPiecewisePolynomials::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const { - for (unsigned int i = 0; i < Dim; ++i) { - if (pos[i] == int(iMax[i])) { + for (uint32_t i = 0; i < Dim; ++i) { + if (pos[i] == int32_t(iMax[i])) { ++pos[i + 1]; std::fill_n(pos, i + 1, 0); } } } -template -void NDPiecewisePolynomials::performFits(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */]) +template +void NDPiecewisePolynomials::performFits(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */]) { - const int nTotalFits = getNPolynomials(); + const int32_t nTotalFits = getNPolynomials(); #ifndef GPUCA_ALIROOT_LIB LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); #endif @@ -519,8 +519,8 @@ void NDPiecewisePolynomials::performFits(const std MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); TLinearFitter fitter = pol.getTLinearFitter(); - unsigned int nPoints = 1; - for (unsigned int i = 0; i < Dim; ++i) { + uint32_t nPoints = 1; + for (uint32_t i = 0; i < Dim; ++i) { nPoints *= nAuxiliaryPoints[i]; } @@ -529,14 +529,14 @@ void NDPiecewisePolynomials::performFits(const std xCords.reserve(Dim * nPoints); response.reserve(nPoints); - unsigned int nPolynomials[Dim]{0}; - for (unsigned int i = 0; i < Dim; ++i) { + uint32_t nPolynomials[Dim]{0}; + for (uint32_t i = 0; i < Dim; ++i) { nPolynomials[i] = getNPolynomials(i); } - int pos[Dim + 1]{0}; - unsigned int counter = 0; - const int printDebugForNFits = int(nTotalFits / 20) + 1; + int32_t pos[Dim + 1]{0}; + uint32_t counter = 0; + const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; for (;;) { const bool debug = !(++counter % printDebugForNFits); @@ -559,37 +559,37 @@ void NDPiecewisePolynomials::performFits(const std } } -template +template void NDPiecewisePolynomials::performFits(const std::vector& x, const std::vector& y) { - const int nTotalFits = getNPolynomials(); + const int32_t nTotalFits = getNPolynomials(); #ifndef GPUCA_ALIROOT_LIB LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); #endif // approximate number of points - unsigned int nPoints = 2 * y.size() / nTotalFits; + uint32_t nPoints = 2 * y.size() / nTotalFits; // polynomial index -> indices to datapoints - std::unordered_map> dataPointsIndices; - for (int i = 0; i < nTotalFits; ++i) { + std::unordered_map> dataPointsIndices; + for (int32_t i = 0; i < nTotalFits; ++i) { dataPointsIndices[i].reserve(nPoints); } // check for each data point which polynomial to use for (size_t i = 0; i < y.size(); ++i) { - std::array index; + std::array index; float xVal[Dim]; std::copy(x.begin() + i * Dim, x.begin() + i * Dim + Dim, xVal); setIndex(xVal, index.data()); - std::array indexClamped{index}; + std::array indexClamped{index}; clamp(xVal, indexClamped.data()); // check if data points are in the grid if (index == indexClamped) { // index of the polyniomial - const unsigned int idx = getDataIndex(index.data()) / MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); + const uint32_t idx = getDataIndex(index.data()) / MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); // store index to data point dataPointsIndices[idx].emplace_back(i); @@ -600,14 +600,14 @@ void NDPiecewisePolynomials::performFits(const std MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); TLinearFitter fitter = pol.getTLinearFitter(); - unsigned int counter = 0; - const int printDebugForNFits = int(nTotalFits / 20) + 1; + uint32_t counter = 0; + const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; // temp storage for x and y values for fitting std::vector xCords; std::vector response; - for (int i = 0; i < nTotalFits; ++i) { + for (int32_t i = 0; i < nTotalFits; ++i) { const bool debug = !(++counter % printDebugForNFits); if (debug) { #ifndef GPUCA_ALIROOT_LIB @@ -634,7 +634,7 @@ void NDPiecewisePolynomials::performFits(const std const size_t idxOrig = dataPointsIndices[i][j]; // insert x values at the end of xCords - const int idxXStart = idxOrig * Dim; + const int32_t idxXStart = idxOrig * Dim; xCords.insert(xCords.end(), x.begin() + idxXStart, x.begin() + idxXStart + Dim); response.emplace_back(y[idxOrig]); } @@ -648,10 +648,10 @@ void NDPiecewisePolynomials::performFits(const std } } -template -void NDPiecewisePolynomials::fitInnerGrid(const std::function& func, const unsigned int nAuxiliaryPoints[/* Dim */], const int currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response) +template +void NDPiecewisePolynomials::fitInnerGrid(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */], const int32_t currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response) { - int pos[Dim + 1]{0}; + int32_t pos[Dim + 1]{0}; // add points which will be used for the fit for (;;) { @@ -661,7 +661,7 @@ void NDPiecewisePolynomials::fitInnerGrid(const st break; } - for (unsigned int iDim = 0; iDim < Dim; ++iDim) { + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { const double stepWidth = getStepWidth(iDim, nAuxiliaryPoints[iDim]); const double vertexPos = getVertexPosition(currentIndex[iDim], iDim); const double realPosTmp = vertexPos + pos[iDim] * stepWidth; @@ -679,24 +679,24 @@ void NDPiecewisePolynomials::fitInnerGrid(const st const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); // store parameters - const unsigned int index = getDataIndex(currentIndex); + const uint32_t index = getDataIndex(currentIndex); std::copy(params.begin(), params.end(), &mParams[index]); } #ifndef GPUCA_ALIROOT_LIB -template -void NDPiecewisePolynomials::dumpToTree(const unsigned int nSamplingPoints[/* Dim */], const char* outName, const char* treeName, const bool recreateFile) const +template +void NDPiecewisePolynomials::dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName, const char* treeName, const bool recreateFile) const { o2::utils::TreeStreamRedirector pcstream(outName, recreateFile ? "RECREATE" : "UPDATE"); double factor[Dim]{}; - for (unsigned int iDim = 0; iDim < Dim; ++iDim) { + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { factor[iDim] = (mMax[iDim] - mMin[iDim]) / (nSamplingPoints[iDim] - 1); } std::vector x(Dim); - std::vector ix(Dim); - int pos[Dim + 1]{0}; + std::vector ix(Dim); + int32_t pos[Dim + 1]{0}; for (;;) { checkPos(nSamplingPoints, pos); @@ -705,7 +705,7 @@ void NDPiecewisePolynomials::dumpToTree(const unsi break; } - for (unsigned int iDim = 0; iDim < Dim; ++iDim) { + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { ix[iDim] = pos[iDim]; x[iDim] = mMin[iDim] + pos[iDim] * factor[iDim]; } diff --git a/GPU/TPCFastTransformation/Spline.h b/GPU/TPCFastTransformation/Spline.h index b7c14b3c12cb9..51d9970028f22 100644 --- a/GPU/TPCFastTransformation/Spline.h +++ b/GPU/TPCFastTransformation/Spline.h @@ -34,11 +34,11 @@ namespace gpu /// /// --- Example of creating a spline --- /// -/// constexpr int nDimX = 2, nDimY = 1; -/// int nKnots[nDimX] = {2, 3}; // 2 x 3 knots -/// int knotsU1[] = {0, 1}; // relative knot positions -/// int knotsU2[] = {0, 2, 5}; -/// int *knotsU[nDimX] = {knotsU1, knotsU2}; +/// constexpr int32_t nDimX = 2, nDimY = 1; +/// int32_t nKnots[nDimX] = {2, 3}; // 2 x 3 knots +/// int32_t knotsU1[] = {0, 1}; // relative knot positions +/// int32_t knotsU2[] = {0, 2, 5}; +/// int32_t *knotsU[nDimX] = {knotsU1, knotsU2}; /// /// o2::gpu::Spline spline(nKnots, knotsU); /// @@ -73,7 +73,7 @@ namespace gpu /// XdimT < 0 : the number of X dimensions will be set in the runtime, and it will not exceed abs(XdimT) /// \param YdimT same for the Y dimensions /// -template +template class Spline : public SplineSpec { diff --git a/GPU/TPCFastTransformation/Spline1D.h b/GPU/TPCFastTransformation/Spline1D.h index e4bcf81b58a10..c977e0bbaee35 100644 --- a/GPU/TPCFastTransformation/Spline1D.h +++ b/GPU/TPCFastTransformation/Spline1D.h @@ -109,9 +109,9 @@ namespace gpu /// f[0] = x*x+3.f; // F(x) /// }; /// -/// const int nKnots = 3; +/// const int32_t nKnots = 3; /// -/// int knots[nKnots] = {0, 1, 5}; // relative(!) knot positions +/// int32_t knots[nKnots] = {0, 1, 5}; // relative(!) knot positions /// /// Spline1D spline( nKnots, knots ); // create 1-dimensional spline with the knots /// @@ -134,7 +134,7 @@ namespace gpu /// YdimT = 0 : the number of Y dimensions will be set in the runtime /// YdimT < 0 : the number of Y dimensions will be set in the runtime, and it will not exceed abs(YdimT) /// -template +template class Spline1D : public Spline1DSpec { diff --git a/GPU/TPCFastTransformation/Spline1DHelper.cxx b/GPU/TPCFastTransformation/Spline1DHelper.cxx index c4f1ca22b4b9e..bfa9614b2abb8 100644 --- a/GPU/TPCFastTransformation/Spline1DHelper.cxx +++ b/GPU/TPCFastTransformation/Spline1DHelper.cxx @@ -43,7 +43,7 @@ Spline1DHelper::Spline1DHelper() : mError(), mSpline() } template -int Spline1DHelper::storeError(int code, const char* msg) +int32_t Spline1DHelper::storeError(int32_t code, const char* msg) { mError = msg; return code; @@ -135,26 +135,26 @@ template void Spline1DHelper::approximateDataPoints( Spline1DContainer& spline, double xMin, double xMax, - const double vx[], const double vf[], int nDataPoints) + const double vx[], const double vf[], int32_t nDataPoints) { /// Create best-fit spline parameters for a given input function F assert(spline.isConstructed()); - const int nYdim = spline.getYdimensions(); + const int32_t nYdim = spline.getYdimensions(); spline.setXrange(xMin, xMax); // create the same spline in double precision setSpline(spline); - const int nPar = 2 * spline.getNumberOfKnots(); // n parameters for 1-Dimentional Y + const int32_t nPar = 2 * spline.getNumberOfKnots(); // n parameters for 1-Dimentional Y // BandMatrixSolver<6> band(nPar, nYdim); SymMatrixSolver band(nPar, nYdim); - for (int iPoint = 0; iPoint < nDataPoints; ++iPoint) { + for (int32_t iPoint = 0; iPoint < nDataPoints; ++iPoint) { double u = mSpline.convXtoU(vx[iPoint]); - int iKnot = mSpline.getLeftKnotIndexForU(u); + int32_t iKnot = mSpline.getLeftKnotIndexForU(u); const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); double cS0, cZ0, cS1, cZ1; getScoefficients(knot0, u, cS0, cZ0, cS1, cZ1); @@ -162,21 +162,21 @@ void Spline1DHelper::approximateDataPoints( // chi2 += (c[0]*S0 + c[1]*Z0 + c[2]*S1 + c[3]*Z1 - f)^2 - int i = 2 * iKnot; // index of parameter S0 - for (int j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 - for (int k = j; k < 4; k++) { // loop over the second parameter + int32_t i = 2 * iKnot; // index of parameter S0 + for (int32_t j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 + for (int32_t k = j; k < 4; k++) { // loop over the second parameter band.A(i + j, i + k) += c[j] * c[k]; } } const double* f = &vf[iPoint * nYdim]; - for (int j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 - for (int dim = 0; dim < nYdim; dim++) { + for (int32_t j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 + for (int32_t dim = 0; dim < nYdim; dim++) { band.B(i + j, dim) += c[j] * f[dim]; } } } - for (int iKnot = 0; iKnot < spline.getNumberOfKnots() - 2; ++iKnot) { + for (int32_t iKnot = 0; iKnot < spline.getNumberOfKnots() - 2; ++iKnot) { const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); const typename Spline1D::Knot& knot1 = mSpline.getKnot(iKnot + 1); // const typename Spline1D::Knot& knot2 = mSpline.getKnot(iKnot + 2); @@ -185,7 +185,7 @@ void Spline1DHelper::approximateDataPoints( // chi2 += w^2*(S''from the left - S'' from the right)^2 // chi2 += w^2*(S'''from the left - S''' from the right)^2 - for (int order = 2; order <= 3; order++) { + for (int32_t order = 2; order <= 3; order++) { double cS0, cZ0, cS1r, cZ1r; double cS1l, cZ1l, cS2, cZ2; if (order == 2) { @@ -203,9 +203,9 @@ void Spline1DHelper::approximateDataPoints( // chi2 += w^2*(c[0]*S0 + c[1]*Z0 + c[2]*S1 + c[3]*Z1 + c[4]*S2 + c[5]*Z2)^2 - int i = 2 * iKnot; // index of parameter S0 - for (int j = 0; j < 6; j++) { // loop over 6 parameters - for (int k = j; k < 6; k++) { // loop over the second parameter + int32_t i = 2 * iKnot; // index of parameter S0 + for (int32_t j = 0; j < 6; j++) { // loop over 6 parameters + for (int32_t k = j; k < 6; k++) { // loop over the second parameter band.A(i + j, i + k) += c[j] * c[k]; } } @@ -214,19 +214,19 @@ void Spline1DHelper::approximateDataPoints( // experimental: set slopes at neighbouring knots equal - doesn't work /* - for (int iKnot = 0; iKnot < spline.getNumberOfKnots() - 2; ++iKnot) { + for (int32_t iKnot = 0; iKnot < spline.getNumberOfKnots() - 2; ++iKnot) { const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); const typename Spline1D::Knot& knot1 = mSpline.getKnot(iKnot + 1); double w = 1.; - int i = 2 * iKnot; // index of parameter S0 + int32_t i = 2 * iKnot; // index of parameter S0 double d = knot1.u - knot0.u; { double c1[4] = {1, d, -1, 0}; double c2[4] = {1, 0, -1, d}; // chi2 += w*(c1[0]*S0 + c1[1]*Z0 + c1[2]*S1 + c1[3]*Z1)^2 // chi2 += w*(c2[0]*S0 + c2[1]*Z0 + c2[2]*S1 + c2[3]*Z1)^2 - for (int j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 - for (int k = j; k < 4; k++) { // loop over the second parameter + for (int32_t j = 0; j < 4; j++) { // parameters S0, Z0, S1, Z1 + for (int32_t k = j; k < 4; k++) { // loop over the second parameter band.A(i + j, i + k) += w * (c1[j] * c1[k] + c2[j] * c2[k]); } } @@ -237,8 +237,8 @@ void Spline1DHelper::approximateDataPoints( band.solve(); - for (int i = 0; i < nPar; i++) { - for (int j = 0; j < nYdim; j++) { + for (int32_t i = 0; i < nPar; i++) { + for (int32_t j = 0; j < nYdim; j++) { spline.getParameters()[i * nYdim + j] = band.B(i, j); } } @@ -247,24 +247,24 @@ void Spline1DHelper::approximateDataPoints( template void Spline1DHelper::approximateDerivatives( Spline1DContainer& spline, - const double vx[], const double vf[], int nDataPoints) + const double vx[], const double vf[], int32_t nDataPoints) { /// Create best-fit spline parameters for a given input function F assert(spline.isConstructed()); - const int nYdim = spline.getYdimensions(); + const int32_t nYdim = spline.getYdimensions(); // create the same spline in double precision setSpline(spline); - const int nPar = spline.getNumberOfKnots(); // n parameters for 1-Dimentional Y + const int32_t nPar = spline.getNumberOfKnots(); // n parameters for 1-Dimentional Y BandMatrixSolver<2> band(nPar, nYdim); - for (int iPoint = 0; iPoint < nDataPoints; ++iPoint) { + for (int32_t iPoint = 0; iPoint < nDataPoints; ++iPoint) { double u = mSpline.convXtoU(vx[iPoint]); - int iKnot = mSpline.getLeftKnotIndexForU(u); + int32_t iKnot = mSpline.getLeftKnotIndexForU(u); const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); double cS0, cZ0, cS1, cZ1; getScoefficients(knot0, u, cS0, cZ0, cS1, cZ1); @@ -273,7 +273,7 @@ void Spline1DHelper::approximateDerivatives( // chi2 += (cS0*S0 + c[0]*Z0 + cS1*S1 + c[1]*Z1 - f)^2 // == (c[0]*Z0 + c[1]*Z1 - (f - cS0*S0 - cS1*S1))^2 - int i = iKnot; // index of parameter Z0 + int32_t i = iKnot; // index of parameter Z0 band.A(i + 0, i + 0) += c[0] * c[0]; band.A(i + 0, i + 1) += c[0] * c[1]; band.A(i + 1, i + 1) += c[1] * c[1]; @@ -281,8 +281,8 @@ void Spline1DHelper::approximateDerivatives( const double* f = &vf[iPoint * nYdim]; const DataT* S0 = &spline.getParameters()[2 * iKnot * nYdim]; const DataT* S1 = &spline.getParameters()[2 * (iKnot + 1) * nYdim]; - for (int j = 0; j < 2; j++) { // parameters Z0, Z1 - for (int dim = 0; dim < nYdim; dim++) { + for (int32_t j = 0; j < 2; j++) { // parameters Z0, Z1 + for (int32_t dim = 0; dim < nYdim; dim++) { band.B(i + j, dim) += c[j] * (f[dim] - cS0 * S0[dim] - cS1 * S1[dim]); } } @@ -290,8 +290,8 @@ void Spline1DHelper::approximateDerivatives( band.solve(); - for (int i = 0; i < nPar; i++) { - for (int j = 0; j < nYdim; j++) { + for (int32_t i = 0; i < nPar; i++) { + for (int32_t j = 0; j < nYdim; j++) { spline.getParameters()[(2 * i + 1) * nYdim + j] = band.B(i, j); } } @@ -304,8 +304,8 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& /// Create classic spline parameters for a given input function F /// set slopes at the knots such, that the second derivative of the spline is continious. - int Ndim = spline.getYdimensions(); - const int nKnots = spline.getNumberOfKnots(); + int32_t Ndim = spline.getYdimensions(); + const int32_t nKnots = spline.getNumberOfKnots(); TMatrixD A(nKnots, nKnots); @@ -341,7 +341,7 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& } // second derivative at other knots is same from the left and from the right - for (int i = 1; i < nKnots - 1; i++) { + for (int32_t i = 1; i < nKnots - 1; i++) { const typename Spline1D::Knot& knot0 = spline.getKnot(i - 1); double cZ0 = (6 - 4) * knot0.Li; double cZ1_0 = (6 - 2) * knot0.Li; @@ -366,17 +366,17 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& double uToXscale = (((double)xMax) - xMin) / spline.getUmax(); - for (int i = 0; i < nKnots; ++i) { + for (int32_t i = 0; i < nKnots; ++i) { const typename Spline1D::Knot& knot = spline.getKnot(i); double u = knot.u; double f[Ndim]; F(xMin + u * uToXscale, f); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { parameters[(2 * i) * Ndim + dim] = f[dim]; } } - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { // second derivative at knot0 is 0 { @@ -399,7 +399,7 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& } // second derivative at other knots is same from the left and from the right - for (int i = 1; i < nKnots - 1; i++) { + for (int32_t i = 1; i < nKnots - 1; i++) { double f0 = parameters[2 * (i - 1) * Ndim + dim]; double f1 = parameters[2 * (i)*Ndim + dim]; double f2 = parameters[2 * (i + 1) * Ndim + dim]; @@ -414,7 +414,7 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& } TVectorD c = A * b; - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { parameters[(2 * i + 1) * Ndim + dim] = c[i]; } } @@ -423,12 +423,12 @@ void Spline1DHelper::approximateFunctionClassic(Spline1DContainer& template void Spline1DHelper::makeDataPoints( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints, std::vector& vx, std::vector& vf) + int32_t nAuxiliaryDataPoints, std::vector& vx, std::vector& vf) { /// Create best-fit spline parameters for a given input function F assert(spline.isConstructed()); - int nFdimensions = spline.getYdimensions(); - int nDataPoints = 0; + int32_t nFdimensions = spline.getYdimensions(); + int32_t nDataPoints = 0; if (nAuxiliaryDataPoints < 2) { storeError(-3, "Spline1DHelper::setSpline: too few nAuxiliaryDataPoints, increase to 2"); nAuxiliaryDataPoints = 2; @@ -441,7 +441,7 @@ void Spline1DHelper::makeDataPoints( vf.resize(nDataPoints * nFdimensions); double scalePoints2Knots = ((double)mSpline.getUmax()) / (nDataPoints - 1.); - for (int i = 0; i < nDataPoints; ++i) { + for (int32_t i = 0; i < nDataPoints; ++i) { double u = i * scalePoints2Knots; double x = mSpline.convUtoX(u); vx[i] = x; @@ -452,7 +452,7 @@ void Spline1DHelper::makeDataPoints( template void Spline1DHelper::approximateFunction( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints) + int32_t nAuxiliaryDataPoints) { /// Create best-fit spline parameters for a given input function F std::vector vx; @@ -464,26 +464,26 @@ void Spline1DHelper::approximateFunction( template void Spline1DHelper::approximateFunctionGradually( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints) + int32_t nAuxiliaryDataPoints) { /// Create best-fit spline parameters for a given input function F std::vector vx; std::vector vf; makeDataPoints(spline, xMin, xMax, F, nAuxiliaryDataPoints, vx, vf); - int nDataPoints = vx.size(); + int32_t nDataPoints = vx.size(); spline.setXrange(xMin, xMax); setSpline(spline); - int nFdimensions = spline.getYdimensions(); + int32_t nFdimensions = spline.getYdimensions(); // set F values at knots - for (int iKnot = 0; iKnot < mSpline.getNumberOfKnots(); ++iKnot) { + for (int32_t iKnot = 0; iKnot < mSpline.getNumberOfKnots(); ++iKnot) { const typename Spline1D::Knot& knot = mSpline.getKnot(iKnot); double x = mSpline.convUtoX(knot.u); double s[nFdimensions]; F(x, s); - for (int dim = 0; dim < nFdimensions; dim++) { + for (int32_t dim = 0; dim < nFdimensions; dim++) { spline.getParameters()[2 * iKnot * nFdimensions + dim] = s[dim]; } } @@ -493,9 +493,9 @@ void Spline1DHelper::approximateFunctionGradually( template void Spline1DHelper::setSpline(const Spline1DContainer& spline) { - const int nKnots = spline.getNumberOfKnots(); - std::vector knots(nKnots); - for (int i = 0; i < nKnots; i++) { + const int32_t nKnots = spline.getNumberOfKnots(); + std::vector knots(nKnots); + for (int32_t i = 0; i < nKnots; i++) { knots[i] = spline.getKnot(i).getU(); } mSpline.recreate(0, nKnots, knots.data()); @@ -504,7 +504,7 @@ void Spline1DHelper::setSpline(const Spline1DContainer& spline) #ifndef GPUCA_ALIROOT_LIB template -int Spline1DHelper::test(const bool draw, const bool drawDataPoints) +int32_t Spline1DHelper::test(const bool draw, const bool drawDataPoints) { using namespace std; @@ -512,19 +512,19 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) // input function F - const int Ndim = 5; - const int Fdegree = 4; + const int32_t Ndim = 5; + const int32_t Fdegree = 4; double Fcoeff[Ndim][2 * (Fdegree + 1)]; auto F = [&](double x, double f[]) -> void { double cosx[Fdegree + 1], sinx[Fdegree + 1]; double xi = 0; - for (int i = 0; i <= Fdegree; i++, xi += x) { + for (int32_t i = 0; i <= Fdegree; i++, xi += x) { GPUCommonMath::SinCosd(xi, sinx[i], cosx[i]); } - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { f[dim] = 0; // Fcoeff[0]/2; - for (int i = 1; i <= Fdegree; i++) { + for (int32_t i = 1; i <= Fdegree; i++) { f[dim] += Fcoeff[dim][2 * i] * cosx[i] + Fcoeff[dim][2 * i + 1] * sinx[i]; } } @@ -547,7 +547,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) LOG(info) << "Test 1D interpolation with the compact spline"; - int nTries = 100; + int32_t nTries = 100; if (draw) { canv = new TCanvas("cQA", "Spline1D QA", 1000, 600); @@ -559,31 +559,31 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) double statDf1D = 0; double statN = 0; - int seed = 1; + int32_t seed = 1; - for (int itry = 0; itry < nTries; itry++) { + for (int32_t itry = 0; itry < nTries; itry++) { // init random F - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { gRandom->SetSeed(seed++); - for (int i = 0; i < 2 * (Fdegree + 1); i++) { + for (int32_t i = 0; i < 2 * (Fdegree + 1); i++) { Fcoeff[dim][i] = gRandom->Uniform(-1, 1); } } // spline - int nKnots = 4; - const int uMax = nKnots * 3; + int32_t nKnots = 4; + const int32_t uMax = nKnots * 3; Spline1D spline1; - int knotsU[nKnots]; + int32_t knotsU[nKnots]; do { // set knots randomly knotsU[0] = 0; double du = 1. * uMax / (nKnots - 1); - for (int i = 1; i < nKnots; i++) { - knotsU[i] = (int)(i * du); // + gRandom->Uniform(-du / 3, du / 3); + for (int32_t i = 1; i < nKnots; i++) { + knotsU[i] = (int32_t)(i * du); // + gRandom->Uniform(-du / 3, du / 3); } knotsU[nKnots - 1] = uMax; spline1.recreate(nKnots, knotsU); @@ -603,7 +603,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) } nKnots = spline1.getNumberOfKnots(); - int nAuxiliaryPoints = 2; + int32_t nAuxiliaryPoints = 2; Spline1D spline2(spline1); spline1.approximateFunction(0., TMath::Pi(), F, nAuxiliaryPoints); @@ -631,7 +631,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) // 1-D splines for each dimension Spline1D splines3[Ndim]; { - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { auto F3 = [&](double u, double f[]) -> void { double ff[Ndim]; F(u, ff); @@ -649,7 +649,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) F(x, f); spline1.interpolate(x, s1); spline2.interpolate(x, s2); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { statDf1 += (s1[dim] - f[dim]) * (s1[dim] - f[dim]); statDf2 += (s2[dim] - f[dim]) * (s2[dim] - f[dim]); DataT s1D = splines3[dim].interpolate(x); @@ -701,7 +701,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) nt->Draw("s:u", "", "P,same"); knots = new TNtuple("knots", "knots", "type:u:s"); - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { double u = spline1.getKnot(i).u; DataT s[Ndim]; spline1.interpolate(spline1.convUtoX(u), s); @@ -718,7 +718,7 @@ int Spline1DHelper::test(const bool draw, const bool drawDataPoints) std::vector vx; std::vector vf; helper.makeDataPoints(spline1, 0., TMath::Pi(), F, nAuxiliaryPoints, vx, vf); - for (unsigned int j = 0; j < vx.size(); j++) { + for (uint32_t j = 0; j < vx.size(); j++) { DataT s[Ndim]; spline1.interpolate(vx[j], s); knots->Fill(2, spline1.convXtoU(vx[j]), s[0]); diff --git a/GPU/TPCFastTransformation/Spline1DHelper.h b/GPU/TPCFastTransformation/Spline1DHelper.h index b9418fe57ca8f..e8388d68a6e05 100644 --- a/GPU/TPCFastTransformation/Spline1DHelper.h +++ b/GPU/TPCFastTransformation/Spline1DHelper.h @@ -54,20 +54,20 @@ class Spline1DHelper /// Create best-fit spline parameters for a set of data points void approximateDataPoints(Spline1DContainer& spline, double xMin, double xMax, - const double vx[], const double vf[], int nDataPoints); + const double vx[], const double vf[], int32_t nDataPoints); /// Create best-fit spline parameters for a function F void approximateFunction( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints = 4); + int32_t nAuxiliaryDataPoints = 4); /// Approximate only derivatives assuming the spline values at knozts are already set void approximateDerivatives(Spline1DContainer& spline, - const double vx[], const double vf[], int nDataPoints); + const double vx[], const double vf[], int32_t nDataPoints); void approximateFunctionGradually( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints); + int32_t nAuxiliaryDataPoints); /// Create classic spline parameters for a given input function F void approximateFunctionClassic(Spline1DContainer& spline, @@ -101,19 +101,19 @@ class Spline1DHelper #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the Spline1D class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif private: /// Stores an error message - int storeError(int code, const char* msg); + int32_t storeError(int32_t code, const char* msg); std::string mError = ""; ///< error string void setSpline(const Spline1DContainer& spline); void makeDataPoints(Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints, std::vector& vx, std::vector& vf); + int32_t nAuxiliaryDataPoints, std::vector& vx, std::vector& vf); /// helpers for the construction of 1D spline diff --git a/GPU/TPCFastTransformation/Spline1DHelperOld.cxx b/GPU/TPCFastTransformation/Spline1DHelperOld.cxx index 6874524ba897b..7b75a8409eada 100644 --- a/GPU/TPCFastTransformation/Spline1DHelperOld.cxx +++ b/GPU/TPCFastTransformation/Spline1DHelperOld.cxx @@ -42,7 +42,7 @@ Spline1DHelperOld::Spline1DHelperOld() : mError(), mSpline(), mFdimension } template -int Spline1DHelperOld::storeError(int code, const char* msg) +int32_t Spline1DHelperOld::storeError(int32_t code, const char* msg) { mError = msg; return code; @@ -137,8 +137,8 @@ void Spline1DHelperOld::approximateFunctionClassic(Spline1DContainer::approximateFunctionClassic(Spline1DContainer::Knot& knot0 = spline.getKnot(i - 1); double cZ0 = (6 - 4) * knot0.Li; double cZ1_0 = (6 - 2) * knot0.Li; @@ -199,17 +199,17 @@ void Spline1DHelperOld::approximateFunctionClassic(Spline1DContainer::Knot& knot = spline.getKnot(i); double u = knot.u; double f[Ndim]; F(xMin + u * uToXscale, f); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { parameters[(2 * i) * Ndim + dim] = f[dim]; } } - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { // second derivative at knot0 is 0 { @@ -232,7 +232,7 @@ void Spline1DHelperOld::approximateFunctionClassic(Spline1DContainer::approximateFunctionClassic(Spline1DContainer void Spline1DHelperOld::approximateDataPoints( Spline1DContainer& spline, double xMin, double xMax, - double vx[], double vf[], int nDataPoints) + double vx[], double vf[], int32_t nDataPoints) { /// Create best-fit spline parameters for a given input function F @@ -269,7 +269,7 @@ void Spline1DHelperOld::approximateDataPoints( template void Spline1DHelperOld::approximateFunction( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints) + int32_t nAuxiliaryDataPoints) { /// Create best-fit spline parameters for a given input function F setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints); @@ -280,7 +280,7 @@ void Spline1DHelperOld::approximateFunction( template void Spline1DHelperOld::approximateFunctionGradually( Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints) + int32_t nAuxiliaryDataPoints) { /// Create best-fit spline parameters gradually for a given input function F setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints); @@ -296,7 +296,7 @@ void Spline1DHelperOld::approximateFunction( /// output in Sparameters std::vector vF(getNumberOfDataPoints() * mFdimensions); double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax(); - for (int i = 0; i < getNumberOfDataPoints(); i++) { + for (int32_t i = 0; i < getNumberOfDataPoints(); i++) { F(xMin + mUtoXscale * mDataPoints[i].u, &vF[i * mFdimensions]); } approximateFunction(Sparameters, vF.data()); @@ -310,15 +310,15 @@ void Spline1DHelperOld::approximateFunctionGradually( /// output in Sparameters std::vector vF(getNumberOfDataPoints() * mFdimensions); double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax(); - for (int i = 0; i < getNumberOfDataPoints(); i++) { + for (int32_t i = 0; i < getNumberOfDataPoints(); i++) { F(xMin + mUtoXscale * mDataPoints[i].u, &vF[i * mFdimensions]); } approximateFunctionGradually(Sparameters, vF.data()); } template -int Spline1DHelperOld::setSpline( - const Spline1DContainer& spline, int nFdimensions, int nAuxiliaryDataPoints) +int32_t Spline1DHelperOld::setSpline( + const Spline1DContainer& spline, int32_t nFdimensions, int32_t nAuxiliaryDataPoints) { // Prepare creation of a best-fit spline // @@ -332,18 +332,18 @@ int Spline1DHelperOld::setSpline( // // The return value is an error index, 0 means no error - int ret = 0; + int32_t ret = 0; mFdimensions = nFdimensions; - int nPoints = 0; + int32_t nPoints = 0; if (!spline.isConstructed()) { ret = storeError(-1, "Spline1DHelperOld::setSpline: input spline is not constructed"); mSpline.recreate(0, 2); nAuxiliaryDataPoints = 2; nPoints = 4; } else { - std::vector knots; - for (int i = 0; i < spline.getNumberOfKnots(); i++) { + std::vector knots; + for (int32_t i = 0; i < spline.getNumberOfKnots(); i++) { knots.push_back(spline.getKnot(i).getU()); } mSpline.recreate(0, spline.getNumberOfKnots(), knots.data()); @@ -356,15 +356,15 @@ int Spline1DHelperOld::setSpline( } } - const int nPar = 2 * mSpline.getNumberOfKnots(); // n parameters for 1D + const int32_t nPar = 2 * mSpline.getNumberOfKnots(); // n parameters for 1D mDataPoints.resize(nPoints); double scalePoints2Knots = ((double)mSpline.getUmax()) / (nPoints - 1.); - for (int i = 0; i < nPoints; ++i) { + for (int32_t i = 0; i < nPoints; ++i) { DataPoint& p = mDataPoints[i]; double u = i * scalePoints2Knots; - int iKnot = mSpline.getLeftKnotIndexForU(u); + int32_t iKnot = mSpline.getLeftKnotIndexForU(u); const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); const typename Spline1D::Knot& knot1 = mSpline.getKnot(iKnot + 1); double l = knot1.u - knot0.u; @@ -381,13 +381,13 @@ int Spline1DHelperOld::setSpline( p.cZ1 = s2 * sm1 * l; } - const int nKnots = mSpline.getNumberOfKnots(); + const int32_t nKnots = mSpline.getNumberOfKnots(); mKnotDataPoints.resize(nKnots); - for (int i = 0; i < nKnots; ++i) { + for (int32_t i = 0; i < nKnots; ++i) { const typename Spline1D::Knot& knot = mSpline.getKnot(i); - int iu = (int)(knot.u + 0.1f); + int32_t iu = (int32_t)(knot.u + 0.1f); mKnotDataPoints[i] = iu * (1 + nAuxiliaryDataPoints); mDataPoints[mKnotDataPoints[i]].isKnot = 1; } @@ -395,9 +395,9 @@ int Spline1DHelperOld::setSpline( TMatrixDSym A(nPar); A.Zero(); - for (int i = 0; i < nPoints; ++i) { + for (int32_t i = 0; i < nPoints; ++i) { DataPoint& p = mDataPoints[i]; - int j = p.iKnot * 2; + int32_t j = p.iKnot * 2; A(j + 0, j + 0) += p.cS0 * p.cS0; A(j + 1, j + 0) += p.cS0 * p.cZ0; A(j + 2, j + 0) += p.cS0 * p.cS1; @@ -415,16 +415,16 @@ int Spline1DHelperOld::setSpline( // copy symmetric matrix elements - for (int i = 0; i < nPar; i++) { - for (int j = i + 1; j < nPar; j++) { + for (int32_t i = 0; i < nPar; i++) { + for (int32_t j = i + 1; j < nPar; j++) { A(i, j) = A(j, i); } } TMatrixDSym Z(nKnots); mLSMmatrixSvalues.resize(nKnots * nKnots); - for (int i = 0, k = 0; i < nKnots; i++) { - for (int j = 0; j < nKnots; j++, k++) { + for (int32_t i = 0, k = 0; i < nKnots; i++) { + for (int32_t j = 0; j < nKnots; j++, k++) { mLSMmatrixSvalues[k] = A(i * 2 + 1, j * 2); Z(i, j) = A(i * 2 + 1, j * 2 + 1); } @@ -439,8 +439,8 @@ int Spline1DHelperOld::setSpline( A.Zero(); } mLSMmatrixFull.resize(nPar * nPar); - for (int i = 0, k = 0; i < nPar; i++) { - for (int j = 0; j < nPar; j++, k++) { + for (int32_t i = 0, k = 0; i < nPar; i++) { + for (int32_t j = 0; j < nPar; j++, k++) { mLSMmatrixFull[k] = A(i, j); } } @@ -453,8 +453,8 @@ int Spline1DHelperOld::setSpline( Z.Zero(); } mLSMmatrixSderivatives.resize(nKnots * nKnots); - for (int i = 0, k = 0; i < nKnots; i++) { - for (int j = 0; j < nKnots; j++, k++) { + for (int32_t i = 0, k = 0; i < nKnots; i++) { + for (int32_t j = 0; j < nKnots; j++, k++) { mLSMmatrixSderivatives[k] = Z(i, j); } } @@ -464,8 +464,8 @@ int Spline1DHelperOld::setSpline( } template -int Spline1DHelperOld::setSpline( - const Spline1DContainer& spline, int nFdimensions, double xMin, double xMax, double vx[], int nDataPoints) +int32_t Spline1DHelperOld::setSpline( + const Spline1DContainer& spline, int32_t nFdimensions, double xMin, double xMax, double vx[], int32_t nDataPoints) { // Prepare creation of a best-fit spline // @@ -479,16 +479,16 @@ int Spline1DHelperOld::setSpline( // // The return value is an error index, 0 means no error - int ret = 0; + int32_t ret = 0; mFdimensions = nFdimensions; - int nPoints = nDataPoints; + int32_t nPoints = nDataPoints; if (!spline.isConstructed()) { ret = storeError(-1, "Spline1DHelperOld::setSpline: input spline is not constructed"); mSpline.recreate(0, 2); } else { - std::vector knots; - for (int i = 0; i < spline.getNumberOfKnots(); i++) { + std::vector knots; + for (int32_t i = 0; i < spline.getNumberOfKnots(); i++) { knots.push_back(spline.getKnot(i).getU()); } mSpline.recreate(0, spline.getNumberOfKnots(), knots.data()); @@ -496,14 +496,14 @@ int Spline1DHelperOld::setSpline( mSpline.setXrange(xMin, xMax); - const int nPar = 2 * mSpline.getNumberOfKnots(); // n parameters for 1D + const int32_t nPar = 2 * mSpline.getNumberOfKnots(); // n parameters for 1D mDataPoints.resize(nPoints); - for (int i = 0; i < nPoints; ++i) { + for (int32_t i = 0; i < nPoints; ++i) { DataPoint& p = mDataPoints[i]; double u = mSpline.convXtoU(vx[i]); - int iKnot = mSpline.getLeftKnotIndexForU(u); + int32_t iKnot = mSpline.getLeftKnotIndexForU(u); p.iKnot = iKnot; p.isKnot = 0; p.u = u; @@ -511,14 +511,14 @@ int Spline1DHelperOld::setSpline( getScoefficients(knot0, u, p.cS0, p.cZ0, p.cS1, p.cZ1); } - const int nKnots = mSpline.getNumberOfKnots(); + const int32_t nKnots = mSpline.getNumberOfKnots(); TMatrixDSym A(nPar); A.Zero(); - for (int i = 0; i < nPoints; ++i) { + for (int32_t i = 0; i < nPoints; ++i) { DataPoint& p = mDataPoints[i]; - int j = p.iKnot * 2; + int32_t j = p.iKnot * 2; A(j + 0, j + 0) += p.cS0 * p.cS0; A(j + 1, j + 0) += p.cS0 * p.cZ0; A(j + 2, j + 0) += p.cS0 * p.cS1; @@ -534,7 +534,7 @@ int Spline1DHelperOld::setSpline( A(j + 3, j + 3) += p.cZ1 * p.cZ1; } - for (int iKnot = 0; iKnot < nKnots - 2; ++iKnot) { + for (int32_t iKnot = 0; iKnot < nKnots - 2; ++iKnot) { const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); const typename Spline1D::Knot& knot1 = mSpline.getKnot(iKnot + 1); // const typename Spline1D::Knot& knot2 = mSpline.getKnot(iKnot + 2); @@ -582,7 +582,7 @@ int Spline1DHelperOld::setSpline( double cS2 = c * 3 * l1 * l1; double cZ2 = c * -l1; - int j = iKnot * 2; + int32_t j = iKnot * 2; A(j + 0, j + 0) += cS0 * cS0; A(j + 1, j + 0) += cS0 * cZ0; @@ -612,7 +612,7 @@ int Spline1DHelperOld::setSpline( A(j + 5, j + 5) += cZ2 * cZ2; } - for (int iKnot = -1; iKnot < nKnots - 2; ++iKnot) { + for (int32_t iKnot = -1; iKnot < nKnots - 2; ++iKnot) { const typename Spline1D::Knot& knot1 = mSpline.getKnot(iKnot + 1); /* @@ -633,7 +633,7 @@ int Spline1DHelperOld::setSpline( double cS2 = c * 3 * l1 * l1; double cZ2 = c * -l1; - int j = iKnot * 2; + int32_t j = iKnot * 2; A(j + 2, j + 2) += cS1 * cS1; A(j + 3, j + 2) += cS1 * cZ1; @@ -651,7 +651,7 @@ int Spline1DHelperOld::setSpline( } { - int iKnot = nKnots - 2; + int32_t iKnot = nKnots - 2; const typename Spline1D::Knot& knot0 = mSpline.getKnot(iKnot); /* ()''u @@ -671,7 +671,7 @@ int Spline1DHelperOld::setSpline( double cS1 = c * -3 * l0 * l0; double cZ1 = c * 2 * l0; - int j = iKnot * 2; + int32_t j = iKnot * 2; A(j + 0, j + 0) += cS0 * cS0; A(j + 1, j + 0) += cS0 * cZ0; @@ -690,16 +690,16 @@ int Spline1DHelperOld::setSpline( // copy symmetric matrix elements - for (int i = 0; i < nPar; i++) { - for (int j = i + 1; j < nPar; j++) { + for (int32_t i = 0; i < nPar; i++) { + for (int32_t j = i + 1; j < nPar; j++) { A(i, j) = A(j, i); } } TMatrixDSym Z(nKnots); mLSMmatrixSvalues.resize(nKnots * nKnots); - for (int i = 0, k = 0; i < nKnots; i++) { - for (int j = 0; j < nKnots; j++, k++) { + for (int32_t i = 0, k = 0; i < nKnots; i++) { + for (int32_t j = 0; j < nKnots; j++, k++) { mLSMmatrixSvalues[k] = A(i * 2 + 1, j * 2); Z(i, j) = A(i * 2 + 1, j * 2 + 1); } @@ -714,8 +714,8 @@ int Spline1DHelperOld::setSpline( A.Zero(); } mLSMmatrixFull.resize(nPar * nPar); - for (int i = 0, k = 0; i < nPar; i++) { - for (int j = 0; j < nPar; j++, k++) { + for (int32_t i = 0, k = 0; i < nPar; i++) { + for (int32_t j = 0; j < nPar; j++, k++) { mLSMmatrixFull[k] = A(i, j); } } @@ -728,8 +728,8 @@ int Spline1DHelperOld::setSpline( Z.Zero(); } mLSMmatrixSderivatives.resize(nKnots * nKnots); - for (int i = 0, k = 0; i < nKnots; i++) { - for (int j = 0; j < nKnots; j++, k++) { + for (int32_t i = 0, k = 0; i < nKnots; i++) { + for (int32_t j = 0; j < nKnots; j++, k++) { mLSMmatrixSderivatives[k] = Z(i, j); } } @@ -745,13 +745,13 @@ void Spline1DHelperOld::approximateFunction( { /// Approximate a function given as an array of values at data points - const int nPar = 2 * mSpline.getNumberOfKnots(); + const int32_t nPar = 2 * mSpline.getNumberOfKnots(); double b[nPar]; - for (int idim = 0; idim < mFdimensions; idim++) { - for (int i = 0; i < nPar; i++) { + for (int32_t idim = 0; idim < mFdimensions; idim++) { + for (int32_t i = 0; i < nPar; i++) { b[i] = 0.; } - for (int i = 0; i < getNumberOfDataPoints(); ++i) { + for (int32_t i = 0; i < getNumberOfDataPoints(); ++i) { const DataPoint& p = mDataPoints[i]; double* bb = &(b[p.iKnot * 2]); double f = (double)DataPointF[i * mFdimensions + idim]; @@ -763,9 +763,9 @@ void Spline1DHelperOld::approximateFunction( const double* row = mLSMmatrixFull.data(); - for (int i = 0; i < nPar; i++, row += nPar) { + for (int32_t i = 0; i < nPar; i++, row += nPar) { double s = 0.; - for (int j = 0; j < nPar; j++) { + for (int32_t j = 0; j < nPar; j++) { s += row[j] * b[j]; } Sparameters[i * mFdimensions + idim] = (float)s; @@ -789,9 +789,9 @@ void Spline1DHelperOld::copySfromDataPoints( { /// a tool for the gradual approximation: set spline values S_i at knots == function values /// output in Sparameters - for (int i = 0; i < mSpline.getNumberOfKnots(); ++i) { // set F values at knots - int ip = mKnotDataPoints[i]; - for (int d = 0; d < mFdimensions; d++) { + for (int32_t i = 0; i < mSpline.getNumberOfKnots(); ++i) { // set F values at knots + int32_t ip = mKnotDataPoints[i]; + for (int32_t d = 0; d < mFdimensions; d++) { Sparameters[2 * i * mFdimensions + d] = DataPointF[ip * mFdimensions + d]; } } @@ -805,19 +805,19 @@ void Spline1DHelperOld::approximateDerivatives( /// calibrate spline derivatives D_i using already calibrated spline values S_i /// input and output output in Sparameters - const int nKnots = mSpline.getNumberOfKnots(); - const int Ndim = mFdimensions; + const int32_t nKnots = mSpline.getNumberOfKnots(); + const int32_t Ndim = mFdimensions; double b[nKnots * mFdimensions]; - for (int i = 0; i < nKnots * Ndim; i++) { + for (int32_t i = 0; i < nKnots * Ndim; i++) { b[i] = 0.; } - for (int i = 0; i < getNumberOfDataPoints(); ++i) { + for (int32_t i = 0; i < getNumberOfDataPoints(); ++i) { const DataPoint& p = mDataPoints[i]; if (p.isKnot) { continue; } - for (int d = 0; d < Ndim; d++) { + for (int32_t d = 0; d < Ndim; d++) { double f = (double)DataPointF[i * Ndim + d]; b[(p.iKnot + 0) * Ndim + d] += f * p.cZ0; b[(p.iKnot + 1) * Ndim + d] += f * p.cZ1; @@ -825,33 +825,33 @@ void Spline1DHelperOld::approximateDerivatives( } const double* row = mLSMmatrixSvalues.data(); - for (int i = 0; i < nKnots; ++i, row += nKnots) { + for (int32_t i = 0; i < nKnots; ++i, row += nKnots) { double s[Ndim]; - for (int d = 0; d < Ndim; d++) { + for (int32_t d = 0; d < Ndim; d++) { s[d] = 0.; } - for (int j = 0; j < nKnots; ++j) { - for (int d = 0; d < Ndim; d++) { + for (int32_t j = 0; j < nKnots; ++j) { + for (int32_t d = 0; d < Ndim; d++) { s[d] += row[j] * Sparameters[2 * j * Ndim + d]; } } - for (int d = 0; d < Ndim; d++) { + for (int32_t d = 0; d < Ndim; d++) { b[i * Ndim + d] -= s[d]; } } row = mLSMmatrixSderivatives.data(); - for (int i = 0; i < nKnots; ++i, row += nKnots) { + for (int32_t i = 0; i < nKnots; ++i, row += nKnots) { double s[Ndim]; - for (int d = 0; d < Ndim; d++) { + for (int32_t d = 0; d < Ndim; d++) { s[d] = 0.; } - for (int j = 0; j < nKnots; ++j) { - for (int d = 0; d < Ndim; d++) { + for (int32_t j = 0; j < nKnots; ++j) { + for (int32_t d = 0; d < Ndim; d++) { s[d] += row[j] * b[j * Ndim + d]; } } - for (int d = 0; d < Ndim; d++) { + for (int32_t d = 0; d < Ndim; d++) { Sparameters[(2 * i + 1) * Ndim + d] = (float)s[d]; } } @@ -859,25 +859,25 @@ void Spline1DHelperOld::approximateDerivatives( #ifndef GPUCA_ALIROOT_LIB template -int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) +int32_t Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) { using namespace std; // input function F - const int Ndim = 5; - const int Fdegree = 4; + const int32_t Ndim = 5; + const int32_t Fdegree = 4; double Fcoeff[Ndim][2 * (Fdegree + 1)]; auto F = [&](double x, double f[]) -> void { double cosx[Fdegree + 1], sinx[Fdegree + 1]; double xi = 0; - for (int i = 0; i <= Fdegree; i++, xi += x) { + for (int32_t i = 0; i <= Fdegree; i++, xi += x) { GPUCommonMath::SinCosd(xi, sinx[i], cosx[i]); } - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { f[dim] = 0; // Fcoeff[0]/2; - for (int i = 1; i <= Fdegree; i++) { + for (int32_t i = 1; i <= Fdegree; i++) { f[dim] += Fcoeff[dim][2 * i] * cosx[i] + Fcoeff[dim][2 * i + 1] * sinx[i]; } } @@ -900,7 +900,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) LOG(info) << "Test 1D interpolation with the compact spline"; - int nTries = 100; + int32_t nTries = 100; if (draw) { canv = new TCanvas("cQA", "Spline1D QA", 1000, 600); @@ -912,31 +912,31 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) double statDf1D = 0; double statN = 0; - int seed = 1; + int32_t seed = 1; - for (int itry = 0; itry < nTries; itry++) { + for (int32_t itry = 0; itry < nTries; itry++) { // init random F - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { gRandom->SetSeed(seed++); - for (int i = 0; i < 2 * (Fdegree + 1); i++) { + for (int32_t i = 0; i < 2 * (Fdegree + 1); i++) { Fcoeff[dim][i] = gRandom->Uniform(-1, 1); } } // spline - int nKnots = 4; - const int uMax = nKnots * 3; + int32_t nKnots = 4; + const int32_t uMax = nKnots * 3; Spline1D spline1; - int knotsU[nKnots]; + int32_t knotsU[nKnots]; do { // set knots randomly knotsU[0] = 0; double du = 1. * uMax / (nKnots - 1); - for (int i = 1; i < nKnots; i++) { - knotsU[i] = (int)(i * du); // + gRandom->Uniform(-du / 3, du / 3); + for (int32_t i = 1; i < nKnots; i++) { + knotsU[i] = (int32_t)(i * du); // + gRandom->Uniform(-du / 3, du / 3); } knotsU[nKnots - 1] = uMax; spline1.recreate(nKnots, knotsU); @@ -956,7 +956,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) } nKnots = spline1.getNumberOfKnots(); - int nAuxiliaryPoints = 1; + int32_t nAuxiliaryPoints = 1; Spline1D spline2(spline1); spline1.approximateFunction(0., TMath::Pi(), F, nAuxiliaryPoints); @@ -985,7 +985,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) // 1-D splines for each dimension Spline1D splines3[Ndim]; { - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { auto F3 = [&](double u, double f[]) -> void { double ff[Ndim]; F(u, ff); @@ -1003,7 +1003,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) F(x, f); spline1.interpolate(x, s1); spline2.interpolate(x, s2); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { statDf1 += (s1[dim] - f[dim]) * (s1[dim] - f[dim]); statDf2 += (s2[dim] - f[dim]) * (s2[dim] - f[dim]); DataT s1D = splines3[dim].interpolate(x); @@ -1055,7 +1055,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) nt->Draw("s:u", "", "P,same"); knots = new TNtuple("knots", "knots", "type:u:s"); - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { double u = spline1.getKnot(i).u; DataT s[Ndim]; spline1.interpolate(spline1.convUtoX(u), s); @@ -1069,7 +1069,7 @@ int Spline1DHelperOld::test(const bool draw, const bool drawDataPoints) knots->Draw("s:u", "type==1", "same"); // knots if (drawDataPoints) { - for (int j = 0; j < helper.getNumberOfDataPoints(); j++) { + for (int32_t j = 0; j < helper.getNumberOfDataPoints(); j++) { const typename Spline1DHelperOld::DataPoint& p = helper.getDataPoint(j); if (p.isKnot) { continue; diff --git a/GPU/TPCFastTransformation/Spline1DHelperOld.h b/GPU/TPCFastTransformation/Spline1DHelperOld.h index 4a83f5a7bc7b6..eaf2f185aa23c 100644 --- a/GPU/TPCFastTransformation/Spline1DHelperOld.h +++ b/GPU/TPCFastTransformation/Spline1DHelperOld.h @@ -46,7 +46,7 @@ class Spline1DHelperOld double cZ0; ///< a coefficient for s'0 double cS1; ///< a coefficient for s1 double cZ1; ///< a coefficient for s'1 - int iKnot; ///< index of the left knot of the segment + int32_t iKnot; ///< index of the left knot of the segment bool isKnot; ///< is the point placed at a knot }; @@ -66,22 +66,22 @@ class Spline1DHelperOld /// _______________ Main functionality ________________________ - void bandGauss(double A[], double b[], int n); + void bandGauss(double A[], double b[], int32_t n); /// Create best-fit spline parameters for a given input function F void approximateDataPoints(Spline1DContainer& spline, double xMin, double xMax, - double x[], double f[], int nDataPoints); + double x[], double f[], int32_t nDataPoints); /// Create best-fit spline parameters for a given input function F void approximateFunction(Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints = 4); + int32_t nAuxiliaryDataPoints = 4); /// Create best-fit spline parameters gradually for a given input function F void approximateFunctionGradually(Spline1DContainer& spline, double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints = 4); + int32_t nAuxiliaryDataPoints = 4); /// Create classic spline parameters for a given input function F void approximateFunctionClassic(Spline1DContainer& spline, @@ -90,10 +90,10 @@ class Spline1DHelperOld /// _______________ Interface for a step-wise construction of the best-fit spline ________________________ /// precompute everything needed for the construction - int setSpline(const Spline1DContainer& spline, int nFdimensions, int nAuxiliaryDataPoints); + int32_t setSpline(const Spline1DContainer& spline, int32_t nFdimensions, int32_t nAuxiliaryDataPoints); /// precompute everything needed for the construction - int setSpline(const Spline1DContainer& spline, int nFdimensions, double xMin, double xMax, double vx[], int nDataPoints); + int32_t setSpline(const Spline1DContainer& spline, int32_t nFdimensions, double xMin, double xMax, double vx[], int32_t nDataPoints); /// approximate std::function, output in Fparameters void approximateFunction(DataT* Fparameters, double xMin, double xMax, std::function F) const; @@ -102,7 +102,7 @@ class Spline1DHelperOld void approximateFunctionGradually(DataT* Fparameters, double xMin, double xMax, std::function F) const; /// number of data points - int getNumberOfDataPoints() const { return mDataPoints.size(); } + int32_t getNumberOfDataPoints() const { return mDataPoints.size(); } /// approximate a function given as an array of values at data points void approximateFunction(DataT* Fparameters, const double DataPointF[/*getNumberOfDataPoints() x nFdim*/]) const; @@ -121,9 +121,9 @@ class Spline1DHelperOld const Spline1D& getSpline() const { return mSpline; } - int getKnotDataPoint(int iknot) const { return mKnotDataPoints[iknot]; } + int32_t getKnotDataPoint(int32_t iknot) const { return mKnotDataPoints[iknot]; } - const DataPoint& getDataPoint(int ip) const { return mDataPoints[ip]; } + const DataPoint& getDataPoint(int32_t ip) const { return mDataPoints[ip]; } /// Get derivatives of the interpolated value {S(u): 1D -> nYdim} at the segment [knotL, next knotR] /// over the spline values Sl, Sr and the slopes Dl, Dr @@ -149,21 +149,21 @@ class Spline1DHelperOld #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the Spline1D class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif private: /// Stores an error message - int storeError(int code, const char* msg); + int32_t storeError(int32_t code, const char* msg); std::string mError = ""; ///< error string /// helpers for the construction of 1D spline Spline1D mSpline; ///< copy of the spline - int mFdimensions; ///< n of F dimensions + int32_t mFdimensions; ///< n of F dimensions std::vector mDataPoints; ///< measurement points - std::vector mKnotDataPoints; ///< which measurement points are at knots + std::vector mKnotDataPoints; ///< which measurement points are at knots std::vector mLSMmatrixFull; ///< a matrix to convert the measurements into the spline parameters with the LSM method std::vector mLSMmatrixSderivatives; std::vector mLSMmatrixSvalues; diff --git a/GPU/TPCFastTransformation/Spline1DSpec.cxx b/GPU/TPCFastTransformation/Spline1DSpec.cxx index 25f25cb4e7a54..7a5b76a71678e 100644 --- a/GPU/TPCFastTransformation/Spline1DSpec.cxx +++ b/GPU/TPCFastTransformation/Spline1DSpec.cxx @@ -35,7 +35,7 @@ using namespace GPUCA_NAMESPACE::gpu; #if !defined(GPUCA_GPUCODE) template -void Spline1DContainer::recreate(int nYdim, int numberOfKnots) +void Spline1DContainer::recreate(int32_t nYdim, int32_t numberOfKnots) { /// Constructor for a regular spline /// \param numberOfKnots Number of knots @@ -44,15 +44,15 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots) numberOfKnots = 2; } - std::vector knots(numberOfKnots); - for (int i = 0; i < numberOfKnots; i++) { + std::vector knots(numberOfKnots); + for (int32_t i = 0; i < numberOfKnots; i++) { knots[i] = i; } recreate(nYdim, numberOfKnots, knots.data()); } template -void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int inputKnots[]) +void Spline1DContainer::recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t inputKnots[]) { /// Main constructor for an irregular spline /// @@ -68,19 +68,19 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int mYdim = (nYdim >= 0) ? nYdim : 0; - std::vector knotU; + std::vector knotU; { // sort knots - std::vector tmp; - for (int i = 0; i < numberOfKnots; i++) { + std::vector tmp; + for (int32_t i = 0; i < numberOfKnots; i++) { tmp.push_back(inputKnots[i]); } std::sort(tmp.begin(), tmp.end()); knotU.push_back(0); // first knot at 0 - for (unsigned int i = 1; i < tmp.size(); ++i) { - int u = tmp[i] - tmp[0]; + for (uint32_t i = 1; i < tmp.size(); ++i) { + int32_t u = tmp[i] - tmp[0]; if (knotU.back() < u) { // remove duplicated knots knotU.push_back(u); } @@ -95,9 +95,9 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int mXmin = 0.; mXtoUscale = 1.; - const int uToKnotMapOffset = mNumberOfKnots * sizeof(Knot); - int parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int); - int bufferSize = parametersOffset; + const int32_t uToKnotMapOffset = mNumberOfKnots * sizeof(Knot); + int32_t parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int32_t); + int32_t bufferSize = parametersOffset; if (mYdim > 0) { parametersOffset = alignSize(bufferSize, getParameterAlignmentBytes()); bufferSize = parametersOffset + getSizeOfParameters(); @@ -105,20 +105,20 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int FlatObject::finishConstruction(bufferSize); - mUtoKnotMap = reinterpret_cast(mFlatBufferPtr + uToKnotMapOffset); + mUtoKnotMap = reinterpret_cast(mFlatBufferPtr + uToKnotMapOffset); mParameters = reinterpret_cast(mFlatBufferPtr + parametersOffset); - for (int i = 0; i < getNumberOfParameters(); i++) { + for (int32_t i = 0; i < getNumberOfParameters(); i++) { mParameters[i] = 0; } Knot* s = getKnots(); - for (int i = 0; i < mNumberOfKnots; i++) { + for (int32_t i = 0; i < mNumberOfKnots; i++) { s[i].u = knotU[i]; } - for (int i = 0; i < mNumberOfKnots - 1; i++) { + for (int32_t i = 0; i < mNumberOfKnots - 1; i++) { s[i].Li = 1. / (s[i + 1].u - s[i].u); // do division in double } @@ -126,9 +126,9 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int // Set up the map (integer U) -> (knot index) - int* map = getUtoKnotMap(); + int32_t* map = getUtoKnotMap(); - const int iKnotMax = mNumberOfKnots - 2; + const int32_t iKnotMax = mNumberOfKnots - 2; // // With iKnotMax=nKnots-2 we map the U==Umax coordinate to the last [nKnots-2, nKnots-1] segment. @@ -136,7 +136,7 @@ void Spline1DContainer::recreate(int nYdim, int numberOfKnots, const int // Any U from [0,Umax] is mapped to some knot_i such, that the next knot_i+1 always exist // - for (int u = 0, iKnot = 0; u <= mUmax; u++) { + for (int32_t u = 0, iKnot = 0; u <= mUmax; u++) { if ((knotU[iKnot + 1] == u) && (iKnot < iKnotMax)) { iKnot = iKnot + 1; } @@ -154,8 +154,8 @@ void Spline1DContainer::print() const printf(" mUmax = %d\n", mUmax); printf(" mUtoKnotMap = %p \n", (void*)mUtoKnotMap); printf(" knots: "); - for (int i = 0; i < mNumberOfKnots; i++) { - printf("%d ", (int)getKnot(i).u); + for (int32_t i = 0; i < mNumberOfKnots; i++) { + printf("%d ", (int32_t)getKnot(i).u); } printf("\n"); } @@ -166,7 +166,7 @@ template void Spline1DContainer::approximateFunction( double xMin, double xMax, std::function F, - int nAxiliaryDataPoints) + int32_t nAxiliaryDataPoints) { /// approximate a function F with this spline Spline1DHelper helper; @@ -175,7 +175,7 @@ void Spline1DContainer::approximateFunction( #ifndef GPUCA_ALIROOT_LIB template -int Spline1DContainer::writeToFile(TFile& outf, const char* name) +int32_t Spline1DContainer::writeToFile(TFile& outf, const char* name) { /// write a class object to the file return FlatObject::writeToFile(*this, outf, name); @@ -243,9 +243,9 @@ void Spline1DContainer::setActualBufferAddress(char* actualFlatBufferPtr) FlatObject::setActualBufferAddress(actualFlatBufferPtr); - const int uToKnotMapOffset = mNumberOfKnots * sizeof(Knot); - mUtoKnotMap = reinterpret_cast(mFlatBufferPtr + uToKnotMapOffset); - int parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int); + const int32_t uToKnotMapOffset = mNumberOfKnots * sizeof(Knot); + mUtoKnotMap = reinterpret_cast(mFlatBufferPtr + uToKnotMapOffset); + int32_t parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int32_t); if (mYdim > 0) { parametersOffset = alignSize(parametersOffset, getParameterAlignmentBytes()); } @@ -263,7 +263,7 @@ void Spline1DContainer::setFutureBufferAddress(char* futureFlatBufferPtr) #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) template -int Spline1DContainer::test(const bool draw, const bool drawDataPoints) +int32_t Spline1DContainer::test(const bool draw, const bool drawDataPoints) { return Spline1DHelper::test(draw, drawDataPoints); } diff --git a/GPU/TPCFastTransformation/Spline1DSpec.h b/GPU/TPCFastTransformation/Spline1DSpec.h index 97aaebb5126bc..e37ee67581c63 100644 --- a/GPU/TPCFastTransformation/Spline1DSpec.h +++ b/GPU/TPCFastTransformation/Spline1DSpec.h @@ -55,13 +55,13 @@ class Spline1DContainer : public FlatObject DataT u; ///< u coordinate of the knot i (an integer number in float format) DataT Li; ///< inverse length of the [knot_i, knot_{i+1}] segment ( == 1./ a (small) integer ) /// Get u as an integer - GPUd() int getU() const { return (int)(u + 0.1f); } + GPUd() int32_t getU() const { return (int32_t)(u + 0.1f); } }; /// _____________ Version control __________________________ /// Version control - GPUd() static constexpr int getVersion() { return 1; } + GPUd() static constexpr int32_t getVersion() { return 1; } /// _____________ C++ constructors / destructors __________________________ @@ -80,14 +80,14 @@ class Spline1DContainer : public FlatObject /// approximate a function F with this spline void approximateFunction(double xMin, double xMax, std::function F, - int nAuxiliaryDataPoints = 4); + int32_t nAuxiliaryDataPoints = 4); #endif /// _______________ IO ________________________ #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// write a class object to the file - int writeToFile(TFile& outf, const char* name); + int32_t writeToFile(TFile& outf, const char* name); /// read a class object from the file static Spline1DContainer* readFromFile(TFile& inpf, const char* name); @@ -96,10 +96,10 @@ class Spline1DContainer : public FlatObject /// _______________ Getters ________________________ /// Get U coordinate of the last knot - GPUd() int getUmax() const { return mUmax; } + GPUd() int32_t getUmax() const { return mUmax; } /// Get number of Y dimensions - GPUd() int getYdimensions() const { return mYdim; } + GPUd() int32_t getYdimensions() const { return mYdim; } /// Get minimal required alignment for the spline parameters GPUd() size_t getParameterAlignmentBytes() const @@ -109,20 +109,20 @@ class Spline1DContainer : public FlatObject } /// Number of parameters - GPUd() int getNumberOfParameters() const { return calcNumberOfParameters(mYdim); } + GPUd() int32_t getNumberOfParameters() const { return calcNumberOfParameters(mYdim); } /// Size of the parameter array in bytes GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * getNumberOfParameters(); } /// Get a number of knots - GPUd() int getNumberOfKnots() const { return mNumberOfKnots; } + GPUd() int32_t getNumberOfKnots() const { return mNumberOfKnots; } /// Get the array of knots GPUd() const Knot* getKnots() const { return reinterpret_cast(mFlatBufferPtr); } /// Get i-th knot template - GPUd() const Knot& getKnot(int i) const + GPUd() const Knot& getKnot(int32_t i) const { if (SafeT == SafetyLevel::kSafe) { i = (i < 0) ? 0 : (i >= mNumberOfKnots ? mNumberOfKnots - 1 : i); @@ -132,7 +132,7 @@ class Spline1DContainer : public FlatObject /// Get index of an associated knot for a given U coordinate. Performs a boundary check. template - GPUd() int getLeftKnotIndexForU(DataT u) const; + GPUd() int32_t getLeftKnotIndexForU(DataT u) const; /// Get spline parameters GPUd() DataT* getParameters() { return mParameters; } @@ -143,7 +143,7 @@ class Spline1DContainer : public FlatObject /// _______________ Technical stuff ________________________ /// Get a map (integer U -> corresponding knot index) - GPUd() const int* getUtoKnotMap() const { return mUtoKnotMap; } + GPUd() const int32_t* getUtoKnotMap() const { return mUtoKnotMap; } /// Convert X coordinate to U GPUd() DataT convXtoU(DataT x) const { return (x - mXmin) * mXtoUscale; } @@ -169,13 +169,13 @@ class Spline1DContainer : public FlatObject /// _______________ Expert tools _______________ /// Number of parameters for given Y dimensions - GPUd() int calcNumberOfParameters(int nYdim) const { return (2 * nYdim) * getNumberOfKnots(); } + GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const { return (2 * nYdim) * getNumberOfKnots(); } ///_______________ Test tools _______________ #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif /// _____________ FlatObject functionality, see FlatObject class for description ____________ @@ -199,24 +199,24 @@ class Spline1DContainer : public FlatObject Knot* getKnots() { return reinterpret_cast(mFlatBufferPtr); } /// Non-const accessor to U->knots map - int* getUtoKnotMap() { return mUtoKnotMap; } + int32_t* getUtoKnotMap() { return mUtoKnotMap; } #if !defined(GPUCA_GPUCODE) /// Constructor for a regular spline - void recreate(int nYdim, int numberOfKnots); + void recreate(int32_t nYdim, int32_t numberOfKnots); /// Constructor for an irregular spline - void recreate(int nYdim, int numberOfKnots, const int knotU[]); + void recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[]); #endif /// _____________ Data members ____________ - int mYdim = 0; ///< dimentionality of F - int mNumberOfKnots = 0; ///< n knots on the grid - int mUmax = 0; ///< U of the last knot + int32_t mYdim = 0; ///< dimentionality of F + int32_t mNumberOfKnots = 0; ///< n knots on the grid + int32_t mUmax = 0; ///< U of the last knot DataT mXmin = 0; ///< X of the first knot DataT mXtoUscale = 0; ///< a scaling factor to convert X to U - int* mUtoKnotMap = nullptr; //! (transient!!) pointer to (integer U -> knot index) map inside the mFlatBufferPtr array + int32_t* mUtoKnotMap = nullptr; //! (transient!!) pointer to (integer U -> knot index) map inside the mFlatBufferPtr array DataT* mParameters = nullptr; //! (transient!!) pointer to F-dependent parameters inside the mFlatBufferPtr array #ifndef GPUCA_ALIROOT_LIB @@ -226,11 +226,11 @@ class Spline1DContainer : public FlatObject template template ::SafetyLevel SafeT> -GPUdi() int Spline1DContainer::getLeftKnotIndexForU(DataT u) const +GPUdi() int32_t Spline1DContainer::getLeftKnotIndexForU(DataT u) const { /// Get i: u is in [knot_i, knot_{i+1}) segment /// when u is otside of [0, mUmax], return a corresponding edge segment - int iu = u < 0 ? 0 : (u > (float)mUmax ? mUmax : (int)u); + int32_t iu = u < 0 ? 0 : (u > (float)mUmax ? mUmax : (int32_t)u); if (SafeT == SafetyLevel::kSafe) { iu = (iu < 0) ? 0 : (iu > mUmax ? mUmax : iu); } @@ -268,14 +268,14 @@ GPUdi() void Spline1DContainer::setXrange(DataT xMin, DataT xMax) /// 2 - nYdim<0: nYdim must be set during runtime /// 3 - specialization where nYdim==1 (a small add-on on top of the other specs) /// -template +template class Spline1DSpec; /// ================================================================================================== /// Specialization 0 declares common methods for all other Spline2D specializations. /// Implementations of the methods may depend on the YdimT value. /// -template +template class Spline1DSpec : public Spline1DContainer { typedef Spline1DContainer TBase; @@ -294,12 +294,12 @@ class Spline1DSpec : public Spline1DContainer /// Get interpolated value for an nYdim-dimensional S(u) using spline parameters Parameters. template - GPUd() void interpolateU(int inpYdim, GPUgeneric() const DataT Parameters[], + GPUd() void interpolateU(int32_t inpYdim, GPUgeneric() const DataT Parameters[], DataT u, GPUgeneric() DataT S[/*nYdim*/]) const { const auto nYdimTmp = SplineUtil::getNdim(inpYdim); const auto nYdim = nYdimTmp.get(); - int iknot = TBase::template getLeftKnotIndexForU(u); + int32_t iknot = TBase::template getLeftKnotIndexForU(u); const DataT* d = Parameters + (2 * nYdim) * iknot; interpolateU(nYdim, getKnots()[iknot], &(d[0]), &(d[nYdim]), &(d[2 * nYdim]), &(d[3 * nYdim]), u, S); } @@ -308,7 +308,7 @@ class Spline1DSpec : public Spline1DContainer /// Get interpolated value {S(u): 1D -> nYdim} at the segment [knotL, next knotR] /// using the spline values Sl, Sr and the slopes Dl, Dr template - GPUd() void interpolateU(int inpYdim, const Knot& knotL, + GPUd() void interpolateU(int32_t inpYdim, const Knot& knotL, GPUgeneric() const T Sl[/*mYdim*/], GPUgeneric() const T Dl[/*mYdim*/], GPUgeneric() const T Sr[/*mYdim*/], GPUgeneric() const T Dr[/*mYdim*/], DataT u, GPUgeneric() T S[/*mYdim*/]) const @@ -318,7 +318,7 @@ class Spline1DSpec : public Spline1DContainer T uu = T(u - knotL.u); T li = T(knotL.Li); T v = uu * li; // scaled u - for (int dim = 0; dim < nYdim; ++dim) { + for (int32_t dim = 0; dim < nYdim; ++dim) { T df = (Sr[dim] - Sl[dim]) * li; T a = Dl[dim] + Dr[dim] - df - df; T b = df - Dl[dim] - a; @@ -374,7 +374,7 @@ class Spline1DSpec : public Spline1DContainer /// Specialization 1: YdimT>0 where the number of Y dimensions is taken from template parameters /// at the compile time /// -template +template class Spline1DSpec : public Spline1DSpec { @@ -389,12 +389,12 @@ class Spline1DSpec Spline1DSpec() : Spline1DSpec(2) {} /// Constructor for a regular spline - Spline1DSpec(int numberOfKnots) : TBase() + Spline1DSpec(int32_t numberOfKnots) : TBase() { recreate(numberOfKnots); } /// Constructor for an irregular spline - Spline1DSpec(int numberOfKnots, const int knotU[]) + Spline1DSpec(int32_t numberOfKnots, const int32_t knotU[]) : TBase() { recreate(numberOfKnots, knotU); @@ -405,17 +405,17 @@ class Spline1DSpec TBase::cloneFromObject(v, nullptr); } /// Constructor for a regular spline - void recreate(int numberOfKnots) { TBase::recreate(YdimT, numberOfKnots); } + void recreate(int32_t numberOfKnots) { TBase::recreate(YdimT, numberOfKnots); } /// Constructor for an irregular spline - void recreate(int numberOfKnots, const int knotU[]) + void recreate(int32_t numberOfKnots, const int32_t knotU[]) { TBase::recreate(YdimT, numberOfKnots, knotU); } #endif /// Get number of Y dimensions - GPUd() constexpr int getYdimensions() const { return YdimT; } + GPUd() constexpr int32_t getYdimensions() const { return YdimT; } /// Get minimal required alignment for the spline parameters GPUd() constexpr size_t getParameterAlignmentBytes() const @@ -425,7 +425,7 @@ class Spline1DSpec } /// Number of parameters - GPUd() int getNumberOfParameters() const { return (2 * YdimT) * getNumberOfKnots(); } + GPUd() int32_t getNumberOfParameters() const { return (2 * YdimT) * getNumberOfKnots(); } /// Size of the parameter array in bytes GPUd() size_t getSizeOfParameters() const { return (sizeof(DataT) * 2 * YdimT) * getNumberOfKnots(); } @@ -465,7 +465,7 @@ class Spline1DSpec /// Specialization 2 (YdimT<=0) where the numbaer of Y dimensions /// must be set in the runtime via a constructor parameter /// -template +template class Spline1DSpec : public Spline1DSpec { @@ -480,12 +480,12 @@ class Spline1DSpec Spline1DSpec() : Spline1DSpec(0, 2) {} /// Constructor for a regular spline - Spline1DSpec(int nYdim, int numberOfKnots) : TBase() + Spline1DSpec(int32_t nYdim, int32_t numberOfKnots) : TBase() { TBase::recreate(nYdim, numberOfKnots); } /// Constructor for an irregular spline - Spline1DSpec(int nYdim, int numberOfKnots, const int knotU[]) : TBase() + Spline1DSpec(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[]) : TBase() { TBase::recreate(nYdim, numberOfKnots, knotU); } @@ -495,10 +495,10 @@ class Spline1DSpec TVeryBase::cloneFromObject(v, nullptr); } /// Constructor for a regular spline - void recreate(int nYdim, int numberOfKnots) { TBase::recreate(nYdim, numberOfKnots); } + void recreate(int32_t nYdim, int32_t numberOfKnots) { TBase::recreate(nYdim, numberOfKnots); } /// Constructor for an irregular spline - void recreate(int nYdim, int numberOfKnots, const int knotU[]) + void recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[]) { TBase::recreate(nYdim, numberOfKnots, knotU); } diff --git a/GPU/TPCFastTransformation/Spline2D.h b/GPU/TPCFastTransformation/Spline2D.h index 47b9f103d3a2c..cbbd91c1d2b8d 100644 --- a/GPU/TPCFastTransformation/Spline2D.h +++ b/GPU/TPCFastTransformation/Spline2D.h @@ -47,10 +47,10 @@ namespace gpu /// auto F = [&](double x1, double x2, double f[] ) { /// f[0] = 1.f + x1 + x2*x2; // F(x1,x2) /// }; -/// const int nKnotsU=2; -/// const int nKnotsV=3; -/// int knotsU[nKnotsU] = {0, 1}; -/// int knotsV[nKnotsV] = {0, 2, 5}; +/// const int32_t nKnotsU=2; +/// const int32_t nKnotsV=3; +/// int32_t knotsU[nKnotsU] = {0, 1}; +/// int32_t knotsV[nKnotsV] = {0, 2, 5}; /// Spline2D spline(nKnotsU, knotsU, nKnotsV, knotsV ); // spline with 1-dimensional codomain /// spline.approximateFunction(0., 1., 0.,1., F); //initialize spline to approximate F on [0., 1.]x[0., 1.] area /// float S = spline.interpolate(.1, .3 ); // interpolated value at (.1,.3) @@ -70,7 +70,7 @@ namespace gpu /// YdimT = 0 : the number of Y dimensions will be set in the runtime /// YdimT < 0 : the number of Y dimensions will be set in the runtime, and it will not exceed abs(YdimT) /// -template +template class Spline2D : public Spline2DSpec { diff --git a/GPU/TPCFastTransformation/Spline2DHelper.cxx b/GPU/TPCFastTransformation/Spline2DHelper.cxx index 2d3f2badecf1d..0801d3b134e88 100644 --- a/GPU/TPCFastTransformation/Spline2DHelper.cxx +++ b/GPU/TPCFastTransformation/Spline2DHelper.cxx @@ -44,7 +44,7 @@ Spline2DHelper::Spline2DHelper() : mError(), mFdimensions(0), mHelperU1() } template -int Spline2DHelper::storeError(int code, const char* msg) +int32_t Spline2DHelper::storeError(int32_t code, const char* msg) { mError = msg; return code; @@ -63,9 +63,9 @@ void Spline2DHelper::approximateFunction( double scaleX1 = (x1Max - x1Min) / ((double)mHelperU1.getSpline().getUmax()); double scaleX2 = (x2Max - x2Min) / ((double)mHelperU2.getSpline().getUmax()); - for (int iv = 0; iv < getNumberOfDataPointsU2(); iv++) { + for (int32_t iv = 0; iv < getNumberOfDataPointsU2(); iv++) { double x2 = x2Min + mHelperU2.getDataPoint(iv).u * scaleX2; - for (int iu = 0; iu < getNumberOfDataPointsU1(); iu++) { + for (int32_t iu = 0; iu < getNumberOfDataPointsU1(); iu++) { double x1 = x1Min + mHelperU1.getDataPoint(iu).u * scaleX1; F(x1, x2, &dataPointF[(iv * getNumberOfDataPointsU1() + iu) * mFdimensions]); } @@ -77,7 +77,7 @@ template void Spline2DHelper::approximateFunctionBatch( DataT* Fparameters, double x1Min, double x1Max, double x2Min, double x2Max, std::function& x1, const std::vector& x2, std::vector f[/*mFdimensions*/])> F, - unsigned int batchsize) const + uint32_t batchsize) const { /// Create best-fit spline parameters for a given input function F. /// F calculates values for a batch of points. @@ -94,18 +94,18 @@ void Spline2DHelper::approximateFunctionBatch( std::vector x2; x2.reserve(batchsize); - std::vector index; + std::vector index; index.reserve(batchsize); std::vector dataPointFTmp[mFdimensions]; - for (int iDim = 0; iDim < mFdimensions; ++iDim) { + for (int32_t iDim = 0; iDim < mFdimensions; ++iDim) { dataPointFTmp[iDim].reserve(batchsize); } - unsigned int counter = 0; - for (int iv = 0; iv < getNumberOfDataPointsU2(); iv++) { + uint32_t counter = 0; + for (int32_t iv = 0; iv < getNumberOfDataPointsU2(); iv++) { double x2Tmp = x2Min + mHelperU2.getDataPoint(iv).u * scaleX2; - for (int iu = 0; iu < getNumberOfDataPointsU1(); iu++) { + for (int32_t iu = 0; iu < getNumberOfDataPointsU1(); iu++) { double x1Tmp = x1Min + mHelperU1.getDataPoint(iu).u * scaleX1; x1.emplace_back(x1Tmp); x2.emplace_back(x2Tmp); @@ -115,11 +115,11 @@ void Spline2DHelper::approximateFunctionBatch( if (counter == batchsize || (iu == (getNumberOfDataPointsU1() - 1) && (iv == (getNumberOfDataPointsU2() - 1)))) { counter = 0; F(x1, x2, dataPointFTmp); - unsigned int entries = index.size(); + uint32_t entries = index.size(); - for (unsigned int i = 0; i < entries; ++i) { - const unsigned int indexTmp = index[i]; - for (int iDim = 0; iDim < mFdimensions; ++iDim) { + for (uint32_t i = 0; i < entries; ++i) { + const uint32_t indexTmp = index[i]; + for (int32_t iDim = 0; iDim < mFdimensions; ++iDim) { dataPointF[indexTmp + iDim] = dataPointFTmp[iDim][i]; } } @@ -127,7 +127,7 @@ void Spline2DHelper::approximateFunctionBatch( x1.clear(); x2.clear(); index.clear(); - for (int iDim = 0; iDim < mFdimensions; ++iDim) { + for (int32_t iDim = 0; iDim < mFdimensions; ++iDim) { dataPointFTmp[iDim].clear(); } } @@ -142,16 +142,16 @@ void Spline2DHelper::approximateFunction( { /// approximate a function given as an array of values at data points - const int Ndim = mFdimensions; - const int Ndim2 = 2 * Ndim; - const int Ndim3 = 3 * Ndim; - const int Ndim4 = 4 * Ndim; + const int32_t Ndim = mFdimensions; + const int32_t Ndim2 = 2 * Ndim; + const int32_t Ndim3 = 3 * Ndim; + const int32_t Ndim4 = 4 * Ndim; - int nDataPointsU = getNumberOfDataPointsU1(); - int nDataPointsV = getNumberOfDataPointsU2(); + int32_t nDataPointsU = getNumberOfDataPointsU1(); + int32_t nDataPointsV = getNumberOfDataPointsU2(); - int nKnotsU = mHelperU1.getSpline().getNumberOfKnots(); - int nKnotsV = mHelperU2.getSpline().getNumberOfKnots(); + int32_t nKnotsU = mHelperU1.getSpline().getNumberOfKnots(); + int32_t nKnotsV = mHelperU2.getSpline().getNumberOfKnots(); std::unique_ptr rotDataPointF(new double[nDataPointsU * nDataPointsV * Ndim]); // U DataPoints x V DataPoints : rotated DataPointF for one output dimension std::unique_ptr Dv(new double[nKnotsV * nDataPointsU * Ndim]); // V knots x U DataPoints @@ -164,9 +164,9 @@ void Spline2DHelper::approximateFunction( // rotated data points (u,v)->(v,u) - for (int ipu = 0; ipu < nDataPointsU; ipu++) { - for (int ipv = 0; ipv < nDataPointsV; ipv++) { - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t ipu = 0; ipu < nDataPointsU; ipu++) { + for (int32_t ipv = 0; ipv < nDataPointsV; ipv++) { + for (int32_t dim = 0; dim < Ndim; dim++) { rotDataPointF[Ndim * (ipu * nDataPointsV + ipv) + dim] = DataPointF[Ndim * (ipv * nDataPointsU + ipu) + dim]; } } @@ -174,28 +174,28 @@ void Spline2DHelper::approximateFunction( // get S and S'u at all the knots by interpolating along the U axis - for (int iKnotV = 0; iKnotV < nKnotsV; ++iKnotV) { - int ipv = mHelperU2.getKnotDataPoint(iKnotV); + for (int32_t iKnotV = 0; iKnotV < nKnotsV; ++iKnotV) { + int32_t ipv = mHelperU2.getKnotDataPoint(iKnotV); const double* DataPointFrow = &(DataPointF[Ndim * ipv * nDataPointsU]); mHelperU1.approximateFunctionGradually(parU.get(), DataPointFrow); - for (int i = 0; i < mHelperU1.getSpline().calcNumberOfParameters(Ndim); i++) { + for (int32_t i = 0; i < mHelperU1.getSpline().calcNumberOfParameters(Ndim); i++) { parUdbl[i] = parU[i]; } - for (int iKnotU = 0; iKnotU < nKnotsU; ++iKnotU) { + for (int32_t iKnotU = 0; iKnotU < nKnotsU; ++iKnotU) { DataT* knotPar = &Fparameters[Ndim4 * (iKnotV * nKnotsU + iKnotU)]; - for (int dim = 0; dim < Ndim; ++dim) { + for (int32_t dim = 0; dim < Ndim; ++dim) { knotPar[dim] = parU[Ndim * (2 * iKnotU) + dim]; // store S for all the knots knotPar[Ndim2 + dim] = parU[Ndim * (2 * iKnotU) + Ndim + dim]; // store S'u for all the knots //SG!!! } } // recalculate F values for all ipu DataPoints at V = ipv - for (int ipu = 0; ipu < nDataPointsU; ipu++) { + for (int32_t ipu = 0; ipu < nDataPointsU; ipu++) { double splineF[Ndim]; double u = mHelperU1.getDataPoint(ipu).u; mHelperU1.getSpline().interpolateU(Ndim, parUdbl.get(), u, splineF); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { rotDataPointF[(ipu * nDataPointsV + ipv) * Ndim + dim] = splineF[dim]; } } @@ -203,11 +203,11 @@ void Spline2DHelper::approximateFunction( // calculate S'v at all data points with V == V of a knot - for (int ipu = 0; ipu < nDataPointsU; ipu++) { + for (int32_t ipu = 0; ipu < nDataPointsU; ipu++) { const double* DataPointFcol = &(rotDataPointF[ipu * nDataPointsV * Ndim]); mHelperU2.approximateFunctionGradually(parV.get(), DataPointFcol); - for (int iKnotV = 0; iKnotV < nKnotsV; iKnotV++) { - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t iKnotV = 0; iKnotV < nKnotsV; iKnotV++) { + for (int32_t dim = 0; dim < Ndim; dim++) { double dv = parV[(iKnotV * 2 + 1) * Ndim + dim]; Dv[(iKnotV * nDataPointsU + ipu) * Ndim + dim] = dv; } @@ -216,11 +216,11 @@ void Spline2DHelper::approximateFunction( // fit S'v and S''_vu at all the knots - for (int iKnotV = 0; iKnotV < nKnotsV; ++iKnotV) { + for (int32_t iKnotV = 0; iKnotV < nKnotsV; ++iKnotV) { const double* Dvrow = &(Dv[iKnotV * nDataPointsU * Ndim]); mHelperU1.approximateFunction(parU.get(), Dvrow); - for (int iKnotU = 0; iKnotU < nKnotsU; ++iKnotU) { - for (int dim = 0; dim < Ndim; ++dim) { + for (int32_t iKnotU = 0; iKnotU < nKnotsU; ++iKnotU) { + for (int32_t dim = 0; dim < Ndim; ++dim) { Fparameters[Ndim4 * (iKnotV * nKnotsU + iKnotU) + Ndim + dim] = parU[Ndim * 2 * iKnotU + dim]; // store S'v for all the knots Fparameters[Ndim4 * (iKnotV * nKnotsU + iKnotU) + Ndim3 + dim] = parU[Ndim * 2 * iKnotU + Ndim + dim]; // store S''vu for all the knots } @@ -233,7 +233,7 @@ void Spline2DHelper::approximateFunctionViaDataPoints( Spline2DContainer& spline, double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsU1, int nAuxiliaryDataPointsU2) + int32_t nAuxiliaryDataPointsU1, int32_t nAuxiliaryDataPointsU2) { /// Create best-fit spline parameters for a given input function F @@ -246,11 +246,11 @@ void Spline2DHelper::approximateFunctionViaDataPoints( double scaleX1 = (x1Max - x1Min) / ((double)mHelperU1.getSpline().getUmax()); double scaleX2 = (x2Max - x2Min) / ((double)mHelperU2.getSpline().getUmax()); - for (int iv = 0; iv < getNumberOfDataPointsU2(); iv++) { + for (int32_t iv = 0; iv < getNumberOfDataPointsU2(); iv++) { double x2 = x2Min + mHelperU2.getDataPoint(iv).u * scaleX2; - for (int iu = 0; iu < getNumberOfDataPointsU1(); iu++) { + for (int32_t iu = 0; iu < getNumberOfDataPointsU1(); iu++) { double x1 = x1Min + mHelperU1.getDataPoint(iu).u * scaleX1; - int ind = iv * getNumberOfDataPointsU1() + iu; + int32_t ind = iv * getNumberOfDataPointsU1() + iu; dataPointX1[ind] = x1; dataPointX2[ind] = x2; F(x1, x2, &dataPointF[ind * mFdimensions]); @@ -265,16 +265,16 @@ void Spline2DHelper::setGrid(Spline2DContainer& spline, double x1M mFdimensions = spline.getYdimensions(); spline.setXrange(x1Min, x1Max, x2Min, x2Max); { - std::vector knots; - for (int i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) { + std::vector knots; + for (int32_t i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) { knots.push_back(spline.getGridX1().getKnot(i).getU()); } fGridU.recreate(0, knots.size(), knots.data()); fGridU.setXrange(x1Min, x1Max); } { - std::vector knots; - for (int i = 0; i < spline.getGridX2().getNumberOfKnots(); i++) { + std::vector knots; + for (int32_t i = 0; i < spline.getGridX2().getNumberOfKnots(); i++) { knots.push_back(spline.getGridX2().getKnot(i).getU()); } fGridV.recreate(0, knots.size(), knots.data()); @@ -283,18 +283,18 @@ void Spline2DHelper::setGrid(Spline2DContainer& spline, double x1M } template -void Spline2DHelper::getScoefficients(int iu, int iv, double u, double v, - double coeff[16], int indices[16]) +void Spline2DHelper::getScoefficients(int32_t iu, int32_t iv, double u, double v, + double coeff[16], int32_t indices[16]) { const typename Spline1D::Knot& knotU = fGridU.getKnot(iu); const typename Spline1D::Knot& knotV = fGridV.getKnot(iv); - int nu = fGridU.getNumberOfKnots(); + int32_t nu = fGridU.getNumberOfKnots(); // indices of parameters that are involved in spline calculation, 1D case - int i00 = (nu * iv + iu) * 4; // values { S, S'v, S'u, S''vu } at {u0, v0} - int i01 = i00 + 4 * nu; // values { ... } at {u0, v1} - int i10 = i00 + 4; - int i11 = i01 + 4; + int32_t i00 = (nu * iv + iu) * 4; // values { S, S'v, S'u, S''vu } at {u0, v0} + int32_t i01 = i00 + 4 * nu; // values { ... } at {u0, v1} + int32_t i10 = i00 + 4; + int32_t i11 = i01 + 4; double dSl, dDl, dSr, dDr; Spline1DHelper::getScoefficients(knotU, u, dSl, dDl, dSr, dDr); @@ -311,10 +311,10 @@ void Spline2DHelper::getScoefficients(int iu, int iv, double u, double v, dSr * dSd, dSr * dDd, dDr * dSd, dDr * dDd, dSl * dSu, dSl * dDu, dDl * dSu, dDl * dDu, dSr * dSu, dSr * dDu, dDr * dSu, dDr * dDu}; - for (int i = 0; i < 16; i++) { + for (int32_t i = 0; i < 16; i++) { coeff[i] = c[i]; } - for (int i = 0; i < 4; i++) { + for (int32_t i = 0; i < 4; i++) { indices[0 + i] = i00 + i; indices[4 + i] = i10 + i; indices[8 + i] = i01 + i; @@ -326,40 +326,40 @@ template void Spline2DHelper::approximateDataPoints( Spline2DContainer& spline, DataT* splineParameters, double x1Min, double x1Max, double x2Min, double x2Max, const double dataPointX1[], const double dataPointX2[], const double dataPointF[/*getNumberOfDataPoints() x nFdim*/], - int nDataPoints) + int32_t nDataPoints) { /// Create best-fit spline parameters for a given input function F setGrid(spline, x1Min, x1Max, x2Min, x2Max); - int nFdim = spline.getYdimensions(); - int nu = fGridU.getNumberOfKnots(); - int nv = fGridV.getNumberOfKnots(); + int32_t nFdim = spline.getYdimensions(); + int32_t nu = fGridU.getNumberOfKnots(); + int32_t nv = fGridV.getNumberOfKnots(); - const int nPar = 4 * spline.getNumberOfKnots(); // n parameters for 1-dimensional F + const int32_t nPar = 4 * spline.getNumberOfKnots(); // n parameters for 1-dimensional F SymMatrixSolver solver(nPar, nFdim); - for (int iPoint = 0; iPoint < nDataPoints; ++iPoint) { + for (int32_t iPoint = 0; iPoint < nDataPoints; ++iPoint) { double u = fGridU.convXtoU(dataPointX1[iPoint]); double v = fGridV.convXtoU(dataPointX2[iPoint]); - int iu = fGridU.getLeftKnotIndexForU(u); - int iv = fGridV.getLeftKnotIndexForU(v); + int32_t iu = fGridU.getLeftKnotIndexForU(u); + int32_t iv = fGridV.getLeftKnotIndexForU(v); double c[16]; - int ind[16]; + int32_t ind[16]; getScoefficients(iu, iv, u, v, c, ind); // S(u,v) = sum c[i]*Parameters[ind[i]] - for (int i = 0; i < 16; i++) { - for (int j = i; j < 16; j++) { + for (int32_t i = 0; i < 16; i++) { + for (int32_t j = i; j < 16; j++) { solver.A(ind[i], ind[j]) += c[i] * c[j]; } } - for (int iDim = 0; iDim < nFdim; iDim++) { + for (int32_t iDim = 0; iDim < nFdim; iDim++) { double f = (double)dataPointF[iPoint * nFdim + iDim]; - for (int i = 0; i < 16; i++) { + for (int32_t i = 0; i < 16; i++) { solver.B(ind[i], iDim) += f * c[i]; } } @@ -367,29 +367,29 @@ void Spline2DHelper::approximateDataPoints( // add extra smoothness in case some data is missing - for (int iu = 0; iu < nu - 1; iu++) { - for (int iv = 0; iv < nv - 1; iv++) { - int smoothPoint[4][2] = { + for (int32_t iu = 0; iu < nu - 1; iu++) { + for (int32_t iv = 0; iv < nv - 1; iv++) { + int32_t smoothPoint[4][2] = { {-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}}; - for (int iSet = 0; iSet < 4; iSet++) { - int pu = iu + smoothPoint[iSet][0]; - int pv = iv + smoothPoint[iSet][1]; - int ip = (nu * pv + pu) * 4; + for (int32_t iSet = 0; iSet < 4; iSet++) { + int32_t pu = iu + smoothPoint[iSet][0]; + int32_t pv = iv + smoothPoint[iSet][1]; + int32_t ip = (nu * pv + pu) * 4; if (pu < 0 || pv < 0 || pu >= nu || pv >= nv) { continue; } double c[17]; - int ind[17]; + int32_t ind[17]; getScoefficients(iu, iv, fGridU.getKnot(pu).u, fGridV.getKnot(pv).u, c, ind); c[16] = -1.; ind[16] = ip; // S = sum c[i]*Par[ind[i]] double w = 1.e-8; - for (int i = 0; i < 17; i++) { - for (int j = i; j < 17; j++) { + for (int32_t i = 0; i < 17; i++) { + for (int32_t j = i; j < 17; j++) { solver.A(ind[i], ind[j]) += w * c[i] * c[j]; } } @@ -398,8 +398,8 @@ void Spline2DHelper::approximateDataPoints( } solver.solve(); - for (int i = 0; i < nPar; i++) { - for (int iDim = 0; iDim < nFdim; iDim++) { + for (int32_t i = 0; i < nPar; i++) { + for (int32_t iDim = 0; iDim < nFdim; iDim++) { splineParameters[i * nFdim + iDim] = solver.B(i, iDim); } } @@ -407,19 +407,19 @@ void Spline2DHelper::approximateDataPoints( #ifndef GPUCA_ALIROOT_LIB template -int Spline2DHelper::test(const bool draw, const bool drawDataPoints) +int32_t Spline2DHelper::test(const bool draw, const bool drawDataPoints) { using namespace std; - const int Ndim = 3; + const int32_t Ndim = 3; - const int Fdegree = 4; + const int32_t Fdegree = 4; double Fcoeff[Ndim][4 * (Fdegree + 1) * (Fdegree + 1)]; - constexpr int nKnots = 10; - constexpr int nAuxiliaryPoints = 2; - constexpr int uMax = nKnots; //* 3; + constexpr int32_t nKnots = 10; + constexpr int32_t nAuxiliaryPoints = 2; + constexpr int32_t uMax = nKnots; //* 3; auto F = [&](double u, double v, double Fuv[]) { const double scale = TMath::Pi() / uMax; @@ -427,14 +427,14 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) double vv = v * scale; double cosu[Fdegree + 1], sinu[Fdegree + 1], cosv[Fdegree + 1], sinv[Fdegree + 1]; double ui = 0, vi = 0; - for (int i = 0; i <= Fdegree; i++, ui += uu, vi += vv) { + for (int32_t i = 0; i <= Fdegree; i++, ui += uu, vi += vv) { GPUCommonMath::SinCosd(ui, sinu[i], cosu[i]); GPUCommonMath::SinCosd(vi, sinv[i], cosv[i]); } - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { double f = 0; // Fcoeff[dim][0]/2; - for (int i = 1; i <= Fdegree; i++) { - for (int j = 1; j <= Fdegree; j++) { + for (int32_t i = 1; i <= Fdegree; i++) { + for (int32_t j = 1; j <= Fdegree; j++) { double* c = &(Fcoeff[dim][4 * (i * Fdegree + j)]); f += c[0] * cosu[i] * cosv[j]; f += c[1] * cosu[i] * sinv[j]; @@ -463,40 +463,40 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) LOG(info) << "Test 2D interpolation with the compact spline"; - int nTries = 100; + int32_t nTries = 100; if (draw) { canv = new TCanvas("cQA", "Spline2D QA", 1500, 800); nTries = 10000; } - long double statDf = 0; - long double statDf1D = 0; - long double statN = 0; + double statDf = 0; + double statDf1D = 0; + double statN = 0; auto statTime = std::chrono::nanoseconds::zero(); - for (int seed = 1; seed < nTries + 1; seed++) { + for (int32_t seed = 1; seed < nTries + 1; seed++) { // LOG(info) << "next try.." ; gRandom->SetSeed(seed); - for (int dim = 0; dim < Ndim; dim++) { - for (int i = 0; i < 4 * (Fdegree + 1) * (Fdegree + 1); i++) { + for (int32_t dim = 0; dim < Ndim; dim++) { + for (int32_t i = 0; i < 4 * (Fdegree + 1) * (Fdegree + 1); i++) { Fcoeff[dim][i] = gRandom->Uniform(-1, 1); } } Spline2D spline; - int knotsU[nKnots], knotsV[nKnots]; + int32_t knotsU[nKnots], knotsV[nKnots]; do { knotsU[0] = 0; knotsV[0] = 0; double du = 1. * uMax / (nKnots - 1); - for (int i = 1; i < nKnots; i++) { - knotsU[i] = (int)(i * du); // + gRandom->Uniform(-du / 3, du / 3); - knotsV[i] = (int)(i * du); // + gRandom->Uniform(-du / 3, du / 3); + for (int32_t i = 1; i < nKnots; i++) { + knotsU[i] = (int32_t)(i * du); // + gRandom->Uniform(-du / 3, du / 3); + knotsV[i] = (int32_t)(i * du); // + gRandom->Uniform(-du / 3, du / 3); } knotsU[nKnots - 1] = uMax; knotsV[nKnots - 1] = uMax; @@ -547,7 +547,7 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) Spline2D splines1D[Ndim]; - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { auto F1 = [&](double x1, double x2, double f[]) { double ff[Ndim]; F(x1, x2, ff); @@ -564,7 +564,7 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) F(u, v, f); DataT s[Ndim]; spline.interpolate(u, v, s); - for (int dim = 0; dim < Ndim; dim++) { + for (int32_t dim = 0; dim < Ndim; dim++) { statDf += (s[dim] - f[dim]) * (s[dim] - f[dim]); DataT s1 = splines1D[dim].interpolate(u, v); statDf1D += (s[dim] - s1) * (s[dim] - s1); @@ -606,8 +606,8 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) nt->SetMarkerColor(kBlue); nt->Draw("s:u:v", "", "same"); - for (int i = 0; i < nKnots; i++) { - for (int j = 0; j < nKnots; j++) { + for (int32_t i = 0; i < nKnots; i++) { + for (int32_t j = 0; j < nKnots; j++) { double u = spline.getGridX1().getKnot(i).u; double v = spline.getGridX2().getKnot(j).u; DataT s[Ndim]; @@ -625,9 +625,9 @@ int Spline2DHelper::test(const bool draw, const bool drawDataPoints) if (drawDataPoints) { Spline2DHelper helper; helper.setSpline(spline, 4, 4); - for (int ipu = 0; ipu < helper.getHelperU1().getNumberOfDataPoints(); ipu++) { + for (int32_t ipu = 0; ipu < helper.getHelperU1().getNumberOfDataPoints(); ipu++) { const typename Spline1DHelperOld::DataPoint& pu = helper.getHelperU1().getDataPoint(ipu); - for (int ipv = 0; ipv < helper.getHelperU2().getNumberOfDataPoints(); ipv++) { + for (int32_t ipv = 0; ipv < helper.getHelperU2().getNumberOfDataPoints(); ipv++) { const typename Spline1DHelperOld::DataPoint& pv = helper.getHelperU2().getDataPoint(ipv); if (pu.isKnot && pv.isKnot) { continue; diff --git a/GPU/TPCFastTransformation/Spline2DHelper.h b/GPU/TPCFastTransformation/Spline2DHelper.h index 3e9b8af5619c1..dc509dc33ea57 100644 --- a/GPU/TPCFastTransformation/Spline2DHelper.h +++ b/GPU/TPCFastTransformation/Spline2DHelper.h @@ -61,25 +61,25 @@ class Spline2DHelper Spline2DContainer& spline, double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsU1 = 4, int nAuxiliaryDataPointsU2 = 4); + int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4); // A wrapper around approximateDataPoints() void approximateFunctionViaDataPoints( Spline2DContainer& spline, double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsU1 = 4, int nAuxiliaryDataPointsU2 = 4); + int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4); /// Create best-fit spline parameters for a given set of data points void approximateDataPoints( Spline2DContainer& spline, DataT* splineParameters, double x1Min, double x1Max, double x2Min, double x2Max, const double dataPointX1[/*nDataPoints*/], const double dataPointX2[/*nDataPoints*/], - const double dataPointF[/*nDataPoints x spline.getYdimensions*/], int nDataPoints); + const double dataPointF[/*nDataPoints x spline.getYdimensions*/], int32_t nDataPoints); /// _______________ Interface for a step-wise construction of the best-fit spline ________________________ /// precompute everything needed for the construction - int setSpline(const Spline2DContainer& spline, int nAuxiliaryPointsU1, int nAuxiliaryPointsU2); + int32_t setSpline(const Spline2DContainer& spline, int32_t nAuxiliaryPointsU1, int32_t nAuxiliaryPointsU2); /// approximate std::function, output in Fparameters void approximateFunction( @@ -90,17 +90,17 @@ class Spline2DHelper void approximateFunctionBatch( DataT* Fparameters, double x1Min, double x1Max, double x2Min, double x2Max, std::function& x1, const std::vector& x2, std::vector f[/*mFdimensions*/])> F, - unsigned int batchsize) const; + uint32_t batchsize) const; /// approximate a function given as an array of values at data points void approximateFunction( DataT* Fparameters, const double DataPointF[/*getNumberOfDataPoints() x nFdim*/]) const; - int getNumberOfDataPointsU1() const { return mHelperU1.getNumberOfDataPoints(); } + int32_t getNumberOfDataPointsU1() const { return mHelperU1.getNumberOfDataPoints(); } - int getNumberOfDataPointsU2() const { return mHelperU2.getNumberOfDataPoints(); } + int32_t getNumberOfDataPointsU2() const { return mHelperU2.getNumberOfDataPoints(); } - int getNumberOfDataPoints() const { return getNumberOfDataPointsU1() * getNumberOfDataPointsU2(); } + int32_t getNumberOfDataPoints() const { return getNumberOfDataPointsU1() * getNumberOfDataPointsU2(); } const Spline1DHelperOld& getHelperU1() const { return mHelperU1; } const Spline1DHelperOld& getHelperU2() const { return mHelperU2; } @@ -112,19 +112,19 @@ class Spline2DHelper #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the Spline2D class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif private: void setGrid(Spline2DContainer& spline, double x1Min, double x1Max, double x2Min, double x2Max); - void getScoefficients(int iu, int iv, double u, double v, - double c[16], int indices[16]); + void getScoefficients(int32_t iu, int32_t iv, double u, double v, + double c[16], int32_t indices[16]); /// Stores an error message - int storeError(int code, const char* msg); + int32_t storeError(int32_t code, const char* msg); std::string mError = ""; ///< error string - int mFdimensions; ///< n of F dimensions + int32_t mFdimensions; ///< n of F dimensions Spline1DHelperOld mHelperU1; Spline1DHelperOld mHelperU2; Spline1D fGridU; @@ -140,7 +140,7 @@ void Spline2DHelper::approximateFunction( Spline2DContainer& spline, double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsU1, int nAuxiliaryDataPointsU2) + int32_t nAuxiliaryDataPointsU1, int32_t nAuxiliaryDataPointsU2) { /// Create best-fit spline parameters for a given input function F setSpline(spline, nAuxiliaryDataPointsU1, nAuxiliaryDataPointsU2); @@ -149,14 +149,14 @@ void Spline2DHelper::approximateFunction( } template -int Spline2DHelper::setSpline( - const Spline2DContainer& spline, int nAuxiliaryPointsU, int nAuxiliaryPointsV) +int32_t Spline2DHelper::setSpline( + const Spline2DContainer& spline, int32_t nAuxiliaryPointsU, int32_t nAuxiliaryPointsV) { // Prepare creation of 2D irregular spline // The should be at least one (better, two) Auxiliary measurements on each segnment between two knots and at least 2*nKnots measurements in total // Returns 0 when the spline can not be constructed with the given nAuxiliaryPoints - int ret = 0; + int32_t ret = 0; mFdimensions = spline.getYdimensions(); if (mHelperU1.setSpline(spline.getGridX1(), mFdimensions, nAuxiliaryPointsU) != 0) { ret = storeError(-2, "Spline2DHelper::setSpline2D: error by setting U axis"); diff --git a/GPU/TPCFastTransformation/Spline2DSpec.cxx b/GPU/TPCFastTransformation/Spline2DSpec.cxx index 3e55c7b346be8..aabf63f3252fe 100644 --- a/GPU/TPCFastTransformation/Spline2DSpec.cxx +++ b/GPU/TPCFastTransformation/Spline2DSpec.cxx @@ -61,8 +61,8 @@ void Spline2DContainer::setActualBufferAddress(char* actualFlatBufferPtr) FlatObject::setActualBufferAddress(actualFlatBufferPtr); const size_t u2Offset = alignSize(mGridX1.getFlatBufferSize(), mGridX2.getBufferAlignmentBytes()); - int parametersOffset = u2Offset; - //int bufferSize = parametersOffset; + int32_t parametersOffset = u2Offset; + // int32_t bufferSize = parametersOffset; mParameters = nullptr; parametersOffset = alignSize(u2Offset + mGridX2.getFlatBufferSize(), getParameterAlignmentBytes()); @@ -128,8 +128,8 @@ void Spline2DContainer::moveBufferTo(char* newFlatBufferPtr) template void Spline2DContainer::recreate( - int nYdim, - int numberOfKnotsU1, const int knotsU1[], int numberOfKnotsU2, const int knotsU2[]) + int32_t nYdim, + int32_t numberOfKnotsU1, const int32_t knotsU1[], int32_t numberOfKnotsU2, const int32_t knotsU2[]) { /// Constructor for an irregular spline @@ -140,8 +140,8 @@ void Spline2DContainer::recreate( mGridX2.recreate(0, numberOfKnotsU2, knotsU2); const size_t u2Offset = alignSize(mGridX1.getFlatBufferSize(), mGridX2.getBufferAlignmentBytes()); - int parametersOffset = u2Offset + mGridX2.getFlatBufferSize(); - int bufferSize = parametersOffset; + int32_t parametersOffset = u2Offset + mGridX2.getFlatBufferSize(); + int32_t bufferSize = parametersOffset; mParameters = nullptr; parametersOffset = alignSize(bufferSize, getParameterAlignmentBytes()); @@ -153,14 +153,14 @@ void Spline2DContainer::recreate( mGridX2.moveBufferTo(mFlatBufferPtr + u2Offset); mParameters = reinterpret_cast(mFlatBufferPtr + parametersOffset); - for (int i = 0; i < getNumberOfParameters(); i++) { + for (int32_t i = 0; i < getNumberOfParameters(); i++) { mParameters[i] = 0; } } template -void Spline2DContainer::recreate(int nYdim, - int numberOfKnotsU1, int numberOfKnotsU2) +void Spline2DContainer::recreate(int32_t nYdim, + int32_t numberOfKnotsU1, int32_t numberOfKnotsU2) { /// Constructor for a regular spline @@ -171,8 +171,8 @@ void Spline2DContainer::recreate(int nYdim, mGridX2.recreate(0, numberOfKnotsU2); const size_t u2Offset = alignSize(mGridX1.getFlatBufferSize(), mGridX2.getBufferAlignmentBytes()); - int parametersOffset = u2Offset + mGridX2.getFlatBufferSize(); - int bufferSize = parametersOffset; + int32_t parametersOffset = u2Offset + mGridX2.getFlatBufferSize(); + int32_t bufferSize = parametersOffset; mParameters = nullptr; parametersOffset = alignSize(bufferSize, getParameterAlignmentBytes()); @@ -184,7 +184,7 @@ void Spline2DContainer::recreate(int nYdim, mGridX2.moveBufferTo(mFlatBufferPtr + u2Offset); mParameters = reinterpret_cast(mFlatBufferPtr + parametersOffset); - for (int i = 0; i < getNumberOfParameters(); i++) { + for (int32_t i = 0; i < getNumberOfParameters(); i++) { mParameters[i] = 0; } } @@ -197,7 +197,7 @@ template void Spline2DContainer::approximateFunction( double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsX1, int nAuxiliaryDataPointsX2) + int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2) { /// approximate a function F with this spline Spline2DHelper helper; @@ -208,7 +208,7 @@ template void Spline2DContainer::approximateFunctionViaDataPoints( double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsX1, int nAuxiliaryDataPointsX2) + int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2) { /// approximate a function F with this spline Spline2DHelper helper; @@ -217,7 +217,7 @@ void Spline2DContainer::approximateFunctionViaDataPoints( #ifndef GPUCA_ALIROOT_LIB template -int Spline2DContainer::writeToFile(TFile& outf, const char* name) +int32_t Spline2DContainer::writeToFile(TFile& outf, const char* name) { /// write a class object to the file return FlatObject::writeToFile(*this, outf, name); @@ -232,7 +232,7 @@ Spline2DContainer* Spline2DContainer::readFromFile( } template -int Spline2DContainer::test(const bool draw, const bool drawDataPoints) +int32_t Spline2DContainer::test(const bool draw, const bool drawDataPoints) { return Spline2DHelper::test(draw, drawDataPoints); } diff --git a/GPU/TPCFastTransformation/Spline2DSpec.h b/GPU/TPCFastTransformation/Spline2DSpec.h index 918522effede5..b0f70752d81cf 100644 --- a/GPU/TPCFastTransformation/Spline2DSpec.h +++ b/GPU/TPCFastTransformation/Spline2DSpec.h @@ -53,7 +53,7 @@ class Spline2DContainer : public FlatObject /// _____________ Version control __________________________ /// Version control - GPUd() static constexpr int getVersion() { return (1 << 16) + Spline1D::getVersion(); } + GPUd() static constexpr int32_t getVersion() { return (1 << 16) + Spline1D::getVersion(); } /// _____________ C++ constructors / destructors __________________________ @@ -72,18 +72,18 @@ class Spline2DContainer : public FlatObject /// approximate a function F with this spline void approximateFunction(double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsU1 = 4, int nAuxiliaryDataPointsU2 = 4); + int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4); void approximateFunctionViaDataPoints(double x1Min, double x1Max, double x2Min, double x2Max, std::function F, - int nAuxiliaryDataPointsX1, int nAuxiliaryDataPointsX2); + int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2); #endif /// _______________ IO ________________________ #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// write a class object to the file - int writeToFile(TFile& outf, const char* name); + int32_t writeToFile(TFile& outf, const char* name); /// read a class object from the file static Spline2DContainer* readFromFile(TFile& inpf, const char* name); @@ -92,19 +92,19 @@ class Spline2DContainer : public FlatObject /// _______________ Getters ________________________ /// Get number of Y dimensions - GPUd() int getYdimensions() const { return mYdim; } + GPUd() int32_t getYdimensions() const { return mYdim; } /// Get minimal required alignment for the spline parameters GPUd() static constexpr size_t getParameterAlignmentBytes() { return 16; } /// Number of parameters - GPUd() int getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); } + GPUd() int32_t getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); } /// Size of the parameter array in bytes GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * this->getNumberOfParameters(); } /// Get a number of knots - GPUd() int getNumberOfKnots() const { return mGridX1.getNumberOfKnots() * mGridX2.getNumberOfKnots(); } + GPUd() int32_t getNumberOfKnots() const { return mGridX1.getNumberOfKnots() * mGridX2.getNumberOfKnots(); } /// Get 1-D grid for the X1 coordinate GPUd() const Spline1D& getGridX1() const { return mGridX1; } @@ -113,17 +113,17 @@ class Spline2DContainer : public FlatObject GPUd() const Spline1D& getGridX2() const { return mGridX2; } /// Get 1-D grid for X1 or X2 coordinate - GPUd() const Spline1D& getGrid(int ix) const { return (ix == 0) ? mGridX1 : mGridX2; } + GPUd() const Spline1D& getGrid(int32_t ix) const { return (ix == 0) ? mGridX1 : mGridX2; } /// Get (u1,u2) of i-th knot - GPUd() void getKnotU(int iKnot, int& u1, int& u2) const + GPUd() void getKnotU(int32_t iKnot, int32_t& u1, int32_t& u2) const { u1 = mGridX1.getKnot(iKnot % mGridX1.getNumberOfKnots()).getU(); u2 = mGridX2.getKnot(iKnot / mGridX1.getNumberOfKnots()).getU(); } /// Get index of a knot (iKnotX1,iKnotX2) - GPUd() int getKnotIndex(int iKnotX1, int iKnotX2) const + GPUd() int32_t getKnotIndex(int32_t iKnotX1, int32_t iKnotX2) const { return mGridX1.getNumberOfKnots() * iKnotX2 + iKnotX1; } @@ -155,13 +155,13 @@ class Spline2DContainer : public FlatObject /// _______________ Expert tools _______________ /// Number of parameters for given Y dimensions - GPUd() int calcNumberOfParameters(int nYdim) const { return (4 * nYdim) * getNumberOfKnots(); } + GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const { return (4 * nYdim) * getNumberOfKnots(); } ///_______________ Test tools _______________ #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif /// _____________ FlatObject functionality, see FlatObject class for description ____________ @@ -183,15 +183,15 @@ class Spline2DContainer : public FlatObject protected: #if !defined(GPUCA_GPUCODE) /// Constructor for a regular spline - void recreate(int nYdim, int nKnotsX1, int nKnotsX2); + void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2); /// Constructor for an irregular spline - void recreate(int nYdim, int nKnotsX1, const int knotU1[], int nKnotsX2, const int knotU2[]); + void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[]); #endif /// _____________ Data members ____________ - int mYdim = 0; ///< dimentionality of F + int32_t mYdim = 0; ///< dimentionality of F Spline1D mGridX1; ///< grid for U axis Spline1D mGridX2; ///< grid for V axis DataT* mParameters = nullptr; //! (transient!!) F-dependent parameters of the spline @@ -219,14 +219,14 @@ class Spline2DContainer : public FlatObject /// 2 - nYdim<0: nYdim must be set during runtime /// 3 - specialization where nYdim==1 (a small add-on on top of the other specs) /// -template +template class Spline2DSpec; /// ================================================================================================== /// Specialization 0 declares common methods for all other Spline2D specializations. /// Implementations of the methods may depend on the YdimT value. /// -template +template class Spline2DSpec : public Spline2DContainer { @@ -246,24 +246,24 @@ class Spline2DSpec /// Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters. template - GPUd() void interpolateUold(int inpYdim, GPUgeneric() const DataT Parameters[], + GPUd() void interpolateUold(int32_t inpYdim, GPUgeneric() const DataT Parameters[], DataT u1, DataT u2, GPUgeneric() DataT S[/*inpYdim*/]) const { const auto nYdimTmp = SplineUtil::getNdim(inpYdim); - const int nYdim = nYdimTmp.get(); + const int32_t nYdim = nYdimTmp.get(); const auto maxYdim = SplineUtil::getMaxNdim(inpYdim); - const int maxYdim4 = 4 * maxYdim.get(); + const int32_t maxYdim4 = 4 * maxYdim.get(); const auto nYdim2 = nYdim * 2; const auto nYdim4 = nYdim * 4; const DataT& u = u1; const DataT& v = u2; - int nu = mGridX1.getNumberOfKnots(); - int iu = mGridX1.template getLeftKnotIndexForU(u); - int iv = mGridX2.template getLeftKnotIndexForU(v); + int32_t nu = mGridX1.getNumberOfKnots(); + int32_t iu = mGridX1.template getLeftKnotIndexForU(u); + int32_t iv = mGridX2.template getLeftKnotIndexForU(v); const typename TBase::Knot& knotU = mGridX1.template getKnot(iu); const typename TBase::Knot& knotV = mGridX2.template getKnot(iv); @@ -278,7 +278,7 @@ class Spline2DSpec DataT Su1[maxYdim4]; // values { {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v0), {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v1) }, at u1 DataT Du1[maxYdim4]; // derivatives {}'_u at u1 - for (int i = 0; i < nYdim2; i++) { + for (int32_t i = 0; i < nYdim2; i++) { Su0[i] = par00[i]; Su0[nYdim2 + i] = par01[i]; @@ -311,24 +311,24 @@ class Spline2DSpec /// Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters. template - GPUd() void interpolateU(int inpYdim, GPUgeneric() const DataT Parameters[], + GPUd() void interpolateU(int32_t inpYdim, GPUgeneric() const DataT Parameters[], DataT u1, DataT u2, GPUgeneric() DataT S[/*inpYdim*/]) const { const auto nYdimTmp = SplineUtil::getNdim(inpYdim); - const int nYdim = nYdimTmp.get(); + const int32_t nYdim = nYdimTmp.get(); // const auto maxYdim = SplineUtil::getMaxNdim(inpYdim); - // const int maxYdim4 = 4 * maxYdim.get(); + // const int32_t maxYdim4 = 4 * maxYdim.get(); // const auto nYdim2 = nYdim * 2; const auto nYdim4 = nYdim * 4; const DataT& u = u1; const DataT& v = u2; - int nu = mGridX1.getNumberOfKnots(); - int iu = mGridX1.template getLeftKnotIndexForU(u); - int iv = mGridX2.template getLeftKnotIndexForU(v); + int32_t nu = mGridX1.getNumberOfKnots(); + int32_t iu = mGridX1.template getLeftKnotIndexForU(u); + int32_t iv = mGridX2.template getLeftKnotIndexForU(v); const typename TBase::Knot& knotU = mGridX1.template getKnot(iu); const typename TBase::Knot& knotV = mGridX2.template getKnot(iv); @@ -354,9 +354,9 @@ class Spline2DSpec // S = sum a[i]*A[i] + b[i]*B[i] - for (int dim = 0; dim < nYdim; dim++) { + for (int32_t dim = 0; dim < nYdim; dim++) { S[dim] = 0; - for (int i = 0; i < 8; i++) { + for (int32_t i = 0; i < 8; i++) { S[dim] += a[i] * A[nYdim * i + dim] + b[i] * B[nYdim * i + dim]; } } @@ -374,7 +374,7 @@ class Spline2DSpec /// Specialization 1: YdimT>0 where the number of Y dimensions is taken from template parameters /// at the compile time /// -template +template class Spline2DSpec : public Spline2DSpec { @@ -389,13 +389,13 @@ class Spline2DSpec Spline2DSpec() : Spline2DSpec(2, 2) {} /// Constructor for a regular spline - Spline2DSpec(int nKnotsX1, int nKnotsX2) : TBase() + Spline2DSpec(int32_t nKnotsX1, int32_t nKnotsX2) : TBase() { recreate(nKnotsX1, nKnotsX2); } /// Constructor for an irregular spline - Spline2DSpec(int nKnotsX1, const int knotU1[], - int nKnotsX2, const int knotU2[]) + Spline2DSpec(int32_t nKnotsX1, const int32_t knotU1[], + int32_t nKnotsX2, const int32_t knotU2[]) : TBase() { recreate(nKnotsX1, knotU1, nKnotsX2, knotU2); @@ -406,24 +406,24 @@ class Spline2DSpec TBase::cloneFromObject(v, nullptr); } /// Constructor for a regular spline - void recreate(int nKnotsX1, int nKnotsX2) + void recreate(int32_t nKnotsX1, int32_t nKnotsX2) { TBase::recreate(YdimT, nKnotsX1, nKnotsX2); } /// Constructor for an irregular spline - void recreate(int nKnotsX1, const int knotU1[], - int nKnotsX2, const int knotU2[]) + void recreate(int32_t nKnotsX1, const int32_t knotU1[], + int32_t nKnotsX2, const int32_t knotU2[]) { TBase::recreate(YdimT, nKnotsX1, knotU1, nKnotsX2, knotU2); } #endif /// Get number of Y dimensions - GPUd() constexpr int getYdimensions() const { return YdimT; } + GPUd() constexpr int32_t getYdimensions() const { return YdimT; } /// Number of parameters - GPUd() int getNumberOfParameters() const { return (4 * YdimT) * getNumberOfKnots(); } + GPUd() int32_t getNumberOfParameters() const { return (4 * YdimT) * getNumberOfKnots(); } /// Size of the parameter array in bytes GPUd() size_t getSizeOfParameters() const { return (sizeof(DataT) * 4 * YdimT) * getNumberOfKnots(); } @@ -460,7 +460,7 @@ class Spline2DSpec /// Specialization 2 (YdimT<=0) where the numbaer of Y dimensions /// must be set in the runtime via a constructor parameter /// -template +template class Spline2DSpec : public Spline2DSpec { @@ -475,14 +475,14 @@ class Spline2DSpec Spline2DSpec() : Spline2DSpec(0, 2, 2) {} /// Constructor for a regular spline - Spline2DSpec(int nYdim, int nKnotsX1, int nKnotsX2) : TBase() + Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2) : TBase() { TBase::recreate(nYdim, nKnotsX1, nKnotsX2); } /// Constructor for an irregular spline - Spline2DSpec(int nYdim, int nKnotsX1, const int knotU1[], - int nKnotsX2, const int knotU2[]) : TBase() + Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], + int32_t nKnotsX2, const int32_t knotU2[]) : TBase() { TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2); } @@ -494,14 +494,14 @@ class Spline2DSpec } /// Constructor for a regular spline - void recreate(int nYdim, int nKnotsX1, int nKnotsX2) + void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2) { TBase::recreate(nYdim, nKnotsX1, nKnotsX2); } /// Constructor for an irregular spline - void recreate(int nYdim, int nKnotsX1, const int knotU1[], - int nKnotsX2, const int knotU2[]) + void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], + int32_t nKnotsX2, const int32_t knotU2[]) { TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2); } diff --git a/GPU/TPCFastTransformation/SplineHelper.cxx b/GPU/TPCFastTransformation/SplineHelper.cxx index b4195532c8f27..b79ba08f8fd4c 100644 --- a/GPU/TPCFastTransformation/SplineHelper.cxx +++ b/GPU/TPCFastTransformation/SplineHelper.cxx @@ -41,7 +41,7 @@ SplineHelper::SplineHelper() : mError(), mXdimensions(0), mFdimensions(0) } template -int SplineHelper::storeError(int code, const char* msg) +int32_t SplineHelper::storeError(int32_t code, const char* msg) { mError = msg; return code; @@ -51,12 +51,12 @@ int SplineHelper::storeError(int code, const char* msg) // pointstoarray // HILFSFUNKTION, template -int SplineHelper::pointstoarray(const int indices[], const int numbers[], int dim) +int32_t SplineHelper::pointstoarray(const int32_t indices[], const int32_t numbers[], int32_t dim) { - int result = 0; - int factor = 1; - for (int i = 0; i < dim; i++) { + int32_t result = 0; + int32_t factor = 1; + for (int32_t i = 0; i < dim; i++) { result += indices[i] * factor; factor *= numbers[i]; } @@ -67,19 +67,19 @@ int SplineHelper::pointstoarray(const int indices[], const int numbers[], //arraytopoints // HILFSFUNKTION template -int SplineHelper::arraytopoints(int point, int result[], const int numbers[], int dim) +int32_t SplineHelper::arraytopoints(int32_t point, int32_t result[], const int32_t numbers[], int32_t dim) { if (point == 0) { - for (int i = 0; i < dim; i++) { + for (int32_t i = 0; i < dim; i++) { result[i] = 0; } } else { - int divisor = 1; - int modoperand = 1; - for (int i = 0; i < dim; i++) { + int32_t divisor = 1; + int32_t modoperand = 1; + for (int32_t i = 0; i < dim; i++) { modoperand *= numbers[i]; - result[i] = (int)((point % modoperand) / divisor); + result[i] = (int32_t)((point % modoperand) / divisor); divisor *= numbers[i]; } } @@ -97,54 +97,54 @@ void SplineHelper::approximateFunction( // MY VERSION // LOG(info) << "approximateFunction(Fparameters, xMin[],xMax[],F) :" ; double scaleX[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { scaleX[i] = (xMax[i] - xMin[i]) / ((double)(mHelpers[i].getSpline().getUmax())); } // calculate F-Values at all datapoints: - int nrOfAllPoints = getNumberOfDataPoints(); + int32_t nrOfAllPoints = getNumberOfDataPoints(); std::vector dataPointF(nrOfAllPoints * mFdimensions); - int nrOfPoints[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + int32_t nrOfPoints[mXdimensions]; + for (int32_t i = 0; i < mXdimensions; i++) { nrOfPoints[i] = mHelpers[i].getNumberOfDataPoints(); } double x[mXdimensions]; - for (int d = 0; d < nrOfAllPoints; d++) { // for all DataPoints + for (int32_t d = 0; d < nrOfAllPoints; d++) { // for all DataPoints - int indices[mXdimensions]; - int modoperand = 1; - int divisor = 1; + int32_t indices[mXdimensions]; + int32_t modoperand = 1; + int32_t divisor = 1; // get the DataPoint index - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { modoperand *= nrOfPoints[i]; - indices[i] = (int)((d % modoperand) / divisor); + indices[i] = (int32_t)((d % modoperand) / divisor); divisor *= nrOfPoints[i]; // get the respecting u-values: x[i] = xMin[i] + mHelpers[i].getDataPoint(indices[i]).u * scaleX[i]; } - for (int j = 0; j < mXdimensions; j++) { + for (int32_t j = 0; j < mXdimensions; j++) { F(x, &dataPointF[d * mFdimensions]); } } // end for all DataPoints d - //END MY VERSION + // END MY VERSION //std::vector dataPointF(getNumberOfDataPoints() * mFdimensions); //DUMYY VERSION Commented out - /* for (int i = 0; i < getNumberOfDataPoints() * mFdimensions; i++) { + /* for (int32_t i = 0; i < getNumberOfDataPoints() * mFdimensions; i++) { dataPointF[i] = 1.; } */ /* double scaleX1 = (x1Max - x1Min) / ((double)mHelperU1.getSpline().getUmax()); double scaleX2 = (x2Max - x2Min) / ((double)mHelperU2.getSpline().getUmax()); - for (int iv = 0; iv < getNumberOfDataPointsU2(); iv++) { + for (int32_t iv = 0; iv < getNumberOfDataPointsU2(); iv++) { DataT x2 = x2Min + mHelperU2.getDataPoint(iv).u * scaleX2; - for (int iu = 0; iu < getNumberOfDataPointsU1(); iu++) { + for (int32_t iu = 0; iu < getNumberOfDataPointsU1(); iu++) { DataT x1 = x1Min + mHelperU1.getDataPoint(iu).u * scaleX1; F(x1, x2, &dataPointF[(iv * getNumberOfDataPointsU1() + iu) * mFdimensions]); } @@ -157,41 +157,41 @@ template void SplineHelper::approximateFunctionBatch( DataT* Fparameters, const double xMin[], const double xMax[], std::function x[], double f[/*mFdimensions*/])> F, - unsigned int batchsize) const + uint32_t batchsize) const { /// Create best-fit spline parameters for a given input function F. /// F calculates values for a batch of points. /// output in Fparameters double scaleX[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { scaleX[i] = (xMax[i] - xMin[i]) / ((double)(mHelpers[i].getSpline().getUmax())); } - const int nrOfAllPoints = getNumberOfDataPoints(); + const int32_t nrOfAllPoints = getNumberOfDataPoints(); std::vector dataPointF(nrOfAllPoints * mFdimensions); - int nrOfPoints[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + int32_t nrOfPoints[mXdimensions]; + for (int32_t i = 0; i < mXdimensions; i++) { nrOfPoints[i] = mHelpers[i].getNumberOfDataPoints(); } std::vector x[mXdimensions]; - for (int iDim = 0; iDim < mXdimensions; ++iDim) { + for (int32_t iDim = 0; iDim < mXdimensions; ++iDim) { x[iDim].reserve(batchsize); } - unsigned int ibatch = 0; - int index = 0; - for (int d = 0; d < nrOfAllPoints; d++) { // for all DataPoints - int indices[mXdimensions]; - int modoperand = 1; - int divisor = 1; + uint32_t ibatch = 0; + int32_t index = 0; + for (int32_t d = 0; d < nrOfAllPoints; d++) { // for all DataPoints + int32_t indices[mXdimensions]; + int32_t modoperand = 1; + int32_t divisor = 1; // get the DataPoint index - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { modoperand *= nrOfPoints[i]; - indices[i] = (int)((d % modoperand) / divisor); + indices[i] = (int32_t)((d % modoperand) / divisor); divisor *= nrOfPoints[i]; // get the respecting u-values: x[i].emplace_back(xMin[i] + mHelpers[i].getDataPoint(indices[i]).u * scaleX[i]); @@ -204,7 +204,7 @@ void SplineHelper::approximateFunctionBatch( F(x, &dataPointF[index]); index = (d + 1) * mFdimensions; - for (int iDim = 0; iDim < mXdimensions; ++iDim) { + for (int32_t iDim = 0; iDim < mXdimensions; ++iDim) { x[iDim].clear(); } } @@ -219,25 +219,25 @@ void SplineHelper::approximateFunction( { /// approximate a function given as an array of values at data points - int numberOfKnots[mXdimensions]; //getting number of Knots for all dimensions into one array - for (int i = 0; i < mXdimensions; i++) { + int32_t numberOfKnots[mXdimensions]; // getting number of Knots for all dimensions into one array + for (int32_t i = 0; i < mXdimensions; i++) { numberOfKnots[i] = mHelpers[i].getSpline().getNumberOfKnots(); } - int numberOfDataPoints[mXdimensions]; // getting number of datapoints (incl knots) in all dimensions into one array - for (int i = 0; i < mXdimensions; i++) { + int32_t numberOfDataPoints[mXdimensions]; // getting number of datapoints (incl knots) in all dimensions into one array + for (int32_t i = 0; i < mXdimensions; i++) { numberOfDataPoints[i] = mHelpers[i].getNumberOfDataPoints(); } - int numberOfAllKnots = 1; // getting Number of all knots for the entire spline - for (int i = 0; i < mXdimensions; i++) { + int32_t numberOfAllKnots = 1; // getting Number of all knots for the entire spline + for (int32_t i = 0; i < mXdimensions; i++) { numberOfAllKnots *= numberOfKnots[i]; } // TO BE REMOVED (TEST-OUTPUT): LOG(info) << "total number of knots: " << numberOfAllKnots << ", "; - int numberOfAllDataPoints = 1; // getting Number of all Datapoints for the entire spline - for (int i = 0; i < mXdimensions; i++) { + int32_t numberOfAllDataPoints = 1; // getting Number of all Datapoints for the entire spline + for (int32_t i = 0; i < mXdimensions; i++) { numberOfAllDataPoints *= numberOfDataPoints[i]; // LOG(info) << mHelpers[0].getNumberOfDataPoints(); } @@ -245,56 +245,56 @@ void SplineHelper::approximateFunction( // TO BE REMOVED TEST: // LOG(info) << "total number of DataPoints (including knots): " << numberOfAllDataPoints << ", "; - int numberOfParameterTypes = (int)(pow(2.0, mXdimensions)); //number of Parameters per Knot + int32_t numberOfParameterTypes = (int32_t)(pow(2.0, mXdimensions)); // number of Parameters per Knot // TO BE REMOVED TEST: // LOG(info) << "number of paramtertypes per knot : " << numberOfParameterTypes << ", "; std::unique_ptr allParameters[numberOfParameterTypes]; //Array for the different parametertypes s, s'u, s'v, s''uv,... - for (int i = 0; i < numberOfParameterTypes; i++) { + for (int32_t i = 0; i < numberOfParameterTypes; i++) { allParameters[i] = std::unique_ptr(new double[numberOfAllDataPoints * mFdimensions]); //To-Do:Fdim!! } //filling allParameters[0] and FParameters with s: - for (int i = 0; i < numberOfAllDataPoints; i++) { - for (int f = 0; f < mFdimensions; f++) { // for all f-dimensions + for (int32_t i = 0; i < numberOfAllDataPoints; i++) { + for (int32_t f = 0; f < mFdimensions; f++) { // for all f-dimensions allParameters[0][i * mFdimensions + f] = DataPointF[i * mFdimensions + f]; // TO DO - Just get the pointer adress there PLEASE! } - int p0indices[mXdimensions]; + int32_t p0indices[mXdimensions]; arraytopoints(i, p0indices, numberOfDataPoints, mXdimensions); bool isKnot = 1; - for (int j = 0; j < mXdimensions; j++) { // is the current datapoint a knot? + for (int32_t j = 0; j < mXdimensions; j++) { // is the current datapoint a knot? if (!mHelpers[j].getDataPoint(p0indices[j]).isKnot) { isKnot = 0; break; } } if (isKnot) { - int knotindices[mXdimensions]; - for (int j = 0; j < mXdimensions; j++) { // calculate KNotindices for all dimensions - //WORKAROUND Getting Knotindices: + int32_t knotindices[mXdimensions]; + for (int32_t j = 0; j < mXdimensions; j++) { // calculate KNotindices for all dimensions + // WORKAROUND Getting Knotindices: knotindices[j] = p0indices[j] / ((numberOfDataPoints[j] - 1) / (numberOfKnots[j] - 1)); //knotindices[j] = mHelpers[j].getDataPoint(p0indices[j]).iKnot; //in der Annahme der wert ist ein Knotenindex und falls der datapoint ein knoten ist, gibt er seinen eigenen knotenindex zurück } // get the knotindexvalue for FParameters: - int knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions); + int32_t knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions); - for (int f = 0; f < mFdimensions; f++) { // for all f-dimensions get function values into Fparameters + for (int32_t f = 0; f < mFdimensions; f++) { // for all f-dimensions get function values into Fparameters Fparameters[knotind * numberOfParameterTypes * mFdimensions + f] = DataPointF[i * mFdimensions + f]; ///write derivatives in FParameters } } // end if isKnot - } //end i (filling DataPointF Values into allParameters[0] and FParameters) - //now: allParameters[0] = dataPointF; + } // end i (filling DataPointF Values into allParameters[0] and FParameters) + // now: allParameters[0] = dataPointF; //Array for input DataPointF-values for Spline1D::approximateFunctionGradually(...); std::unique_ptr dataPointF1D[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { dataPointF1D[i] = std::unique_ptr(new double[numberOfDataPoints[i] * mFdimensions]); // To-Do:Fdim!! For s and derivetives at all knots. } //Array to be filled by Spline1D::approximateFunctionGradually(...); std::unique_ptr par[mXdimensions]; std::unique_ptr parD[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + for (int32_t i = 0; i < mXdimensions; i++) { par[i] = std::unique_ptr(new DataT[numberOfKnots[i] * mFdimensions * 2]); parD[i] = std::unique_ptr(new double[numberOfKnots[i] * mFdimensions * 2]); } @@ -302,81 +302,81 @@ void SplineHelper::approximateFunction( // LOG(info) << "NumberOfParameters: " << mNumberOfParameters ; //STARTING MAIN-LOOP, for all Parametertypes: - for (int p = 1; p < numberOfParameterTypes; p++) { // p = 1!! Wir kriegen s (p0) durch approximateFunction()oben - int dimension = 0; // find the dimension for approximation - for (int i = (int)(log2f((float)p)); i >= 0; i--) { - if (p % (int)(pow(2.0, i)) == 0) { + for (int32_t p = 1; p < numberOfParameterTypes; p++) { // p = 1!! Wir kriegen s (p0) durch approximateFunction()oben + int32_t dimension = 0; // find the dimension for approximation + for (int32_t i = (int32_t)(log2f((float)p)); i >= 0; i--) { + if (p % (int32_t)(pow(2.0, i)) == 0) { dimension = i; break; } } - int currentDataPointF = p - (int)(pow(2.0, dimension)); + int32_t currentDataPointF = p - (int32_t)(pow(2.0, dimension)); // LOG(info) << "\n" << "p:" << p << ", dim of approximation: " << dimension << ", based on: " << currentDataPointF ; - int nrOf1DSplines = (numberOfAllDataPoints / numberOfDataPoints[dimension]); // number of Splines for Parametertyp p in direction dim + int32_t nrOf1DSplines = (numberOfAllDataPoints / numberOfDataPoints[dimension]); // number of Splines for Parametertyp p in direction dim // LOG(info) << "nr of splines: " << nrOf1DSplines; // getting the numbers of Datapoints for all dimension eccept the dimension of interpolation - int currentNumbers[mXdimensions - 1]; - for (int i = 0; i < dimension; i++) { + int32_t currentNumbers[mXdimensions - 1]; + for (int32_t i = 0; i < dimension; i++) { currentNumbers[i] = numberOfDataPoints[i]; } - for (int i = dimension; i < mXdimensions - 1; i++) { + for (int32_t i = dimension; i < mXdimensions - 1; i++) { currentNumbers[i] = numberOfDataPoints[i + 1]; } /// LOG(info) << " current numbers: "; - for (int i = 0; i < mXdimensions - 1; i++) { + for (int32_t i = 0; i < mXdimensions - 1; i++) { // LOG(info) << currentNumbers[i] << ","; } // LOG(info) ; //// for all Splines in current dimension: - for (int s = 0; s < nrOf1DSplines; s++) { - int indices[mXdimensions - 1]; + for (int32_t s = 0; s < nrOf1DSplines; s++) { + int32_t indices[mXdimensions - 1]; arraytopoints(s, indices, currentNumbers, mXdimensions - 1); - int startpoint[mXdimensions]; //startpoint for the current 1DSpline - for (int i = 0; i < dimension; i++) { + int32_t startpoint[mXdimensions]; // startpoint for the current 1DSpline + for (int32_t i = 0; i < dimension; i++) { startpoint[i] = indices[i]; } startpoint[dimension] = 0; - for (int i = dimension + 1; i < mXdimensions; i++) { + for (int32_t i = dimension + 1; i < mXdimensions; i++) { startpoint[i] = indices[i - 1]; } // NOW WE HAVE THE DATAPOINTINDICES OF THE CURRENT STARTPOINT IN startpoint-Array. - int startdatapoint = pointstoarray(startpoint, numberOfDataPoints, mXdimensions); - int distance = 1; // distance to the next dataPoint in the array for the current dimension - for (int i = 0; i < dimension; i++) { + int32_t startdatapoint = pointstoarray(startpoint, numberOfDataPoints, mXdimensions); + int32_t distance = 1; // distance to the next dataPoint in the array for the current dimension + for (int32_t i = 0; i < dimension; i++) { distance *= numberOfDataPoints[i]; } distance *= mFdimensions; - for (int i = 0; i < numberOfDataPoints[dimension]; i++) { //Fill the dataPointF1D-Array - for (int f = 0; f < mFdimensions; f++) { + for (int32_t i = 0; i < numberOfDataPoints[dimension]; i++) { // Fill the dataPointF1D-Array + for (int32_t f = 0; f < mFdimensions; f++) { dataPointF1D[dimension][i * mFdimensions + f] = allParameters[currentDataPointF][startdatapoint * mFdimensions + (i * distance + f)]; // uiuiui index kuddelmuddel???!! } } mHelpers[dimension].approximateFunction(par[dimension].get(), dataPointF1D[dimension].get()); - for (int i = 0; i < numberOfKnots[dimension] * mFdimensions * 2; i++) { + for (int32_t i = 0; i < numberOfKnots[dimension] * mFdimensions * 2; i++) { parD[dimension][i] = par[dimension][i]; } // now we have all s and s' values in par[dimension] - int redistributionindex[mXdimensions]; - for (int i = 0; i < mXdimensions; i++) { + int32_t redistributionindex[mXdimensions]; + for (int32_t i = 0; i < mXdimensions; i++) { redistributionindex[i] = startpoint[i]; } //redistributing the derivatives at dimension-Knots into array p - for (int i = 0; i < numberOfKnots[dimension]; i++) { //for all dimension-Knots + for (int32_t i = 0; i < numberOfKnots[dimension]; i++) { // for all dimension-Knots redistributionindex[dimension] = mHelpers[dimension].getKnotDataPoint(i); //find the indices - int finalposition = pointstoarray(redistributionindex, numberOfDataPoints, mXdimensions); + int32_t finalposition = pointstoarray(redistributionindex, numberOfDataPoints, mXdimensions); - for (int f = 0; f < mFdimensions; f++) { + for (int32_t f = 0; f < mFdimensions; f++) { allParameters[p][finalposition * mFdimensions + f] = par[dimension][2 * i * mFdimensions + mFdimensions + f]; } bool isKnot = 1; - for (int j = 0; j < mXdimensions; j++) { //is dataPoint a knot? + for (int32_t j = 0; j < mXdimensions; j++) { // is dataPoint a knot? if (!mHelpers[j].getDataPoint(redistributionindex[j]).isKnot) { isKnot = 0; break; @@ -384,25 +384,25 @@ void SplineHelper::approximateFunction( } if (isKnot) { // for all knots - int knotindices[mXdimensions]; + int32_t knotindices[mXdimensions]; - for (int j = 0; j < mXdimensions; j++) { // calculate Knotindices for all dimensions + for (int32_t j = 0; j < mXdimensions; j++) { // calculate Knotindices for all dimensions knotindices[j] = redistributionindex[j] / ((numberOfDataPoints[j] - 1) / (numberOfKnots[j] - 1)); //knotindices[j] = mHelpers[j].getDataPoint(redistributionindex[j]).iKnot; //in der Annahme der wert ist ein Knotenindex und falls der datapoint ein knoten ist, gibt er seinen eigenen knotenindex zurück } // get the knotindexvalue for FParameters: - int knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions); - for (int f = 0; f < mFdimensions; f++) { + int32_t knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions); + for (int32_t f = 0; f < mFdimensions; f++) { Fparameters[knotind * numberOfParameterTypes * mFdimensions + p * mFdimensions + f] = par[dimension][2 * i * mFdimensions + mFdimensions + f]; ///write derivatives in FParameters } } } // end for all fknots (for redistribution) // recalculation: - for (int i = 0; i < numberOfDataPoints[dimension]; i++) { // this is somehow still redundant// TO DO: ONLY PART OF approximateFunction WHERE NDIM is considerd!! + for (int32_t i = 0; i < numberOfDataPoints[dimension]; i++) { // this is somehow still redundant// TO DO: ONLY PART OF approximateFunction WHERE NDIM is considerd!! redistributionindex[dimension] = i; // getting current datapointindices bool isKnot = 1; // check is current datapoint a knot? - for (int j = 0; j < mXdimensions; j++) { + for (int32_t j = 0; j < mXdimensions; j++) { if (!mHelpers[j].getDataPoint(redistributionindex[j]).isKnot) { isKnot = 0; break; @@ -411,59 +411,59 @@ void SplineHelper::approximateFunction( double splineF[mFdimensions]; double u = mHelpers[dimension].getDataPoint(i).u; mHelpers[dimension].getSpline().interpolateU(mFdimensions, parD[dimension].get(), u, splineF); //recalculate at all datapoints of dimension - for (int dim = 0; dim < mFdimensions; dim++) { //writing it in allParameters - // LOG(info)< -int SplineHelper::test(const bool draw, const bool drawDataPoints) +int32_t SplineHelper::test(const bool draw, const bool drawDataPoints) { // Test method using namespace std; - constexpr int nDimX = 2; - constexpr int nDimY = 2; - constexpr int Fdegree = 4; + constexpr int32_t nDimX = 2; + constexpr int32_t nDimY = 2; + constexpr int32_t Fdegree = 4; double xMin[nDimX]; double xMax[nDimX]; - int nKnots[nDimX]; - int* knotsU[nDimX]; - int nAxiliaryDatapoints[nDimX]; + int32_t nKnots[nDimX]; + int32_t* knotsU[nDimX]; + int32_t nAxiliaryDatapoints[nDimX]; - for (int i = 0; i < nDimX; i++) { + for (int32_t i = 0; i < nDimX; i++) { xMin[i] = 0.; xMax[i] = 1.; nKnots[i] = 4; - knotsU[i] = new int[nKnots[i]]; + knotsU[i] = new int32_t[nKnots[i]]; nAxiliaryDatapoints[i] = 4; } // Function F - const int nTerms1D = 2 * (Fdegree + 1); - int nFcoeff = nDimY; - for (int i = 0; i < nDimX; i++) { + const int32_t nTerms1D = 2 * (Fdegree + 1); + int32_t nFcoeff = nDimY; + for (int32_t i = 0; i < nDimX; i++) { nFcoeff *= nTerms1D; } @@ -472,28 +472,28 @@ int SplineHelper::test(const bool draw, const bool drawDataPoints) auto F = [&](const double x[nDimX], double f[nDimY]) { double a[nFcoeff]; a[0] = 1; - int na = 1; - for (int d = 0; d < nDimX; d++) { + int32_t na = 1; + for (int32_t d = 0; d < nDimX; d++) { double b[nFcoeff]; - int nb = 0; + int32_t nb = 0; double t = (x[d] - xMin[d]) * TMath::Pi() / (xMax[d] - xMin[d]); - for (int i = 0; i < nTerms1D; i++) { + for (int32_t i = 0; i < nTerms1D; i++) { double c = (i % 2) ? cos((i / 2) * t) : cos((i / 2) * t); - for (int j = 0; j < na; j++) { + for (int32_t j = 0; j < na; j++) { b[nb++] = c * a[j]; assert(nb <= nFcoeff); } } na = nb; - for (int i = 0; i < nb; i++) { + for (int32_t i = 0; i < nb; i++) { a[i] = b[i]; } } double* c = Fcoeff; - for (int dim = 0; dim < nDimY; dim++) { + for (int32_t dim = 0; dim < nDimY; dim++) { f[dim] = 0; - for (int i = 0; i < na; i++) { + for (int32_t i = 0; i < na; i++) { f[dim] += a[i] * (*c++); } } @@ -504,19 +504,19 @@ int SplineHelper::test(const bool draw, const bool drawDataPoints) F(x, f); }; - for (int seed = 1; seed < 10; seed++) { + for (int32_t seed = 1; seed < 10; seed++) { gRandom->SetSeed(seed); // getting the coefficents filled randomly - for (int i = 0; i < nFcoeff; i++) { + for (int32_t i = 0; i < nFcoeff; i++) { Fcoeff[i] = gRandom->Uniform(-1, 1); } - for (int i = 0; i < nDimX; i++) { + for (int32_t i = 0; i < nDimX; i++) { knotsU[i][0] = 0; - for (int j = 1; j < nKnots[i]; j++) { - knotsU[i][j] = j * 4; //+ int(gRandom->Integer(3)) - 1; + for (int32_t j = 1; j < nKnots[i]; j++) { + knotsU[i][j] = j * 4; //+ int32_t(gRandom->Integer(3)) - 1; } } @@ -527,13 +527,13 @@ int SplineHelper::test(const bool draw, const bool drawDataPoints) spline2D.approximateFunction(xMin[0], xMax[0], xMin[1], xMax[1], F2D, nAxiliaryDatapoints[0], nAxiliaryDatapoints[0]); - long double statDf = 0; - long double statDf2D = 0; + double statDf = 0; + double statDf2D = 0; - long double statN = 0; + double statN = 0; double x[nDimX]; - for (int i = 0; i < nDimX; i++) { + for (int32_t i = 0; i < nDimX; i++) { x[i] = xMin[i]; } do { @@ -541,19 +541,19 @@ int SplineHelper::test(const bool draw, const bool drawDataPoints) float s[nDimY]; float s2D[nDimY]; double f[nDimY]; - for (int i = 0; i < nDimX; i++) { + for (int32_t i = 0; i < nDimX; i++) { xf[i] = x[i]; } F(x, f); spline.interpolate(xf, s); spline2D.interpolate(xf[0], xf[1], s2D); - for (int dim = 0; dim < nDimY; dim++) { + for (int32_t dim = 0; dim < nDimY; dim++) { statDf += (s[dim] - f[dim]) * (s[dim] - f[dim]); statDf2D += (s2D[dim] - f[dim]) * (s2D[dim] - f[dim]); statN++; } - int dim = 0; + int32_t dim = 0; for (; dim < nDimX; dim++) { x[dim] += 0.01; if (x[dim] <= xMax[dim]) { @@ -571,7 +571,7 @@ int SplineHelper::test(const bool draw, const bool drawDataPoints) } // seed - for (int i = 0; i < nDimX; i++) { + for (int32_t i = 0; i < nDimX; i++) { delete[] knotsU[i]; } diff --git a/GPU/TPCFastTransformation/SplineHelper.h b/GPU/TPCFastTransformation/SplineHelper.h index 9fe47132cc58f..06b1cd9412c0f 100644 --- a/GPU/TPCFastTransformation/SplineHelper.h +++ b/GPU/TPCFastTransformation/SplineHelper.h @@ -60,12 +60,12 @@ class SplineHelper void approximateFunction(SplineContainer& spline, const double xMin[/* Xdim */], const double xMax[/* Xdim */], std::function F, - const int nAxiliaryDataPoints[/* Xdim */] = nullptr); + const int32_t nAxiliaryDataPoints[/* Xdim */] = nullptr); /// _______________ Interface for a step-wise construction of the best-fit spline ________________________ /// precompute everything needed for the construction - int setSpline(const SplineContainer& spline, const int nAxiliaryPoints[/* Xdim */]); + int32_t setSpline(const SplineContainer& spline, const int32_t nAxiliaryPoints[/* Xdim */]); /// approximate std::function, output in Fparameters void approximateFunction( @@ -76,17 +76,17 @@ class SplineHelper void approximateFunctionBatch( DataT* Fparameters, const double xMin[/* mXdimensions */], const double xMax[/* mXdimensions */], std::function x[/* mXdimensions */], double f[/*mFdimensions*/])> F, - unsigned int batchsize) const; + uint32_t batchsize) const; /// approximate a function given as an array of values at data points void approximateFunction( DataT* Fparameters, const double DataPointF[/*getNumberOfDataPoints() x nFdim*/]) const; - int getNumberOfDataPoints(int dimX) const { return mHelpers[dimX].getNumberOfDataPoints(); } + int32_t getNumberOfDataPoints(int32_t dimX) const { return mHelpers[dimX].getNumberOfDataPoints(); } - int getNumberOfDataPoints() const { return mNumberOfDataPoints; } + int32_t getNumberOfDataPoints() const { return mNumberOfDataPoints; } - const Spline1DHelperOld& getHelper(int dimX) const { return mHelpers[dimX]; } + const Spline1DHelperOld& getHelper(int32_t dimX) const { return mHelpers[dimX]; } /// _______________ Utilities ________________________ @@ -95,22 +95,22 @@ class SplineHelper #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// Test the Spline class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif - static int arraytopoints(int point, int result[], const int numbers[], int dim); + static int32_t arraytopoints(int32_t point, int32_t result[], const int32_t numbers[], int32_t dim); - static int pointstoarray(const int indices[], const int numbers[], int dim); + static int32_t pointstoarray(const int32_t indices[], const int32_t numbers[], int32_t dim); private: /// Stores an error message - int storeError(Int_t code, const char* msg); + int32_t storeError(Int_t code, const char* msg); TString mError = ""; ///< error string - int mXdimensions; ///< number of X dimensions - int mFdimensions; ///< number of F dimensions - int mNumberOfParameters; ///< number of parameters - int mNumberOfDataPoints; ///< number of data points + int32_t mXdimensions; ///< number of X dimensions + int32_t mFdimensions; ///< number of F dimensions + int32_t mNumberOfParameters; ///< number of parameters + int32_t mNumberOfDataPoints; ///< number of data points std::vector> mHelpers; }; @@ -119,14 +119,14 @@ void SplineHelper::approximateFunction( SplineContainer& spline, const double xMin[/* Xdim */], const double xMax[/* Xdim */], std::function F, - const int nAxiliaryDataPoints[/* Xdim */]) + const int32_t nAxiliaryDataPoints[/* Xdim */]) { /// Create best-fit spline parameters for a given input function F setSpline(spline, nAxiliaryDataPoints); approximateFunction(spline.getParameters(), xMin, xMax, F); DataT xxMin[spline.getXdimensions()]; DataT xxMax[spline.getXdimensions()]; - for (int i = 0; i < spline.getXdimensions(); i++) { + for (int32_t i = 0; i < spline.getXdimensions(); i++) { xxMin[i] = xMin[i]; xxMax[i] = xMax[i]; } @@ -134,22 +134,22 @@ void SplineHelper::approximateFunction( } template -int SplineHelper::setSpline( - const SplineContainer& spline, const int nAxiliaryPoints[/* Xdim */]) +int32_t SplineHelper::setSpline( + const SplineContainer& spline, const int32_t nAxiliaryPoints[/* Xdim */]) { // Prepare creation of an irregular spline // The should be at least one (better, two) axiliary measurements on each segnment between two knots and at least 2*nKnots measurements in total // Returns 0 when the spline can not be constructed with the given nAxiliaryPoints - int ret = 0; + int32_t ret = 0; mXdimensions = spline.getXdimensions(); mFdimensions = spline.getYdimensions(); mNumberOfParameters = spline.getNumberOfParameters(); mNumberOfDataPoints = 1; mHelpers.clear(); mHelpers.resize(mXdimensions); - for (int i = 0; i < mXdimensions; i++) { - int np = (nAxiliaryPoints != nullptr) ? nAxiliaryPoints[i] : 4; + for (int32_t i = 0; i < mXdimensions; i++) { + int32_t np = (nAxiliaryPoints != nullptr) ? nAxiliaryPoints[i] : 4; if (mHelpers[i].setSpline(spline.getGrid(i), mFdimensions, np) != 0) { ret = storeError(-2, "SplineHelper::setSpline: error by setting an axis"); } diff --git a/GPU/TPCFastTransformation/SplineSpec.cxx b/GPU/TPCFastTransformation/SplineSpec.cxx index 85239788526b9..521b418e3f099 100644 --- a/GPU/TPCFastTransformation/SplineSpec.cxx +++ b/GPU/TPCFastTransformation/SplineSpec.cxx @@ -61,8 +61,8 @@ void SplineContainer::setActualBufferAddress(char* actualFlatBufferPtr) FlatObject::setActualBufferAddress(actualFlatBufferPtr); mGrid = reinterpret_cast*>(mFlatBufferPtr); - int offset = sizeof(*mGrid) * mXdim; - for (int i = 0; i < mXdim; i++) { + int32_t offset = sizeof(*mGrid) * mXdim; + for (int32_t i = 0; i < mXdim; i++) { offset = alignSize(offset, mGrid[i].getBufferAlignmentBytes()); mGrid[i].setActualBufferAddress(mFlatBufferPtr + offset); offset += mGrid[i].getFlatBufferSize(); @@ -76,7 +76,7 @@ void SplineContainer::setFutureBufferAddress(char* futureFlatBufferPtr) { /// See FlatObject for description mParameters = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParameters); - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { char* buffer = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mGrid[i].getFlatBufferPtr()); mGrid[i].setFutureBufferAddress(buffer); } @@ -88,7 +88,7 @@ template void SplineContainer::print() const { printf(" Irregular Spline %dD->%dD: \n", mXdim, mYdim); - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { printf(" grid X%d: \n", i); mGrid[i].print(); } @@ -108,7 +108,7 @@ void SplineContainer::cloneFromObject(const SplineContainer& obj, mNknots = obj.mNknots; Spline1D* newGrid = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mGrid); - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { char* buffer = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mGrid[i].getFlatBufferPtr()); newGrid[i].cloneFromObject(obj.mGrid[i], buffer); } @@ -129,7 +129,7 @@ void SplineContainer::moveBufferTo(char* newFlatBufferPtr) template void SplineContainer::recreate( - int nXdim, int nYdim, const int numberOfKnots[/* nXdim */], const int* const knots[/* nXdim */]) + int32_t nXdim, int32_t nYdim, const int32_t numberOfKnots[/* nXdim */], const int32_t* const knots[/* nXdim */]) { /// Constructor for an irregular spline @@ -140,7 +140,7 @@ void SplineContainer::recreate( Spline1D vGrids[mXdim]; mNknots = 1; - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { if (knots) { vGrids[i].recreate(0, numberOfKnots[i], knots[i]); } else if (numberOfKnots) { @@ -151,9 +151,9 @@ void SplineContainer::recreate( mNknots *= vGrids[i].getNumberOfKnots(); } - int offset = sizeof(Spline1D) * mXdim; + int32_t offset = sizeof(Spline1D) * mXdim; - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { offset = alignSize(offset, vGrids[i].getBufferAlignmentBytes()); offset += vGrids[i].getFlatBufferSize(); } @@ -167,7 +167,7 @@ void SplineContainer::recreate( offset = sizeof(Spline1D) * mXdim; - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { new (&mGrid[i]) Spline1D; // constructor offset = alignSize(offset, mGrid[i].getBufferAlignmentBytes()); mGrid[i].cloneFromObject(vGrids[i], mFlatBufferPtr + offset); @@ -178,14 +178,14 @@ void SplineContainer::recreate( mParameters = reinterpret_cast(mFlatBufferPtr + offset); offset += getSizeOfParameters(); - for (int i = 0; i < getNumberOfParameters(); i++) { + for (int32_t i = 0; i < getNumberOfParameters(); i++) { mParameters[i] = 0; } } template void SplineContainer::recreate( - int nXdim, int nYdim, const int numberOfKnots[/* nXdim */]) + int32_t nXdim, int32_t nYdim, const int32_t numberOfKnots[/* nXdim */]) { /// Constructor for a regular spline recreate(nXdim, nYdim, numberOfKnots, nullptr); @@ -199,7 +199,7 @@ template void SplineContainer:: approximateFunction(const double xMin[/* mXdim */], const double xMax[/* mXdim */], std::function F, - const int nAuxiliaryDataPoints[/* mXdim */]) + const int32_t nAuxiliaryDataPoints[/* mXdim */]) { /// approximate a function F with this spline SplineHelper helper; @@ -208,7 +208,7 @@ void SplineContainer:: #ifndef GPUCA_ALIROOT_LIB template -int SplineContainer::writeToFile(TFile& outf, const char* name) +int32_t SplineContainer::writeToFile(TFile& outf, const char* name) { /// write a class object to the file return FlatObject::writeToFile(*this, outf, name); @@ -223,7 +223,7 @@ SplineContainer* SplineContainer::readFromFile( } template -int SplineContainer::test(const bool draw, const bool drawDataPoints) +int32_t SplineContainer::test(const bool draw, const bool drawDataPoints) { return SplineHelper::test(draw, drawDataPoints); } diff --git a/GPU/TPCFastTransformation/SplineSpec.h b/GPU/TPCFastTransformation/SplineSpec.h index d8f0570cf99ab..f9c14b6374337 100644 --- a/GPU/TPCFastTransformation/SplineSpec.h +++ b/GPU/TPCFastTransformation/SplineSpec.h @@ -53,7 +53,7 @@ class SplineContainer : public FlatObject /// _____________ Version control __________________________ /// Version control - GPUd() static constexpr int getVersion() { return (1 << 16) + Spline1D::getVersion(); } + GPUd() static constexpr int32_t getVersion() { return (1 << 16) + Spline1D::getVersion(); } /// _____________ C++ constructors / destructors __________________________ @@ -72,14 +72,14 @@ class SplineContainer : public FlatObject /// approximate a function F with this spline void approximateFunction(const double xMin[/* mXdim */], const double xMax[/* mXdim */], std::function F, - const int nAuxiliaryDataPoints[/* mXdim */] = nullptr); + const int32_t nAuxiliaryDataPoints[/* mXdim */] = nullptr); #endif /// _______________ IO ________________________ #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// write a class object to the file - int writeToFile(TFile& outf, const char* name); + int32_t writeToFile(TFile& outf, const char* name); /// read a class object from the file static SplineContainer* readFromFile(TFile& inpf, const char* name); @@ -88,34 +88,34 @@ class SplineContainer : public FlatObject /// _______________ Getters ________________________ /// Get number of X dimensions - GPUd() int getXdimensions() const { return mXdim; } + GPUd() int32_t getXdimensions() const { return mXdim; } /// Get number of Y dimensions - GPUd() int getYdimensions() const { return mYdim; } + GPUd() int32_t getYdimensions() const { return mYdim; } /// Get minimal required alignment for the spline parameters GPUd() static constexpr size_t getParameterAlignmentBytes() { return 16; } /// Number of parameters - GPUd() int getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); } + GPUd() int32_t getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); } /// Size of the parameter array in bytes GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * this->getNumberOfParameters(); } /// Get a number of knots - GPUd() int getNumberOfKnots() const { return mNknots; } + GPUd() int32_t getNumberOfKnots() const { return mNknots; } /// Number of parameters per knot - GPUd() int getNumberOfParametersPerKnot() const { return calcNumberOfParametersPerKnot(mYdim); } + GPUd() int32_t getNumberOfParametersPerKnot() const { return calcNumberOfParametersPerKnot(mYdim); } /// Get 1-D grid for dimX dimension - GPUd() const Spline1D& getGrid(int dimX) const { return mGrid[dimX]; } + GPUd() const Spline1D& getGrid(int32_t dimX) const { return mGrid[dimX]; } /// Get u[] coordinate of i-th knot - GPUd() void getKnotU(int iKnot, int u[/* mXdim */]) const; + GPUd() void getKnotU(int32_t iKnot, int32_t u[/* mXdim */]) const; /// Get index of a knot (iKnot1,iKnot2,..,iKnotN) - GPUd() int getKnotIndex(const int iKnot[/* mXdim */]) const; + GPUd() int32_t getKnotIndex(const int32_t iKnot[/* mXdim */]) const; /// Get spline parameters GPUd() DataT* getParameters() { return mParameters; } @@ -126,7 +126,7 @@ class SplineContainer : public FlatObject /// _______________ Technical stuff ________________________ /// Get offset of Grid[dimX] flat data in the flat buffer - GPUd() size_t getGridOffset(int dimX) const { return mGrid[dimX].getFlatBufferPtr() - mFlatBufferPtr; } + GPUd() size_t getGridOffset(int32_t dimX) const { return mGrid[dimX].getFlatBufferPtr() - mFlatBufferPtr; } /// Set X range GPUd() void setXrange(const DataT xMin[/* mXdim */], const DataT xMax[/* mXdim */]); @@ -137,13 +137,13 @@ class SplineContainer : public FlatObject /// _______________ Expert tools _______________ /// Number of parameters for given Y dimensions - GPUd() int calcNumberOfParameters(int nYdim) const + GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const { return calcNumberOfParametersPerKnot(nYdim) * getNumberOfKnots(); } /// Number of parameters per knot - GPUd() int calcNumberOfParametersPerKnot(int nYdim) const + GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const { return (1 << mXdim) * nYdim; // 2^mXdim parameters per Y dimension } @@ -152,7 +152,7 @@ class SplineContainer : public FlatObject #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) // code invisible on GPU and in the standalone compilation /// Test the class functionality - static int test(const bool draw = 0, const bool drawDataPoints = 1); + static int32_t test(const bool draw = 0, const bool drawDataPoints = 1); #endif /// _____________ FlatObject functionality, see FlatObject class for description ____________ @@ -174,17 +174,17 @@ class SplineContainer : public FlatObject protected: #if !defined(GPUCA_GPUCODE) /// Constructor for a regular spline - void recreate(int nXdim, int nYdim, const int nKnots[/* nXdim */]); + void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */]); /// Constructor for an irregular spline - void recreate(int nXdim, int nYdim, const int nKnots[/* nXdim */], const int* const knotU[/* nXdim */]); + void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */]); #endif /// _____________ Data members ____________ - int mXdim = 0; ///< dimentionality of X - int mYdim = 0; ///< dimentionality of Y - int mNknots = 0; ///< number of spline knots + int32_t mXdim = 0; ///< dimentionality of X + int32_t mYdim = 0; ///< dimentionality of Y + int32_t mNknots = 0; ///< number of spline knots Spline1D* mGrid; //! (transient!!) mXdim grids DataT* mParameters; //! (transient!!) F-dependent parameters of the spline @@ -195,23 +195,23 @@ class SplineContainer : public FlatObject }; template -GPUdi() void SplineContainer::getKnotU(int iKnot, int u[/* mXdim */]) const +GPUdi() void SplineContainer::getKnotU(int32_t iKnot, int32_t u[/* mXdim */]) const { /// Get u[] coordinate of i-th knot - for (int dim = 0; dim < mXdim; dim++) { - int n = mGrid[dim].getNumberOfKnots(); + for (int32_t dim = 0; dim < mXdim; dim++) { + int32_t n = mGrid[dim].getNumberOfKnots(); u[dim] = mGrid[dim].getKnot(iKnot % n).getU(); iKnot /= n; } } template -GPUdi() int SplineContainer::getKnotIndex(const int iKnot[/* mXdim */]) const +GPUdi() int32_t SplineContainer::getKnotIndex(const int32_t iKnot[/* mXdim */]) const { /// Get index of a knot (iKnot1,iKnot2,..,iKnotN) - int ind = iKnot[0]; - int n = 1; - for (int dim = 1; dim < mXdim; dim++) { + int32_t ind = iKnot[0]; + int32_t n = 1; + for (int32_t dim = 1; dim < mXdim; dim++) { n *= mGrid[dim - 1].getNumberOfKnots(); ind += n * iKnot[dim]; } @@ -223,7 +223,7 @@ GPUdi() void SplineContainer:: setXrange(const DataT xMin[/* mXdim */], const DataT xMax[/* mXdim */]) { /// Set X range - for (int i = 0; i < mXdim; i++) { + for (int32_t i = 0; i < mXdim; i++) { mGrid[i].setXrange(xMin[i], xMax[i]); } } @@ -250,14 +250,14 @@ GPUdi() void SplineContainer:: /// 2 - at least one of the dimensions must be set during runtime /// 3 - specialization where nYdim==1 (a small add-on on top of the other specs) /// -template +template class SplineSpec; /// ================================================================================================== /// Specialization 0 declares common methods for all other Spline specializations. /// Implementations of the methods may depend on the YdimT value. /// -template +template class SplineSpec : public SplineContainer { typedef SplineContainer TBase; @@ -275,7 +275,7 @@ class SplineSpec : public SplineContainer const auto nXdim = nXdimTmp.get(); const auto maxXdimTmp = SplineUtil::getMaxNdim(mXdim); DataT u[maxXdimTmp.get()]; - for (int i = 0; i < nXdim; i++) { + for (int32_t i = 0; i < nXdim; i++) { u[i] = mGrid[i].convXtoU(x[i]); } interpolateU(mXdim, mYdim, mParameters, u, S); @@ -283,7 +283,7 @@ class SplineSpec : public SplineContainer /// Get interpolated value for S(u):inpXdim->inpYdim using spline parameters Parameters template - GPUd() void interpolateU(int inpXdim, int inpYdim, GPUgeneric() const DataT Parameters[], + GPUd() void interpolateU(int32_t inpXdim, int32_t inpYdim, GPUgeneric() const DataT Parameters[], const DataT u[/*inpXdim*/], GPUgeneric() DataT S[/*inpYdim*/]) const { const auto nXdimTmp = SplineUtil::getNdim(mXdim); @@ -303,19 +303,19 @@ class SplineSpec : public SplineContainer //get the indices of the "most left" Knot: - int indices[maxXdim]; //indices of the 'most left' knot - for (int i = 0; i < nXdim; i++) { + int32_t indices[maxXdim]; // indices of the 'most left' knot + for (int32_t i = 0; i < nXdim; i++) { indices[i] = mGrid[i].getLeftKnotIndexForU(u[i]); } // get all the needed parameters into one array iParameters[nParameters]: - int indicestmp[maxXdim]; - for (int i = 0; i < nKnotParametersPerY; i++) { // for every necessary Knot - for (int k = 0; k < nXdim; k++) { + int32_t indicestmp[maxXdim]; + for (int32_t i = 0; i < nKnotParametersPerY; i++) { // for every necessary Knot + for (int32_t k = 0; k < nXdim; k++) { indicestmp[k] = indices[k] + (i / (1 << k)) % 2; //get the knot-indices in every dimension (mirrored order binary counting) } - int index = TBase::getKnotIndex(indicestmp); //get index of the current Knot + int32_t index = TBase::getKnotIndex(indicestmp); // get index of the current Knot - for (int j = 0; j < nKnotParameters; j++) { //and fill the iparameter array with according parameters + for (int32_t j = 0; j < nKnotParameters; j++) { // and fill the iparameter array with according parameters iParameters[i * nKnotParameters + j] = Parameters[index * nKnotParameters + j]; } } @@ -328,20 +328,20 @@ class SplineSpec : public SplineContainer DataT S1[maxInterpolations]; DataT D1[maxInterpolations]; - int nInterpolations = (1 << (2 * nXdim - 2)) * nYdim; - int nKnots = 1 << (nXdim); + int32_t nInterpolations = (1 << (2 * nXdim - 2)) * nYdim; + int32_t nKnots = 1 << (nXdim); - for (int d = 0; d < nXdim; d++) { //for every dimension + for (int32_t d = 0; d < nXdim; d++) { // for every dimension DataT* pointer[4] = {S0, D0, S1, D1}; // pointers for interpolation arrays S0, D0, S1, D1 point to Arraystart - for (int i = 0; i < nKnots; i++) { //for every knot - for (int j = 0; j < nKnots; j++) { // for every parametertype - int pointernr = 2 * (i % 2) + (j % 2); //to which array should it be delivered - for (int k = 0; k < nYdim; k++) { + for (int32_t i = 0; i < nKnots; i++) { // for every knot + for (int32_t j = 0; j < nKnots; j++) { // for every parametertype + int32_t pointernr = 2 * (i % 2) + (j % 2); // to which array should it be delivered + for (int32_t k = 0; k < nYdim; k++) { pointer[pointernr][0] = iParameters[(i * nKnots + j) * nYdim + k]; pointer[pointernr]++; } } // end for j (every parametertype) - } // end for i (every knot) + } // end for i (every knot) const typename Spline1D::Knot& knotL = mGrid[d].getKnot(indices[d]); DataT coordinate = u[d]; @@ -350,9 +350,9 @@ class SplineSpec : public SplineContainer gridX.interpolateU(nInterpolations, knotL, S0, D0, S1, D1, coordinate, iParameters); nInterpolations /= 4; nKnots /= 2; - } //end d (every dimension) + } // end d (every dimension) - for (int i = 0; i < nYdim; i++) { + for (int32_t i = 0; i < nYdim; i++) { S[i] = iParameters[i]; // write into result-array // LOG(info)< : public SplineContainer /// Specialization 1: XdimT>0, YdimT>0 where the number of dimensions is taken from template parameters /// at the compile time /// -template +template class SplineSpec : public SplineSpec { @@ -385,12 +385,12 @@ class SplineSpec SplineSpec() : SplineSpec(nullptr) {} /// Constructor for a regular spline - SplineSpec(const int nKnots[/*XdimT*/]) : TBase() + SplineSpec(const int32_t nKnots[/*XdimT*/]) : TBase() { recreate(nKnots); } /// Constructor for an irregular spline - SplineSpec(const int nKnots[/*XdimT*/], const int* const knotU[/*XdimT*/]) + SplineSpec(const int32_t nKnots[/*XdimT*/], const int32_t* const knotU[/*XdimT*/]) : TBase() { recreate(nKnots, knotU); @@ -401,23 +401,23 @@ class SplineSpec TBase::cloneFromObject(v, nullptr); } /// Constructor for a regular spline - void recreate(const int nKnots[/*XdimT*/]) + void recreate(const int32_t nKnots[/*XdimT*/]) { TBase::recreate(XdimT, YdimT, nKnots); } /// Constructor for an irregular spline - void recreate(const int nKnots[/*XdimT*/], const int* const knotU[/*XdimT*/]) + void recreate(const int32_t nKnots[/*XdimT*/], const int32_t* const knotU[/*XdimT*/]) { TBase::recreate(XdimT, YdimT, nKnots, knotU); } #endif /// Get number of X dimensions - GPUd() constexpr int getXdimensions() const { return XdimT; } + GPUd() constexpr int32_t getXdimensions() const { return XdimT; } /// Get number of Y dimensions - GPUd() constexpr int getYdimensions() const { return YdimT; } + GPUd() constexpr int32_t getYdimensions() const { return YdimT; } /// _______ Expert tools: interpolation with given nYdim and external Parameters _______ @@ -441,7 +441,7 @@ class SplineSpec /// Specialization 2 (XdimT<=0 || YdimT<=0) where at least one of the dimensions /// must be set in the runtime via a constructor parameter /// -template +template class SplineSpec : public SplineSpec { @@ -456,13 +456,13 @@ class SplineSpec SplineSpec() : SplineSpec((XdimT > 0 ? XdimT : 0), (YdimT > 0 ? YdimT : 0), nullptr) {} /// Constructor for a regular spline - SplineSpec(int nXdim, int nYdim, const int nKnots[/* nXdim */]) : TBase() + SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */]) : TBase() { this->recreate(nXdim, nYdim, nKnots); } /// Constructor for an irregular spline - SplineSpec(int nXdim, int nYdim, const int nKnots[/* nXdim */], const int* const knotU[/* nXdim */]) + SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */]) : TBase() { this->recreate(nXdim, nYdim, nKnots, knotU); @@ -475,14 +475,14 @@ class SplineSpec } /// Constructor for a regular spline - void recreate(int nXdim, int nYdim, const int nKnots[/* nXdim */]) + void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */]) { checkDimensions(nXdim, nYdim); TBase::recreate(nXdim, nYdim, nKnots); } /// Constructor for an irregular spline - void recreate(int nXdim, int nYdim, const int nKnots[/* nXdim */], const int* const knotU[/* nXdim */]) + void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */]) { checkDimensions(nXdim, nYdim); TBase::recreate(nXdim, nYdim, nKnots, knotU); @@ -495,7 +495,7 @@ class SplineSpec using TBase::interpolateU; /// Check dimensions - void checkDimensions(int& nXdim, int& nYdim) + void checkDimensions(int32_t& nXdim, int32_t& nYdim) { if (XdimT > 0 && nXdim != XdimT) { assert(0); @@ -527,7 +527,7 @@ class SplineSpec /// ================================================================================================== /// Specialization 3 where the number of Y dimensions is 1. /// -template +template class SplineSpec : public SplineSpec { diff --git a/GPU/TPCFastTransformation/SplineUtil.h b/GPU/TPCFastTransformation/SplineUtil.h index c4c695c2b3636..b2226eb8e383a 100644 --- a/GPU/TPCFastTransformation/SplineUtil.h +++ b/GPU/TPCFastTransformation/SplineUtil.h @@ -30,7 +30,7 @@ class SplineUtil public: /// Calculate a Spline specialization number depending on nXdim, nYdim /// - static constexpr int getSpec(int nXdim, int nYdim) + static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim) { // List of the Spline class specializations: // @@ -55,59 +55,59 @@ class SplineUtil /// Spline1D & Spline2D specialization number depending on nYdim /// - static constexpr int getSpec(int nYdim) + static constexpr int32_t getSpec(int32_t nYdim) { return getSpec(1, nYdim); } /// abs() as a constexpr method, to make the GPU compiler happy - static constexpr int abs(int v) { return (v >= 0) ? v : -v; } + static constexpr int32_t abs(int32_t v) { return (v >= 0) ? v : -v; } - /// class lets one to switch between constexpr int ValTrueT and int mValFalse, depending on the ConditionT - template + /// class lets one to switch between constexpr int32_t ValTrueT and int32_t mValFalse, depending on the ConditionT + template class Switch; /// An expression - /// const auto tmp = getNdim(int Ndim); + /// const auto tmp = getNdim(int32_t Ndim); /// tmp.get(); /// returns either a constexpr integer NdimT, or an integer Ndim, depending on the (NdimT>0) value /// (a temporary variable tmp is needed to make the GPU compiler happy) /// - template - GPUd() static Switch<(NdimT > 0), NdimT> getNdim(int Ndim) + template + GPUd() static Switch<(NdimT > 0), NdimT> getNdim(int32_t Ndim) { return Switch<(NdimT > 0), NdimT>(Ndim); } /// An expression - /// const auto tmp = getMaxNdim(int Ndim); + /// const auto tmp = getMaxNdim(int32_t Ndim); /// tmp.get(); /// returns either a constexpr integer abs(NdimT), or an integer Ndim, depending on the (NdimT!=0) value /// - template - GPUd() static Switch<(NdimT != 0), abs(NdimT)> getMaxNdim(int Ndim) + template + GPUd() static Switch<(NdimT != 0), abs(NdimT)> getMaxNdim(int32_t Ndim) { return Switch<(NdimT != 0), abs(NdimT)>(Ndim); } }; -template +template class SplineUtil::Switch { public: - GPUd() Switch(int /*valFalse*/) {} - GPUd() static constexpr int get() { return ValTrueT; } + GPUd() Switch(int32_t /*valFalse*/) {} + GPUd() static constexpr int32_t get() { return ValTrueT; } }; -template +template class SplineUtil::Switch { public: - GPUd() Switch(int valFalse) : mValFalse(valFalse) {} - GPUd() int get() const { return mValFalse; } + GPUd() Switch(int32_t valFalse) : mValFalse(valFalse) {} + GPUd() int32_t get() const { return mValFalse; } private: - int mValFalse; + int32_t mValFalse; }; } // namespace gpu diff --git a/GPU/TPCFastTransformation/SymMatrixSolver.cxx b/GPU/TPCFastTransformation/SymMatrixSolver.cxx index 2166012c88b68..1991dd76e7ad0 100644 --- a/GPU/TPCFastTransformation/SymMatrixSolver.cxx +++ b/GPU/TPCFastTransformation/SymMatrixSolver.cxx @@ -32,32 +32,32 @@ ClassImp(GPUCA_NAMESPACE::gpu::SymMatrixSolver); void SymMatrixSolver::solve() { // Upper Triangulization - for (int i = 0; i < mN; i++) { + for (int32_t i = 0; i < mN; i++) { double* rowI = &mA[i * mShift]; double* rowIb = &mA[i * mShift + mN]; double c = (fabs(rowI[i]) > 1.e-10) ? 1. / rowI[i] : 0.; double* rowJ = rowI + mShift; - for (int j = i + 1; j < mN; j++, rowJ += mShift) { // row j + for (int32_t j = i + 1; j < mN; j++, rowJ += mShift) { // row j if (rowI[j] != 0.) { double aij = c * rowI[j]; // A[i][j] / A[i][i] - for (int k = j; k < mShift; k++) { + for (int32_t k = j; k < mShift; k++) { rowJ[k] -= aij * rowI[k]; // A[j][k] -= A[i][k]/A[i][i]*A[j][i] } rowI[j] = aij; // A[i][j] /= A[i][i] } } - for (int k = 0; k < mM; k++) { + for (int32_t k = 0; k < mM; k++) { rowIb[k] *= c; } } // Diagonalization - for (int i = mN - 1; i >= 0; i--) { + for (int32_t i = mN - 1; i >= 0; i--) { double* rowIb = &mA[i * mShift + mN]; double* rowJb = rowIb - mShift; - for (int j = i - 1; j >= 0; j--, rowJb -= mShift) { // row j + for (int32_t j = i - 1; j >= 0; j--, rowJb -= mShift) { // row j double aji = mA[j * mShift + i]; if (aji != 0.) { - for (int k = 0; k < mM; k++) { + for (int32_t k = 0; k < mM; k++) { rowJb[k] -= aji * rowIb[k]; } } @@ -67,61 +67,61 @@ void SymMatrixSolver::solve() void SymMatrixSolver::print() { - for (int i = 0; i < mN; i++) { + for (int32_t i = 0; i < mN; i++) { LOG(info) << ""; - for (int j = 0; j < mN; j++) { + for (int32_t j = 0; j < mN; j++) { LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << A(i, j) << " "; } LOG(info) << " | "; - for (int j = 0; j < mM; j++) { + for (int32_t j = 0; j < mM; j++) { LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << B(i, j) << " "; } } LOG(info) << std::setprecision(-1); } -int SymMatrixSolver::test(bool prn) +int32_t SymMatrixSolver::test(bool prn) { - constexpr int n = 30; - constexpr int d = 3; + constexpr int32_t n = 30; + constexpr int32_t d = 3; // std::random_device rd; // Will be used to obtain a seed for the random std::mt19937 gen(1); // Standard mersenne_twister_engine seeded with 1 std::uniform_real_distribution<> uniform(-.999, .999); double maxDiff = 0.; - int nTries = 10000; + int32_t nTries = 10000; auto tmpTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(tmpTime - tmpTime); auto durationMult = duration; - for (int iter = 0; iter < nTries; iter++) { + for (int32_t iter = 0; iter < nTries; iter++) { double x[n][d]; double A[n][n]; { - for (int i = 0; i < n; i++) { - for (int j = 0; j < d; j++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t j = 0; j < d; j++) { x[i][j] = 1. * uniform(gen); } } - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { A[i][i] = fabs(2. + uniform(gen)); } - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n; j++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t j = i + 1; j < n; j++) { A[i][j] = A[i][i] * A[j][j] * uniform(gen); A[j][i] = A[i][j]; } } - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { A[i][i] = A[i][i] * A[i][i]; } if (prn && iter == nTries - 1) { - for (int i = 0; i < n; i++) { + for (int32_t i = 0; i < n; i++) { LOG(info) << ""; - for (int j = 0; j < n; j++) { + for (int32_t j = 0; j < n; j++) { LOG(info) << std::fixed << std::setw(5) << std::setprecision(2) << A[i][j] << " "; } } @@ -130,12 +130,12 @@ int SymMatrixSolver::test(bool prn) } double b[n][d]; auto startMult = std::chrono::high_resolution_clock::now(); - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { b[i][k] = 0.; } - for (int j = 0; j < n; j++) { - for (int k = 0; k < d; k++) { + for (int32_t j = 0; j < n; j++) { + for (int32_t k = 0; k < d; k++) { b[i][k] += x[j][k] * A[i][j]; } } @@ -145,11 +145,11 @@ int SymMatrixSolver::test(bool prn) SymMatrixSolver sym(n, d); - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { sym.B(i, k) = b[i][k]; } - for (int j = i; j < n; j++) { + for (int32_t j = i; j < n; j++) { sym.A(i, j) = A[i][j]; } } @@ -160,8 +160,8 @@ int SymMatrixSolver::test(bool prn) duration += std::chrono::duration_cast(stop - start); double diff = 0.; - for (int i = 0; i < n; i++) { - for (int k = 0; k < d; k++) { + for (int32_t i = 0; i < n; i++) { + for (int32_t k = 0; k < d; k++) { double t = fabs(x[i][k] - sym.B(i, k)); if (diff < t) { diff = t; @@ -175,7 +175,7 @@ int SymMatrixSolver::test(bool prn) // LOG(info) << "\n\n max diff " < 0 && M > 0); mA.resize(mN * mShift, 0.); } /// access to A elements - double& A(int i, int j) + double& A(int32_t i, int32_t j) { auto ij = std::minmax(i, j); assert(ij.first >= 0 && ij.second < mN); @@ -53,7 +53,7 @@ class SymMatrixSolver } /// access to B elements - double& B(int i, int j) + double& B(int32_t i, int32_t j) { assert(i >= 0 && i < mN && j >= 0 && j < mM); return mA[i * mShift + mN + j]; @@ -66,13 +66,13 @@ class SymMatrixSolver void print(); /// Test the class functionality. Returns 1 when ok, 0 when not ok - static int test(bool prn = 0); + static int32_t test(bool prn = 0); private: private: - int mN = 0; - int mM = 0; - int mShift = 0; + int32_t mN = 0; + int32_t mM = 0; + int32_t mShift = 0; std::vector mA; #ifndef GPUCA_ALIROOT_LIB diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.cxx b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.cxx index 912f81c9f98bb..ec32eca959d4f 100644 --- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.cxx +++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.cxx @@ -71,7 +71,7 @@ void TPCFastSpaceChargeCorrection::destroy() mSliceRowInfoPtr = nullptr; mScenarioPtr = nullptr; mTimeStamp = -1; - for (int is = 0; is < 3; is++) { + for (int32_t is = 0; is < 3; is++) { mSplineData[is] = nullptr; mSliceDataSizeBytes[is] = 0; } @@ -84,7 +84,7 @@ void TPCFastSpaceChargeCorrection::relocateBufferPointers(const char* oldBuffer, mSliceRowInfoPtr = FlatObject::relocatePointer(oldBuffer, newBuffer, mSliceRowInfoPtr); mScenarioPtr = FlatObject::relocatePointer(oldBuffer, newBuffer, mScenarioPtr); - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { SplineType& sp = mScenarioPtr[i]; char* newSplineBuf = relocatePointer(oldBuffer, newBuffer, sp.getFlatBufferPtr()); sp.setActualBufferAddress(newSplineBuf); @@ -112,7 +112,7 @@ void TPCFastSpaceChargeCorrection::cloneFromObject(const TPCFastSpaceChargeCorre mTimeStamp = obj.mTimeStamp; - for (int i = 0; i < TPCFastTransformGeo::getNumberOfSlices(); ++i) { + for (int32_t i = 0; i < TPCFastTransformGeo::getNumberOfSlices(); ++i) { mSliceInfo[i] = obj.mSliceInfo[i]; } @@ -164,13 +164,13 @@ void TPCFastSpaceChargeCorrection::setActualBufferAddress(char* actualFlatBuffer size_t scBufferOffset = alignSize(scOffset + scSize, SplineType::getBufferAlignmentBytes()); size_t scBufferSize = 0; - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { SplineType& sp = mScenarioPtr[i]; sp.setActualBufferAddress(mFlatBufferPtr + scBufferOffset + scBufferSize); scBufferSize = alignSize(scBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes()); } size_t bufferSize = scBufferOffset + scBufferSize; - for (int is = 0; is < 3; is++) { + for (int32_t is = 0; is < 3; is++) { size_t sliceDataOffset = alignSize(bufferSize, SplineType::getParameterAlignmentBytes()); mSplineData[is] = reinterpret_cast(mFlatBufferPtr + sliceDataOffset); bufferSize = sliceDataOffset + mSliceDataSizeBytes[is] * mGeo.getNumberOfSlices(); @@ -192,7 +192,7 @@ void TPCFastSpaceChargeCorrection::setFutureBufferAddress(char* futureFlatBuffer mRowInfoPtr = relocatePointer(oldBuffer, newBuffer, mRowInfoPtr); mSliceRowInfoPtr = relocatePointer(oldBuffer, newBuffer, mSliceRowInfoPtr); - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { SplineType& sp = mScenarioPtr[i]; char* newSplineBuf = relocatePointer(oldBuffer, newBuffer, sp.getFlatBufferPtr()); sp.setFutureBufferAddress(newSplineBuf); @@ -214,27 +214,27 @@ void TPCFastSpaceChargeCorrection::print() const LOG(info) << " mSliceDataSizeBytes = " << mSliceDataSizeBytes[0] << " " << mSliceDataSizeBytes[1] << " " << mSliceDataSizeBytes[2]; if (mRowInfoPtr) { LOG(info) << " TPC rows: "; - for (int i = 0; i < mGeo.getNumberOfRows(); i++) { + for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) { RowInfo& r = mRowInfoPtr[i]; LOG(info) << " tpc row " << i << ": splineScenarioID = " << r.splineScenarioID << " dataOffsetBytes = " << r.dataOffsetBytes; } } if (mScenarioPtr) { - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { LOG(info) << " SplineScenario " << i << ": "; mScenarioPtr[i].print(); } } if (mRowInfoPtr && mScenarioPtr && mSliceRowInfoPtr) { LOG(info) << " Spline Data: "; - for (int is = 0; is < mGeo.getNumberOfSlices(); is++) { - for (int ir = 0; ir < mGeo.getNumberOfRows(); ir++) { + for (int32_t is = 0; is < mGeo.getNumberOfSlices(); is++) { + for (int32_t ir = 0; ir < mGeo.getNumberOfRows(); ir++) { LOG(info) << "slice " << is << " row " << ir << ": "; const SplineType& spline = getSpline(is, ir); const float* d = getSplineData(is, ir); - int k = 0; - for (int i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) { - for (int j = 0; j < spline.getGridX2().getNumberOfKnots(); j++, k++) { + int32_t k = 0; + for (int32_t i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) { + for (int32_t j = 0; j < spline.getGridX2().getNumberOfKnots(); j++, k++) { LOG(info) << d[k] << " "; } LOG(info) << ""; @@ -248,7 +248,7 @@ void TPCFastSpaceChargeCorrection::print() const #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) -void TPCFastSpaceChargeCorrection::startConstruction(const TPCFastTransformGeo& geo, int numberOfSplineScenarios) +void TPCFastSpaceChargeCorrection::startConstruction(const TPCFastTransformGeo& geo, int32_t numberOfSplineScenarios) { /// Starts the construction procedure, reserves temporary memory @@ -269,11 +269,11 @@ void TPCFastSpaceChargeCorrection::startConstruction(const TPCFastTransformGeo& assert(mConstructionRowInfos != nullptr); assert(mConstructionScenarios != nullptr); - for (int i = 0; i < mGeo.getNumberOfRows(); i++) { + for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) { mConstructionRowInfos[i].splineScenarioID = -1; } - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { mConstructionScenarios[i].destroy(); } @@ -282,13 +282,13 @@ void TPCFastSpaceChargeCorrection::startConstruction(const TPCFastTransformGeo& mRowInfoPtr = nullptr; mSliceRowInfoPtr = nullptr; mScenarioPtr = nullptr; - for (int s = 0; s < 3; s++) { + for (int32_t s = 0; s < 3; s++) { mSplineData[s] = nullptr; mSliceDataSizeBytes[s] = 0; } } -void TPCFastSpaceChargeCorrection::setRowScenarioID(int iRow, int iScenario) +void TPCFastSpaceChargeCorrection::setRowScenarioID(int32_t iRow, int32_t iScenario) { /// Initializes a TPC row assert(mConstructionMask & ConstructionState::InProgress); @@ -296,12 +296,12 @@ void TPCFastSpaceChargeCorrection::setRowScenarioID(int iRow, int iScenario) RowInfo& row = mConstructionRowInfos[iRow]; row.splineScenarioID = iScenario; - for (int s = 0; s < 3; s++) { + for (int32_t s = 0; s < 3; s++) { row.dataOffsetBytes[s] = 0; } } -void TPCFastSpaceChargeCorrection::setSplineScenario(int scenarioIndex, const SplineType& spline) +void TPCFastSpaceChargeCorrection::setSplineScenario(int32_t scenarioIndex, const SplineType& spline) { /// Sets approximation scenario assert(mConstructionMask & ConstructionState::InProgress); @@ -317,10 +317,10 @@ void TPCFastSpaceChargeCorrection::finishConstruction() assert(mConstructionMask & ConstructionState::InProgress); - for (int i = 0; i < mGeo.getNumberOfRows(); i++) { + for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) { assert(mConstructionRowInfos[i].splineScenarioID >= 0); } - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { assert(mConstructionScenarios[i].isConstructed()); } @@ -339,17 +339,17 @@ void TPCFastSpaceChargeCorrection::finishConstruction() scBufferOffsets[0] = alignSize(scOffset + scSize, SplineType::getBufferAlignmentBytes()); size_t scBufferSize = 0; - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { SplineType& sp = mConstructionScenarios[i]; scBufferOffsets[i] = scBufferOffsets[0] + scBufferSize; scBufferSize = alignSize(scBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes()); } size_t bufferSize = scBufferOffsets[0] + scBufferSize; size_t sliceDataOffset[3]; - for (int is = 0; is < 3; is++) { + for (int32_t is = 0; is < 3; is++) { sliceDataOffset[is] = alignSize(bufferSize, SplineType::getParameterAlignmentBytes()); mSliceDataSizeBytes[is] = 0; - for (int i = 0; i < mGeo.getNumberOfRows(); i++) { + for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) { RowInfo& row = mConstructionRowInfos[i]; SplineType& spline = mConstructionScenarios[row.splineScenarioID]; row.dataOffsetBytes[is] = alignSize(mSliceDataSizeBytes[is], SplineType::getParameterAlignmentBytes()); @@ -362,13 +362,13 @@ void TPCFastSpaceChargeCorrection::finishConstruction() FlatObject::finishConstruction(bufferSize); mRowInfoPtr = reinterpret_cast(mFlatBufferPtr + rowsOffset); - for (int i = 0; i < mGeo.getNumberOfRows(); i++) { + for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) { mRowInfoPtr[i] = mConstructionRowInfos[i]; } mSliceRowInfoPtr = reinterpret_cast(mFlatBufferPtr + sliceRowsOffset); - for (int s = 0; s < mGeo.getNumberOfSlices(); s++) { - for (int r = 0; r < mGeo.getNumberOfRows(); r++) { + for (int32_t s = 0; s < mGeo.getNumberOfSlices(); s++) { + for (int32_t r = 0; r < mGeo.getNumberOfRows(); r++) { mSliceRowInfoPtr[s * mGeo.getNumberOfRows() + r].gridCorrU0 = 0.; mSliceRowInfoPtr[s * mGeo.getNumberOfRows() + r].scaleCorrUtoGrid = 0.; mSliceRowInfoPtr[s * mGeo.getNumberOfRows() + r].scaleCorrVtoGrid = 0.; @@ -377,14 +377,14 @@ void TPCFastSpaceChargeCorrection::finishConstruction() mScenarioPtr = reinterpret_cast(mFlatBufferPtr + scOffset); - for (int i = 0; i < mNumberOfScenarios; i++) { + for (int32_t i = 0; i < mNumberOfScenarios; i++) { SplineType& sp0 = mConstructionScenarios[i]; SplineType& sp1 = mScenarioPtr[i]; new (&sp1) SplineType(); // first, call a constructor sp1.cloneFromObject(sp0, mFlatBufferPtr + scBufferOffsets[i]); } - for (int is = 0; is < 3; is++) { + for (int32_t is = 0; is < 3; is++) { mSplineData[is] = reinterpret_cast(mFlatBufferPtr + sliceDataOffset[is]); } releaseConstructionMemory(); @@ -397,30 +397,30 @@ void TPCFastSpaceChargeCorrection::finishConstruction() GPUd() void TPCFastSpaceChargeCorrection::setNoCorrection() { // initialise all corrections to 0. - for (int slice = 0; slice < mGeo.getNumberOfSlices(); slice++) { + for (int32_t slice = 0; slice < mGeo.getNumberOfSlices(); slice++) { double vLength = (slice < mGeo.getNumberOfSlicesA()) ? mGeo.getTPCzLengthA() : mGeo.getTPCzLengthC(); SliceInfo& sliceInfo = getSliceInfo(slice); sliceInfo.vMax = vLength; - for (int row = 0; row < mGeo.getNumberOfRows(); row++) { + for (int32_t row = 0; row < mGeo.getNumberOfRows(); row++) { const SplineType& spline = getSpline(slice, row); - for (int is = 0; is < 3; is++) { + for (int32_t is = 0; is < 3; is++) { float* data = getSplineData(slice, row, is); - int nPar = spline.getNumberOfParameters(); + int32_t nPar = spline.getNumberOfParameters(); if (is == 1) { nPar = nPar / 3; } if (is == 2) { nPar = nPar * 2 / 3; } - for (int i = 0; i < nPar; i++) { + for (int32_t i = 0; i < nPar; i++) { data[i] = 0.f; } } SliceRowInfo& info = getSliceRowInfo(slice, row); RowActiveArea& area = info.activeArea; - for (int i = 1; i < 5; i++) { + for (int32_t i = 1; i < 5; i++) { area.maxDriftLengthCheb[i] = 0; } area.maxDriftLengthCheb[0] = vLength; @@ -434,14 +434,14 @@ GPUd() void TPCFastSpaceChargeCorrection::setNoCorrection() info.scaleCorrUtoGrid = spline.getGridX1().getUmax() / (area.cuMax - area.cuMin); info.scaleCorrVtoGrid = spline.getGridX2().getUmax() / area.cvMax; } // row - } // slice + } // slice } void TPCFastSpaceChargeCorrection::constructWithNoCorrection(const TPCFastTransformGeo& geo) { - const int nCorrectionScenarios = 1; + const int32_t nCorrectionScenarios = 1; startConstruction(geo, nCorrectionScenarios); - for (int row = 0; row < geo.getNumberOfRows(); row++) { + for (int32_t row = 0; row < geo.getNumberOfRows(); row++) { setRowScenarioID(row, 0); } { @@ -468,13 +468,13 @@ double TPCFastSpaceChargeCorrection::testInverse(bool prn) double maxDtpc[3] = {0, 0, 0}; double maxD = 0; - for (int slice = 0; slice < mGeo.getNumberOfSlices(); slice++) { + for (int32_t slice = 0; slice < mGeo.getNumberOfSlices(); slice++) { if (prn) { LOG(info) << "check inverse transform for slice " << slice; } double vLength = (slice < mGeo.getNumberOfSlicesA()) ? mGeo.getTPCzLengthA() : mGeo.getTPCzLengthC(); double maxDslice[3] = {0, 0, 0}; - for (int row = 0; row < mGeo.getNumberOfRows(); row++) { + for (int32_t row = 0; row < mGeo.getNumberOfRows(); row++) { float u0, u1, v0, v1; mGeo.convScaledUVtoUV(slice, row, 0., 0., u0, v0); mGeo.convScaledUVtoUV(slice, row, 1., 1., u1, v1); @@ -497,7 +497,7 @@ double TPCFastSpaceChargeCorrection::testInverse(bool prn) getCorrectionInvCorrectedX(slice, row, cu, cv, nx); getCorrectionInvUV(slice, row, cu, cv, nu, nv); double d[3] = {nx - cx, nu - u, nv - v}; - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { if (fabs(d[i]) > fabs(maxDrow[i])) { maxDrow[i] = d[i]; } @@ -515,7 +515,7 @@ double TPCFastSpaceChargeCorrection::testInverse(bool prn) LOG(info) << "slice " << slice << " row " << row << " dx " << maxDrow[0] << " du " << maxDrow[1] << " dv " << maxDrow[2]; } - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { if (fabs(maxDslice[i]) < fabs(maxDrow[i])) { maxDslice[i] = maxDrow[i]; } diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h index dc6c737b3c430..8fec1be5c459a 100644 --- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h +++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h @@ -43,7 +43,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject /// \brief The struct contains necessary info for TPC padrow /// struct RowInfo { - int splineScenarioID{0}; ///< scenario index (which of Spline2D splines to use) + int32_t splineScenarioID{0}; ///< scenario index (which of Spline2D splines to use) size_t dataOffsetBytes[3]{0}; ///< offset for the spline data withing a TPC slice #ifndef GPUCA_ALIROOT_LIB ClassDefNV(RowInfo, 1); @@ -121,13 +121,13 @@ class TPCFastSpaceChargeCorrection : public FlatObject /// _______________ Construction interface ________________________ /// Starts the construction procedure, reserves temporary memory - void startConstruction(const TPCFastTransformGeo& geo, int numberOfSplineScenarios); + void startConstruction(const TPCFastTransformGeo& geo, int32_t numberOfSplineScenarios); /// Initializes a TPC row - void setRowScenarioID(int iRow, int iScenario); + void setRowScenarioID(int32_t iRow, int32_t iScenario); /// Sets approximation scenario - void setSplineScenario(int scenarioIndex, const SplineType& spline); + void setSplineScenario(int32_t scenarioIndex, const SplineType& spline); /// Finishes construction: puts everything to the flat buffer, releases temporary memory void finishConstruction(); @@ -140,59 +140,59 @@ class TPCFastSpaceChargeCorrection : public FlatObject GPUd() void setNoCorrection(); /// Sets the time stamp of the current calibaration - GPUd() void setTimeStamp(long v) { mTimeStamp = v; } + GPUd() void setTimeStamp(int64_t v) { mTimeStamp = v; } /// Set safety marging for the interpolation around the TPC row. /// Outside of this area the interpolation returns the boundary values. GPUd() void setInterpolationSafetyMargin(float val) { fInterpolationSafetyMargin = val; } /// Gives const pointer to a spline - GPUd() const SplineType& getSpline(int slice, int row) const; + GPUd() const SplineType& getSpline(int32_t slice, int32_t row) const; /// Gives pointer to a spline - GPUd() SplineType& getSpline(int slice, int row); + GPUd() SplineType& getSpline(int32_t slice, int32_t row); /// Gives pointer to spline data - GPUd() float* getSplineData(int slice, int row, int iSpline = 0); + GPUd() float* getSplineData(int32_t slice, int32_t row, int32_t iSpline = 0); /// Gives pointer to spline data - GPUd() const float* getSplineData(int slice, int row, int iSpline = 0) const; + GPUd() const float* getSplineData(int32_t slice, int32_t row, int32_t iSpline = 0) const; /// _______________ The main method: cluster correction _______________________ /// - GPUd() int getCorrection(int slice, int row, float u, float v, float& dx, float& du, float& dv) const; + GPUd() int32_t getCorrection(int32_t slice, int32_t row, float u, float v, float& dx, float& du, float& dv) const; /// inverse correction: Corrected U and V -> coorrected X - GPUd() void getCorrectionInvCorrectedX(int slice, int row, float corrU, float corrV, float& corrX) const; + GPUd() void getCorrectionInvCorrectedX(int32_t slice, int32_t row, float corrU, float corrV, float& corrX) const; /// inverse correction: Corrected U and V -> uncorrected U and V - GPUd() void getCorrectionInvUV(int slice, int row, float corrU, float corrV, float& nomU, float& nomV) const; + GPUd() void getCorrectionInvUV(int32_t slice, int32_t row, float corrU, float corrV, float& nomU, float& nomV) const; /// maximal possible drift length of the active area - GPUd() float getMaxDriftLength(int slice, int row, float pad) const; + GPUd() float getMaxDriftLength(int32_t slice, int32_t row, float pad) const; /// maximal possible drift length of the active area - GPUd() float getMaxDriftLength(int slice, int row) const; + GPUd() float getMaxDriftLength(int32_t slice, int32_t row) const; /// maximal possible drift length of the active area - GPUd() float getMaxDriftLength(int slice) const; + GPUd() float getMaxDriftLength(int32_t slice) const; /// _______________ Utilities _______________________________________________ /// shrink u,v coordinats to the TPC row area +/- fkInterpolationSafetyMargin - GPUd() void schrinkUV(int slice, int row, float& u, float& v) const; + GPUd() void schrinkUV(int32_t slice, int32_t row, float& u, float& v) const; /// shrink corrected u,v coordinats to the TPC row area +/- fkInterpolationSafetyMargin - GPUd() void schrinkCorrectedUV(int slice, int row, float& corrU, float& corrV) const; + GPUd() void schrinkCorrectedUV(int32_t slice, int32_t row, float& corrU, float& corrV) const; /// convert u,v to internal grid coordinates - GPUd() void convUVtoGrid(int slice, int row, float u, float v, float& gridU, float& gridV) const; + GPUd() void convUVtoGrid(int32_t slice, int32_t row, float u, float v, float& gridU, float& gridV) const; /// convert u,v to internal grid coordinates - GPUd() void convGridToUV(int slice, int row, float gridU, float gridV, float& u, float& v) const; + GPUd() void convGridToUV(int32_t slice, int32_t row, float gridU, float gridV, float& u, float& v) const; /// convert corrected u,v to internal grid coordinates - GPUd() void convCorrectedUVtoGrid(int slice, int row, float cu, float cv, float& gridU, float& gridV) const; + GPUd() void convCorrectedUVtoGrid(int32_t slice, int32_t row, float cu, float cv, float& gridU, float& gridV) const; /// TPC geometry information GPUd() const TPCFastTransformGeo& getGeometry() const @@ -201,34 +201,34 @@ class TPCFastSpaceChargeCorrection : public FlatObject } /// Gives the time stamp of the current calibaration parameters - long getTimeStamp() const { return mTimeStamp; } + int64_t getTimeStamp() const { return mTimeStamp; } /// Gives the interpolation safety marging around the TPC row. GPUd() float getInterpolationSafetyMargin() const { return fInterpolationSafetyMargin; } /// Gives TPC row info - GPUd() const RowInfo& getRowInfo(int row) const { return mRowInfoPtr[row]; } + GPUd() const RowInfo& getRowInfo(int32_t row) const { return mRowInfoPtr[row]; } /// Gives TPC slice info - GPUd() const SliceInfo& getSliceInfo(int slice) const + GPUd() const SliceInfo& getSliceInfo(int32_t slice) const { return mSliceInfo[slice]; } /// Gives TPC slice info - GPUd() SliceInfo& getSliceInfo(int slice) + GPUd() SliceInfo& getSliceInfo(int32_t slice) { return mSliceInfo[slice]; } /// Gives TPC slice & row info - GPUd() const SliceRowInfo& getSliceRowInfo(int slice, int row) const + GPUd() const SliceRowInfo& getSliceRowInfo(int32_t slice, int32_t row) const { return mSliceRowInfoPtr[mGeo.getNumberOfRows() * slice + row]; } /// Gives TPC slice & row info - GPUd() SliceRowInfo& getSliceRowInfo(int slice, int row) + GPUd() SliceRowInfo& getSliceRowInfo(int32_t slice, int32_t row) { return mSliceRowInfoPtr[mGeo.getNumberOfRows() * slice + row]; } @@ -246,7 +246,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject void releaseConstructionMemory(); /// temporary method with the an way of calculating 2D spline - GPUd() int getCorrectionOld(int slice, int row, float u, float v, float& dx, float& du, float& dv) const; + GPUd() int32_t getCorrectionOld(int32_t slice, int32_t row, float u, float v, float& dx, float& du, float& dv) const; /// _______________ Data members _______________________________________________ @@ -259,7 +259,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject TPCFastTransformGeo mGeo; ///< TPC geometry information - int mNumberOfScenarios; ///< Number of approximation spline scenarios + int32_t mNumberOfScenarios; ///< Number of approximation spline scenarios SliceInfo mSliceInfo[TPCFastTransformGeo::getNumberOfSlices()]; ///< SliceInfo array @@ -269,7 +269,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject /// _______________ Calibration data _______________________________________________ - long mTimeStamp; ///< time stamp of the current calibration + int64_t mTimeStamp; ///< time stamp of the current calibration char* mSplineData[3]; //! (transient!!) pointer to the spline data in the flat buffer @@ -286,35 +286,35 @@ class TPCFastSpaceChargeCorrection : public FlatObject /// Inline implementations of some methods /// ==================================================== -GPUdi() const TPCFastSpaceChargeCorrection::SplineType& TPCFastSpaceChargeCorrection::getSpline(int slice, int row) const +GPUdi() const TPCFastSpaceChargeCorrection::SplineType& TPCFastSpaceChargeCorrection::getSpline(int32_t slice, int32_t row) const { /// Gives const pointer to spline const RowInfo& rowInfo = mRowInfoPtr[row]; return mScenarioPtr[rowInfo.splineScenarioID]; } -GPUdi() TPCFastSpaceChargeCorrection::SplineType& TPCFastSpaceChargeCorrection::getSpline(int slice, int row) +GPUdi() TPCFastSpaceChargeCorrection::SplineType& TPCFastSpaceChargeCorrection::getSpline(int32_t slice, int32_t row) { /// Gives pointer to spline const RowInfo& rowInfo = mRowInfoPtr[row]; return mScenarioPtr[rowInfo.splineScenarioID]; } -GPUdi() float* TPCFastSpaceChargeCorrection::getSplineData(int slice, int row, int iSpline) +GPUdi() float* TPCFastSpaceChargeCorrection::getSplineData(int32_t slice, int32_t row, int32_t iSpline) { /// Gives pointer to spline data const RowInfo& rowInfo = mRowInfoPtr[row]; return reinterpret_cast(mSplineData[iSpline] + mSliceDataSizeBytes[iSpline] * slice + rowInfo.dataOffsetBytes[iSpline]); } -GPUdi() const float* TPCFastSpaceChargeCorrection::getSplineData(int slice, int row, int iSpline) const +GPUdi() const float* TPCFastSpaceChargeCorrection::getSplineData(int32_t slice, int32_t row, int32_t iSpline) const { /// Gives pointer to spline data const RowInfo& rowInfo = mRowInfoPtr[row]; return reinterpret_cast(mSplineData[iSpline] + mSliceDataSizeBytes[iSpline] * slice + rowInfo.dataOffsetBytes[iSpline]); } -GPUdi() void TPCFastSpaceChargeCorrection::schrinkUV(int slice, int row, float& u, float& v) const +GPUdi() void TPCFastSpaceChargeCorrection::schrinkUV(int32_t slice, int32_t row, float& u, float& v) const { /// shrink u,v coordinats to the TPC row area +/- fInterpolationSafetyMargin @@ -337,7 +337,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::schrinkUV(int slice, int row, float& } } -GPUdi() void TPCFastSpaceChargeCorrection::schrinkCorrectedUV(int slice, int row, float& corrU, float& corrV) const +GPUdi() void TPCFastSpaceChargeCorrection::schrinkCorrectedUV(int32_t slice, int32_t row, float& corrU, float& corrV) const { /// shrink corrected u,v coordinats to the TPC row area +/- fInterpolationSafetyMargin @@ -364,7 +364,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::schrinkCorrectedUV(int slice, int row } } -GPUdi() void TPCFastSpaceChargeCorrection::convUVtoGrid(int slice, int row, float u, float v, float& gu, float& gv) const +GPUdi() void TPCFastSpaceChargeCorrection::convUVtoGrid(int32_t slice, int32_t row, float u, float v, float& gu, float& gv) const { // TODO optimise !!! gu = 0.f; @@ -384,7 +384,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::convUVtoGrid(int slice, int row, floa gv *= spline.getGridX2().getUmax(); } -GPUdi() void TPCFastSpaceChargeCorrection::convGridToUV(int slice, int row, float gridU, float gridV, float& u, float& v) const +GPUdi() void TPCFastSpaceChargeCorrection::convGridToUV(int32_t slice, int32_t row, float gridU, float gridV, float& u, float& v) const { // TODO optimise /// convert u,v to internal grid coordinates @@ -397,7 +397,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::convGridToUV(int slice, int row, floa mGeo.convScaledUVtoUV(slice, row, su, sv, u, v); } -GPUdi() void TPCFastSpaceChargeCorrection::convCorrectedUVtoGrid(int slice, int row, float corrU, float corrV, float& gridU, float& gridV) const +GPUdi() void TPCFastSpaceChargeCorrection::convCorrectedUVtoGrid(int32_t slice, int32_t row, float corrU, float corrV, float& gridU, float& gridV) const { schrinkCorrectedUV(slice, row, corrU, corrV); @@ -407,7 +407,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::convCorrectedUVtoGrid(int slice, int gridV = (corrV - sliceRowInfo.gridCorrV0) * sliceRowInfo.scaleCorrVtoGrid; } -GPUdi() int TPCFastSpaceChargeCorrection::getCorrection(int slice, int row, float u, float v, float& dx, float& du, float& dv) const +GPUdi() int32_t TPCFastSpaceChargeCorrection::getCorrection(int32_t slice, int32_t row, float u, float v, float& dx, float& du, float& dv) const { const SplineType& spline = getSpline(slice, row); const float* splineData = getSplineData(slice, row); @@ -424,7 +424,7 @@ GPUdi() int TPCFastSpaceChargeCorrection::getCorrection(int slice, int row, floa return 0; } -GPUdi() int TPCFastSpaceChargeCorrection::getCorrectionOld(int slice, int row, float u, float v, float& dx, float& du, float& dv) const +GPUdi() int32_t TPCFastSpaceChargeCorrection::getCorrectionOld(int32_t slice, int32_t row, float u, float v, float& dx, float& du, float& dv) const { const SplineType& spline = getSpline(slice, row); const float* splineData = getSplineData(slice, row); @@ -442,7 +442,7 @@ GPUdi() int TPCFastSpaceChargeCorrection::getCorrectionOld(int slice, int row, f } GPUdi() void TPCFastSpaceChargeCorrection::getCorrectionInvCorrectedX( - int slice, int row, float corrU, float corrV, float& x) const + int32_t slice, int32_t row, float corrU, float corrV, float& x) const { float gridU, gridV; convCorrectedUVtoGrid(slice, row, corrU, corrV, gridU, gridV); @@ -458,7 +458,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::getCorrectionInvCorrectedX( } GPUdi() void TPCFastSpaceChargeCorrection::getCorrectionInvUV( - int slice, int row, float corrU, float corrV, float& nomU, float& nomV) const + int32_t slice, int32_t row, float corrU, float corrV, float& nomU, float& nomV) const { float gridU, gridV; convCorrectedUVtoGrid(slice, row, corrU, corrV, gridU, gridV); @@ -475,7 +475,7 @@ GPUdi() void TPCFastSpaceChargeCorrection::getCorrectionInvUV( nomV = corrV - duv[1]; } -GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int slice, int row, float pad) const +GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int32_t slice, int32_t row, float pad) const { const RowActiveArea& area = getSliceRowInfo(slice, row).activeArea; const float* c = area.maxDriftLengthCheb; @@ -484,7 +484,7 @@ GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int slice, int row float f0 = 1.f; float f1 = x; x *= 2.f; - for (int i = 2; i < 5; i++) { + for (int32_t i = 2; i < 5; i++) { double f = x * f1 - f0; y += c[i] * f; f0 = f1; @@ -493,12 +493,12 @@ GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int slice, int row return y; } -GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int slice, int row) const +GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int32_t slice, int32_t row) const { return getSliceRowInfo(slice, row).activeArea.vMax; } -GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int slice) const +GPUdi() float TPCFastSpaceChargeCorrection::getMaxDriftLength(int32_t slice) const { return getSliceInfo(slice).vMax; } diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrectionMap.h b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrectionMap.h index 9b93b50fa8d9e..998c810300098 100644 --- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrectionMap.h +++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrectionMap.h @@ -49,7 +49,7 @@ class TPCFastSpaceChargeCorrectionMap /// _____________ Constructors / destructors __________________________ /// Default constructor: creates an empty uninitialized object - TPCFastSpaceChargeCorrectionMap(int nRocs, int nRows) + TPCFastSpaceChargeCorrectionMap(int32_t nRocs, int32_t nRows) { init(nRocs, nRows); } @@ -58,43 +58,43 @@ class TPCFastSpaceChargeCorrectionMap ~TPCFastSpaceChargeCorrectionMap() = default; /// (re-)init the map - void init(int nRocs, int nRows) + void init(int32_t nRocs, int32_t nRows) { mNrocs = nRocs; mNrows = nRows; - int n = mNrocs * mNrows; + int32_t n = mNrocs * mNrows; fDataPoints.resize(n); - for (unsigned int i = 0; i < fDataPoints.size(); ++i) { + for (uint32_t i = 0; i < fDataPoints.size(); ++i) { fDataPoints[i].clear(); } } /// Starts the construction procedure, reserves temporary memory - void addCorrectionPoint(int iRoc, int iRow, + void addCorrectionPoint(int32_t iRoc, int32_t iRow, double y, double z, double dx, double dy, double dz) { - int ind = mNrows * iRoc + iRow; + int32_t ind = mNrows * iRoc + iRow; fDataPoints.at(ind).push_back(CorrectionPoint{y, z, dx, dy, dz}); } - const std::vector& getPoints(int iRoc, int iRow) const + const std::vector& getPoints(int32_t iRoc, int32_t iRow) const { - int ind = mNrows * iRoc + iRow; + int32_t ind = mNrows * iRoc + iRow; return fDataPoints.at(ind); } - int getNrocs() const { return mNrocs; } + int32_t getNrocs() const { return mNrocs; } - int getNrows() const { return mNrows; } + int32_t getNrows() const { return mNrows; } bool isInitialized() const { return mNrocs > 0 && mNrows > 0; } private: /// _______________ Data members _______________________________________________ - int mNrocs{0}; - int mNrows{0}; + int32_t mNrocs{0}; + int32_t mNrows{0}; std::vector> fDataPoints; //! (transient!!) points with space charge correction #ifndef GPUCA_ALIROOT_LIB diff --git a/GPU/TPCFastTransformation/TPCFastTransform.cxx b/GPU/TPCFastTransformation/TPCFastTransform.cxx index 2e6e9a64c457d..eee8527962a6b 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransform.cxx @@ -117,7 +117,7 @@ void TPCFastTransform::startConstruction(const TPCFastSpaceChargeCorrection& cor mCorrection.cloneFromObject(correction, nullptr); } -void TPCFastTransform::setCalibration(long timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ) +void TPCFastTransform::setCalibration(int64_t timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ) { /// Sets all drift calibration parameters and the time stamp /// @@ -167,7 +167,7 @@ void TPCFastTransform::print() const #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) -int TPCFastTransform::writeToFile(std::string outFName, std::string name) +int32_t TPCFastTransform::writeToFile(std::string outFName, std::string name) { /// store to file assert(isConstructed()); @@ -237,7 +237,7 @@ TPCSlowSpaceChargeCorrection::~TPCSlowSpaceChargeCorrection() delete mCorr; } -void TPCSlowSpaceChargeCorrection::getCorrections(const float gx, const float gy, const float gz, const int slice, float& gdxC, float& gdyC, float& gdzC) const +void TPCSlowSpaceChargeCorrection::getCorrections(const float gx, const float gy, const float gz, const int32_t slice, float& gdxC, float& gdyC, float& gdzC) const { const o2::tpc::Side side = (slice < o2::tpc::SECTORSPERSIDE) ? o2::tpc::Side::A : o2::tpc::Side::C; mCorr->getCorrections(gx, gy, gz, side, gdxC, gdyC, gdzC); diff --git a/GPU/TPCFastTransformation/TPCFastTransform.h b/GPU/TPCFastTransformation/TPCFastTransform.h index 5bd30a557f295..80c8a04f849c6 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.h +++ b/GPU/TPCFastTransformation/TPCFastTransform.h @@ -46,14 +46,14 @@ struct TPCSlowSpaceChargeCorrection { ~TPCSlowSpaceChargeCorrection(); /// getting the corrections for global coordinates - void getCorrections(const float gx, const float gy, const float gz, const int slice, float& gdxC, float& gdyC, float& gdzC) const; + void getCorrections(const float gx, const float gy, const float gz, const int32_t slice, float& gdxC, float& gdyC, float& gdzC) const; o2::tpc::SpaceCharge* mCorr{nullptr}; ///< reference space charge corrections #else ~TPCSlowSpaceChargeCorrection() CON_DEFAULT; /// setting dummy corrections for GPU - GPUd() void getCorrections(const float gx, const float gy, const float gz, const int slice, float& gdxC, float& gdyC, float& gdzC) const + GPUd() void getCorrections(const float gx, const float gy, const float gz, const int32_t slice, float& gdxC, float& gdyC, float& gdzC) const { gdxC = 0; gdyC = 0; @@ -73,7 +73,7 @@ struct TPCSlowSpaceChargeCorrection { /// /// The following coordinate systems are used: /// -/// 1. raw coordinate system: TPC row number [int], readout pad number [float], drift time [float] +/// 1. raw coordinate system: TPC row number [int32_t], readout pad number [float], drift time [float] /// /// 2. drift volume coordinate system (x,u,v)[cm]. These are cartesian coordinates: /// x = local x, @@ -158,7 +158,7 @@ class TPCFastTransform : public FlatObject /// /// It must be called once during construction, /// but also may be called afterwards to reset these parameters. - void setCalibration(long timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ); + void setCalibration(int64_t timeStamp, float t0, float vDrift, float vDriftCorrY, float lDriftCorr, float tofCorr, float primVtxZ); /// Set Lumi info void setLumi(float l) { mLumi = l; } @@ -166,7 +166,7 @@ class TPCFastTransform : public FlatObject void setLumiScaleFactor(float s) { mLumiScaleFactor = s; } /// Sets the time stamp of the current calibaration - void setTimeStamp(long v) { mTimeStamp = v; } + void setTimeStamp(int64_t v) { mTimeStamp = v; } /// Gives a reference for external initialization of TPC corrections GPUd() const TPCFastSpaceChargeCorrection& getCorrection() const { return mCorrection; } @@ -182,46 +182,46 @@ class TPCFastTransform : public FlatObject /// Transforms raw TPC coordinates to local XYZ withing a slice /// taking calibration + alignment into account. /// - GPUd() void Transform(int slice, int row, float pad, float time, float& x, float& y, float& z, float vertexTime = 0, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int scaleMode = 0) const; - GPUd() void TransformXYZ(int slice, int row, float& x, float& y, float& z, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int scaleMode = 0) const; + GPUd() void Transform(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float vertexTime = 0, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int32_t scaleMode = 0) const; + GPUd() void TransformXYZ(int32_t slice, int32_t row, float& x, float& y, float& z, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int32_t scaleMode = 0) const; /// Transformation in the time frame - GPUd() void TransformInTimeFrame(int slice, int row, float pad, float time, float& x, float& y, float& z, float maxTimeBin) const; - GPUd() void TransformInTimeFrame(int slice, float time, float& z, float maxTimeBin) const; + GPUd() void TransformInTimeFrame(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float maxTimeBin) const; + GPUd() void TransformInTimeFrame(int32_t slice, float time, float& z, float maxTimeBin) const; /// Inverse transformation - GPUd() void InverseTransformInTimeFrame(int slice, int row, float /*x*/, float y, float z, float& pad, float& time, float maxTimeBin) const; + GPUd() void InverseTransformInTimeFrame(int32_t slice, int32_t row, float /*x*/, float y, float z, float& pad, float& time, float maxTimeBin) const; /// Inverse transformation: Transformed Y and Z -> transformed X - GPUd() void InverseTransformYZtoX(int slice, int row, float y, float z, float& x, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int scaleMode = 0) const; + GPUd() void InverseTransformYZtoX(int32_t slice, int32_t row, float y, float z, float& x, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int32_t scaleMode = 0) const; /// Inverse transformation: Transformed Y and Z -> Y and Z, transformed w/o space charge correction - GPUd() void InverseTransformYZtoNominalYZ(int slice, int row, float y, float z, float& ny, float& nz, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int scaleMode = 0) const; + GPUd() void InverseTransformYZtoNominalYZ(int32_t slice, int32_t row, float y, float z, float& ny, float& nz, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int32_t scaleMode = 0) const; /// Inverse transformation: Transformed X, Y and Z -> X, Y and Z, transformed w/o space charge correction - GPUd() void InverseTransformXYZtoNominalXYZ(int slice, int row, float x, float y, float z, float& nx, float& ny, float& nz, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int scaleMode = 0) const; + GPUd() void InverseTransformXYZtoNominalXYZ(int32_t slice, int32_t row, float x, float y, float z, float& nx, float& ny, float& nz, const TPCFastTransform* ref = nullptr, const TPCFastTransform* ref2 = nullptr, float scale = 0.f, float scale2 = 0.f, int32_t scaleMode = 0) const; /// Ideal transformation with Vdrift only - without calibration - GPUd() void TransformIdeal(int slice, int row, float pad, float time, float& x, float& y, float& z, float vertexTime) const; - GPUd() void TransformIdealZ(int slice, float time, float& z, float vertexTime) const; + GPUd() void TransformIdeal(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float vertexTime) const; + GPUd() void TransformIdealZ(int32_t slice, float time, float& z, float vertexTime) const; - GPUd() void convPadTimeToUV(int slice, int row, float pad, float time, float& u, float& v, float vertexTime) const; - GPUd() void convPadTimeToUVinTimeFrame(int slice, int row, float pad, float time, float& u, float& v, float maxTimeBin) const; - GPUd() void convTimeToVinTimeFrame(int slice, float time, float& v, float maxTimeBin) const; + GPUd() void convPadTimeToUV(int32_t slice, int32_t row, float pad, float time, float& u, float& v, float vertexTime) const; + GPUd() void convPadTimeToUVinTimeFrame(int32_t slice, int32_t row, float pad, float time, float& u, float& v, float maxTimeBin) const; + GPUd() void convTimeToVinTimeFrame(int32_t slice, float time, float& v, float maxTimeBin) const; - GPUd() void convUVtoPadTime(int slice, int row, float u, float v, float& pad, float& time, float vertexTime) const; - GPUd() void convUVtoPadTimeInTimeFrame(int slice, int row, float u, float v, float& pad, float& time, float maxTimeBin) const; + GPUd() void convUVtoPadTime(int32_t slice, int32_t row, float u, float v, float& pad, float& time, float vertexTime) const; + GPUd() void convUVtoPadTimeInTimeFrame(int32_t slice, int32_t row, float u, float v, float& pad, float& time, float maxTimeBin) const; GPUd() void convVtoTime(float v, float& time, float vertexTime) const; - GPUd() float convTimeToZinTimeFrame(int slice, float time, float maxTimeBin) const; - GPUd() float convZtoTimeInTimeFrame(int slice, float z, float maxTimeBin) const; - GPUd() float convDeltaTimeToDeltaZinTimeFrame(int slice, float deltaTime) const; - GPUd() float convDeltaZtoDeltaTimeInTimeFrame(int slice, float deltaZ) const; + GPUd() float convTimeToZinTimeFrame(int32_t slice, float time, float maxTimeBin) const; + GPUd() float convZtoTimeInTimeFrame(int32_t slice, float z, float maxTimeBin) const; + GPUd() float convDeltaTimeToDeltaZinTimeFrame(int32_t slice, float deltaTime) const; + GPUd() float convDeltaZtoDeltaTimeInTimeFrame(int32_t slice, float deltaZ) const; GPUd() float convDeltaZtoDeltaTimeInTimeFrameAbs(float deltaZ) const; - GPUd() float convZOffsetToVertexTime(int slice, float zOffset, float maxTimeBin) const; - GPUd() float convVertexTimeToZOffset(int slice, float vertexTime, float maxTimeBin) const; + GPUd() float convZOffsetToVertexTime(int32_t slice, float zOffset, float maxTimeBin) const; + GPUd() float convVertexTimeToZOffset(int32_t slice, float vertexTime, float maxTimeBin) const; - GPUd() void getTOFcorrection(int slice, int row, float x, float y, float z, float& dz) const; + GPUd() void getTOFcorrection(int32_t slice, int32_t row, float x, float y, float z, float& dz) const; void setApplyCorrectionOn() { mApplyCorrection = 1; } void setApplyCorrectionOff() { mApplyCorrection = 0; } @@ -233,7 +233,7 @@ class TPCFastTransform : public FlatObject GPUd() const TPCFastTransformGeo& getGeometry() const { return mCorrection.getGeometry(); } /// Gives the time stamp of the current calibaration parameters - GPUd() long getTimeStamp() const { return mTimeStamp; } + GPUd() int64_t getTimeStamp() const { return mTimeStamp; } /// Return mVDrift in cm / time bin GPUd() float getVDrift() const { return mVdrift; } @@ -260,17 +260,17 @@ class TPCFastTransform : public FlatObject GPUd() float getLumiScaleFactor() const { return mLumiScaleFactor; } /// maximal possible drift time of the active area - GPUd() float getMaxDriftTime(int slice, int row, float pad) const; + GPUd() float getMaxDriftTime(int32_t slice, int32_t row, float pad) const; /// maximal possible drift time of the active area - GPUd() float getMaxDriftTime(int slice, int row) const; + GPUd() float getMaxDriftTime(int32_t slice, int32_t row) const; /// maximal possible drift time of the active area - GPUd() float getMaxDriftTime(int slice) const; + GPUd() float getMaxDriftTime(int32_t slice) const; #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && !defined(GPUCA_ALIROOT_LIB) - int writeToFile(std::string outFName = "", std::string name = ""); + int32_t writeToFile(std::string outFName = "", std::string name = ""); void rectifyAfterReadingFromFile(); @@ -289,7 +289,7 @@ class TPCFastTransform : public FlatObject private: /// Enumeration of possible initialization states - enum ConstructionExtraState : unsigned int { + enum ConstructionExtraState : uint32_t { CalibrationIsSet = 0x4 ///< the drift calibration is set }; @@ -299,7 +299,7 @@ class TPCFastTransform : public FlatObject /// _______________ Calibration data. See Transform() method ________________________________ - long mTimeStamp; ///< time stamp of the current calibration + int64_t mTimeStamp; ///< time stamp of the current calibration /// Correction of (x,u,v) with irregular splines. /// @@ -339,7 +339,7 @@ class TPCFastTransform : public FlatObject /// Correction of (x,u,v) with tricubic interpolator on a regular grid TPCSlowSpaceChargeCorrection* mCorrectionSlow{nullptr}; ///< reference space charge corrections - GPUd() void TransformInternal(int slice, int row, float& u, float& v, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const; + GPUd() void TransformInternal(int32_t slice, int32_t row, float& u, float& v, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const; #ifndef GPUCA_ALIROOT_LIB ClassDefNV(TPCFastTransform, 3); @@ -350,7 +350,7 @@ class TPCFastTransform : public FlatObject // Inline implementations of some methods // ======================================================================= -GPUdi() void TPCFastTransform::convPadTimeToUV(int slice, int row, float pad, float time, float& u, float& v, float vertexTime) const +GPUdi() void TPCFastTransform::convPadTimeToUV(int32_t slice, int32_t row, float pad, float time, float& u, float& v, float vertexTime) const { bool sideC = (slice >= getGeometry().getNumberOfSlicesA()); @@ -366,7 +366,7 @@ GPUdi() void TPCFastTransform::convPadTimeToUV(int slice, int row, float pad, fl v = (time - mT0 - vertexTime) * (mVdrift + mVdriftCorrY * yLab) + mLdriftCorr; // drift length cm } -GPUdi() void TPCFastTransform::convTimeToVinTimeFrame(int slice, float time, float& v, float maxTimeBin) const +GPUdi() void TPCFastTransform::convTimeToVinTimeFrame(int32_t slice, float time, float& v, float maxTimeBin) const { v = (time - mT0 - maxTimeBin) * mVdrift + mLdriftCorr; // drift length cm if (slice < getGeometry().getNumberOfSlicesA()) { @@ -376,14 +376,14 @@ GPUdi() void TPCFastTransform::convTimeToVinTimeFrame(int slice, float time, flo } } -GPUdi() void TPCFastTransform::convPadTimeToUVinTimeFrame(int slice, int row, float pad, float time, float& u, float& v, float maxTimeBin) const +GPUdi() void TPCFastTransform::convPadTimeToUVinTimeFrame(int32_t slice, int32_t row, float pad, float time, float& u, float& v, float maxTimeBin) const { const TPCFastTransformGeo::RowInfo& rowInfo = getGeometry().getRowInfo(row); u = (pad - 0.5f * rowInfo.maxPad) * rowInfo.padWidth; convTimeToVinTimeFrame(slice, time, v, maxTimeBin); } -GPUdi() float TPCFastTransform::convZOffsetToVertexTime(int slice, float zOffset, float maxTimeBin) const +GPUdi() float TPCFastTransform::convZOffsetToVertexTime(int32_t slice, float zOffset, float maxTimeBin) const { if (slice < getGeometry().getNumberOfSlicesA()) { return maxTimeBin - (getGeometry().getTPCzLengthA() + zOffset) / mVdrift; @@ -392,7 +392,7 @@ GPUdi() float TPCFastTransform::convZOffsetToVertexTime(int slice, float zOffset } } -GPUdi() float TPCFastTransform::convVertexTimeToZOffset(int slice, float vertexTime, float maxTimeBin) const +GPUdi() float TPCFastTransform::convVertexTimeToZOffset(int32_t slice, float vertexTime, float maxTimeBin) const { if (slice < getGeometry().getNumberOfSlicesA()) { return (maxTimeBin - vertexTime) * mVdrift - getGeometry().getTPCzLengthA(); @@ -401,7 +401,7 @@ GPUdi() float TPCFastTransform::convVertexTimeToZOffset(int slice, float vertexT } } -GPUdi() void TPCFastTransform::convUVtoPadTime(int slice, int row, float u, float v, float& pad, float& time, float vertexTime) const +GPUdi() void TPCFastTransform::convUVtoPadTime(int32_t slice, int32_t row, float u, float v, float& pad, float& time, float vertexTime) const { bool sideC = (slice >= getGeometry().getNumberOfSlicesA()); @@ -422,7 +422,7 @@ GPUdi() void TPCFastTransform::convVtoTime(float v, float& time, float vertexTim time = mT0 + vertexTime + (v - mLdriftCorr) / (mVdrift + mVdriftCorrY * yLab); } -GPUdi() void TPCFastTransform::convUVtoPadTimeInTimeFrame(int slice, int row, float u, float v, float& pad, float& time, float maxTimeBin) const +GPUdi() void TPCFastTransform::convUVtoPadTimeInTimeFrame(int32_t slice, int32_t row, float u, float v, float& pad, float& time, float maxTimeBin) const { if (slice < getGeometry().getNumberOfSlicesA()) { v -= getGeometry().getTPCzLengthA(); @@ -434,7 +434,7 @@ GPUdi() void TPCFastTransform::convUVtoPadTimeInTimeFrame(int slice, int row, fl time = mT0 + maxTimeBin + (v - mLdriftCorr) / mVdrift; } -GPUdi() void TPCFastTransform::getTOFcorrection(int slice, int /*row*/, float x, float y, float z, float& dz) const +GPUdi() void TPCFastTransform::getTOFcorrection(int32_t slice, int32_t /*row*/, float x, float y, float z, float& dz) const { // calculate time of flight correction for z coordinate @@ -444,7 +444,7 @@ GPUdi() void TPCFastTransform::getTOFcorrection(int slice, int /*row*/, float x, dz = sideC ? dv : -dv; } -GPUdi() void TPCFastTransform::TransformInternal(int slice, int row, float& u, float& v, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::TransformInternal(int32_t slice, int32_t row, float& u, float& v, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { GPUCA_RTC_SPECIAL_CODE(ref2 = nullptr; scale2 = 0.f;); if (mApplyCorrection) { @@ -583,7 +583,7 @@ GPUdi() void TPCFastTransform::TransformInternal(int slice, int row, float& u, f } } -GPUdi() void TPCFastTransform::TransformXYZ(int slice, int row, float& x, float& y, float& z, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::TransformXYZ(int32_t slice, int32_t row, float& x, float& y, float& z, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { float u, v; getGeometry().convLocalToUV(slice, y, z, u, v); @@ -594,7 +594,7 @@ GPUdi() void TPCFastTransform::TransformXYZ(int slice, int row, float& x, float& z += dzTOF; } -GPUdi() void TPCFastTransform::Transform(int slice, int row, float pad, float time, float& x, float& y, float& z, float vertexTime, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::Transform(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float vertexTime, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { /// _______________ The main method: cluster transformation _______________________ /// @@ -620,14 +620,14 @@ GPUdi() void TPCFastTransform::Transform(int slice, int row, float pad, float ti z += dzTOF; } -GPUdi() void TPCFastTransform::TransformInTimeFrame(int slice, float time, float& z, float maxTimeBin) const +GPUdi() void TPCFastTransform::TransformInTimeFrame(int32_t slice, float time, float& z, float maxTimeBin) const { float v = 0; convTimeToVinTimeFrame(slice, time, v, maxTimeBin); getGeometry().convVtoLocal(slice, v, z); } -GPUdi() void TPCFastTransform::TransformInTimeFrame(int slice, int row, float pad, float time, float& x, float& y, float& z, float maxTimeBin) const +GPUdi() void TPCFastTransform::TransformInTimeFrame(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float maxTimeBin) const { /// _______________ Special cluster transformation for a time frame _______________________ /// @@ -642,7 +642,7 @@ GPUdi() void TPCFastTransform::TransformInTimeFrame(int slice, int row, float pa getGeometry().convUVtoLocal(slice, u, v, y, z); } -GPUdi() void TPCFastTransform::InverseTransformInTimeFrame(int slice, int row, float /*x*/, float y, float z, float& pad, float& time, float maxTimeBin) const +GPUdi() void TPCFastTransform::InverseTransformInTimeFrame(int32_t slice, int32_t row, float /*x*/, float y, float z, float& pad, float& time, float maxTimeBin) const { /// Inverse transformation to TransformInTimeFrame float u = 0, v = 0; @@ -650,7 +650,7 @@ GPUdi() void TPCFastTransform::InverseTransformInTimeFrame(int slice, int row, f convUVtoPadTimeInTimeFrame(slice, row, u, v, pad, time, maxTimeBin); } -GPUdi() void TPCFastTransform::TransformIdealZ(int slice, float time, float& z, float vertexTime) const +GPUdi() void TPCFastTransform::TransformIdealZ(int32_t slice, float time, float& z, float vertexTime) const { /// _______________ The main method: cluster transformation _______________________ /// @@ -663,7 +663,7 @@ GPUdi() void TPCFastTransform::TransformIdealZ(int slice, float time, float& z, getGeometry().convVtoLocal(slice, v, z); } -GPUdi() void TPCFastTransform::TransformIdeal(int slice, int row, float pad, float time, float& x, float& y, float& z, float vertexTime) const +GPUdi() void TPCFastTransform::TransformIdeal(int32_t slice, int32_t row, float pad, float time, float& x, float& y, float& z, float vertexTime) const { /// _______________ The main method: cluster transformation _______________________ /// @@ -681,7 +681,7 @@ GPUdi() void TPCFastTransform::TransformIdeal(int slice, int row, float pad, flo getGeometry().convUVtoLocal(slice, u, v, y, z); } -GPUdi() float TPCFastTransform::convTimeToZinTimeFrame(int slice, float time, float maxTimeBin) const +GPUdi() float TPCFastTransform::convTimeToZinTimeFrame(int32_t slice, float time, float maxTimeBin) const { /// _______________ Special cluster transformation for a time frame _______________________ /// @@ -700,7 +700,7 @@ GPUdi() float TPCFastTransform::convTimeToZinTimeFrame(int slice, float time, fl return z; } -GPUdi() float TPCFastTransform::convZtoTimeInTimeFrame(int slice, float z, float maxTimeBin) const +GPUdi() float TPCFastTransform::convZtoTimeInTimeFrame(int32_t slice, float z, float maxTimeBin) const { /// Inverse transformation of convTimeToZinTimeFrame() float v; @@ -712,7 +712,7 @@ GPUdi() float TPCFastTransform::convZtoTimeInTimeFrame(int slice, float z, float return mT0 + maxTimeBin + (v - mLdriftCorr) / mVdrift; } -GPUdi() float TPCFastTransform::convDeltaTimeToDeltaZinTimeFrame(int slice, float deltaTime) const +GPUdi() float TPCFastTransform::convDeltaTimeToDeltaZinTimeFrame(int32_t slice, float deltaTime) const { float deltaZ = deltaTime * mVdrift; return slice < getGeometry().getNumberOfSlicesA() ? -deltaZ : deltaZ; @@ -723,14 +723,14 @@ GPUdi() float TPCFastTransform::convDeltaZtoDeltaTimeInTimeFrameAbs(float deltaZ return deltaZ / mVdrift; } -GPUdi() float TPCFastTransform::convDeltaZtoDeltaTimeInTimeFrame(int slice, float deltaZ) const +GPUdi() float TPCFastTransform::convDeltaZtoDeltaTimeInTimeFrame(int32_t slice, float deltaZ) const { float deltaT = deltaZ / mVdrift; return slice < getGeometry().getNumberOfSlicesA() ? -deltaT : deltaT; } /* -GPUdi() float TPCFastTransform::getLastCalibratedTimeBin(int slice) const +GPUdi() float TPCFastTransform::getLastCalibratedTimeBin(int32_t slice) const { /// Return a value of the last timebin where correction map is valid float u, v, pad, time; @@ -740,7 +740,7 @@ GPUdi() float TPCFastTransform::getLastCalibratedTimeBin(int slice) const } */ -GPUdi() float TPCFastTransform::getMaxDriftTime(int slice, int row, float pad) const +GPUdi() float TPCFastTransform::getMaxDriftTime(int32_t slice, int32_t row, float pad) const { /// maximal possible drift time of the active area float maxL = mCorrection.getMaxDriftLength(slice, row, pad); @@ -757,7 +757,7 @@ GPUdi() float TPCFastTransform::getMaxDriftTime(int slice, int row, float pad) c return mT0 + (maxL - mLdriftCorr) / (mVdrift + mVdriftCorrY * yLab); } -GPUdi() float TPCFastTransform::getMaxDriftTime(int slice, int row) const +GPUdi() float TPCFastTransform::getMaxDriftTime(int32_t slice, int32_t row) const { /// maximal possible drift time of the active area float maxL = mCorrection.getMaxDriftLength(slice, row); @@ -766,7 +766,7 @@ GPUdi() float TPCFastTransform::getMaxDriftTime(int slice, int row) const return maxTime; } -GPUdi() float TPCFastTransform::getMaxDriftTime(int slice) const +GPUdi() float TPCFastTransform::getMaxDriftTime(int32_t slice) const { /// maximal possible drift time of the active area float maxL = mCorrection.getMaxDriftLength(slice); @@ -775,7 +775,7 @@ GPUdi() float TPCFastTransform::getMaxDriftTime(int slice) const return maxTime; } -GPUdi() void TPCFastTransform::InverseTransformYZtoX(int slice, int row, float y, float z, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::InverseTransformYZtoX(int32_t slice, int32_t row, float y, float z, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { GPUCA_RTC_SPECIAL_CODE(ref2 = nullptr; scale2 = 0.f;); /// Transformation y,z -> x @@ -816,7 +816,7 @@ GPUdi() void TPCFastTransform::InverseTransformYZtoX(int slice, int row, float y }) } -GPUdi() void TPCFastTransform::InverseTransformYZtoNominalYZ(int slice, int row, float y, float z, float& ny, float& nz, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::InverseTransformYZtoNominalYZ(int32_t slice, int32_t row, float y, float z, float& ny, float& nz, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { GPUCA_RTC_SPECIAL_CODE(ref2 = nullptr; scale2 = 0.f;); /// Transformation y,z -> x @@ -866,10 +866,10 @@ GPUdi() void TPCFastTransform::InverseTransformYZtoNominalYZ(int slice, int row, }) } -GPUdi() void TPCFastTransform::InverseTransformXYZtoNominalXYZ(int slice, int row, float x, float y, float z, float& nx, float& ny, float& nz, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int scaleMode) const +GPUdi() void TPCFastTransform::InverseTransformXYZtoNominalXYZ(int32_t slice, int32_t row, float x, float y, float z, float& nx, float& ny, float& nz, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const { /// Inverse transformation: Transformed X, Y and Z -> X, Y and Z, transformed w/o space charge correction - int row2 = row + 1; + int32_t row2 = row + 1; if (row2 >= getGeometry().getNumberOfRows()) { row2 = row - 1; } diff --git a/GPU/TPCFastTransformation/TPCFastTransformGeo.cxx b/GPU/TPCFastTransformation/TPCFastTransformGeo.cxx index 64fae22b96685..b4cfc7e7eb5b6 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformGeo.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransformGeo.cxx @@ -29,7 +29,7 @@ TPCFastTransformGeo::TPCFastTransformGeo() { // Default Constructor: creates an empty uninitialized object double dAlpha = 2. * M_PI / (NumberOfSlicesA); - for (int i = 0; i < NumberOfSlices; i++) { + for (int32_t i = 0; i < NumberOfSlices; i++) { SliceInfo& s = mSliceInfos[i]; double alpha = dAlpha * (i + 0.5); s.sinAlpha = sin(alpha); @@ -37,12 +37,12 @@ TPCFastTransformGeo::TPCFastTransformGeo() } mSliceInfos[NumberOfSlices] = SliceInfo{0.f, 0.f}; - for (int i = 0; i < MaxNumberOfRows + 1; i++) { + for (int32_t i = 0; i < MaxNumberOfRows + 1; i++) { mRowInfos[i] = RowInfo{0.f, -1, 0.f, 0.f, 0.f, 0.f}; } } -void TPCFastTransformGeo::startConstruction(int numberOfRows) +void TPCFastTransformGeo::startConstruction(int32_t numberOfRows) { /// Starts the construction procedure @@ -59,7 +59,7 @@ void TPCFastTransformGeo::startConstruction(int numberOfRows) mScaleSVtoVsideA = 0.f; mScaleSVtoVsideC = 0.f; - for (int i = 0; i < MaxNumberOfRows; i++) { + for (int32_t i = 0; i < MaxNumberOfRows; i++) { mRowInfos[i] = RowInfo{0.f, -1, 0.f, 0.f, 0.f, 0.f}; } } @@ -90,7 +90,7 @@ void TPCFastTransformGeo::setTPCalignmentZ(float tpcAlignmentZ) mConstructionMask |= ConstructionState::AlignmentIsSet; } -void TPCFastTransformGeo::setTPCrow(int iRow, float x, int nPads, float padWidth) +void TPCFastTransformGeo::setTPCrow(int32_t iRow, float x, int32_t nPads, float padWidth) { /// Initializes a TPC row assert(mConstructionMask & ConstructionState::InProgress); @@ -125,11 +125,11 @@ void TPCFastTransformGeo::finishConstruction() assert(mConstructionMask & ConstructionState::GeometryIsSet); // geometry is set assert(mConstructionMask & ConstructionState::AlignmentIsSet); // alignment is set - for (int i = 0; i < mNumberOfRows; i++) { // all TPC rows are initialized + for (int32_t i = 0; i < mNumberOfRows; i++) { // all TPC rows are initialized assert(getRowInfo(i).maxPad > 0); } - mConstructionMask = (unsigned int)ConstructionState::Constructed; // clear all other construction flags + mConstructionMask = (uint32_t)ConstructionState::Constructed; // clear all other construction flags } void TPCFastTransformGeo::print() const @@ -142,17 +142,17 @@ void TPCFastTransformGeo::print() const LOG(info) << "mTPCzLengthC = " << mTPCzLengthC; LOG(info) << "mTPCalignmentZ = " << mTPCalignmentZ; LOG(info) << "TPC Rows : "; - for (int i = 0; i < mNumberOfRows; i++) { + for (int32_t i = 0; i < mNumberOfRows; i++) { LOG(info) << " tpc row " << i << ": x = " << mRowInfos[i].x << " maxPad = " << mRowInfos[i].maxPad << " padWidth = " << mRowInfos[i].padWidth; } #endif } -int TPCFastTransformGeo::test(int slice, int row, float ly, float lz) const +int32_t TPCFastTransformGeo::test(int32_t slice, int32_t row, float ly, float lz) const { /// Check consistency of the class - int error = 0; + int32_t error = 0; if (!isConstructed()) { error = -1; @@ -213,7 +213,7 @@ int TPCFastTransformGeo::test(int slice, int row, float ly, float lz) const return error; } -int TPCFastTransformGeo::test() const +int32_t TPCFastTransformGeo::test() const { /// Check consistency of the class diff --git a/GPU/TPCFastTransformation/TPCFastTransformGeo.h b/GPU/TPCFastTransformation/TPCFastTransformGeo.h index 9cf57e7140035..ec1915dc4288d 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformGeo.h +++ b/GPU/TPCFastTransformation/TPCFastTransformGeo.h @@ -46,7 +46,7 @@ class TPCFastTransformGeo /// The struct contains necessary info about TPC padrow struct RowInfo { float x; ///< nominal X coordinate of the row [cm] - int maxPad; ///< maximal pad number = n pads - 1 + int32_t maxPad; ///< maximal pad number = n pads - 1 float padWidth; ///< width of pads [cm] float u0; ///< min. u coordinate float scaleUtoSU; ///< scale for su (scaled u ) coordinate @@ -81,10 +81,10 @@ class TPCFastTransformGeo /// _______________ Construction interface ________________________ /// Starts the initialization procedure, reserves temporary memory - void startConstruction(int numberOfRows); + void startConstruction(int32_t numberOfRows); /// Initializes a TPC row - void setTPCrow(int iRow, float x, int nPads, float padWidth); + void setTPCrow(int32_t iRow, float x, int32_t nPads, float padWidth); /// Sets TPC geometry /// @@ -101,24 +101,24 @@ class TPCFastTransformGeo void finishConstruction(); /// Is the object constructed - bool isConstructed() const { return (mConstructionMask == (unsigned int)ConstructionState::Constructed); } + bool isConstructed() const { return (mConstructionMask == (uint32_t)ConstructionState::Constructed); } /// _______________ Getters _________________________________ /// Gives number of TPC slices - GPUd() static constexpr int getNumberOfSlices() { return NumberOfSlices; } + GPUd() static constexpr int32_t getNumberOfSlices() { return NumberOfSlices; } /// Gives number of TPC slices in A side - GPUd() static constexpr int getNumberOfSlicesA() { return NumberOfSlicesA; } + GPUd() static constexpr int32_t getNumberOfSlicesA() { return NumberOfSlicesA; } /// Gives number of TPC rows - GPUd() int getNumberOfRows() const { return mNumberOfRows; } + GPUd() int32_t getNumberOfRows() const { return mNumberOfRows; } /// Gives slice info - GPUd() const SliceInfo& getSliceInfo(int slice) const; + GPUd() const SliceInfo& getSliceInfo(int32_t slice) const; /// Gives TPC row info - GPUd() const RowInfo& getRowInfo(int row) const; + GPUd() const RowInfo& getRowInfo(int32_t row) const; /// Gives Z length of the TPC, side A GPUd() float getTPCzLengthA() const { return mTPCzLengthA; } @@ -127,7 +127,7 @@ class TPCFastTransformGeo GPUd() float getTPCzLengthC() const { return mTPCzLengthC; } /// Gives Z length of the TPC, depending on the slice - GPUd() float getTPCzLength(int slice) const + GPUd() float getTPCzLength(int32_t slice) const { return (slice < NumberOfSlicesA) ? mTPCzLengthA : mTPCzLengthC; @@ -139,53 +139,53 @@ class TPCFastTransformGeo /// _______________ Conversion of coordinate systems __________ /// convert Local -> Global c.s. - GPUd() void convLocalToGlobal(int slice, float lx, float ly, float lz, float& gx, float& gy, float& gz) const; + GPUd() void convLocalToGlobal(int32_t slice, float lx, float ly, float lz, float& gx, float& gy, float& gz) const; /// convert Global->Local c.s. - GPUd() void convGlobalToLocal(int slice, float gx, float gy, float gz, float& lx, float& ly, float& lz) const; + GPUd() void convGlobalToLocal(int32_t slice, float gx, float gy, float gz, float& lx, float& ly, float& lz) const; /// convert UV -> Local c.s. - GPUd() void convUVtoLocal(int slice, float u, float v, float& y, float& z) const; - GPUd() void convVtoLocal(int slice, float v, float& z) const; + GPUd() void convUVtoLocal(int32_t slice, float u, float v, float& y, float& z) const; + GPUd() void convVtoLocal(int32_t slice, float v, float& z) const; /// convert Local-> UV c.s. - GPUd() void convLocalToUV(int slice, float y, float z, float& u, float& v) const; + GPUd() void convLocalToUV(int32_t slice, float y, float z, float& u, float& v) const; /// convert UV -> Scaled UV - GPUd() void convUVtoScaledUV(int slice, int row, float u, float v, float& su, float& sv) const; + GPUd() void convUVtoScaledUV(int32_t slice, int32_t row, float u, float v, float& su, float& sv) const; /// convert Scaled UV -> UV - GPUd() void convScaledUVtoUV(int slice, int row, float su, float sv, float& u, float& v) const; + GPUd() void convScaledUVtoUV(int32_t slice, int32_t row, float su, float sv, float& u, float& v) const; /// convert Scaled UV -> Local c.s. - GPUd() void convScaledUVtoLocal(int slice, int row, float su, float sv, float& ly, float& lz) const; + GPUd() void convScaledUVtoLocal(int32_t slice, int32_t row, float su, float sv, float& ly, float& lz) const; /// convert Pad coordinate -> U - GPUd() float convPadToU(int row, float pad) const; + GPUd() float convPadToU(int32_t row, float pad) const; /// convert U -> Pad coordinate - GPUd() float convUtoPad(int row, float u) const; + GPUd() float convUtoPad(int32_t row, float u) const; /// Print method void print() const; /// Method for testing consistency - int test(int slice, int row, float ly, float lz) const; + int32_t test(int32_t slice, int32_t row, float ly, float lz) const; /// Method for testing consistency - int test() const; + int32_t test() const; private: /// _______________ Data members _______________________________________________ - static constexpr int NumberOfSlices = 36; ///< Number of TPC slices ( slice = inner + outer sector ) - static constexpr int NumberOfSlicesA = NumberOfSlices / 2; ///< Number of TPC slices side A - static constexpr int MaxNumberOfRows = 160; ///< Max Number of TPC rows in a slice + static constexpr int32_t NumberOfSlices = 36; ///< Number of TPC slices ( slice = inner + outer sector ) + static constexpr int32_t NumberOfSlicesA = NumberOfSlices / 2; ///< Number of TPC slices side A + static constexpr int32_t MaxNumberOfRows = 160; ///< Max Number of TPC rows in a slice /// _______________ Construction control _______________________________________________ /// Enumeration of construction states - enum ConstructionState : unsigned int { + enum ConstructionState : uint32_t { NotConstructed = 0x0, ///< the object is not constructed Constructed = 0x1, ///< the object is constructed, temporary memory is released InProgress = 0x2, ///< construction started: temporary memory is reserved @@ -193,11 +193,11 @@ class TPCFastTransformGeo AlignmentIsSet = 0x8 ///< the TPC alignment is set }; - unsigned int mConstructionMask = ConstructionState::NotConstructed; ///< mask for constructed object members, first two bytes are used by this class + uint32_t mConstructionMask = ConstructionState::NotConstructed; ///< mask for constructed object members, first two bytes are used by this class /// _______________ Geometry _______________________________________________ - int mNumberOfRows = 0; ///< Number of TPC rows. It is different for the Run2 and the Run3 setups + int32_t mNumberOfRows = 0; ///< Number of TPC rows. It is different for the Run2 and the Run3 setups float mTPCzLengthA = 0.f; ///< Z length of the TPC, side A float mTPCzLengthC = 0.f; ///< Z length of the TPC, side C float mTPCalignmentZ = 0.f; ///< Global Z shift of the TPC detector. It is applied at the end of the transformation. @@ -218,7 +218,7 @@ class TPCFastTransformGeo // Inline implementations of some methods // ======================================================================= -GPUdi() const TPCFastTransformGeo::SliceInfo& TPCFastTransformGeo::getSliceInfo(int slice) const +GPUdi() const TPCFastTransformGeo::SliceInfo& TPCFastTransformGeo::getSliceInfo(int32_t slice) const { /// Gives slice info if (slice < 0 || slice >= NumberOfSlices) { // return zero object @@ -227,7 +227,7 @@ GPUdi() const TPCFastTransformGeo::SliceInfo& TPCFastTransformGeo::getSliceInfo( return mSliceInfos[slice]; } -GPUdi() const TPCFastTransformGeo::RowInfo& TPCFastTransformGeo::getRowInfo(int row) const +GPUdi() const TPCFastTransformGeo::RowInfo& TPCFastTransformGeo::getRowInfo(int32_t row) const { /// Gives TPC row info if (row < 0 || row >= mNumberOfRows) { // return zero object @@ -236,7 +236,7 @@ GPUdi() const TPCFastTransformGeo::RowInfo& TPCFastTransformGeo::getRowInfo(int return mRowInfos[row]; } -GPUdi() void TPCFastTransformGeo::convLocalToGlobal(int slice, float lx, float ly, float lz, float& gx, float& gy, float& gz) const +GPUdi() void TPCFastTransformGeo::convLocalToGlobal(int32_t slice, float lx, float ly, float lz, float& gx, float& gy, float& gz) const { /// convert Local -> Global c.s. const SliceInfo& sliceInfo = getSliceInfo(slice); @@ -245,7 +245,7 @@ GPUdi() void TPCFastTransformGeo::convLocalToGlobal(int slice, float lx, float l gz = lz; } -GPUdi() void TPCFastTransformGeo::convGlobalToLocal(int slice, float gx, float gy, float gz, float& lx, float& ly, float& lz) const +GPUdi() void TPCFastTransformGeo::convGlobalToLocal(int32_t slice, float gx, float gy, float gz, float& lx, float& ly, float& lz) const { /// convert Global -> Local c.s. const SliceInfo& sliceInfo = getSliceInfo(slice); @@ -254,7 +254,7 @@ GPUdi() void TPCFastTransformGeo::convGlobalToLocal(int slice, float gx, float g lz = gz; } -GPUdi() void TPCFastTransformGeo::convVtoLocal(int slice, float v, float& lz) const +GPUdi() void TPCFastTransformGeo::convVtoLocal(int32_t slice, float v, float& lz) const { /// convert UV -> Local c.s. if (slice < NumberOfSlicesA) { // TPC side A @@ -265,7 +265,7 @@ GPUdi() void TPCFastTransformGeo::convVtoLocal(int slice, float v, float& lz) co lz += mTPCalignmentZ; // global TPC alignment } -GPUdi() void TPCFastTransformGeo::convUVtoLocal(int slice, float u, float v, float& ly, float& lz) const +GPUdi() void TPCFastTransformGeo::convUVtoLocal(int32_t slice, float u, float v, float& ly, float& lz) const { /// convert UV -> Local c.s. if (slice < NumberOfSlicesA) { // TPC side A @@ -278,7 +278,7 @@ GPUdi() void TPCFastTransformGeo::convUVtoLocal(int slice, float u, float v, flo lz += mTPCalignmentZ; // global TPC alignment } -GPUdi() void TPCFastTransformGeo::convLocalToUV(int slice, float ly, float lz, float& u, float& v) const +GPUdi() void TPCFastTransformGeo::convLocalToUV(int32_t slice, float ly, float lz, float& u, float& v) const { /// convert Local-> UV c.s. lz = lz - mTPCalignmentZ; // global TPC alignment @@ -291,7 +291,7 @@ GPUdi() void TPCFastTransformGeo::convLocalToUV(int slice, float ly, float lz, f } } -GPUdi() void TPCFastTransformGeo::convUVtoScaledUV(int slice, int row, float u, float v, float& su, float& sv) const +GPUdi() void TPCFastTransformGeo::convUVtoScaledUV(int32_t slice, int32_t row, float u, float v, float& su, float& sv) const { /// convert UV -> Scaled UV const RowInfo& rowInfo = getRowInfo(row); @@ -303,7 +303,7 @@ GPUdi() void TPCFastTransformGeo::convUVtoScaledUV(int slice, int row, float u, } } -GPUdi() void TPCFastTransformGeo::convScaledUVtoUV(int slice, int row, float su, float sv, float& u, float& v) const +GPUdi() void TPCFastTransformGeo::convScaledUVtoUV(int32_t slice, int32_t row, float su, float sv, float& u, float& v) const { /// convert Scaled UV -> UV const RowInfo& rowInfo = getRowInfo(row); @@ -315,7 +315,7 @@ GPUdi() void TPCFastTransformGeo::convScaledUVtoUV(int slice, int row, float su, } } -GPUdi() void TPCFastTransformGeo::convScaledUVtoLocal(int slice, int row, float su, float sv, float& ly, float& lz) const +GPUdi() void TPCFastTransformGeo::convScaledUVtoLocal(int32_t slice, int32_t row, float su, float sv, float& ly, float& lz) const { /// convert Scaled UV -> Local c.s. float u, v; @@ -323,14 +323,14 @@ GPUdi() void TPCFastTransformGeo::convScaledUVtoLocal(int slice, int row, float convUVtoLocal(slice, u, v, ly, lz); } -GPUdi() float TPCFastTransformGeo::convPadToU(int row, float pad) const +GPUdi() float TPCFastTransformGeo::convPadToU(int32_t row, float pad) const { /// convert Pad coordinate -> U const RowInfo& rowInfo = getRowInfo(row); return (pad - 0.5f * rowInfo.maxPad) * rowInfo.padWidth; } -GPUdi() float TPCFastTransformGeo::convUtoPad(int row, float u) const +GPUdi() float TPCFastTransformGeo::convUtoPad(int32_t row, float u) const { /// convert U -> Pad coordinate const RowInfo& rowInfo = getRowInfo(row); diff --git a/GPU/TPCFastTransformation/TPCFastTransformManager.cxx b/GPU/TPCFastTransformation/TPCFastTransformManager.cxx index 3c573b3288c50..f16a84c96d565 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformManager.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransformManager.cxx @@ -28,9 +28,9 @@ using namespace GPUCA_NAMESPACE::gpu; TPCFastTransformManager::TPCFastTransformManager() : mError(), mOrigTransform(nullptr), fLastTimeBin(0) {} -int TPCFastTransformManager::create(TPCFastTransform& fastTransform, - AliTPCTransform* transform, - Long_t TimeStamp) +int32_t TPCFastTransformManager::create(TPCFastTransform& fastTransform, + AliTPCTransform* transform, + long TimeStamp) { /// Initializes TPCFastTransform object @@ -78,7 +78,7 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, fLastTimeBin = rec->GetLastBin(); - const int nRows = tpcParam->GetNRowLow() + tpcParam->GetNRowUp(); + const int32_t nRows = tpcParam->GetNRowLow() + tpcParam->GetNRowUp(); TPCFastTransformGeo geo; @@ -92,8 +92,8 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, geo.setTPCzLength(tpcZlengthSideA, tpcZlengthSideC); geo.setTPCalignmentZ(-mOrigTransform->GetDeltaZCorrTime()); - for (int row = 0; row < geo.getNumberOfRows(); row++) { - int slice = 0, sector = 0, secrow = 0; + for (int32_t row = 0; row < geo.getNumberOfRows(); row++) { + int32_t slice = 0, sector = 0, secrow = 0; AliHLTTPCGeometry::Slice2Sector(slice, row, sector, secrow); Int_t nPads = tpcParam->GetNPads(sector, secrow); float xRow = tpcParam->GetPadRowRadii(sector, secrow); @@ -110,17 +110,17 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, { // create the correction map - const int nDistortionScenarios = 1; + const int32_t nDistortionScenarios = 1; correction.startConstruction(geo, nDistortionScenarios); TPCFastSpaceChargeCorrection::SplineType spline; spline.recreate(8, 20); - int scenario = 0; + int32_t scenario = 0; correction.setSplineScenario(scenario, spline); - for (int row = 0; row < geo.getNumberOfRows(); row++) { + for (int32_t row = 0; row < geo.getNumberOfRows(); row++) { correction.setRowScenarioID(row, scenario); } @@ -134,7 +134,7 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, // tell the transformation to apply the space charge corrections fastTransform.setApplyCorrectionOn(); - // set some initial calibration values, will be reinitialised later int + // set some initial calibration values, will be reinitialised later int32_t // updateCalibration() const float t0 = 0.; const float vDrift = 0.f; @@ -142,7 +142,7 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, const float ldCorr = 0.; const float tofCorr = 0.; const float primVtxZ = 0.; - const long initTimeStamp = -1; + const int64_t initTimeStamp = -1; fastTransform.setCalibration(initTimeStamp, t0, vDrift, vdCorrY, ldCorr, tofCorr, primVtxZ); @@ -152,12 +152,12 @@ int TPCFastTransformManager::create(TPCFastTransform& fastTransform, return updateCalibration(fastTransform, TimeStamp); } -int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, - Long_t TimeStamp) +int32_t TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, + long TimeStamp) { // Update the calibration with the new time stamp - Long_t lastTS = fastTransform.getTimeStamp(); + long lastTS = fastTransform.getTimeStamp(); // deinitialize @@ -219,7 +219,7 @@ int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, // set the current time stamp - mOrigTransform->SetCurrentTimeStamp(static_cast(TimeStamp)); + mOrigTransform->SetCurrentTimeStamp(static_cast(TimeStamp)); fastTransform.setTimeStamp(TimeStamp); // find last calibrated time bin @@ -272,9 +272,9 @@ int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, recoParam->SetUseTOFCorrection(kFALSE); - for (int slice = 0; slice < geo.getNumberOfSlices(); slice++) { + for (int32_t slice = 0; slice < geo.getNumberOfSlices(); slice++) { - for (int row = 0; row < geo.getNumberOfRows(); row++) { + for (int32_t row = 0; row < geo.getNumberOfRows(); row++) { const TPCFastTransformGeo::RowInfo& rowInfo = geo.getRowInfo(row); @@ -304,9 +304,9 @@ int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, // time-of-flight correction float ox = 0, oy = 0, oz = 0; { - int sector = 0, secrow = 0; + int32_t sector = 0, secrow = 0; AliHLTTPCGeometry::Slice2Sector(slice, row, sector, secrow); - int is[] = {sector}; + int32_t is[] = {sector}; double xx[] = {static_cast(secrow), pad, time}; mOrigTransform->Transform(xx, is, 0, 1); ox = xx[0]; @@ -325,7 +325,7 @@ int TPCFastTransformManager::updateCalibration(TPCFastTransform& fastTransform, helper.approximateFunction(data, 0., 1., 0., 1., F); } // row - } // slice + } // slice // set back the time-of-flight correction; diff --git a/GPU/TPCFastTransformation/TPCFastTransformManager.h b/GPU/TPCFastTransformation/TPCFastTransformManager.h index e13ca67b9a05e..d932c41ca8c18 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformManager.h +++ b/GPU/TPCFastTransformation/TPCFastTransformManager.h @@ -54,10 +54,10 @@ class TPCFastTransformManager /// _______________ Main functionality ________________________ /// Initializes TPCFastTransform object - int create(TPCFastTransform& spline, AliTPCTransform* transform, Long_t TimeStamp); + int32_t create(TPCFastTransform& spline, AliTPCTransform* transform, long TimeStamp); /// Updates the transformation with the new time stamp - Int_t updateCalibration(TPCFastTransform& spline, Long_t TimeStamp); + Int_t updateCalibration(TPCFastTransform& spline, long TimeStamp); /// _______________ Utilities ________________________ @@ -68,14 +68,14 @@ class TPCFastTransformManager private: /// Stores an error message - int storeError(Int_t code, const char* msg); + int32_t storeError(Int_t code, const char* msg); TString mError; ///< error string AliTPCTransform* mOrigTransform; ///< transient - int fLastTimeBin; ///< last calibrated time bin + int32_t fLastTimeBin; ///< last calibrated time bin }; -inline int TPCFastTransformManager::storeError(int code, const char* msg) +inline int32_t TPCFastTransformManager::storeError(int32_t code, const char* msg) { mError = msg; return code; diff --git a/GPU/TPCFastTransformation/TPCFastTransformQA.cxx b/GPU/TPCFastTransformation/TPCFastTransformQA.cxx index 29c7d6de62c0c..cbe9e10060c36 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformQA.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransformQA.cxx @@ -36,7 +36,7 @@ using namespace std; TPCFastTransformQA::TPCFastTransformQA() {} -int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) +int32_t TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) { const char* fileName = "fastTransformQA.root"; @@ -61,7 +61,7 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) } rec->Print(); - int lastTimeBin = rec->GetLastBin(); + int32_t lastTimeBin = rec->GetLastBin(); // measure execution time { @@ -70,8 +70,8 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) double sum1 = 0; for (Int_t iSec = 0; iSec < 1; iSec++) { LOG(info) << "Measure original transformation time for TPC sector " << iSec << " .."; - int nRows = tpcParam->GetNRow(iSec); - for (int iRow = 0; iRow < nRows; iRow++) { + int32_t nRows = tpcParam->GetNRow(iSec); + for (int32_t iRow = 0; iRow < nRows; iRow++) { Int_t nPads = tpcParam->GetNPads(iSec, iRow); for (float pad = 0.5; pad < nPads; pad += 1.) { for (float time = 0; time < lastTimeBin; time++) { @@ -91,10 +91,10 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) double sum2 = 0; for (Int_t iSec = 0; iSec < 1; iSec++) { LOG(info) << "Measure fast transformation time for TPC sector " << iSec << " .."; - int nRows = tpcParam->GetNRow(iSec); - for (int iRow = 0; iRow < nRows; iRow++) { + int32_t nRows = tpcParam->GetNRow(iSec); + for (int32_t iRow = 0; iRow < nRows; iRow++) { Int_t nPads = tpcParam->GetNPads(iSec, iRow); - int slice = 0, slicerow = 0; + int32_t slice = 0, slicerow = 0; AliHLTTPCGeometry::Sector2Slice(slice, slicerow, iSec, iRow); for (float pad = 0.5; pad < nPads; pad += 1.) { for (float time = 0; time < lastTimeBin; time++) { @@ -114,7 +114,7 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) LOG(info) << "Fast Transformation speedup: " << 1. * timer1.RealTime() / timer2.RealTime() * nCalls2 / nCalls1; - int size = sizeof(fastTransform) + fastTransform.getFlatBufferSize(); + int32_t size = sizeof(fastTransform) + fastTransform.getFlatBufferSize(); LOG(info) << "Fast Transformation memory usage: " << size / 1000. / 1000. << " MB"; LOG(info) << "ignore this " << sum1 << " " << sum2; } @@ -128,11 +128,11 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) TNtuple* nt = new TNtuple("fastTransformQA", "fastTransformQA", "sec:row:pad:time:x:y:z:fx:fy:fz"); for (Int_t iSec = 0; iSec < 1; iSec++) { - int nRows = tpcParam->GetNRow(iSec); - for (int iRow = 0; iRow < nRows; iRow++) { + int32_t nRows = tpcParam->GetNRow(iSec); + for (int32_t iRow = 0; iRow < nRows; iRow++) { LOG(info) << "Write fastTransform QA for TPC sector " << iSec << ", row " << iRow << " .."; Int_t nPads = tpcParam->GetNPads(iSec, iRow); - int slice = 0, slicerow = 0; + int32_t slice = 0, slicerow = 0; AliHLTTPCGeometry::Sector2Slice(slice, slicerow, iSec, iRow); for (float pad = 0.5; pad < nPads; pad += 1.) { for (float time = 0; time < lastTimeBin; time++) { @@ -154,7 +154,7 @@ int TPCFastTransformQA::doQA(const TPCFastTransform& fastTransform) return 0; } -int TPCFastTransformQA::doQA(Long_t TimeStamp) +int32_t TPCFastTransformQA::doQA(long TimeStamp) { TPCFastTransform fastTransform; TPCFastTransformManager man; diff --git a/GPU/TPCFastTransformation/TPCFastTransformQA.h b/GPU/TPCFastTransformation/TPCFastTransformQA.h index 30fd762278ef7..f27f9be04efb9 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformQA.h +++ b/GPU/TPCFastTransformation/TPCFastTransformQA.h @@ -57,18 +57,18 @@ class TPCFastTransformQA /// _______________ Main functionality ________________________ /// create fast transformation and perform a quality check - int doQA(Long_t TimeStamp); + int32_t doQA(long TimeStamp); /// create perform quality check - int doQA(const TPCFastTransform& fastTransform); + int32_t doQA(const TPCFastTransform& fastTransform); private: /// Stores an error message - int storeError(Int_t code, const char* msg); + int32_t storeError(Int_t code, const char* msg); TString mError; ///< error string }; -inline int TPCFastTransformQA::storeError(int code, const char* msg) +inline int32_t TPCFastTransformQA::storeError(int32_t code, const char* msg) { mError = msg; LOG(info) << msg; diff --git a/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C b/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C index 7d5915b7a6237..3af3be7760ecf 100644 --- a/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C +++ b/GPU/TPCFastTransformation/alirootMacro/createTPCFastTransform.C @@ -32,7 +32,7 @@ using namespace std; using namespace GPUCA_NAMESPACE::gpu; -int createTPCFastTransform(TPCFastTransform& fastTransform) +int32_t createTPCFastTransform(TPCFastTransform& fastTransform) { AliTPCcalibDB* tpcCalib = AliTPCcalibDB::Instance(); @@ -41,14 +41,14 @@ int createTPCFastTransform(TPCFastTransform& fastTransform) return -1; } AliTPCTransform* origTransform = tpcCalib->GetTransform(); - unsigned int timeStamp = origTransform->GetCurrentTimeStamp(); + uint32_t timeStamp = origTransform->GetCurrentTimeStamp(); TPCFastTransformManager manager; TStopwatch timer; timer.Start(); - int err = manager.create(fastTransform, origTransform, timeStamp); + int32_t err = manager.create(fastTransform, origTransform, timeStamp); timer.Stop(); diff --git a/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C b/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C index 5f64dac5bef63..e63e045373b11 100644 --- a/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C +++ b/GPU/TPCFastTransformation/alirootMacro/generateTPCDistortionNTupleAliRoot.C @@ -49,7 +49,7 @@ using namespace std; using namespace GPUCA_NAMESPACE::gpu; -int generateTPCDistortionNTupleAliRoot() +int32_t generateTPCDistortionNTupleAliRoot() { AliTPCcalibDB* tpcCalib = AliTPCcalibDB::Instance(); if (!tpcCalib) { @@ -64,12 +64,12 @@ int generateTPCDistortionNTupleAliRoot() return -1; } - unsigned int timeStamp = origTransform->GetCurrentTimeStamp(); + uint32_t timeStamp = origTransform->GetCurrentTimeStamp(); TPCFastTransformManager manager; TPCFastTransform fastTransform; - int err = manager.create(fastTransform, origTransform, timeStamp); + int32_t err = manager.create(fastTransform, origTransform, timeStamp); if (err != 0) { cerr << "Cannot create fast transformation object from AliTPCcalibDB, TPCFastTransformManager returns " << err << endl; @@ -85,19 +85,19 @@ int generateTPCDistortionNTupleAliRoot() TFile* f = new TFile("tpcDistortionNTuple.root", "RECREATE"); TNtuple* nt = new TNtuple("dist", "dist", "slice:row:su:sv:dx:du:dv"); - int nSlices = 1; //fastTransform.getNumberOfSlices(); - //for( int slice=0; slice (x,y,z) without time-of-flight correction float ox = 0, oy = 0, oz = 0; { - int sector = 0, secrow = 0; + int32_t sector = 0, secrow = 0; AliHLTTPCGeometry::Slice2Sector(slice, row, sector, secrow); - int is[] = {sector}; + int32_t is[] = {sector}; double xx[] = {static_cast(secrow), pad, time}; origTransform->Transform(xx, is, 0, 1); ox = xx[0]; diff --git a/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C b/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C index c4fdd733b610f..9ae938f67907c 100644 --- a/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C +++ b/GPU/TPCFastTransformation/alirootMacro/initTPCcalibration.C @@ -48,7 +48,7 @@ using namespace std; -int initTPCcalibration(const Char_t* cdbUri, int runNumber, bool isMC) +int32_t initTPCcalibration(const Char_t* cdbUri, int32_t runNumber, bool isMC) { // -------------------------------------- @@ -179,7 +179,7 @@ int initTPCcalibration(const Char_t* cdbUri, int runNumber, bool isMC) recParam = new AliTPCRecoParam(*recParam); - unsigned int timeStamp = grpObj->GetTimeStart(); + uint32_t timeStamp = grpObj->GetTimeStart(); if (isMC && !recParam->GetUseCorrectionMap()) { timeStamp = 0; @@ -188,7 +188,7 @@ int initTPCcalibration(const Char_t* cdbUri, int runNumber, bool isMC) tpcCalib->GetTransform()->SetCurrentRecoParam(recParam); AliTPCTransform* origTransform = tpcCalib->GetTransform(); - origTransform->SetCurrentTimeStamp(static_cast(timeStamp)); + origTransform->SetCurrentTimeStamp(static_cast(timeStamp)); Double_t bz = AliTracker::GetBz(); cout << "\n\nBz field is set to " << bz << ", time stamp is set to " << timeStamp << endl diff --git a/GPU/TPCFastTransformation/alirootMacro/moveTPCFastTransform.C b/GPU/TPCFastTransformation/alirootMacro/moveTPCFastTransform.C index 542f64a522556..8d34d973210d7 100644 --- a/GPU/TPCFastTransformation/alirootMacro/moveTPCFastTransform.C +++ b/GPU/TPCFastTransformation/alirootMacro/moveTPCFastTransform.C @@ -23,7 +23,7 @@ using namespace std; using namespace GPUCA_NAMESPACE::gpu; -int moveTPCFastTransform() +int32_t moveTPCFastTransform() { // gSystem->Load("libAliTPCFastTransformation"); diff --git a/GPU/TPCFastTransformation/devtools/ChebFitTest.C b/GPU/TPCFastTransformation/devtools/ChebFitTest.C index 0783312554f37..217bec534e6c8 100644 --- a/GPU/TPCFastTransformation/devtools/ChebFitTest.C +++ b/GPU/TPCFastTransformation/devtools/ChebFitTest.C @@ -18,14 +18,14 @@ #endif -const int Fdegree = 4; +const int32_t Fdegree = 4; static double Fcoeff[2 * (Fdegree + 1)]; double F(double x) { double f = Fcoeff[0] / 2; - for (int i = 1; i <= Fdegree; i++) { + for (int32_t i = 1; i <= Fdegree; i++) { f += Fcoeff[2 * i] * TMath::Cos(i * x) + Fcoeff[2 * i + 1] * TMath::Sin(i * x); } @@ -44,23 +44,23 @@ bool ask() return (str != "q" && str != ".q"); } -int ChebFitTest() +int32_t ChebFitTest() { const double xMin = 0.5; const double xMax = M_PI - 0.5; - const int nFitPoints = 10; - const int nCoeff = 10; + const int32_t nFitPoints = 10; + const int32_t nCoeff = 10; using namespace o2::gpu; gRandom->SetSeed(0); - for (int seed = 1;; seed++) { + for (int32_t seed = 1;; seed++) { gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; - for (int i = 0; i < 2 * (Fdegree + 1); i++) { + for (int32_t i = 0; i < 2 * (Fdegree + 1); i++) { Fcoeff[i] = gRandom->Uniform(-1, 1); } @@ -70,7 +70,7 @@ int ChebFitTest() o2::gpu::ChebyshevFit1D cheb1(nCoeff - 1, xMin + 0.5, xMax - 0.5); double dx = (xMax - xMin) / (nFitPoints - 1); - for (int ip = 0; ip < nFitPoints; ip++) { + for (int32_t ip = 0; ip < nFitPoints; ip++) { double x = xMin + ip * dx; double f = F(x); cheb1.addMeasurement(x, f); diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline1D.cxx b/GPU/TPCFastTransformation/devtools/IrregularSpline1D.cxx index 2b2ef10f032c5..3a125628d898c 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline1D.cxx +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline1D.cxx @@ -49,7 +49,7 @@ void IrregularSpline1D::cloneFromObject(const IrregularSpline1D& obj, char* newF mBin2KnotMapOffset = obj.mBin2KnotMapOffset; } -void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], int numberOfAxisBins) +void IrregularSpline1D::construct(int32_t numberOfKnots, const float inputKnots[], int32_t numberOfAxisBins) { /// Constructor. /// Initialises the spline with a grid with numberOfKnots knots in the interval [0,1] @@ -77,16 +77,16 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i numberOfAxisBins = 4; } - std::vector vKnotBins; + std::vector vKnotBins; { // reorganize knots - int lastBin = numberOfAxisBins; // last bin starts with U value 1.f, therefore it is outside of the [0.,1.] interval + int32_t lastBin = numberOfAxisBins; // last bin starts with U value 1.f, therefore it is outside of the [0.,1.] interval vKnotBins.push_back(0); // obligatory knot at 0.0 - for (int i = 0; i < numberOfKnots; ++i) { - int bin = (int)roundf(inputKnots[i] * numberOfAxisBins); + for (int32_t i = 0; i < numberOfKnots; ++i) { + int32_t bin = (int32_t)roundf(inputKnots[i] * numberOfAxisBins); if (bin <= vKnotBins.back() || bin >= lastBin) { continue; // same knot } @@ -98,9 +98,9 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i if (vKnotBins.size() < 5) { // too less knots, make a grid with 5 knots vKnotBins.clear(); vKnotBins.push_back(0); - vKnotBins.push_back((int)roundf(0.25 * numberOfAxisBins)); - vKnotBins.push_back((int)roundf(0.50 * numberOfAxisBins)); - vKnotBins.push_back((int)roundf(0.75 * numberOfAxisBins)); + vKnotBins.push_back((int32_t)roundf(0.25 * numberOfAxisBins)); + vKnotBins.push_back((int32_t)roundf(0.50 * numberOfAxisBins)); + vKnotBins.push_back((int32_t)roundf(0.75 * numberOfAxisBins)); vKnotBins.push_back(lastBin); } } @@ -109,16 +109,16 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i mNumberOfAxisBins = numberOfAxisBins; mBin2KnotMapOffset = mNumberOfKnots * sizeof(IrregularSpline1D::Knot); - FlatObject::finishConstruction(mBin2KnotMapOffset + (numberOfAxisBins + 1) * sizeof(int)); + FlatObject::finishConstruction(mBin2KnotMapOffset + (numberOfAxisBins + 1) * sizeof(int32_t)); IrregularSpline1D::Knot* s = getKnotsNonConst(); - for (int i = 0; i < mNumberOfKnots; i++) { + for (int32_t i = 0; i < mNumberOfKnots; i++) { s[i].u = vKnotBins[i] / ((double)mNumberOfAxisBins); // do division in double } { // values will not be used, we define them for consistency - int i = 0; + int32_t i = 0; double du = (s[i + 1].u - s[i].u); double x3 = (s[i + 2].u - s[i].u) / du; s[i].scale = 1. / du; @@ -128,7 +128,7 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i s[i].scaleR3 = 1. / (x3 * (x3 - 1.)); } - for (int i = 1; i < mNumberOfKnots - 2; i++) { + for (int32_t i = 1; i < mNumberOfKnots - 2; i++) { double du = (s[i + 1].u - s[i].u); double x0 = (s[i - 1].u - s[i].u) / du; double x3 = (s[i + 2].u - s[i].u) / du; @@ -140,7 +140,7 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i } { // values will not be used, we define them for consistency - int i = mNumberOfKnots - 2; + int32_t i = mNumberOfKnots - 2; double du = (s[i + 1].u - s[i].u); double x0 = (s[i - 1].u - s[i].u) / du; s[i].scale = 1. / du; @@ -151,7 +151,7 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i } { // values will not be used, we define them for consistency - int i = mNumberOfKnots - 1; + int32_t i = mNumberOfKnots - 1; s[i].scale = 0; // undefined s[i].scaleL0 = 0; // undefined s[i].scaleL2 = 0; // undefined @@ -161,10 +161,10 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i // Set up map (U bin) -> (knot index) - int* map = getBin2KnotMapNonConst(); + int32_t* map = getBin2KnotMapNonConst(); - int iKnotMin = 1; - int iKnotMax = mNumberOfKnots - 3; + int32_t iKnotMin = 1; + int32_t iKnotMax = mNumberOfKnots - 3; // // With iKnotMin=1, iKnotMax=nKnots-3 we release edge intervals: @@ -176,7 +176,7 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i // Any U from [0,1] is mapped to some knote i, where i-1, i, i+1, and i+2 knots always exist // - for (int iBin = 0, iKnot = iKnotMin; iBin <= mNumberOfAxisBins; iBin++) { + for (int32_t iBin = 0, iKnot = iKnotMin; iBin <= mNumberOfAxisBins; iBin++) { if ((iKnot < iKnotMax) && vKnotBins[iKnot + 1] == iBin) { iKnot = iKnot + 1; } @@ -184,7 +184,7 @@ void IrregularSpline1D::construct(int numberOfKnots, const float inputKnots[], i } } -void IrregularSpline1D::constructRegular(int numberOfKnots) +void IrregularSpline1D::constructRegular(int32_t numberOfKnots) { /// Constructor for a regular spline /// \param numberOfKnots Number of knots @@ -196,7 +196,7 @@ void IrregularSpline1D::constructRegular(int numberOfKnots) std::vector knots(numberOfKnots); double du = 1. / (numberOfKnots - 1.); - for (int i = 1; i < numberOfKnots - 1; i++) { + for (int32_t i = 1; i < numberOfKnots - 1; i++) { knots[i] = i * du; } knots[0] = 0.f; @@ -212,7 +212,7 @@ void IrregularSpline1D::print() const LOG(info) << " mNumberOfAxisBins = " << mNumberOfAxisBins; LOG(info) << " mBin2KnotMapOffset = " << mBin2KnotMapOffset; LOG(info) << " knots: "; - for (int i = 0; i < mNumberOfKnots; i++) { + for (int32_t i = 0; i < mNumberOfKnots; i++) { LOG(info) << getKnot(i).u << " "; } LOG(info); diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline1D.h b/GPU/TPCFastTransformation/devtools/IrregularSpline1D.h index 56e45dd44321c..e15aa4b701002 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline1D.h +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline1D.h @@ -57,7 +57,7 @@ namespace gpu /// Therefore one can use the same class for different F functions. /// The function values {F0,..Fn} have to be provided by user for each call. /// -/// The class performs a fast search of a spline interval: (float U ) -> [int iKnot, int iKnot+1 ). +/// The class performs a fast search of a spline interval: (float U ) -> [int32_t iKnot, int32_t iKnot+1 ). /// For that purpose, initial U coordinates of the knots are rounded to the closest i*1./nAxisBins values. /// /// The minimal number of knots is 5, the minimal number of axis bins is 4 @@ -97,7 +97,7 @@ namespace gpu /// /// Example of creating a spline: /// -/// const int nKnots=5; +/// const int32_t nKnots=5; /// float knots[nKnots] = {0., 0.25, 0.5, 0.7, 1.}; /// IrregularSpline1D spline; /// spline.construct(nKnots, knots, 4); @@ -181,10 +181,10 @@ class IrregularSpline1D : public FlatObject /// an appropriate [knot(i),knot(i+1)] interval. /// The knot positions have a "granularity" of 1./numberOfAxisBins /// - void construct(int numberOfKnots, const float knots[], int numberOfAxisBins); + void construct(int32_t numberOfKnots, const float knots[], int32_t numberOfAxisBins); /// Constructor for a regular spline - void constructRegular(int numberOfKnotsU); + void constructRegular(int32_t numberOfKnotsU); /// _______________ Main functionality ________________________ @@ -205,17 +205,17 @@ class IrregularSpline1D : public FlatObject GPUd() T getSpline(const T correctedData[], float u) const; /// Get number of knots - GPUd() int getNumberOfKnots() const { return mNumberOfKnots; } + GPUd() int32_t getNumberOfKnots() const { return mNumberOfKnots; } /// Get index of associated knot for a given U coordinate. /// /// Note: U values from the first interval are mapped to the second inrerval. /// Values from the last interval are mapped to the previous interval. /// - GPUd() int getKnotIndex(float u) const; + GPUd() int32_t getKnotIndex(float u) const; /// Get i-th knot, no border check performed! - GPUd() const IrregularSpline1D::Knot& getKnot(int i) const { return getKnots()[i]; } + GPUd() const IrregularSpline1D::Knot& getKnot(int32_t i) const { return getKnots()[i]; } /// Get array of knots GPUd() const IrregularSpline1D::Knot* getKnots() const { return reinterpret_cast(mFlatBufferPtr); } @@ -232,10 +232,10 @@ class IrregularSpline1D : public FlatObject /// technical stuff /// Get a map (U axis bin index) -> (corresponding knot index) - GPUd() const int* getBin2KnotMap() const { return reinterpret_cast(mFlatBufferPtr + mBin2KnotMapOffset); } + GPUd() const int32_t* getBin2KnotMap() const { return reinterpret_cast(mFlatBufferPtr + mBin2KnotMapOffset); } /// Get number of axis bins - int getNumberOfAxisBins() const { return mNumberOfAxisBins; } + int32_t getNumberOfAxisBins() const { return mNumberOfAxisBins; } /// Get coefficients for edge correction /// @@ -256,15 +256,15 @@ class IrregularSpline1D : public FlatObject IrregularSpline1D::Knot* getKnotsNonConst() { return reinterpret_cast(mFlatBufferPtr); } /// Non-const accessor to bins->knots map - int* getBin2KnotMapNonConst() { return reinterpret_cast(mFlatBufferPtr + mBin2KnotMapOffset); } + int32_t* getBin2KnotMapNonConst() { return reinterpret_cast(mFlatBufferPtr + mBin2KnotMapOffset); } /// /// ==== Data members ==== /// - int mNumberOfKnots; ///< n knots on the grid - int mNumberOfAxisBins; ///< number of axis bins - unsigned int mBin2KnotMapOffset; ///< pointer to (axis bin) -> (knot) map in mFlatBufferPtr array + int32_t mNumberOfKnots; ///< n knots on the grid + int32_t mNumberOfAxisBins; ///< number of axis bins + uint32_t mBin2KnotMapOffset; ///< pointer to (axis bin) -> (knot) map in mFlatBufferPtr array #ifndef GPUCA_ALIROOT_LIB ClassDefNV(IrregularSpline1D, 1); @@ -310,16 +310,16 @@ template GPUdi() T IrregularSpline1D::getSpline(const T correctedData[], float u) const { /// Get interpolated value for f(u) using data array correctedData[getNumberOfKnots()] with corrected edges - int iknot = getKnotIndex(u); + int32_t iknot = getKnotIndex(u); const IrregularSpline1D::Knot& knot = getKnot(iknot); const T* f = correctedData + iknot - 1; return getSpline(knot, f[0], f[1], f[2], f[3], u); } -GPUdi() int IrregularSpline1D::getKnotIndex(float u) const +GPUdi() int32_t IrregularSpline1D::getKnotIndex(float u) const { /// get i: u is in [knot_i, knot_{i+1}) - int ibin = (int)(u * mNumberOfAxisBins); + int32_t ibin = (int32_t)(u * mNumberOfAxisBins); if (ibin < 0) { ibin = 0; } @@ -396,7 +396,7 @@ GPUdi() void IrregularSpline1D::correctEdges(T* data) const double c0, c1, c2, c3; getEdgeCorrectionCoefficients(s[0].u, s[1].u, s[2].u, s[3].u, c0, c1, c2, c3); data[0] = c0 * data[0] + c1 * data[1] + c2 * data[2] + c3 * data[3]; - int i = mNumberOfKnots - 1; + int32_t i = mNumberOfKnots - 1; getEdgeCorrectionCoefficients(s[i - 0].u, s[i - 1].u, s[i - 2].u, s[i - 3].u, c0, c1, c2, c3); data[i] = c0 * data[i - 0] + c1 * data[i - 1] + c2 * data[i - 2] + c3 * data[i - 3]; } diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C b/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C index 35da74bd7e5a5..a5e2dfc2261eb 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline1DTest.C @@ -22,7 +22,7 @@ #include "TCanvas.h" #include "IrregularSpline1D.h" -const int PolynomDegree = 7; +const int32_t PolynomDegree = 7; double coeff[PolynomDegree + 1]; float F(float u) @@ -30,7 +30,7 @@ float F(float u) u -= 0.5; double uu = 1.; double f = 0; - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { f += coeff[i] * uu; uu *= u; } @@ -39,37 +39,37 @@ float F(float u) typedef double myfloat; -int IrregularSpline1DTest() +int32_t IrregularSpline1DTest() { using namespace GPUCA_NAMESPACE::gpu; std::cout << "Test roundf(): " << std::endl; for (float x = 0.; x <= 1.; x += 0.1) { - std::cout << "roundf(" << x << ") = " << roundf(x) << " " << (int)roundf(x) << std::endl; + std::cout << "roundf(" << x << ") = " << roundf(x) << " " << (int32_t)roundf(x) << std::endl; } std::cout << "Test 5 knots for n bins:" << std::endl; - for (int n = 4; n < 20; n++) { - int bin1 = (int)roundf(.25 * n); - int bin2 = (int)roundf(.50 * n); - int bin3 = (int)roundf(.75 * n); + for (int32_t n = 4; n < 20; n++) { + int32_t bin1 = (int32_t)roundf(.25 * n); + int32_t bin2 = (int32_t)roundf(.50 * n); + int32_t bin3 = (int32_t)roundf(.75 * n); std::cout << n << ": 0 " << bin1 << " " << bin2 << " " << bin3 << " " << n << std::endl; } std::cout << "Test interpolation.." << std::endl; gRandom->SetSeed(0); - unsigned int seed = gRandom->Integer(100000); // 605 + uint32_t seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { coeff[i] = gRandom->Uniform(-1, 1); } - const int initNKnotsU = 10; - int nAxisBinsU = 10; + const int32_t initNKnotsU = 10; + int32_t nAxisBinsU = 10; float du = 1. / (initNKnotsU - 1); @@ -78,7 +78,7 @@ int IrregularSpline1DTest() knotsU[0] = 0; knotsU[initNKnotsU - 1] = 1; - for (int i = 1; i < initNKnotsU - 1; i++) { + for (int32_t i = 1; i < initNKnotsU - 1; i++) { knotsU[i] = i * du + gRandom->Uniform(-du / 3, du / 3); } @@ -86,9 +86,9 @@ int IrregularSpline1DTest() spline.construct(initNKnotsU, knotsU, nAxisBinsU); - int nKnotsTot = spline.getNumberOfKnots(); + int32_t nKnotsTot = spline.getNumberOfKnots(); std::cout << "Knots: initial " << initNKnotsU << ", created " << nKnotsTot << std::endl; - for (int i = 0; i < nKnotsTot; i++) { + for (int32_t i = 0; i < nKnotsTot; i++) { std::cout << "knot " << i << ": " << spline.getKnot(i).u << std::endl; } @@ -97,9 +97,9 @@ int IrregularSpline1DTest() myfloat* data0 = new myfloat[nKnotsTot]; // original data myfloat* data = new myfloat[nKnotsTot]; // corrected data - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); - for (int i = 0; i < gridU.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < gridU.getNumberOfKnots(); i++) { data0[i] = F(gridU.getKnot(i).u); // SG random data0[i] = gRandom->Uniform(-1., 1.); @@ -113,13 +113,13 @@ int IrregularSpline1DTest() TH1F* qaX = new TH1F("qaX", "qaX [um]", 1000, -1000., 1000.); - int iter = 0; + int32_t iter = 0; float stepu = 1.e-4; - int nSteps = (int)(1. / stepu + 1); + int32_t nSteps = (int32_t)(1. / stepu + 1); TNtuple* knots = new TNtuple("knots", "knots", "u:f"); double diff = 0; - for (int i = 0; i < nu; i++) { + for (int32_t i = 0; i < nu; i++) { double u = gridU.getKnot(i).u; double f0 = data0[i]; knots->Fill(u, f0); diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.cxx b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.cxx index d949ed0d501ff..fca4b2da84c2b 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.cxx +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.cxx @@ -81,7 +81,7 @@ void IrregularSpline2D3D::setFutureBufferAddress(char* futureFlatBufferPtr) FlatObject::setFutureBufferAddress(futureFlatBufferPtr); } -void IrregularSpline2D3D::construct(int numberOfKnotsU, const float knotsU[], int numberOfAxisBinsU, int numberOfKnotsV, const float knotsV[], int numberOfAxisBinsV) +void IrregularSpline2D3D::construct(int32_t numberOfKnotsU, const float knotsU[], int32_t numberOfAxisBinsU, int32_t numberOfKnotsV, const float knotsV[], int32_t numberOfAxisBinsV) { /// Constructor /// @@ -117,7 +117,7 @@ void IrregularSpline2D3D::construct(int numberOfKnotsU, const float knotsU[], in mGridV.moveBufferTo(mFlatBufferPtr + vOffset); } -void IrregularSpline2D3D::constructRegular(int numberOfKnotsU, int numberOfKnotsV) +void IrregularSpline2D3D::constructRegular(int32_t numberOfKnotsU, int32_t numberOfKnotsV) { /// Constructor for a regular spline /// \param numberOfKnotsU U axis: Number of knots in knots[] array diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h index 16c1690c635ac..a13884ef6ee02 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h @@ -51,8 +51,8 @@ namespace gpu /// /// Example of creating a spline: /// -/// const int nKnotsU=5; -/// const int nKnotsV=6; +/// const int32_t nKnotsU=5; +/// const int32_t nKnotsV=6; /// float knotsU[nKnotsU] = {0., 0.25, 0.5, 0.7, 1.}; /// float knotsV[nKnotsV] = {0., 0.2, 0.3, 0.45, 0.8, 1.}; /// IrregularSpline2D3D spline(nKnotsU, knotsU, 4, nKnotsV, knotsV, 10 ); @@ -122,10 +122,10 @@ class IrregularSpline2D3D : public FlatObject /// an appropriate [knot(i),knot(i+1)] interval. /// The knot positions have a "granularity" of 1./numberOfAxisBins /// - void construct(int numberOfKnotsU, const float knotsU[], int numberOfAxisBinsU, int numberOfKnotsV, const float knotsV[], int numberOfAxisBinsV); + void construct(int32_t numberOfKnotsU, const float knotsU[], int32_t numberOfAxisBinsU, int32_t numberOfKnotsV, const float knotsV[], int32_t numberOfAxisBinsV); /// Constructor for a regular spline - void constructRegular(int numberOfKnotsU, int numberOfKnotsV); + void constructRegular(int32_t numberOfKnotsU, int32_t numberOfKnotsV); /// _______________ Main functionality ________________________ @@ -146,7 +146,7 @@ class IrregularSpline2D3D : public FlatObject GPUd() void getSplineVec(const float* correctedData, float u, float v, float& x, float& y, float& z) const; /// Get number total of knots: UxV - GPUd() int getNumberOfKnots() const { return mGridU.getNumberOfKnots() * mGridV.getNumberOfKnots(); } + GPUd() int32_t getNumberOfKnots() const { return mGridU.getNumberOfKnots() * mGridV.getNumberOfKnots(); } /// Get 1-D grid for U coordinate GPUd() const IrregularSpline1D& getGridU() const { return mGridU; } @@ -155,10 +155,10 @@ class IrregularSpline2D3D : public FlatObject GPUd() const IrregularSpline1D& getGridV() const { return mGridV; } /// Get 1-D grid for U or V coordinate - GPUd() const IrregularSpline1D& getGrid(int uv) const { return (uv == 0) ? mGridU : mGridV; } + GPUd() const IrregularSpline1D& getGrid(int32_t uv) const { return (uv == 0) ? mGridU : mGridV; } /// Get u,v of i-th knot - GPUd() void getKnotUV(int iKnot, float& u, float& v) const; + GPUd() void getKnotUV(int32_t iKnot, float& u, float& v) const; /// Get size of the mFlatBuffer data size_t getFlatBufferSize() const { return mFlatBufferSize; } @@ -203,14 +203,14 @@ class IrregularSpline2D3D : public FlatObject /// Inline implementations of some methods /// ==================================================== -GPUdi() void IrregularSpline2D3D::getKnotUV(int iKnot, float& u, float& v) const +GPUdi() void IrregularSpline2D3D::getKnotUV(int32_t iKnot, float& u, float& v) const { /// Get u,v of i-th knot const IrregularSpline1D& gridU = getGridU(); const IrregularSpline1D& gridV = getGridV(); - int nu = gridU.getNumberOfKnots(); - int iv = iKnot / nu; - int iu = iKnot % nu; + int32_t nu = gridU.getNumberOfKnots(); + int32_t iv = iKnot / nu; + int32_t iu = iKnot % nu; u = gridU.getKnot(iu).u; v = gridV.getKnot(iv).u; } @@ -220,68 +220,68 @@ GPUd() void IrregularSpline2D3D::correctEdges(T* data) const { const IrregularSpline1D& gridU = getGridU(); const IrregularSpline1D& gridV = getGridV(); - int nu = gridU.getNumberOfKnots(); - int nv = gridV.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); + int32_t nv = gridV.getNumberOfKnots(); { // left edge of U - int iu = 0; + int32_t iu = 0; const IrregularSpline1D::Knot* s = gridU.getKnots() + iu; double c0, c1, c2, c3; gridU.getEdgeCorrectionCoefficients(s[0].u, s[1].u, s[2].u, s[3].u, c0, c1, c2, c3); - for (int iv = 0; iv < nv; iv++) { + for (int32_t iv = 0; iv < nv; iv++) { T* f0 = data + (nu * (iv) + iu) * 3; T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(c0 * f0[idim] + c1 * f1[idim] + c2 * f2[idim] + c3 * f3[idim]); } } } { // right edge of U - int iu = nu - 4; + int32_t iu = nu - 4; const IrregularSpline1D::Knot* s = gridU.getKnots() + iu; double c0, c1, c2, c3; gridU.getEdgeCorrectionCoefficients(s[3].u, s[2].u, s[1].u, s[0].u, c3, c2, c1, c0); - for (int iv = 0; iv < nv; iv++) { + for (int32_t iv = 0; iv < nv; iv++) { T* f0 = data + (nu * (iv) + iu) * 3; T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(c0 * f0[idim] + c1 * f1[idim] + c2 * f2[idim] + c3 * f3[idim]); } } } { // low edge of V - int iv = 0; + int32_t iv = 0; const IrregularSpline1D::Knot* s = gridV.getKnots() + iv; double c0, c1, c2, c3; gridV.getEdgeCorrectionCoefficients(s[0].u, s[1].u, s[2].u, s[3].u, c0, c1, c2, c3); - for (int iu = 0; iu < nu; iu++) { + for (int32_t iu = 0; iu < nu; iu++) { T* f0 = data + (nu * iv + iu) * 3; T* f1 = f0 + nu * 3; T* f2 = f0 + nu * 6; T* f3 = f0 + nu * 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(c0 * f0[idim] + c1 * f1[idim] + c2 * f2[idim] + c3 * f3[idim]); } } } { // high edge of V - int iv = nv - 4; + int32_t iv = nv - 4; const IrregularSpline1D::Knot* s = gridV.getKnots() + iv; double c0, c1, c2, c3; gridV.getEdgeCorrectionCoefficients(s[3].u, s[2].u, s[1].u, s[0].u, c3, c2, c1, c0); - for (int iu = 0; iu < nu; iu++) { + for (int32_t iu = 0; iu < nu; iu++) { T* f0 = data + (nu * iv + iu) * 3; T* f1 = f0 + nu * 3; T* f2 = f0 + nu * 6; T* f3 = f0 + nu * 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(c0 * f0[idim] + c1 * f1[idim] + c2 * f2[idim] + c3 * f3[idim]); } } @@ -295,9 +295,9 @@ GPUdi() void IrregularSpline2D3D::getSpline(GPUgeneric() const T* correctedData, const IrregularSpline1D& gridU = getGridU(); const IrregularSpline1D& gridV = getGridV(); - int nu = gridU.getNumberOfKnots(); - int iu = gridU.getKnotIndex(u); - int iv = gridV.getKnotIndex(v); + int32_t nu = gridU.getNumberOfKnots(); + int32_t iu = gridU.getKnotIndex(u); + int32_t iv = gridV.getKnotIndex(v); const IrregularSpline1D::Knot& knotU = gridU.getKnot(iu); const IrregularSpline1D::Knot& knotV = gridV.getKnot(iv); @@ -308,7 +308,7 @@ GPUdi() void IrregularSpline2D3D::getSpline(GPUgeneric() const T* correctedData, const T* dataV3 = dataV0 + 9 * nu; T dataV[12]; - for (int i = 0; i < 12; i++) { + for (int32_t i = 0; i < 12; i++) { dataV[i] = gridV.getSpline(knotV, dataV0[i], dataV1[i], dataV2[i], dataV3[i], v); } @@ -318,7 +318,7 @@ GPUdi() void IrregularSpline2D3D::getSpline(GPUgeneric() const T* correctedData, T* dataU3 = dataV + 9; T res[3]; - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { res[i] = gridU.getSpline(knotU, dataU0[i], dataU1[i], dataU2[i], dataU3[i], u); } x = res[0]; @@ -334,9 +334,9 @@ GPUdi() void IrregularSpline2D3D::getSplineVec(const float* correctedData, float #if !defined(__CINT__) && !defined(__ROOTCINT__) && !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC) && defined(__cplusplus) && __cplusplus >= 201703L const IrregularSpline1D& gridU = getGridU(); const IrregularSpline1D& gridV = getGridV(); - int nu = gridU.getNumberOfKnots(); - int iu = gridU.getKnotIndex(u); - int iv = gridV.getKnotIndex(v); + int32_t nu = gridU.getNumberOfKnots(); + int32_t iu = gridU.getKnotIndex(u); + int32_t iv = gridV.getKnotIndex(v); const IrregularSpline1D::Knot& knotU = gridU.getKnot(iu); const IrregularSpline1D::Knot& knotV = gridV.getKnot(iv); @@ -358,7 +358,7 @@ GPUdi() void IrregularSpline2D3D::getSplineVec(const float* correctedData, float //dataVvec.scatter(dataV, Vc::SimdArray(Vc::IndexesFromZero)); dataVvec.store(dataV, Vc::Unaligned); - for (unsigned int i = 12; i < 9 + V::size(); i++) { // fill not used part of the vector with 0 + for (uint32_t i = 12; i < 9 + V::size(); i++) { // fill not used part of the vector with 0 dataV[i] = 0.f; } // calculate F values at V==v and U == u diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.cxx b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.cxx index c8c6eb8424df6..ffce9376fe60b 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.cxx +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.cxx @@ -34,13 +34,13 @@ IrregularSpline2D3DCalibrator::IrregularSpline2D3DCalibrator() setMaxNKnots(5, 5); } -void IrregularSpline2D3DCalibrator::setRasterSize(int nKnotsU, int nKnotsV) +void IrregularSpline2D3DCalibrator::setRasterSize(int32_t nKnotsU, int32_t nKnotsV) { /// set maximal size of the spline grid - int n[2] = {nKnotsU, nKnotsV}; + int32_t n[2] = {nKnotsU, nKnotsV}; - for (int uv = 0; uv < 2; ++uv) { + for (int32_t uv = 0; uv < 2; ++uv) { if (n[uv] < mMaxNKnots[uv]) { n[uv] = mMaxNKnots[uv]; } @@ -49,14 +49,14 @@ void IrregularSpline2D3DCalibrator::setRasterSize(int nKnotsU, int nKnotsV) mRaster.constructRegular(n[0], n[1]); } -void IrregularSpline2D3DCalibrator::setMaxNKnots(int nKnotsU, int nKnotsV) +void IrregularSpline2D3DCalibrator::setMaxNKnots(int32_t nKnotsU, int32_t nKnotsV) { /// set maximal size of the spline grid mMaxNKnots[0] = nKnotsU; mMaxNKnots[1] = nKnotsV; - for (int uv = 0; uv < 2; ++uv) { + for (int32_t uv = 0; uv < 2; ++uv) { if (mMaxNKnots[uv] < 5) { mMaxNKnots[uv] = 5; } @@ -70,7 +70,7 @@ void IrregularSpline2D3DCalibrator::startCalibration(std::functionuv; + int32_t uv = knot->uv; bool isSpaceUp = 0; @@ -189,8 +189,8 @@ IrregularSpline2D3DCalibrator::Action IrregularSpline2D3DCalibrator::checkAction } // get the area of interest - int regionKnotFirst = knot->rasterKnot; - int regionKnotLast = knot->rasterKnot; + int32_t regionKnotFirst = knot->rasterKnot; + int32_t regionKnotLast = knot->rasterKnot; getRegionOfInfluence(knot, regionKnotFirst, regionKnotLast); // get the current cost @@ -231,15 +231,15 @@ IrregularSpline2D3DCalibrator::Action IrregularSpline2D3DCalibrator::checkAction ret.cost = mMaxDeviation + 1.e10; ret.iter = knot; - int uv = knot->uv; + int32_t uv = knot->uv; if (mSpline.getGrid(uv).getNumberOfKnots() <= 5) { return ret; } // get the area of interest - int regionKnotFirst = knot->rasterKnot; - int regionKnotLast = knot->rasterKnot; + int32_t regionKnotFirst = knot->rasterKnot; + int32_t regionKnotLast = knot->rasterKnot; getRegionOfInfluence(knot, regionKnotFirst, regionKnotLast); @@ -259,14 +259,14 @@ IrregularSpline2D3DCalibrator::Action IrregularSpline2D3DCalibrator::checkAction return ret; } -void IrregularSpline2D3DCalibrator::getRegionOfInfluence(std::list::iterator knot, int& regionKnotFirst, int& regionKnotLast) const +void IrregularSpline2D3DCalibrator::getRegionOfInfluence(std::list::iterator knot, int32_t& regionKnotFirst, int32_t& regionKnotLast) const { - int uv = knot->uv; + int32_t uv = knot->uv; regionKnotFirst = knot->rasterKnot; regionKnotLast = knot->rasterKnot; std::list::iterator next = knot; std::list::iterator prev = knot; - for (int i = 0; i < 3; ++i) { + for (int32_t i = 0; i < 3; ++i) { if (prev != mKnots[uv].begin()) { --prev; regionKnotFirst = prev->rasterKnot; @@ -295,7 +295,7 @@ bool IrregularSpline2D3DCalibrator::doCalibrationStep() bestAction.action = Action::Move::No; bestAction.cost = 1.e10; - for (int uv = 0; uv < 2; ++uv) { + for (int32_t uv = 0; uv < 2; ++uv) { for (std::list::iterator i = mKnots[uv].begin(); i != mKnots[uv].end(); ++i) { Action a = checkActionShift(i); if (a.cost < bestAction.cost) { @@ -322,11 +322,11 @@ bool IrregularSpline2D3DCalibrator::doCalibrationStep() // second, try to remove a knot - //for (int axis = 0; axis < 2; axis++) { + // for (int32_t axis = 0; axis < 2; axis++) { bestAction.action = Action::Move::No; bestAction.cost = mMaxDeviation + 1.e10; - for (int uv = 0; uv < 2; ++uv) { + for (int32_t uv = 0; uv < 2; ++uv) { for (std::list::iterator i = mKnots[uv].begin(); i != mKnots[uv].end(); ++i) { Action a = checkActionRemove(i); @@ -366,21 +366,21 @@ std::unique_ptr IrregularSpline2D3DCalibrator::calibrateSpline(Irregula createCurrentSpline(); spline_uv.cloneFromObject(mSpline, nullptr); std::unique_ptr tmp(new float[mSpline.getNumberOfKnots()]); - for (int i = 0; i < mSpline.getNumberOfKnots(); ++i) { + for (int32_t i = 0; i < mSpline.getNumberOfKnots(); ++i) { tmp[i] = mSplineData[i]; } return tmp; } -double IrregularSpline2D3DCalibrator::getMaxDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int axis0, int knot0) const +double IrregularSpline2D3DCalibrator::getMaxDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int32_t axis0, int32_t knot0) const { - int axis1 = (axis0 == 0) ? 1 : 0; + int32_t axis1 = (axis0 == 0) ? 1 : 0; float u[2]; u[axis0] = mRaster.getGrid(axis0).getKnot(knot0).u; double dMax2 = 0.; - for (int knot1 = 0; knot1 < mRaster.getGrid(axis1).getNumberOfKnots(); ++knot1) { + for (int32_t knot1 = 0; knot1 < mRaster.getGrid(axis1).getNumberOfKnots(); ++knot1) { u[axis1] = mRaster.getGrid(axis1).getKnot(knot1).u; float fx0, fy0, fz0, fx, fy, fz; mRaster.getSplineVec(mRasterData.data(), u[0], u[1], fx0, fy0, fz0); @@ -397,10 +397,10 @@ double IrregularSpline2D3DCalibrator::getMaxDeviationLine(const IrregularSpline2 } double IrregularSpline2D3DCalibrator::getMaxDeviationArea(const IrregularSpline2D3D& spline, const std::vector& data, - int axis, int knotFirst, int knotLast) const + int32_t axis, int32_t knotFirst, int32_t knotLast) const { double dMax = 0.; - for (int knot = knotFirst; knot <= knotLast; ++knot) { + for (int32_t knot = knotFirst; knot <= knotLast; ++knot) { double d = getMaxDeviationLine(spline, data, axis, knot); if (dMax < d) { dMax = d; @@ -409,15 +409,15 @@ double IrregularSpline2D3DCalibrator::getMaxDeviationArea(const IrregularSpline2 return dMax; } -double IrregularSpline2D3DCalibrator::getIntegralDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int axis0, int knot0) const +double IrregularSpline2D3DCalibrator::getIntegralDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int32_t axis0, int32_t knot0) const { - int axis1 = (axis0 == 0) ? 1 : 0; + int32_t axis1 = (axis0 == 0) ? 1 : 0; float u[2]; u[axis0] = mRaster.getGrid(axis0).getKnot(knot0).u; double sum = 0.; - for (int knot1 = 0; knot1 < mRaster.getGrid(axis1).getNumberOfKnots(); ++knot1) { + for (int32_t knot1 = 0; knot1 < mRaster.getGrid(axis1).getNumberOfKnots(); ++knot1) { u[axis1] = mRaster.getGrid(axis1).getKnot(knot1).u; float fx0, fy0, fz0, fx, fy, fz; mRaster.getSplineVec(mRasterData.data(), u[0], u[1], fx0, fy0, fz0); @@ -433,10 +433,10 @@ double IrregularSpline2D3DCalibrator::getIntegralDeviationLine(const IrregularSp } double IrregularSpline2D3DCalibrator::getIntegralDeviationArea(const IrregularSpline2D3D& spline, const std::vector& data, - int axis, int knotFirst, int knotLast) const + int32_t axis, int32_t knotFirst, int32_t knotLast) const { double sum = 0.; - for (int knot = knotFirst; knot <= knotLast; ++knot) { + for (int32_t knot = knotFirst; knot <= knotLast; ++knot) { sum += getIntegralDeviationLine(spline, data, axis, knot); } return sum; diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.h b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.h index 5dfceceb2df99..12696710e0a5b 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.h +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibrator.h @@ -33,8 +33,8 @@ class IrregularSpline2D3DCalibrator { public: struct KnotData { - int uv; // is the knot on U or V coordinate axis - int rasterKnot; // index of the raster knot + int32_t uv; // is the knot on U or V coordinate axis + int32_t rasterKnot; // index of the raster knot }; struct Action { @@ -60,10 +60,10 @@ class IrregularSpline2D3DCalibrator ~IrregularSpline2D3DCalibrator() CON_DEFAULT; /// set size of the raster grid - void setRasterSize(int nKnotsU, int nKnotsV); + void setRasterSize(int32_t nKnotsU, int32_t nKnotsV); /// set maximal size of the spline grid - void setMaxNKnots(int nKnotsU, int nKnotsV); + void setMaxNKnots(int32_t nKnotsU, int32_t nKnotsV); /// set maximal tolerated deviation between the spline and the input function void setMaximalDeviation(float maxDeviation) @@ -112,18 +112,18 @@ class IrregularSpline2D3DCalibrator Action checkActionRemove(std::list::iterator& knot); - void getRegionOfInfluence(std::list::iterator knot, int& regionKnotFirst, int& regionKnotLast) const; + void getRegionOfInfluence(std::list::iterator knot, int32_t& regionKnotFirst, int32_t& regionKnotLast) const; - double getMaxDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int axis, int knot) const; + double getMaxDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int32_t axis, int32_t knot) const; double getMaxDeviationArea(const IrregularSpline2D3D& spline, const std::vector& data, - int axis, int knotFirst, int knotLast) const; - double getIntegralDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int axis, int knot) const; + int32_t axis, int32_t knotFirst, int32_t knotLast) const; + double getIntegralDeviationLine(const IrregularSpline2D3D& spline, const std::vector& data, int32_t axis, int32_t knot) const; double getIntegralDeviationArea(const IrregularSpline2D3D& spline, const std::vector& data, - int axis, int knotFirst, int knotLast) const; + int32_t axis, int32_t knotFirst, int32_t knotLast) const; /// Class members - int mMaxNKnots[2] = {5, 5}; ///< max N knots, U / V axis + int32_t mMaxNKnots[2] = {5, 5}; ///< max N knots, U / V axis std::list mKnots[2]; ///< list of knots for U/V axis diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibratorTest.C b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibratorTest.C index a46c3522b9d86..b09c4fb5aed5e 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibratorTest.C +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DCalibratorTest.C @@ -53,16 +53,16 @@ float* splineF_data = 0; void initF() { - const int nKnotsU = 6; - const int nKnotsV = 6; + const int32_t nKnotsU = 6; + const int32_t nKnotsV = 6; float knotsU[nKnotsU]; float knotsV[nKnotsV]; - for (int i = 0; i < nKnotsU; i++) { + for (int32_t i = 0; i < nKnotsU; i++) { knotsU[i] = i / (double)(nKnotsU - 1); } knotsU[0] = 0.; knotsU[nKnotsU - 1] = 1.; - for (int i = 0; i < nKnotsV; i++) { + for (int32_t i = 0; i < nKnotsV; i++) { knotsV[i] = i / (double)(nKnotsV - 1); } knotsV[0] = 0.; @@ -73,13 +73,13 @@ void initF() std::cout << "number of knots: " << splineF.getNumberOfKnots() << std::endl; splineF_data = new float[splineF.getNumberOfKnots() * 3]; - for (int i = 0; i < splineF.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < splineF.getNumberOfKnots(); i++) { splineF_data[3 * i + 0] = gRandom->Uniform(-1., 1.); splineF_data[3 * i + 1] = gRandom->Uniform(-1., 1.); splineF_data[3 * i + 2] = gRandom->Uniform(-1., 1.); } - for (int i = 0; i < splineF.getNumberOfKnots(); i++) { // set Fy=Fz=Fx + for (int32_t i = 0; i < splineF.getNumberOfKnots(); i++) { // set Fy=Fz=Fx splineF_data[3 * i + 1] = splineF_data[3 * i + 0]; splineF_data[3 * i + 2] = splineF_data[3 * i + 0]; } @@ -92,7 +92,7 @@ void F(float u, float v, float& fx, float& fy, float& fz) splineF.getSplineVec(splineF_data, u, v, fx, fy, fz); } -bool initTPC(const char* fileName, int slice, int row) +bool initTPC(const char* fileName, int32_t slice, int32_t row) { // open NTuple file @@ -116,15 +116,15 @@ bool initTPC(const char* fileName, int slice, int row) nt->SetBranchAddress("du", &du); nt->SetBranchAddress("dv", &dv); - int nKnots = 101; + int32_t nKnots = 101; splineF.constructRegular(nKnots, nKnots); delete[] splineF_data; splineF_data = new float[3 * splineF.getNumberOfKnots()]; - for (int i = 0; i < 3 * splineF.getNumberOfKnots(); i++) + for (int32_t i = 0; i < 3 * splineF.getNumberOfKnots(); i++) splineF_data[i] = 0.; - int nent = 0; - for (int i = 0; i < nt->GetEntriesFast(); i++) { + int32_t nent = 0; + for (int32_t i = 0; i < nt->GetEntriesFast(); i++) { nt->GetEntry(i); if (nearbyint(fslice) != slice || nearbyint(frow) != row) continue; @@ -144,7 +144,7 @@ bool initTPC(const char* fileName, int slice, int row) return 1; } -int IrregularSpline2D3DCalibratorTest() +int32_t IrregularSpline2D3DCalibratorTest() { const bool kDraw = 1; @@ -176,12 +176,12 @@ int IrregularSpline2D3DCalibratorTest() TH1F* qaX = new TH1F("qaX", "diff F - spline", 1000, -0.05, 0.05); char keyPressed = '\0'; - for (int sample = 1; (keyPressed != 'q') && (sample < 2); sample++) { + for (int32_t sample = 1; (keyPressed != 'q') && (sample < 2); sample++) { - int seed = sample; + int32_t seed = sample; /* gRandom->SetSeed(0); - seed = gRandom->Integer(100); + seed = gRandom->Integer(100); */ gRandom->SetSeed(seed); if (kTestTPC) { @@ -234,10 +234,10 @@ int IrregularSpline2D3DCalibratorTest() { const IrregularSpline1D& gridU = splineF.getGridU(); const IrregularSpline1D& gridV = splineF.getGridV(); - int nKnots = 0; - for (int i = 0; i < gridU.getNumberOfKnots(); i++) { + int32_t nKnots = 0; + for (int32_t i = 0; i < gridU.getNumberOfKnots(); i++) { double u = gridU.getKnot(i).u; - for (int j = 0; j < gridV.getNumberOfKnots(); j++) { + for (int32_t j = 0; j < gridV.getNumberOfKnots(); j++) { double v = gridV.getKnot(j).u; float fx, fy, fz; F(u, v, fx, fy, fz); @@ -249,10 +249,10 @@ int IrregularSpline2D3DCalibratorTest() const IrregularSpline1D& gridU = finder.getSpline().getGridU(); const IrregularSpline1D& gridV = finder.getSpline().getGridV(); - int nKnots = 0; - for (int i = 0; i < gridU.getNumberOfKnots(); i++) { + int32_t nKnots = 0; + for (int32_t i = 0; i < gridU.getNumberOfKnots(); i++) { double u = gridU.getKnot(i).u; - for (int j = 0; j < gridV.getNumberOfKnots(); j++) { + for (int32_t j = 0; j < gridV.getNumberOfKnots(); j++) { double v = gridV.getKnot(j).u; float fx, fy, fz; F(u, v, fx, fy, fz); @@ -265,7 +265,7 @@ int IrregularSpline2D3DCalibratorTest() float stepu = 1.e-2; float stepv = 1.e-2; - int nPoints = 0; + int32_t nPoints = 0; for (float u = 0; u <= 1; u += stepu) { for (float v = 0; v <= 1; v += stepv) { float fx0, fy0, fz0; diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C index 92a1d6d18e814..c5c1ceaac9a02 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3DTest.C @@ -37,12 +37,12 @@ float Fx(float u, float v) { - const int PolynomDegree = 7; + const int32_t PolynomDegree = 7; static double cu[PolynomDegree + 1], cv[PolynomDegree + 1]; static bool isInitialized = 0; if (!isInitialized) { - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { cu[i] = i * gRandom->Uniform(-1, 1); cv[i] = i * gRandom->Uniform(-1, 1); } @@ -53,7 +53,7 @@ float Fx(float u, float v) double uu = 1.; double vv = 1.; double f = 0; - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { f += cu[i] * uu; f += cv[i] * vv; uu *= u; @@ -65,30 +65,30 @@ float Fx(float u, float v) float Fy(float u, float v) { return v; } float Fz(float u, float v) { return (u - .5) * (u - .5); } -int IrregularSpline2D3DTest() +int32_t IrregularSpline2D3DTest() { using namespace o2::gpu; gRandom->SetSeed(0); - unsigned int seed = gRandom->Integer(100000); // 605 + uint32_t seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; IrregularSpline2D3D spline; { - const int nKnotsU = 7, nKnotsV = 7; + const int32_t nKnotsU = 7, nKnotsV = 7; float knotsU[nKnotsU], knotsV[nKnotsV]; - int nAxisTicksU = 20; - int nAxisTicksV = 20; + int32_t nAxisTicksU = 20; + int32_t nAxisTicksV = 20; double du = 1. / (nKnotsU - 1); double dv = 1. / (nKnotsV - 1); - for (int i = 1; i < nKnotsU - 1; i++) { + for (int32_t i = 1; i < nKnotsU - 1; i++) { knotsU[i] = i * du + gRandom->Uniform(-du / 3., du / 3.); } - for (int i = 1; i < nKnotsV - 1; i++) { + for (int32_t i = 1; i < nKnotsV - 1; i++) { knotsV[i] = i * dv + gRandom->Uniform(-dv / 3., dv / 3.); } @@ -103,7 +103,7 @@ int IrregularSpline2D3DTest() spline.construct(nKnotsU, knotsU, nAxisTicksU, nKnotsV, knotsV, nAxisTicksV); } - int nKnotsTot = spline.getNumberOfKnots(); + int32_t nKnotsTot = spline.getNumberOfKnots(); const IrregularSpline1D& gridU = spline.getGridU(); const IrregularSpline1D& gridV = spline.getGridV(); @@ -111,13 +111,13 @@ int IrregularSpline2D3DTest() float* data0 = new float[3 * nKnotsTot]; float* data = new float[3 * nKnotsTot]; - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); - for (int i = 0; i < gridU.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < gridU.getNumberOfKnots(); i++) { double u = gridU.getKnot(i).u; - for (int j = 0; j < gridV.getNumberOfKnots(); j++) { + for (int32_t j = 0; j < gridV.getNumberOfKnots(); j++) { double v = gridV.getKnot(j).u; - int ind = (nu * j + i) * 3; + int32_t ind = (nu * j + i) * 3; data0[ind + 0] = Fx(u, v); data0[ind + 1] = Fy(u, v); data0[ind + 2] = Fz(u, v); @@ -126,7 +126,7 @@ int IrregularSpline2D3DTest() } } - for (int i = 0; i < 3 * nKnotsTot; i++) { + for (int32_t i = 0; i < 3 * nKnotsTot; i++) { data[i] = data0[i]; } @@ -145,14 +145,14 @@ int IrregularSpline2D3DTest() gknots->SetMarkerStyle(8); gknots->SetMarkerColor(kRed); - int gknotsN = 0; + int32_t gknotsN = 0; TNtuple* knots = new TNtuple("knots", "knots", "u:v:f"); double diff = 0; - for (int i = 0; i < gridU.getNumberOfKnots(); i++) { - for (int j = 0; j < gridV.getNumberOfKnots(); j++) { + for (int32_t i = 0; i < gridU.getNumberOfKnots(); i++) { + for (int32_t j = 0; j < gridV.getNumberOfKnots(); j++) { double u = gridU.getKnot(i).u; double v = gridV.getKnot(j).u; - int ind = (nu * j + i) * 3; + int32_t ind = (nu * j + i) * 3; double fx0 = data0[ind + 0]; knots->Fill(u, v, fx0); float x, y, z; @@ -173,19 +173,19 @@ int IrregularSpline2D3DTest() gf0->SetName("gf0"); gf0->SetTitle("gf0"); gf0->SetLineColor(kRed); - int gf0N = 0; + int32_t gf0N = 0; TGraph2D* gfs = new TGraph2D(); gfs->SetName("gfs"); gfs->SetTitle("gfs"); gfs->SetLineColor(kBlue); - int gfsN = 0; + int32_t gfsN = 0; TH1F* qaX = new TH1F("qaX", "qaX [um]", 1000, -100., 100.); TH1F* qaY = new TH1F("qaY", "qaY [um]", 1000, -10., 10.); TH1F* qaZ = new TH1F("qaZ", "qaZ [um]", 1000, -10., 10.); - int iter = 0; + int32_t iter = 0; float stepu = 1.e-3; float stepv = 1.e-3; diff --git a/GPU/TPCFastTransformation/devtools/RegularSpline1D.h b/GPU/TPCFastTransformation/devtools/RegularSpline1D.h index 10540b84bdabc..aa5acbe411dcd 100644 --- a/GPU/TPCFastTransformation/devtools/RegularSpline1D.h +++ b/GPU/TPCFastTransformation/devtools/RegularSpline1D.h @@ -43,7 +43,7 @@ class RegularSpline1D ~RegularSpline1D() CON_DEFAULT; /// Constructor. Number of knots will be set to at least 5 - void construct(int numberOfKnots); + void construct(int32_t numberOfKnots); /// _______________ Main functionality ________________________ @@ -56,41 +56,41 @@ class RegularSpline1D /// Get interpolated value for f(u) using spline at knot "knot_1" and function values at knots {knot_0,knot_1,knot_2,knot_3} template - T getSpline(const int iknot, T f0, T f1, T f2, T f3, float u) const; + T getSpline(const int32_t iknot, T f0, T f1, T f2, T f3, float u) const; /// Get interpolated value for f(u) using data array correctedData[getNumberOfKnots()] with corrected edges template T getSpline(const T correctedData[], float u) const; /// Get number of knots - int getNumberOfKnots() const { return mNumberOfKnots; } + int32_t getNumberOfKnots() const { return mNumberOfKnots; } /// Get the U-Coordinate depending on the given knot-Index - double knotIndexToU(int index) const; + double knotIndexToU(int32_t index) const; /// Get index of associated knot for a given U coordinate. /// /// Note: U values from the first interval are mapped to the second inrerval. /// Values from the last interval are mapped to the previous interval. /// - int getKnotIndex(float u) const; + int32_t getKnotIndex(float u) const; private: - unsigned char mNumberOfKnots = 5; ///< n knots on the grid + uint8_t mNumberOfKnots = 5; ///< n knots on the grid }; /// ==================================================== /// Inline implementations of some methods /// ==================================================== -inline void RegularSpline1D::construct(int numberOfKnots) +inline void RegularSpline1D::construct(int32_t numberOfKnots) { /// Constructor mNumberOfKnots = (numberOfKnots < 5) ? 5 : numberOfKnots; } template -inline T RegularSpline1D::getSpline(const int iknot1, T f0, T f1, T f2, T f3, float u) const +inline T RegularSpline1D::getSpline(const int32_t iknot1, T f0, T f1, T f2, T f3, float u) const { /// static method /// Get interpolated value for f(u) using a spline polynom for [iknot1,iknot2] interval. @@ -135,12 +135,12 @@ template inline T RegularSpline1D::getSpline(const T correctedData[], float u) const { /// Get interpolated value for f(u) using data array correctedData[getNumberOfKnots()] with corrected edges - int iknot = getKnotIndex(u); + int32_t iknot = getKnotIndex(u); const T* f = correctedData + iknot - 1; return getSpline(iknot, f[0], f[1], f[2], f[3], u); } -inline double RegularSpline1D::knotIndexToU(int iknot) const +inline double RegularSpline1D::knotIndexToU(int32_t iknot) const { if (iknot <= 0) { return 0; @@ -151,10 +151,10 @@ inline double RegularSpline1D::knotIndexToU(int iknot) const return iknot / ((double)mNumberOfKnots - 1.); } -inline int RegularSpline1D::getKnotIndex(float u) const +inline int32_t RegularSpline1D::getKnotIndex(float u) const { //index is just u elem [0, 1] * numberOfKnots and then floored. (so the "left" coordinate beside u gets chosen) - int index = (int)(u * (mNumberOfKnots - 1)); + int32_t index = (int32_t)(u * (mNumberOfKnots - 1)); if (index <= 1) { index = 1; } else if (index >= mNumberOfKnots - 3) { @@ -168,7 +168,7 @@ inline void RegularSpline1D::correctEdges(T* data) const { // data[i] is the i-th f-value constexpr T c0(0.5), c1(1.5); - const int i = mNumberOfKnots - 1; + const int32_t i = mNumberOfKnots - 1; data[0] = c0 * (data[0] + data[3]) + c1 * (data[1] - data[2]); data[i] = c0 * (data[i - 0] + data[i - 3]) + c1 * (data[i - 1] - data[i - 2]); } diff --git a/GPU/TPCFastTransformation/devtools/RegularSpline1DTest.C b/GPU/TPCFastTransformation/devtools/RegularSpline1DTest.C index fb96b4e2f5dca..8ba3a0e11b9f4 100644 --- a/GPU/TPCFastTransformation/devtools/RegularSpline1DTest.C +++ b/GPU/TPCFastTransformation/devtools/RegularSpline1DTest.C @@ -35,12 +35,12 @@ float F(float u) { // A test function - const int PolynomDegree = 7; + const int32_t PolynomDegree = 7; static double coeff[PolynomDegree + 1]; static bool firstCall = 1; if (firstCall) { gRandom->SetSeed(0); - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { coeff[i] = gRandom->Uniform(-1, 1); } firstCall = 0; @@ -49,7 +49,7 @@ float F(float u) u -= 0.5; double uu = 1.; double f = 0; - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { f += coeff[i] * uu; uu *= u; } @@ -59,26 +59,26 @@ float F(float u) using namespace o2::gpu; typedef double myfloat; -int RegularSpline1DTest() +int32_t RegularSpline1DTest() { std::cout << "Test roundf(): " << std::endl; for (float x = 0.; x <= 1.; x += 0.1) { - std::cout << "roundf(" << x << ") = " << roundf(x) << " " << (int)roundf(x) << std::endl; + std::cout << "roundf(" << x << ") = " << roundf(x) << " " << (int32_t)roundf(x) << std::endl; } std::cout << "Test 5 knots for n bins:" << std::endl; - for (int n = 4; n < 20; n++) { - int bin1 = (int)roundf(.25 * n); - int bin2 = (int)roundf(.50 * n); - int bin3 = (int)roundf(.75 * n); + for (int32_t n = 4; n < 20; n++) { + int32_t bin1 = (int32_t)roundf(.25 * n); + int32_t bin2 = (int32_t)roundf(.50 * n); + int32_t bin3 = (int32_t)roundf(.75 * n); std::cout << n << ": 0 " << bin1 << " " << bin2 << " " << bin3 << " " << n << std::endl; } std::cout << "Test interpolation.." << std::endl; - const int initNKnotsU = 10; - int nAxisBinsU = 10; + const int32_t initNKnotsU = 10; + int32_t nAxisBinsU = 10; float du = 1. / (initNKnotsU - 1); @@ -87,7 +87,7 @@ int RegularSpline1DTest() knotsU[0] = 0; knotsU[initNKnotsU - 1] = 1; - for (int i = 1; i < initNKnotsU - 1; i++) { + for (int32_t i = 1; i < initNKnotsU - 1; i++) { knotsU[i] = i * du + gRandom->Uniform(-du / 3, du / 3); } @@ -95,25 +95,25 @@ int RegularSpline1DTest() spline.construct(initNKnotsU); - int nKnotsTot = spline.getNumberOfKnots(); + int32_t nKnotsTot = spline.getNumberOfKnots(); std::cout << "Knots: initial " << initNKnotsU << ", created " << nKnotsTot << std::endl; - for (int i = 0; i < nKnotsTot; i++) { + for (int32_t i = 0; i < nKnotsTot; i++) { std::cout << "knot " << i << ": " << spline.knotIndexToU(i) << std::endl; } myfloat* data0 = new myfloat[nKnotsTot]; // original data myfloat* data = new myfloat[nKnotsTot]; // corrected data - int nu = spline.getNumberOfKnots(); + int32_t nu = spline.getNumberOfKnots(); - for (int i = 0; i < spline.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < spline.getNumberOfKnots(); i++) { data0[i] = F(spline.knotIndexToU(i)); //SG random data0[i] = gRandom->Uniform(-1., 1.); data[i] = data0[i]; } - for (int i = 1; i < nKnotsTot; i++) { + for (int32_t i = 1; i < nKnotsTot; i++) { std::cout << "data[" << i << "]: " << data[i] << std::endl; } @@ -121,13 +121,13 @@ int RegularSpline1DTest() TH1F* qaX = new TH1F("qaX", "qaX [um]", 1000, -1000., 1000.); - int iter = 0; + int32_t iter = 0; float stepu = 1.e-4; - int nSteps = (int)(1. / stepu + 1); + int32_t nSteps = (int32_t)(1. / stepu + 1); TNtuple* knots = new TNtuple("knots", "knots", "u:f"); double diff = 0; - for (int i = 0; i < nu; i++) { + for (int32_t i = 0; i < nu; i++) { double u = spline.knotIndexToU(i); double f0 = data0[i]; knots->Fill(u, f0); diff --git a/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3D.cxx b/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3D.cxx index 5abd6c4beedaf..2401a16dc6f16 100644 --- a/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3D.cxx +++ b/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3D.cxx @@ -45,12 +45,12 @@ void SemiregularSpline2D3D::relocateBufferPointers(const char* oldBuffer, char* /// relocate pointers from old to new buffer location /*char *bufferV = FlatObject::relocatePointer( oldBuffer, actualBuffer, mGridV.getFlatBufferPtr() ); - mGridV.setActualBufferAddress( bufferV );*/ + mGridV.setActualBufferAddress( bufferV );*/ - /*for( int i=0; i(mFlatBufferPtr); } - const int* getDataIndexMap() const + const int32_t* getDataIndexMap() const { - return reinterpret_cast(mFlatBufferPtr + mDataIndexMapOffset); + return reinterpret_cast(mFlatBufferPtr + mDataIndexMapOffset); } private: @@ -169,9 +169,9 @@ class SemiregularSpline2D3D : public FlatObject return reinterpret_cast(mFlatBufferPtr); } - int* getDataIndexMapNonConst() + int32_t* getDataIndexMapNonConst() { - return reinterpret_cast(mFlatBufferPtr + mDataIndexMapOffset); + return reinterpret_cast(mFlatBufferPtr + mDataIndexMapOffset); } /// @@ -179,9 +179,9 @@ class SemiregularSpline2D3D : public FlatObject /// RegularSpline1D mGridV; ///< grid for V axis - int mNumberOfRows; - int mNumberOfKnots; - int mDataIndexMapOffset; + int32_t mNumberOfRows; + int32_t mNumberOfKnots; + int32_t mDataIndexMapOffset; #ifndef GPUCA_ALIROOT_LIB ClassDefNV(SemiregularSpline2D3D, 1); @@ -192,23 +192,23 @@ class SemiregularSpline2D3D : public FlatObject /// Inline implementations of some methods /// ==================================================== -inline int SemiregularSpline2D3D::getDataIndex(int u, int v) const +inline int32_t SemiregularSpline2D3D::getDataIndex(int32_t u, int32_t v) const { return (getDataIndexMap()[v] + u) * 3; } -inline int SemiregularSpline2D3D::getDataIndex0(int u, int v) const +inline int32_t SemiregularSpline2D3D::getDataIndex0(int32_t u, int32_t v) const { return (getDataIndexMap()[v] + u); } -inline void SemiregularSpline2D3D::getKnotUV(int iKnot, float& u, float& v) const +inline void SemiregularSpline2D3D::getKnotUV(int32_t iKnot, float& u, float& v) const { // iterate through all RegularSpline1D's - for (int i = 0; i < mNumberOfRows; i++) { + for (int32_t i = 0; i < mNumberOfRows; i++) { const RegularSpline1D& gridU = getGridU(i); - const int nk = gridU.getNumberOfKnots(); + const int32_t nk = gridU.getNumberOfKnots(); // if the searched index is less or equal as the number of knots in the current spline // the searched u-v-coordinates have to be in this spline. @@ -234,19 +234,19 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const //Regular v-Grid (vertical) const RegularSpline1D& gridV = getGridV(); - int nv = mNumberOfRows; + int32_t nv = mNumberOfRows; //EIGENTLICH V VOR U!!! //Wegen Splines aber U vor V { // ==== left edge of U ==== //loop through all gridUs - for (int iv = 1; iv < mNumberOfRows - 1; iv++) { + for (int32_t iv = 1; iv < mNumberOfRows - 1; iv++) { T* f0 = data + getDataIndex(0, iv); T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -254,14 +254,14 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const { // ==== right edge of U ==== //loop through all gridUs - for (int iv = 1; iv < mNumberOfRows - 1; iv++) { + for (int32_t iv = 1; iv < mNumberOfRows - 1; iv++) { const RegularSpline1D& gridU = getGridU(iv); - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); T* f0 = data + getDataIndex(nu - 4, iv); T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -269,9 +269,9 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const { // ==== low edge of V ==== const RegularSpline1D& gridU = getGridU(0); - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); - for (int iu = 0; iu < nu; iu++) { + for (int32_t iu = 0; iu < nu; iu++) { //f0 to f3 are the x,y,z values of 4 points in the grid along the v axis. //Since there are no knots because of the irregularity you can get this by using the getSplineMethod. T* f0 = data + getDataIndex(iu, 0); @@ -285,16 +285,16 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const T f1[3] = {x1, y1, z1}; T f2[3] = {x2, y2, z2}; T f3[3] = {x3, y3, z3}; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]); } } } { // ==== high edge of V ==== - int nu = getGridU(nv - 1).getNumberOfKnots(); + int32_t nu = getGridU(nv - 1).getNumberOfKnots(); - for (int iu = 0; iu < nu; iu++) { + for (int32_t iu = 0; iu < nu; iu++) { float u = getGridU(nv - 1).knotIndexToU(iu); @@ -307,7 +307,7 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const T f1[3] = {x2, y2, z2}; T f2[3] = {x3, y3, z3}; T* f3 = data + getDataIndex(iu, nv - 1); - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -320,7 +320,7 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -328,12 +328,12 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const { // ==== Lower right corner with u-direction === const RegularSpline1D& gridU = getGridU(0); - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); T* f0 = data + getDataIndex(nu - 4, 0); T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -343,19 +343,19 @@ inline void SemiregularSpline2D3D::correctEdges(T* data) const T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]); } } { // ==== upper right corner with u-direction === const RegularSpline1D& gridU = getGridU(nv - 1); - int nu = gridU.getNumberOfKnots(); + int32_t nu = gridU.getNumberOfKnots(); T* f0 = data + getDataIndex(nu - 4, nv - 1); T* f1 = f0 + 3; T* f2 = f0 + 6; T* f3 = f0 + 9; - for (int idim = 0; idim < 3; idim++) { + for (int32_t idim = 0; idim < 3; idim++) { f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]); } } @@ -367,22 +367,22 @@ inline void SemiregularSpline2D3D::getSpline(const T* correctedData, float u, fl // Get interpolated value for f(u,v) using data array correctedData[getNumberOfKnots()] with corrected edges // find the v indizes of the u-splines that are needed. - int iknotv = mGridV.getKnotIndex(v); + int32_t iknotv = mGridV.getKnotIndex(v); // to save the index positions of u-coordinates we create an array T dataVx[12]; - //int dataOffset0 = getDataIndex0(0, iknotv-1); //index of the very left point in the vi-1-th gridU + // int32_t dataOffset0 = getDataIndex0(0, iknotv-1); //index of the very left point in the vi-1-th gridU // we loop through the 4 needed u-Splines - int vxIndex = 0; - for (int vi = 0; vi < 4; vi++, vxIndex += 3) { + int32_t vxIndex = 0; + for (int32_t vi = 0; vi < 4; vi++, vxIndex += 3) { - const int vDelta = iknotv + vi - 1; + const int32_t vDelta = iknotv + vi - 1; const RegularSpline1D& gridU = getGridU(vDelta); // and find at which index in that specific spline the u-coordinate must lay. - const int ui = gridU.getKnotIndex(u); - const int dataOffset = getDataIndex(ui - 1, vDelta); //(dataOffset0 + (ui-1))*3; + const int32_t ui = gridU.getKnotIndex(u); + const int32_t dataOffset = getDataIndex(ui - 1, vDelta); //(dataOffset0 + (ui-1))*3; dataVx[vxIndex + 0] = gridU.getSpline(ui, correctedData[dataOffset], correctedData[dataOffset + 3], correctedData[dataOffset + 6], correctedData[dataOffset + 9], u); dataVx[vxIndex + 1] = gridU.getSpline(ui, correctedData[dataOffset + 1], correctedData[dataOffset + 4], correctedData[dataOffset + 7], correctedData[dataOffset + 10], u); @@ -429,15 +429,15 @@ inline void SemiregularSpline2D3D::getSplineVec(const float* correctedData, floa */ //workaround 1: - int vGridi = mGridV.getKnotIndex(v); + int32_t vGridi = mGridV.getKnotIndex(v); float dataU[12]; - int vOffset = 0; - for (int vi = 0; vi < 4; vi++, vOffset += 3) { + int32_t vOffset = 0; + for (int32_t vi = 0; vi < 4; vi++, vOffset += 3) { const RegularSpline1D& gridU = getGridU(vi + vGridi - 1); // and find at which index in that specific spline the u-coordinate must lay. - int ui = gridU.getKnotIndex(u); + int32_t ui = gridU.getKnotIndex(u); // using getDataIndex we know at which position knot (ui, vi) is saved. // dataU0 to U3 are 4 points along the u-spline surrounding the u coordinate. diff --git a/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3DTest.C b/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3DTest.C index a84198859bc15..a140a77ffc17e 100644 --- a/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3DTest.C +++ b/GPU/TPCFastTransformation/devtools/SemiregularSpline2D3DTest.C @@ -38,11 +38,11 @@ using namespace std; float Fx(float u, float v) { - const int PolynomDegree = 7; + const int32_t PolynomDegree = 7; static double cu[PolynomDegree + 1], cv[PolynomDegree + 1]; static bool isInitialized = 0; if (!isInitialized) { - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { cu[i] = i * gRandom->Uniform(-1, 1); cv[i] = i * gRandom->Uniform(-1, 1); } @@ -54,7 +54,7 @@ float Fx(float u, float v) double uu = 1.; double vv = 1.; double f = 0; - for (int i = 0; i <= PolynomDegree; i++) { + for (int32_t i = 0; i <= PolynomDegree; i++) { f += cu[i] * uu; f += cv[i] * vv; uu *= u; @@ -78,20 +78,20 @@ bool equalityCheck(const string title, const T expected, const T received) return check; } -int SemiregularSpline2D3DTest() +int32_t SemiregularSpline2D3DTest() { using namespace o2::gpu; gRandom->SetSeed(0); - const int numberOfRows = 6; - int numbersOfKnots[numberOfRows]; - for (int i = 0; i < numberOfRows; i++) { + const int32_t numberOfRows = 6; + int32_t numbersOfKnots[numberOfRows]; + for (int32_t i = 0; i < numberOfRows; i++) { numbersOfKnots[i] = 5 + gRandom->Integer(5); } - int knotAmountExp = 0; //Expected amount of knots in total - for (int i = 0; i < numberOfRows; i++) { + int32_t knotAmountExp = 0; // Expected amount of knots in total + for (int32_t i = 0; i < numberOfRows; i++) { knotAmountExp += numbersOfKnots[i]; } @@ -99,7 +99,7 @@ int SemiregularSpline2D3DTest() spline.construct(numberOfRows, numbersOfKnots); std::vector checker; - int nKnotsTot = spline.getNumberOfKnots(); + int32_t nKnotsTot = spline.getNumberOfKnots(); checker.push_back(equalityCheck("Number of rows", numberOfRows, spline.getNumberOfRows())); checker.push_back(equalityCheck("Number of knots", knotAmountExp, nKnotsTot)); @@ -108,12 +108,12 @@ int SemiregularSpline2D3DTest() float* data0 = new float[6 * nKnotsTot]; float* data = new float[6 * nKnotsTot]; - int nv = gridV.getNumberOfKnots(); //4 + int32_t nv = gridV.getNumberOfKnots(); // 4 checker.push_back(equalityCheck("Number of Knots in gridV", numberOfRows, nv)); //loop through all rows (v-coordinate) - for (int i = 0; i < nv; i++) { + for (int32_t i = 0; i < nv; i++) { //get each v coordinate double v = gridV.knotIndexToU(i); @@ -122,10 +122,10 @@ int SemiregularSpline2D3DTest() const RegularSpline1D& gridU = spline.getGridU(i); //loop through all u-indexes - for (int j = 0; j < gridU.getNumberOfKnots(); j++) { + for (int32_t j = 0; j < gridU.getNumberOfKnots(); j++) { //get the u coodrinate double u = gridU.knotIndexToU(j); - int ind = spline.getDataIndex(j, i); + int32_t ind = spline.getDataIndex(j, i); data0[ind + 0] = Fx(u, v); data0[ind + 1] = Fy(u, v); data0[ind + 2] = Fz(u, v); @@ -134,7 +134,7 @@ int SemiregularSpline2D3DTest() } } - for (int i = 0; i < nKnotsTot * 3; i++) { + for (int32_t i = 0; i < nKnotsTot * 3; i++) { data[i] = data0[i]; } @@ -155,15 +155,15 @@ int SemiregularSpline2D3DTest() gknots->SetMarkerStyle(8); gknots->SetMarkerColor(kRed); - int gknotsN = 0; + int32_t gknotsN = 0; TNtuple* knots = new TNtuple("knots", "knots", "u:v:f"); double diff = 0; - for (int i = 0; i < gridV.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < gridV.getNumberOfKnots(); i++) { const RegularSpline1D& gridU = spline.getGridU(i); - for (int j = 0; j < gridU.getNumberOfKnots(); j++) { + for (int32_t j = 0; j < gridU.getNumberOfKnots(); j++) { double v = gridV.knotIndexToU(i); double u = gridU.knotIndexToU(j); - int ind = spline.getDataIndex(j, i); + int32_t ind = spline.getDataIndex(j, i); double fx0 = data0[ind + 0]; knots->Fill(u, v, fx0); float x, y, z; @@ -186,19 +186,19 @@ int SemiregularSpline2D3DTest() gf0->SetName("gf0"); gf0->SetTitle("gf0"); gf0->SetLineColor(kRed); - int gf0N = 0; + int32_t gf0N = 0; TGraph2D* gfs = new TGraph2D(); gfs->SetName("gfs"); gfs->SetTitle("gfs"); gfs->SetLineColor(kBlue); - int gfsN = 0; + int32_t gfsN = 0; TH1F* qaX = new TH1F("qaX", "qaX [um]", 1000, -100., 100.); TH1F* qaY = new TH1F("qaY", "qaY [um]", 1000, -10., 10.); TH1F* qaZ = new TH1F("qaZ", "qaZ [um]", 1000, -10., 10.); - int iter = 0; + int32_t iter = 0; float stepu = 1.e-3; float stepv = 1.e-3; @@ -228,7 +228,7 @@ int SemiregularSpline2D3DTest() //Check if everything went good bool success = true; - for (unsigned int i = 0; i < checker.size(); i++) { + for (uint32_t i = 0; i < checker.size(); i++) { success = success && checker[i]; if (!success) { std::cout << "Something went wrong!" << std::endl; diff --git a/GPU/TPCFastTransformation/macro/SplineDemo.C b/GPU/TPCFastTransformation/macro/SplineDemo.C index 2aa23b2f41f8d..84c0200016564 100644 --- a/GPU/TPCFastTransformation/macro/SplineDemo.C +++ b/GPU/TPCFastTransformation/macro/SplineDemo.C @@ -23,8 +23,8 @@ #endif -const int Fdegree = 5; -int nKnots = 4; +const int32_t Fdegree = 5; +int32_t nKnots = 4; static double Fcoeff[2 * (Fdegree + 1)]; @@ -32,7 +32,7 @@ void F(double u, double f[]) { double uu = u * TMath::Pi() / (nKnots - 1); f[0] = 0; //Fcoeff[0]/2; - for (int i = 1; i <= Fdegree; i++) { + for (int32_t i = 1; i <= Fdegree; i++) { f[0] += Fcoeff[2 * i] * TMath::Cos(i * uu) + Fcoeff[2 * i + 1] * TMath::Sin(i * uu); } } @@ -44,7 +44,7 @@ void F(float u, float f[]) double t0=1; double t1 = uu; f[0] = 0; - for (int i = 1; i <= Fdegree*2; i++) { + for (int32_t i = 1; i <= Fdegree*2; i++) { double t = t = 2*uu*t1-t0; f[0] += Fcoeff[i]*t; t0 = t1; @@ -105,10 +105,10 @@ bool askStep() return (!doAskSteps) ? 1 : ask(); } -int SplineDemo() +int32_t SplineDemo() { - const int nAxiliaryPoints = 10; + const int32_t nAxiliaryPoints = 10; using namespace o2::gpu; @@ -123,14 +123,14 @@ int SplineDemo() TH1F* histMinMaxBestFit = new TH1F("histMinMaxBestFit", "MinMax BestFit", 100, -1., 1.); TH1F* histMinMaxCheb = new TH1F("histMinMaxCheb", "MinMax Chebyshev", 100, -1., 1.); - for (int seed = 12;; seed++) { + for (int32_t seed = 12;; seed++) { //seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; - for (int i = 0; i < 2 * (Fdegree + 1); i++) { + for (int32_t i = 0; i < 2 * (Fdegree + 1); i++) { Fcoeff[i] = gRandom->Uniform(-1, 1); } @@ -142,11 +142,11 @@ int SplineDemo() helper.approximateFunctionClassic(splineClassic, 0, nKnots - 1, F); IrregularSpline1D splineLocal; - int nKnotsLocal = 2 * nKnots - 1; + int32_t nKnotsLocal = 2 * nKnots - 1; splineLocal.constructRegular(nKnotsLocal); std::unique_ptr parametersLocal(new float[nKnotsLocal]); - for (int i = 0; i < nKnotsLocal; i++) { + for (int32_t i = 0; i < nKnotsLocal; i++) { parametersLocal[i] = Flocal(splineLocal.getKnot(i).u); } splineLocal.correctEdges(parametersLocal.get()); @@ -161,14 +161,14 @@ int SplineDemo() TNtuple* knots = new TNtuple("knots", "knots", "type:u:f"); - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { double u = splineClassic.getKnot(i).u; double fs = splineClassic.interpolate(splineClassic.convUtoX(u)); knots->Fill(1, u, fs); } helper.setSpline(spline, 1, nAxiliaryPoints); - for (int j = 0; j < helper.getNumberOfDataPoints(); j++) { + for (int32_t j = 0; j < helper.getNumberOfDataPoints(); j++) { const typename Spline1DHelperOld::DataPoint& p = helper.getDataPoint(j); double f0; F(p.u, &f0); @@ -184,7 +184,7 @@ int SplineDemo() knots->Fill(5, uCheb, fCheb); } - for (int i = 0; i < splineLocal.getNumberOfKnots(); i++) { + for (int32_t i = 0; i < splineLocal.getNumberOfKnots(); i++) { double u = splineLocal.getKnot(i).u; double fs = splineLocal.getSpline(parametersLocal.get(), u); knots->Fill(4, u * (nKnots - 1), fs); @@ -193,7 +193,7 @@ int SplineDemo() TNtuple* nt = new TNtuple("nt", "nt", "u:f0:fBestFit:fClass:fLocal:fCheb"); float stepS = 1.e-4; - int nSteps = (int)(1. / stepS + 1); + int32_t nSteps = (int32_t)(1. / stepS + 1); double statDfBestFit = 0; double statDfClass = 0; @@ -207,7 +207,7 @@ int SplineDemo() double drawMax = -1.e20; double drawMin = 1.e20; - int statN = 0; + int32_t statN = 0; for (float s = 0; s < 1. + stepS; s += stepS) { double u = s * (nKnots - 1); double f0; diff --git a/GPU/TPCFastTransformation/macro/SplineRecoveryDemo.C b/GPU/TPCFastTransformation/macro/SplineRecoveryDemo.C index 093b027b742e6..3da93d7c83b78 100644 --- a/GPU/TPCFastTransformation/macro/SplineRecoveryDemo.C +++ b/GPU/TPCFastTransformation/macro/SplineRecoveryDemo.C @@ -23,8 +23,8 @@ #endif -const int Fdegree = 10; -int nKnots = 6; +const int32_t Fdegree = 10; +int32_t nKnots = 6; static double Fcoeff[2 * (Fdegree + 1)]; @@ -32,7 +32,7 @@ void F(double u, double f[]) { double uu = u * TMath::Pi() / (nKnots - 1); f[0] = 0; // Fcoeff[0]/2; - for (int i = 1; i <= Fdegree; i++) { + for (int32_t i = 1; i <= Fdegree; i++) { f[0] += Fcoeff[2 * i] * TMath::Cos(i * uu) + Fcoeff[2 * i + 1] * TMath::Sin(i * uu); } } @@ -77,10 +77,10 @@ bool askStep() return doContinie; } -int SplineRecoveryDemo() +int32_t SplineRecoveryDemo() { - const int nAxiliaryPoints = 10; + const int32_t nAxiliaryPoints = 10; using namespace o2::gpu; @@ -93,25 +93,25 @@ int SplineRecoveryDemo() TH1F* histDfBestFit = new TH1F("histDfBestFit", "Df BestFit", 100, -1., 1.); TH1F* histMinMaxBestFit = new TH1F("histMinMaxBestFit", "MinMax BestFit", 100, -1., 1.); - for (int seed = 12; doContinie; seed++) { + for (int32_t seed = 12; doContinie; seed++) { // seed = gRandom->Integer(100000); // 605 gRandom->SetSeed(seed); std::cout << "Random seed: " << seed << " " << gRandom->GetSeed() << std::endl; - for (int i = 0; i < 2 * (Fdegree + 1); i++) { + for (int32_t i = 0; i < 2 * (Fdegree + 1); i++) { Fcoeff[i] = gRandom->Uniform(-1, 1); } - for (int deadRegion = -1; doContinie && (deadRegion < nKnots - 1); deadRegion++) { + for (int32_t deadRegion = -1; doContinie && (deadRegion < nKnots - 1); deadRegion++) { TNtuple* knots = new TNtuple("knots", "knots", "type:u:f"); o2::gpu::Spline1D spline(nKnots); spline.approximateFunction(0, nKnots - 1, F, nAxiliaryPoints); - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { double u = spline.getKnot(i).u; double fs = spline.interpolate(spline.convUtoX(u)); knots->Fill(2, u, fs); @@ -121,11 +121,11 @@ int SplineRecoveryDemo() o2::gpu::Spline1DHelper helper; { vector vu, vy; - for (int i = 0; i < nKnots - 1; i++) { + for (int32_t i = 0; i < nKnots - 1; i++) { if (i < deadRegion || i > deadRegion + 1) { double u = spline.getKnot(i).u; double du = (spline.getKnot(i + 1).u - u) / (nAxiliaryPoints + 1); - for (int iax = 0; iax < nAxiliaryPoints + 1; iax++, u += du) { + for (int32_t iax = 0; iax < nAxiliaryPoints + 1; iax++, u += du) { double f = F1D(u); vu.push_back(u); vy.push_back(f); @@ -134,7 +134,7 @@ int SplineRecoveryDemo() } } { - int i = nKnots - 1; + int32_t i = nKnots - 1; if (i < deadRegion || i > deadRegion + 2) { double u = spline.getKnot(i).u; double f = F1D(u); @@ -150,7 +150,7 @@ int SplineRecoveryDemo() canv->Draw(); - for (int i = 0; i < nKnots; i++) { + for (int32_t i = 0; i < nKnots; i++) { double u = splineRecovered.getKnot(i).u; double fs = splineRecovered.interpolate(splineRecovered.convUtoX(u)); knots->Fill(1, u, fs); @@ -159,7 +159,7 @@ int SplineRecoveryDemo() TNtuple* nt = new TNtuple("nt", "nt", "u:f0:fBestFit:fRec"); float stepS = 1.e-4; - int nSteps = (int)(1. / stepS + 1); + int32_t nSteps = (int32_t)(1. / stepS + 1); double statDfBestFit = 0; double statDfRec = 0; @@ -169,7 +169,7 @@ int SplineRecoveryDemo() double drawMax = -1.e20; double drawMin = 1.e20; - int statN = 0; + int32_t statN = 0; for (float s = 0; s < 1. + stepS; s += stepS) { double u = s * (nKnots - 1); double f0; @@ -251,7 +251,7 @@ int SplineRecoveryDemo() break; } { - int col = kGreen + 2; + int32_t col = kGreen + 2; nt->SetMarkerColor(col); nt->SetMarkerStyle(8); nt->SetMarkerSize(1.); @@ -281,7 +281,7 @@ int SplineRecoveryDemo() } { - int col = kRed; + int32_t col = kRed; nt->SetMarkerSize(1.); nt->SetMarkerColor(col); nt->Draw("fRec:u", "", "P,same"); @@ -328,7 +328,7 @@ int SplineRecoveryDemo() delete legend; } // dead region - } // random F + } // random F return 0; } diff --git a/GPU/TPCFastTransformation/macro/TPCFastTransformInit.C b/GPU/TPCFastTransformation/macro/TPCFastTransformInit.C index 152b02375205c..6b3756aca3b73 100644 --- a/GPU/TPCFastTransformation/macro/TPCFastTransformInit.C +++ b/GPU/TPCFastTransformation/macro/TPCFastTransformInit.C @@ -102,11 +102,11 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", // the difference double maxDiff[3] = {0., 0., 0.}; - int maxDiffRoc[3] = {0, 0, 0}; - int maxDiffRow[3] = {0, 0, 0}; + int32_t maxDiffRoc[3] = {0, 0, 0}; + int32_t maxDiffRow[3] = {0, 0, 0}; double sumDiff[3] = {0., 0., 0.}; - long nDiff = 0; + int64_t nDiff = 0; // a debug file with some NTuples @@ -162,23 +162,23 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", branch->SetAddress(&v); branch->SetAutoDelete(kTRUE); - for (int iVox = 0; iVox < voxResTree->GetEntriesFast(); iVox++) { + for (int32_t iVox = 0; iVox < voxResTree->GetEntriesFast(); iVox++) { voxResTree->GetEntry(iVox); float voxEntries = v->stat[o2::tpc::TrackResiduals::VoxV]; - int xBin = + int32_t xBin = v->bvox[o2::tpc::TrackResiduals::VoxX]; // bin number in x (= pad row) - int y2xBin = + int32_t y2xBin = v->bvox[o2::tpc::TrackResiduals::VoxF]; // bin number in y/x 0..14 - int z2xBin = + int32_t z2xBin = v->bvox[o2::tpc::TrackResiduals::VoxZ]; // bin number in z/x 0..4 - int iRoc = (int)v->bsec; - int iRow = (int)xBin; + int32_t iRoc = (int32_t)v->bsec; + int32_t iRow = (int32_t)xBin; double x = trackResiduals.getX(xBin); // radius of the pad row @@ -219,7 +219,7 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", cy -= y; cz -= z; double d[3] = {cx - correctionX, cy - correctionY, cz - correctionZ}; - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { if (fabs(maxDiff[i]) < fabs(d[i])) { maxDiff[i] = d[i]; maxDiffRoc[i] = iRoc; @@ -236,10 +236,10 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", std::cout << "create debug ntuples ..." << std::endl; - for (int iRoc = 0; iRoc < geo.getNumberOfSlices(); iRoc++) { - // for (int iRoc = 0; iRoc < 1; iRoc++) { + for (int32_t iRoc = 0; iRoc < geo.getNumberOfSlices(); iRoc++) { + // for (int32_t iRoc = 0; iRoc < 1; iRoc++) { std::cout << "debug ntules for roc " << iRoc << std::endl; - for (int iRow = 0; iRow < geo.getNumberOfRows(); iRow++) { + for (int32_t iRow = 0; iRow < geo.getNumberOfRows(); iRow++) { double x = geo.getRowInfo(iRow).x; @@ -265,9 +265,9 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", const auto& gridU = corr.getSpline(iRoc, iRow).getGridX1(); const auto& gridV = corr.getSpline(iRoc, iRow).getGridX2(); - for (int iu = 0; iu < gridU.getNumberOfKnots(); iu++) { + for (int32_t iu = 0; iu < gridU.getNumberOfKnots(); iu++) { double su = gridU.convUtoX(gridU.getKnot(iu).getU()); - for (int iv = 0; iv < gridV.getNumberOfKnots(); iv++) { + for (int32_t iv = 0; iv < gridV.getNumberOfKnots(); iv++) { double sv = gridV.convUtoX(gridV.getKnot(iv).getU()); float u, v; corr.convGridToUV(iRoc, iRow, iu, iv, u, v); @@ -291,7 +291,7 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", corrHelper->getCorrectionMap(); auto& points = map.getPoints(iRoc, iRow); - for (unsigned int ip = 0; ip < points.size(); ip++) { + for (uint32_t ip = 0; ip < points.size(); ip++) { auto point = points[ip]; float y = point.mY; float z = point.mZ; @@ -312,7 +312,7 @@ void TPCFastTransformInit(const char* fileName = "debugVoxRes.root", } } - for (int i = 0; i < 3; i++) { + for (int32_t i = 0; i < 3; i++) { sumDiff[i] = sqrt(sumDiff[i]) / nDiff; } diff --git a/GPU/TPCFastTransformation/macro/fastTransformQA.C b/GPU/TPCFastTransformation/macro/fastTransformQA.C index 513adfd66e846..62115160f25e9 100644 --- a/GPU/TPCFastTransformation/macro/fastTransformQA.C +++ b/GPU/TPCFastTransformation/macro/fastTransformQA.C @@ -6,7 +6,7 @@ #include "TH1.h" #include "TCanvas.h" -int fastTransformQA() +int32_t fastTransformQA() { const char* fname = "fastTransformQA.root"; @@ -46,9 +46,9 @@ int fastTransformQA() TH1F* qaY = new TH1F("qaY", "qaY [um]", 1000, -500., 500.); TH1F* qaZ = new TH1F("qaZ", "qaZ [um]", 1000, -500., 500.); - for (int i = 0; i < nt->GetEntriesFast(); i++) { + for (int32_t i = 0; i < nt->GetEntriesFast(); i++) { if (i % 10000000 == 0) { - std::cout << "processing " << i << " out of " << nt->GetEntriesFast() << " (" << ((long)i) * 100 / nt->GetEntriesFast() << " %)" << std::endl; + std::cout << "processing " << i << " out of " << nt->GetEntriesFast() << " (" << ((int64_t)i) * 100 / nt->GetEntriesFast() << " %)" << std::endl; canv->cd(1); qaX->Draw(); canv->cd(2); @@ -58,7 +58,7 @@ int fastTransformQA() canv->cd(0); canv->Update(); } - int ret = nt->GetEntry(i); + int32_t ret = nt->GetEntry(i); if (ret <= 0) { std::cout << "Wrong entry, ret == " << ret << std::endl; continue; diff --git a/GPU/TPCFastTransformation/macro/generateTPCCorrectionNTuple.C b/GPU/TPCFastTransformation/macro/generateTPCCorrectionNTuple.C index bec09ef5acf2d..67a0f09522f60 100644 --- a/GPU/TPCFastTransformation/macro/generateTPCCorrectionNTuple.C +++ b/GPU/TPCFastTransformation/macro/generateTPCCorrectionNTuple.C @@ -84,12 +84,12 @@ void generateTPCCorrectionNTuple(const char* path = "InputSCDensityHistograms.ro TFile* f = new TFile("tpcCorrection.root", "RECREATE"); TNtuple* nt = new TNtuple("dist", "dist", "slice:row:su:sv:dx:du:dv"); - int nSlices = 1; // fastTransform->getNumberOfSlices(); - // for( int slice=0; slicegetNumberOfSlices(); + // for( int32_t slice=0; slice polCT; // compile time polynomial @@ -59,10 +59,10 @@ BOOST_AUTO_TEST_CASE(Polynomials5D) BOOST_CHECK(nPar5D4Deg == polRT.getNParams()); float par[nPar5D4Deg]{20}; - for (int iter = 0; iter < 10; ++iter) { + for (int32_t iter = 0; iter < 10; ++iter) { // draw random parameters - for (int i = 1; i < nPar5D4Deg; ++i) { + for (int32_t i = 1; i < nPar5D4Deg; ++i) { par[i] = genRand(); } @@ -92,9 +92,9 @@ BOOST_AUTO_TEST_CASE(Polynomials5D) BOOST_AUTO_TEST_CASE(Polynomials5D_InteractionOnly) { std::srand(std::time(nullptr)); - const int nPar5D5DegInteraction = 32; // number of parameters - const int nDim = 5; // dimensions - const int nDegree = 5; // degree + const int32_t nPar5D5DegInteraction = 32; // number of parameters + const int32_t nDim = 5; // dimensions + const int32_t nDegree = 5; // degree const float abstolerance = 0.0001f; // abosulte difference between refernce to polynomial class const bool interactionOnly = true; @@ -106,10 +106,10 @@ BOOST_AUTO_TEST_CASE(Polynomials5D_InteractionOnly) BOOST_CHECK(nPar5D5DegInteraction == polRT.getNParams()); float par[nPar5D5DegInteraction]{20}; - for (int iter = 0; iter < 10; ++iter) { + for (int32_t iter = 0; iter < 10; ++iter) { // draw random parameters - for (int i = 1; i < nPar5D5DegInteraction; ++i) { + for (int32_t i = 1; i < nPar5D5DegInteraction; ++i) { par[i] = genRand(); } @@ -139,9 +139,9 @@ BOOST_AUTO_TEST_CASE(Polynomials5D_InteractionOnly) BOOST_AUTO_TEST_CASE(Piecewise_polynomials) { std::srand(std::time(nullptr)); - const int nPar5D5DegInteraction = 32; // number of parameters - const int nDim = 5; // dimensions - const int nDegree = 5; // degree + const int32_t nPar5D5DegInteraction = 32; // number of parameters + const int32_t nDim = 5; // dimensions + const int32_t nDegree = 5; // degree const bool interactionOnly = true; // consider only interaction terms // reference polynomial which will be approximated by the NDPiecewisePolynomials @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(Piecewise_polynomials) // define picewise polynomials with a lower degree than the original reference function std::vector xMin(nDim, 0); std::vector xMax(nDim, 1); - const std::vector nVert(nDim, 4); + const std::vector nVert(nDim, 4); NDPiecewisePolynomials piecewisePol(xMin.data(), xMax.data(), nVert.data()); // define function which will be used to approximate the picewise polynomials @@ -161,18 +161,18 @@ BOOST_AUTO_TEST_CASE(Piecewise_polynomials) }; float par[nPar5D5DegInteraction]{20}; - for (int iter = 0; iter < 5; ++iter) { + for (int32_t iter = 0; iter < 5; ++iter) { // draw random parameters - for (int i = 1; i < nPar5D5DegInteraction; ++i) { + for (int32_t i = 1; i < nPar5D5DegInteraction; ++i) { par[i] = genRand(); } polCT.setParams(par); // define number of axiliary points which will be used for the fitting - const unsigned int nAux = 4; - const std::vector nAxiliaryPoints(nDim, nAux); + const uint32_t nAux = 4; + const std::vector nAxiliaryPoints(nDim, nAux); // perform the fitting of the picewise polynomials piecewisePol.performFits(refFunc, nAxiliaryPoints.data()); @@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE(Piecewise_polynomials) } // check for safe evaluation outside of the grid at upper boundary - const std::vector indexHigh(nDim, nAux - 2); + const std::vector indexHigh(nDim, nAux - 2); for (float a = xMax[0]; a <= xMax[0] + 10; a += 2.f) { for (float b = xMax[1]; b <= xMax[1] + 10; b += 2.f) { for (float c = xMax[2]; c <= xMax[2] + 10; c += 2.f) { diff --git a/GPU/TPCFastTransformation/test/testSplines.cxx b/GPU/TPCFastTransformation/test/testSplines.cxx index ab15cd4594551..0e573b48a59b4 100644 --- a/GPU/TPCFastTransformation/test/testSplines.cxx +++ b/GPU/TPCFastTransformation/test/testSplines.cxx @@ -27,10 +27,10 @@ namespace o2::gpu BOOST_AUTO_TEST_CASE(Spline_test1) { - int err1 = o2::gpu::Spline1D::test(0); + int32_t err1 = o2::gpu::Spline1D::test(0); BOOST_CHECK_MESSAGE(err1 == 0, "test of GPU/TPCFastTransform/Spline1D failed with the error code " << err1); - int err2 = o2::gpu::Spline2D::test(0); + int32_t err2 = o2::gpu::Spline2D::test(0); BOOST_CHECK_MESSAGE(err2 == 0, "test of GPU/TPCFastTransform/Spline2D failed with the error code " << err2); } } // namespace o2::gpu diff --git a/GPU/Utils/FlatObject.h b/GPU/Utils/FlatObject.h index ac06d7646abd7..d9b3ca8370813 100644 --- a/GPU/Utils/FlatObject.h +++ b/GPU/Utils/FlatObject.h @@ -67,7 +67,7 @@ namespace gpu /// a) by calling /// void startConstruction(); /// ... do something .. -/// void finishConstruction( int flatBufferSize ); +/// void finishConstruction( int32_t flatBufferSize ); /// /// b) or by cloning from another constructed(!) object: /// obj.CloneFromObject(..) @@ -118,7 +118,7 @@ namespace gpu #ifndef GPUCA_GPUCODE // code invisible on GPU template -T* resizeArray(T*& ptr, int oldSize, int newSize, T* newPtr = nullptr) +T* resizeArray(T*& ptr, int32_t oldSize, int32_t newSize, T* newPtr = nullptr) { // Resize array pointed by ptr. T must be a POD class. // If the non-null newPtr is provided, use it instead of allocating a new one. @@ -131,7 +131,7 @@ T* resizeArray(T*& ptr, int oldSize, int newSize, T* newPtr = nullptr) if (!newPtr) { newPtr = new T[newSize]; } - int mcp = std::min(newSize, oldSize); + int32_t mcp = std::min(newSize, oldSize); if (mcp) { assert(ptr); std::memmove(newPtr, ptr, mcp * sizeof(T)); @@ -146,7 +146,7 @@ T* resizeArray(T*& ptr, int oldSize, int newSize, T* newPtr = nullptr) } template -T** resizeArray(T**& ptr, int oldSize, int newSize, T** newPtr = nullptr) +T** resizeArray(T**& ptr, int32_t oldSize, int32_t newSize, T** newPtr = nullptr) { // Resize array of pointers pointed by ptr. // If the non-null newPtr is provided, use it instead of allocating a new one. @@ -159,7 +159,7 @@ T** resizeArray(T**& ptr, int oldSize, int newSize, T** newPtr = nullptr) if (!newPtr) { newPtr = new T*[newSize]; } - int mcp = std::min(newSize, oldSize); + int32_t mcp = std::min(newSize, oldSize); std::memmove(newPtr, ptr, mcp * sizeof(T*)); if (newSize > oldSize) { std::memset(newPtr + mcp, 0, (newSize - oldSize) * sizeof(T*)); @@ -204,7 +204,7 @@ class FlatObject /// Finishes construction: creates internal flat buffer. /// A daughter class should put all created variable-size members to this buffer /// - void finishConstruction(int flatBufferSize); + void finishConstruction(int32_t flatBufferSize); /// Initializes from another object, copies data to newBufferPtr /// When newBufferPtr==nullptr, an internal container will be created, the data will be copied there. @@ -259,7 +259,7 @@ class FlatObject const char* getFlatBufferPtr() const { return mFlatBufferPtr; } /// Tells if the object is constructed - bool isConstructed() const { return (mConstructionMask & (unsigned int)ConstructionState::Constructed); } + bool isConstructed() const { return (mConstructionMask & (uint32_t)ConstructionState::Constructed); } /// Tells if the buffer is internal bool isBufferInternal() const { return ((mFlatBufferPtr != nullptr) && (mFlatBufferPtr == mFlatBufferContainer)); } @@ -291,7 +291,7 @@ class FlatObject /// write a child class object to the file template - static int writeToFile(T& obj, TFile& outf, const char* name); + static int32_t writeToFile(T& obj, TFile& outf, const char* name); /// read a child class object from the file template @@ -313,14 +313,14 @@ class FlatObject /// _______________ Data members _______________________________________________ /// Enumeration of construction states - enum ConstructionState : unsigned int { + enum ConstructionState : uint32_t { NotConstructed = 0x0, ///< the object is not constructed Constructed = 0x1, ///< the object is constructed, temporary memory is released InProgress = 0x2 ///< construction started: temporary memory is reserved }; - int mFlatBufferSize = 0; ///< size of the flat buffer - unsigned int mConstructionMask = ConstructionState::NotConstructed; ///< mask for constructed object members, first two bytes are used by this class + int32_t mFlatBufferSize = 0; ///< size of the flat buffer + uint32_t mConstructionMask = ConstructionState::NotConstructed; ///< mask for constructed object members, first two bytes are used by this class char* mFlatBufferContainer = nullptr; //[mFlatBufferSize] Optional container for the flat buffer char* mFlatBufferPtr = nullptr; //! Pointer to the flat buffer @@ -357,19 +357,19 @@ inline void FlatObject::destroy() mConstructionMask = ConstructionState::NotConstructed; } -inline void FlatObject::finishConstruction(int flatBufferSize) +inline void FlatObject::finishConstruction(int32_t flatBufferSize) { /// Finishes construction: creates internal flat buffer. /// A daughter class should put all created variable-size members to this buffer - assert(mConstructionMask & (unsigned int)ConstructionState::InProgress); + assert(mConstructionMask & (uint32_t)ConstructionState::InProgress); mFlatBufferSize = flatBufferSize; mFlatBufferPtr = mFlatBufferContainer = new char[mFlatBufferSize]; memset((void*)mFlatBufferPtr, 0, mFlatBufferSize); // just to avoid random behavior in case of bugs - mConstructionMask = (unsigned int)ConstructionState::Constructed; // clear other possible construction flags + mConstructionMask = (uint32_t)ConstructionState::Constructed; // clear other possible construction flags } inline void FlatObject::cloneFromObject(const FlatObject& obj, char* newFlatBufferPtr) @@ -392,7 +392,7 @@ inline void FlatObject::cloneFromObject(const FlatObject& obj, char* newFlatBuff mFlatBufferSize = obj.mFlatBufferSize; mFlatBufferContainer = newFlatBufferPtr ? nullptr : mFlatBufferPtr; // external buffer is not provided, make object to own the buffer std::memcpy(mFlatBufferPtr, obj.mFlatBufferPtr, obj.mFlatBufferSize); - mConstructionMask = (unsigned int)ConstructionState::Constructed; + mConstructionMask = (uint32_t)ConstructionState::Constructed; } inline void FlatObject::moveBufferTo(char* newFlatBufferPtr) @@ -461,8 +461,8 @@ inline void FlatObject::printC() const { /// Print the content of the flat buffer bool lfdone = false; - for (int i = 0; i < mFlatBufferSize; i++) { - unsigned char v = mFlatBufferPtr[i]; + for (int32_t i = 0; i < mFlatBufferSize; i++) { + uint8_t v = mFlatBufferPtr[i]; lfdone = false; printf("0x%02x ", v); if (i && ((i + 1) % 20) == 0) { @@ -479,7 +479,7 @@ inline void FlatObject::printC() const #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU template -inline int FlatObject::writeToFile(T& obj, TFile& outf, const char* name) +inline int32_t FlatObject::writeToFile(T& obj, TFile& outf, const char* name) { /// store to file assert(obj.isConstructed()); diff --git a/GPU/Utils/GPUCommonBitSet.h b/GPU/Utils/GPUCommonBitSet.h index e4e8e87442681..03b494dbd1231 100644 --- a/GPU/Utils/GPUCommonBitSet.h +++ b/GPU/Utils/GPUCommonBitSet.h @@ -30,7 +30,7 @@ namespace o2::gpu::gpustd { -template +template class bitset { static_assert(N <= 32, "> 32 bits not supported"); @@ -41,17 +41,17 @@ class bitset #ifdef __OPENCL__ GPUdDefault() constexpr bitset(const __constant bitset&) = default; #endif // __OPENCL__ - GPUd() constexpr bitset(unsigned int vv) : v(vv){}; - static constexpr unsigned int full_set = ((1ul << N) - 1ul); + GPUd() constexpr bitset(uint32_t vv) : v(vv) {}; + static constexpr uint32_t full_set = ((1ul << N) - 1ul); GPUd() constexpr bool all() const { return (v & full_set) == full_set; } GPUd() constexpr bool any() const { return v & full_set; } GPUd() constexpr bool none() const { return !any(); } GPUd() constexpr void set() { v = full_set; } - GPUd() constexpr void set(unsigned int i) { v |= (1u << i) & full_set; } + GPUd() constexpr void set(uint32_t i) { v |= (1u << i) & full_set; } GPUd() constexpr void reset() { v = 0; } - GPUd() constexpr void reset(unsigned int i) { v &= ~(1u << i); } + GPUd() constexpr void reset(uint32_t i) { v &= ~(1u << i); } GPUd() constexpr void flip() { v = (~v) & full_set; } GPUdDefault() constexpr bitset& operator=(const bitset&) = default; @@ -77,11 +77,11 @@ class bitset GPUd() constexpr bool operator==(const bitset b) const { return v == b.v; } GPUd() constexpr bool operator!=(const bitset b) const { return v != b.v; } - GPUd() constexpr bool operator[](unsigned int i) const { return (v >> i) & 1u; } + GPUd() constexpr bool operator[](uint32_t i) const { return (v >> i) & 1u; } - GPUd() constexpr unsigned int to_ulong() const { return v; } + GPUd() constexpr uint32_t to_ulong() const { return v; } - GPUd() constexpr unsigned int count() const + GPUd() constexpr uint32_t count() const { // count number of non-0 bits in 32bit word return GPUCommonMath::Popcount(v); @@ -92,22 +92,22 @@ class bitset #endif private: - unsigned int v = 0; + uint32_t v = 0; ClassDefNV(bitset, 1); }; #ifndef GPUCA_GPUCODE_DEVICE -template +template inline std::string bitset::to_string() const { std::string retVal; - for (unsigned int i = N; i--;) { - retVal += std::to_string((int)((*this)[i])); + for (uint32_t i = N; i--;) { + retVal += std::to_string((int32_t)((*this)[i])); } return retVal; } -template +template std::basic_ostream& operator<<(std::basic_ostream& os, const bitset& x) { os << x.to_string(); diff --git a/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx b/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx index 1246d4e491bc2..52c3421fa8eb5 100644 --- a/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx +++ b/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx @@ -22,7 +22,7 @@ using namespace o2::gpu; struct GPUWorkflowHelper::tmpDataContainer { std::vector> ITSClustersArray; - std::vector tpcLinkITS, tpcLinkTRD, tpcLinkTOF; + std::vector tpcLinkITS, tpcLinkTRD, tpcLinkTOF; std::vector globalTracks; std::vector globalTrackTimes; }; @@ -213,11 +213,11 @@ std::shared_ptr GPUWorkflowHelper::fi }; recoCont.createTracksVariadic(creator); if (maskTrk[GID::TPC] && retVal->tpcLinkTRD.size()) { - for (unsigned int i = 0; i < ioPtr.nTRDTracksTPCTRD; i++) { // TODO: This should be handled by the createTracks logic, but so far it lacks the TRD tracks + for (uint32_t i = 0; i < ioPtr.nTRDTracksTPCTRD; i++) { // TODO: This should be handled by the createTracks logic, but so far it lacks the TRD tracks retVal->tpcLinkTRD[ioPtr.trdTracksTPCTRD[i].getRefGlobalTrackId().getIndex()] = i; } if (ioPtr.nTracksTPCITSO2) { - for (unsigned int i = 0; i < ioPtr.nTRDTracksITSTPCTRD; i++) { + for (uint32_t i = 0; i < ioPtr.nTRDTracksITSTPCTRD; i++) { retVal->tpcLinkTRD[ioPtr.tracksTPCITSO2[ioPtr.trdTracksITSTPCTRD[i].getRefGlobalTrackId().getIndex()].getRefTPC().getIndex()] = i | 0x40000000; } } diff --git a/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h b/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h index 17f88d0417979..b4b240f3bd541 100644 --- a/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h +++ b/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h @@ -34,7 +34,7 @@ class TStopwatch; namespace fair::mq { struct RegionInfo; -enum class State : int; +enum class State : int32_t; } // namespace fair::mq namespace o2 { @@ -101,12 +101,12 @@ class GPURecoWorkflowSpec : public o2::framework::Task using CompletionPolicyData = std::vector; struct Config { - int itsTriggerType = 0; - int lumiScaleMode = 0; + int32_t itsTriggerType = 0; + int32_t lumiScaleMode = 0; bool enableMShape = false; bool enableCTPLumi = false; - int enableDoublePipeline = 0; - int tpcDeadMapSources = -1; + int32_t enableDoublePipeline = 0; + int32_t tpcDeadMapSources = -1; bool decompressTPC = false; bool decompressTPCFromROOT = false; bool caClusterer = false; @@ -124,14 +124,14 @@ class GPURecoWorkflowSpec : public o2::framework::Task bool runTPCTracking = false; bool runTRDTracking = false; bool readTRDtracklets = false; - int lumiScaleType = 0; // 0=off, 1=CTP, 2=TPC scalers + int32_t lumiScaleType = 0; // 0=off, 1=CTP, 2=TPC scalers bool outputErrorQA = false; bool runITSTracking = false; bool itsOverrBeamEst = false; bool tpcTriggerHandling = false; }; - GPURecoWorkflowSpec(CompletionPolicyData* policyData, Config const& specconfig, std::vector const& tpcsectors, unsigned long tpcSectorMask, std::shared_ptr& ggr, std::function** gPolicyOrder = nullptr); + GPURecoWorkflowSpec(CompletionPolicyData* policyData, Config const& specconfig, std::vector const& tpcsectors, uint64_t tpcSectorMask, std::shared_ptr& ggr, std::function** gPolicyOrder = nullptr); ~GPURecoWorkflowSpec() override; void init(o2::framework::InitContext& ic) final; void run(o2::framework::ProcessingContext& pc) final; @@ -174,12 +174,12 @@ class GPURecoWorkflowSpec : public o2::framework::Task template void processInputs(o2::framework::ProcessingContext&, D&, E&, F&, G&, bool&, H&, I&, J&, K&); - int runMain(o2::framework::ProcessingContext* pc, GPUTrackingInOutPointers* ptrs, GPUInterfaceOutputs* outputRegions, int threadIndex = 0, GPUInterfaceInputUpdate* inputUpdateCallback = nullptr); - int runITSTracking(o2::framework::ProcessingContext& pc); + int32_t runMain(o2::framework::ProcessingContext* pc, GPUTrackingInOutPointers* ptrs, GPUInterfaceOutputs* outputRegions, int32_t threadIndex = 0, GPUInterfaceInputUpdate* inputUpdateCallback = nullptr); + int32_t runITSTracking(o2::framework::ProcessingContext& pc); - int handlePipeline(o2::framework::ProcessingContext& pc, GPUTrackingInOutPointers& ptrs, gpurecoworkflow_internals::GPURecoWorkflowSpec_TPCZSBuffers& tpcZSmeta, o2::gpu::GPUTrackingInOutZS& tpcZS, std::unique_ptr& context); + int32_t handlePipeline(o2::framework::ProcessingContext& pc, GPUTrackingInOutPointers& ptrs, gpurecoworkflow_internals::GPURecoWorkflowSpec_TPCZSBuffers& tpcZSmeta, o2::gpu::GPUTrackingInOutZS& tpcZS, std::unique_ptr& context); void RunReceiveThread(); - void RunWorkerThread(int id); + void RunWorkerThread(int32_t id); void ExitPipeline(); void handlePipelineEndOfStream(o2::framework::EndOfStreamContext& ec); void handlePipelineStop(); @@ -204,23 +204,23 @@ class GPURecoWorkflowSpec : public o2::framework::Task std::unique_ptr mConfig; std::unique_ptr mConfParam; std::unique_ptr mTimer; - std::vector> mErrorQA; - int mQATaskMask = 0; + std::vector> mErrorQA; + int32_t mQATaskMask = 0; std::unique_ptr mQA; - std::vector mClusterOutputIds; - std::vector mTPCSectors; + std::vector mClusterOutputIds; + std::vector mTPCSectors; std::unique_ptr mITSTrackingInterface; std::unique_ptr mPipeline; o2::its::TimeFrame* mITSTimeFrame = nullptr; std::vector mRegionInfos; const o2::itsmft::TopologyDictionary* mITSDict = nullptr; const o2::dataformats::MeanVertexObject* mMeanVertex; - unsigned long mTPCSectorMask = 0; - long mCreationForCalib = -1; ///< creation time for calib manipulation - int mVerbosity = 0; - unsigned int mNTFs = 0; - unsigned int mNDebugDumps = 0; - unsigned int mNextThreadIndex = 0; + uint64_t mTPCSectorMask = 0; + int64_t mCreationForCalib = -1; ///< creation time for calib manipulation + int32_t mVerbosity = 0; + uint32_t mNTFs = 0; + uint32_t mNDebugDumps = 0; + uint32_t mNextThreadIndex = 0; bool mUpdateGainMapCCDB = true; std::unique_ptr mTFSettings; Config mSpecConfig; diff --git a/GPU/Workflow/src/GPUWorkflowITS.cxx b/GPU/Workflow/src/GPUWorkflowITS.cxx index 5f6ec171d27c1..552c5fca5b83e 100644 --- a/GPU/Workflow/src/GPUWorkflowITS.cxx +++ b/GPU/Workflow/src/GPUWorkflowITS.cxx @@ -23,7 +23,7 @@ namespace o2::gpu { -int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc) +int32_t GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc) { mITSTimeFrame->setDevicePropagator(mGPUReco->GetDeviceO2Propagator()); LOGP(debug, "GPUChainITS is giving me device propagator: {}", (void*)mGPUReco->GetDeviceO2Propagator()); diff --git a/GPU/Workflow/src/GPUWorkflowInternal.h b/GPU/Workflow/src/GPUWorkflowInternal.h index 60efb80dd4723..2e30adbd0130f 100644 --- a/GPU/Workflow/src/GPUWorkflowInternal.h +++ b/GPU/Workflow/src/GPUWorkflowInternal.h @@ -30,9 +30,9 @@ namespace gpurecoworkflow_internals struct GPURecoWorkflowSpec_TPCZSBuffers { std::vector Pointers[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; - std::vector Sizes[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; + std::vector Sizes[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; const void** Pointers2[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; - const unsigned int* Sizes2[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; + const uint32_t* Sizes2[GPUTrackingInOutZS::NSLICES][GPUTrackingInOutZS::NENDPOINTS]; }; struct GPURecoWorkflow_QueueObject { @@ -42,11 +42,11 @@ struct GPURecoWorkflow_QueueObject { GPUTrackingInOutPointers ptrs; o2::framework::DataProcessingHeader::StartTime timeSliceId; - unsigned long mTFId; + uint64_t mTFId; bool jobSubmitted = false; bool jobFinished = false; - int jobReturnValue = 0; + int32_t jobReturnValue = 0; std::mutex jobFinishedMutex; std::condition_variable jobFinishedNotify; bool jobInputFinal = false; @@ -89,10 +89,10 @@ struct GPURecoWorkflowSpec_PipelineInternals { std::mutex completionPolicyMutex; std::condition_variable completionPolicyNotify; - unsigned long mNTFReceived = 0; + uint64_t mNTFReceived = 0; volatile bool mayInject = true; - volatile unsigned long mayInjectTFId = 0; + volatile uint64_t mayInjectTFId = 0; std::mutex mayInjectMutex; std::condition_variable mayInjectCondition; }; diff --git a/GPU/Workflow/src/GPUWorkflowPipeline.cxx b/GPU/Workflow/src/GPUWorkflowPipeline.cxx index 9abea564c06b5..fb23680266ae2 100644 --- a/GPU/Workflow/src/GPUWorkflowPipeline.cxx +++ b/GPU/Workflow/src/GPUWorkflowPipeline.cxx @@ -73,13 +73,13 @@ void GPURecoWorkflowSpec::initPipeline(o2::framework::InitContext& ic) return false; }; mPipeline->receiveThread = std::thread([this]() { RunReceiveThread(); }); - for (unsigned int i = 0; i < mPipeline->workers.size(); i++) { + for (uint32_t i = 0; i < mPipeline->workers.size(); i++) { mPipeline->workers[i].thread = std::thread([this, i]() { RunWorkerThread(i); }); } } } -void GPURecoWorkflowSpec::RunWorkerThread(int id) +void GPURecoWorkflowSpec::RunWorkerThread(int32_t id) { LOG(debug) << "Running pipeline worker " << id; auto& workerContext = mPipeline->workers[id]; @@ -154,7 +154,7 @@ void GPURecoWorkflowSpec::finalizeInputPipelinedJob(GPUTrackingInOutPointers* pt context->jobInputFinalNotify.notify_one(); } -int GPURecoWorkflowSpec::handlePipeline(ProcessingContext& pc, GPUTrackingInOutPointers& ptrs, GPURecoWorkflowSpec_TPCZSBuffers& tpcZSmeta, o2::gpu::GPUTrackingInOutZS& tpcZS, std::unique_ptr& context) +int32_t GPURecoWorkflowSpec::handlePipeline(ProcessingContext& pc, GPUTrackingInOutPointers& ptrs, GPURecoWorkflowSpec_TPCZSBuffers& tpcZSmeta, o2::gpu::GPUTrackingInOutZS& tpcZS, std::unique_ptr& context) { mPipeline->runStarted = true; mPipeline->stateNotify.notify_all(); @@ -181,8 +181,8 @@ int GPURecoWorkflowSpec::handlePipeline(ProcessingContext& pc, GPUTrackingInOutP size_t ptrsTotal = 0; const void* firstPtr = nullptr; - for (unsigned int i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { if (firstPtr == nullptr && ptrs.tpcZS->slice[i].count[j]) { firstPtr = ptrs.tpcZS->slice[i].zsPtr[j][0]; } @@ -201,15 +201,15 @@ int GPURecoWorkflowSpec::handlePipeline(ProcessingContext& pc, GPUTrackingInOutP size_t* ptrBuffer = messageBuffer.data() + sizeof(preMessage) / sizeof(size_t); size_t ptrsCopied = 0; - int lastRegion = -1; - for (unsigned int i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + int32_t lastRegion = -1; + for (uint32_t i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { preMessage.pointerCounts[i][j] = ptrs.tpcZS->slice[i].count[j]; - for (unsigned int k = 0; k < ptrs.tpcZS->slice[i].count[j]; k++) { + for (uint32_t k = 0; k < ptrs.tpcZS->slice[i].count[j]; k++) { const void* curPtr = ptrs.tpcZS->slice[i].zsPtr[j][k]; bool regionFound = lastRegion != -1 && (size_t)curPtr >= (size_t)mRegionInfos[lastRegion].ptr && (size_t)curPtr < (size_t)mRegionInfos[lastRegion].ptr + mRegionInfos[lastRegion].size; if (!regionFound) { - for (unsigned int l = 0; l < mRegionInfos.size(); l++) { + for (uint32_t l = 0; l < mRegionInfos.size(); l++) { if ((size_t)curPtr >= (size_t)mRegionInfos[l].ptr && (size_t)curPtr < (size_t)mRegionInfos[l].ptr + mRegionInfos[l].size) { lastRegion = l; regionFound = true; @@ -286,7 +286,7 @@ void GPURecoWorkflowSpec::RunReceiveThread() auto* device = mPipeline->fmqDevice; while (!mPipeline->shouldTerminate) { bool received = false; - int recvTimeot = 1000; + int32_t recvTimeot = 1000; fair::mq::MessagePtr msg; LOG(debug) << "Waiting for out of band message"; auto shouldReceive = [this]() { return ((mPipeline->fmqState == fair::mq::State::Running || (mPipeline->fmqState == fair::mq::State::Ready && mPipeline->fmqPreviousState == fair::mq::State::Running)) && !mPipeline->endOfStreamAsyncReceived); }; @@ -352,16 +352,16 @@ void GPURecoWorkflowSpec::RunReceiveThread() size_t* ptrBuffer = (size_t*)msg->GetData() + sizeof(pipelinePrepareMessage) / sizeof(size_t); context->tpcZSmeta.Pointers[0][0].resize(m->pointersTotal); context->tpcZSmeta.Sizes[0][0].resize(m->pointersTotal); - int lastRegion = -1; - for (unsigned int i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + int32_t lastRegion = -1; + for (uint32_t i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { context->tpcZS.slice[i].count[j] = m->pointerCounts[i][j]; - for (unsigned int k = 0; k < context->tpcZS.slice[i].count[j]; k++) { + for (uint32_t k = 0; k < context->tpcZS.slice[i].count[j]; k++) { bool regionManaged = ptrBuffer[2 * m->pointersTotal + ptrsCopied + k]; size_t regionId = ptrBuffer[3 * m->pointersTotal + ptrsCopied + k]; bool regionFound = lastRegion != -1 && mRegionInfos[lastRegion].managed == regionManaged && mRegionInfos[lastRegion].id == regionId; if (!regionFound) { - for (unsigned int l = 0; l < mRegionInfos.size(); l++) { + for (uint32_t l = 0; l < mRegionInfos.size(); l++) { if (mRegionInfos[l].managed == regionManaged && mRegionInfos[l].id == regionId) { lastRegion = l; regionFound = true; @@ -370,7 +370,7 @@ void GPURecoWorkflowSpec::RunReceiveThread() } } if (!regionFound) { - LOG(fatal) << "Received ZS Ptr for SHM region (managed " << (int)regionManaged << ", id " << regionId << "), which was not registered for us"; + LOG(fatal) << "Received ZS Ptr for SHM region (managed " << (int32_t)regionManaged << ", id " << regionId << "), which was not registered for us"; } context->tpcZSmeta.Pointers[0][0][ptrsCopied + k] = (void*)(ptrBuffer[ptrsCopied + k] + (size_t)mRegionInfos[lastRegion].ptr); context->tpcZSmeta.Sizes[0][0][ptrsCopied + k] = ptrBuffer[m->pointersTotal + ptrsCopied + k]; @@ -402,13 +402,13 @@ void GPURecoWorkflowSpec::ExitPipeline() mPipeline->fmqDevice = nullptr; mPipeline->shouldTerminate = true; mPipeline->stateNotify.notify_all(); - for (unsigned int i = 0; i < mPipeline->workers.size(); i++) { + for (uint32_t i = 0; i < mPipeline->workers.size(); i++) { mPipeline->workers[i].inputQueueNotify.notify_one(); } if (mPipeline->receiveThread.joinable()) { mPipeline->receiveThread.join(); } - for (unsigned int i = 0; i < mPipeline->workers.size(); i++) { + for (uint32_t i = 0; i < mPipeline->workers.size(); i++) { if (mPipeline->workers[i].thread.joinable()) { mPipeline->workers[i].thread.join(); } diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index c5e3ea7924115..f16082cb6c0da 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -109,7 +109,7 @@ using namespace o2::gpu::gpurecoworkflow_internals; namespace o2::gpu { -GPURecoWorkflowSpec::GPURecoWorkflowSpec(GPURecoWorkflowSpec::CompletionPolicyData* policyData, Config const& specconfig, std::vector const& tpcsectors, unsigned long tpcSectorMask, std::shared_ptr& ggr, std::function** gPolicyOrder) : o2::framework::Task(), mPolicyData(policyData), mTPCSectorMask(tpcSectorMask), mTPCSectors(tpcsectors), mSpecConfig(specconfig), mGGR(ggr) +GPURecoWorkflowSpec::GPURecoWorkflowSpec(GPURecoWorkflowSpec::CompletionPolicyData* policyData, Config const& specconfig, std::vector const& tpcsectors, uint64_t tpcSectorMask, std::shared_ptr& ggr, std::function** gPolicyOrder) : o2::framework::Task(), mPolicyData(policyData), mTPCSectorMask(tpcSectorMask), mTPCSectors(tpcsectors), mSpecConfig(specconfig), mGGR(ggr) { if (mSpecConfig.outputCAClusters && !mSpecConfig.caClusterer && !mSpecConfig.decompressTPC) { throw std::runtime_error("inconsistent configuration: cluster output is only possible if CA clusterer is activated"); @@ -159,8 +159,8 @@ void GPURecoWorkflowSpec::init(InitContext& ic) mConfig->configGRP.continuousMaxTimeBin = (256 * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; } if (mConfig->configProcessing.deviceNum == -2) { - int myId = ic.services().get().inputTimesliceId; - int idMax = ic.services().get().maxInputTimeslices; + int32_t myId = ic.services().get().inputTimesliceId; + int32_t idMax = ic.services().get().maxInputTimeslices; mConfig->configProcessing.deviceNum = myId; LOG(info) << "GPU device number selected from pipeline id: " << myId << " / " << idMax; } @@ -322,10 +322,10 @@ void GPURecoWorkflowSpec::init(InitContext& ic) if (mSpecConfig.enableDoublePipeline == 2) { return; } - if (mConfParam->registerSelectedSegmentIds != -1 && info.managed && info.id != (unsigned int)mConfParam->registerSelectedSegmentIds) { + if (mConfParam->registerSelectedSegmentIds != -1 && info.managed && info.id != (uint32_t)mConfParam->registerSelectedSegmentIds) { return; } - int fd = 0; + int32_t fd = 0; if (mConfParam->mutexMemReg) { mode_t mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; fd = open("/tmp/o2_gpu_memlock_mutex.lock", O_RDWR | O_CREAT | O_CLOEXEC, mask); @@ -396,8 +396,8 @@ void GPURecoWorkflowSpec::processInputs(ProcessingContext& pc, D& tpcZSmeta, E& constexpr static size_t NEndpoints = o2::gpu::GPUTrackingInOutZS::NENDPOINTS; if (mSpecConfig.zsOnTheFly || mSpecConfig.zsDecoder) { - for (unsigned int i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { tpcZSmeta.Pointers[i][j].clear(); tpcZSmeta.Sizes[i][j].clear(); } @@ -412,7 +412,7 @@ void GPURecoWorkflowSpec::processInputs(ProcessingContext& pc, D& tpcZSmeta, E& if (recvsizes) { throw std::runtime_error("Received multiple ZSSIZES data"); } - tpcZSonTheFlySizes = pc.inputs().get>(ref); + tpcZSonTheFlySizes = pc.inputs().get>(ref); recvsizes = true; } // zs pages @@ -428,10 +428,10 @@ void GPURecoWorkflowSpec::processInputs(ProcessingContext& pc, D& tpcZSmeta, E& throw std::runtime_error("TPC ZS on the fly data not received"); } - unsigned int offset = 0; - for (unsigned int i = 0; i < NSectors; i++) { - unsigned int pageSector = 0; - for (unsigned int j = 0; j < NEndpoints; j++) { + uint32_t offset = 0; + for (uint32_t i = 0; i < NSectors; i++) { + uint32_t pageSector = 0; + for (uint32_t j = 0; j < NEndpoints; j++) { pageSector += tpcZSonTheFlySizes[i * NEndpoints + j]; offset += tpcZSonTheFlySizes[i * NEndpoints + j]; } @@ -457,24 +457,24 @@ void GPURecoWorkflowSpec::processInputs(ProcessingContext& pc, D& tpcZSmeta, E& }; auto insertPages = [&tpcZSmeta, checkForZSData](const char* ptr, size_t count, uint32_t subSpec) -> void { if (checkForZSData(ptr, subSpec)) { - int rawcru = o2::tpc::rdh_utils::getCRU(ptr); - int rawendpoint = o2::tpc::rdh_utils::getEndPoint(ptr); + int32_t rawcru = o2::tpc::rdh_utils::getCRU(ptr); + int32_t rawendpoint = o2::tpc::rdh_utils::getEndPoint(ptr); tpcZSmeta.Pointers[rawcru / 10][(rawcru % 10) * 2 + rawendpoint].emplace_back(ptr); tpcZSmeta.Sizes[rawcru / 10][(rawcru % 10) * 2 + rawendpoint].emplace_back(count); } }; if (DPLRawPageSequencer(pc.inputs(), filter)(isSameRdh, insertPages, checkForZSData)) { debugTFDump = true; - static unsigned int nErrors = 0; + static uint32_t nErrors = 0; nErrors++; if (nErrors == 1 || (nErrors < 100 && nErrors % 10 == 0) || nErrors % 1000 == 0 || mNTFs % 1000 == 0) { LOG(error) << "DPLRawPageSequencer failed to process TPC raw data - data most likely not padded correctly - Using slow page scan instead (this alarm is downscaled from now on, so far " << nErrors << " of " << mNTFs << " TFs affected)"; } } - int totalCount = 0; - for (unsigned int i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + int32_t totalCount = 0; + for (uint32_t i = 0; i < GPUTrackingInOutZS::NSLICES; i++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { tpcZSmeta.Pointers2[i][j] = tpcZSmeta.Pointers[i][j].data(); tpcZSmeta.Sizes2[i][j] = tpcZSmeta.Sizes[i][j].data(); tpcZS.slice[i].zsPtr[j] = tpcZSmeta.Pointers2[i][j]; @@ -503,9 +503,9 @@ void GPURecoWorkflowSpec::processInputs(ProcessingContext& pc, D& tpcZSmeta, E& } } -int GPURecoWorkflowSpec::runMain(o2::framework::ProcessingContext* pc, GPUTrackingInOutPointers* ptrs, GPUInterfaceOutputs* outputRegions, int threadIndex, GPUInterfaceInputUpdate* inputUpdateCallback) +int32_t GPURecoWorkflowSpec::runMain(o2::framework::ProcessingContext* pc, GPUTrackingInOutPointers* ptrs, GPUInterfaceOutputs* outputRegions, int32_t threadIndex, GPUInterfaceInputUpdate* inputUpdateCallback) { - int retVal = 0; + int32_t retVal = 0; if (mConfParam->dump < 2) { retVal = mGPUReco->RunTracking(ptrs, outputRegions, threadIndex, inputUpdateCallback); @@ -546,7 +546,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) o2::tpc::CompressedClusters compClustersDummy; o2::gpu::GPUTrackingInOutZS tpcZS; GPURecoWorkflowSpec_TPCZSBuffers tpcZSmeta; - std::array tpcZSonTheFlySizes; + std::array tpcZSonTheFlySizes; gsl::span inputZS; std::unique_ptr tmpEmptyCompClusters; @@ -594,8 +594,8 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) static uint32_t lastFirstTFOrbit = -1; static uint32_t lastTFCounter = -1; if (lastFirstTFOrbit != -1 && lastTFCounter != -1) { - int diffOrbit = tinfo.firstTForbit - lastFirstTFOrbit; - int diffCounter = tinfo.tfCounter - lastTFCounter; + int32_t diffOrbit = tinfo.firstTForbit - lastFirstTFOrbit; + int32_t diffCounter = tinfo.tfCounter - lastTFCounter; if (diffOrbit != diffCounter * mTFSettings->nHBFPerTF) { LOG(error) << "Time frame has mismatching firstTfOrbit - Last orbit/counter: " << lastFirstTFOrbit << " " << lastTFCounter << " - Current: " << tinfo.firstTForbit << " " << tinfo.tfCounter; } @@ -618,7 +618,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) if (mSpecConfig.decompressTPC) { ptrs.tpcCompressedClusters = pCompClustersFlat; } else if (mSpecConfig.zsOnTheFly) { - const unsigned long* buffer = reinterpret_cast(&inputZS[0]); + const uint64_t* buffer = reinterpret_cast(&inputZS[0]); o2::gpu::GPUReconstructionConvert::RunZSEncoderCreateMeta(buffer, tpcZSonTheFlySizes.data(), *&ptrEp, &tpcZS); ptrs.tpcZS = &tpcZS; doInputDigits = doInputDigitsMC = mSpecConfig.processMC; @@ -636,10 +636,10 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) if (mTPCSectorMask != 0xFFFFFFFFF) { // Clean out the unused sectors, such that if they were present by chance, they are not processed, and if the values are uninitialized, we should not crash - for (unsigned int i = 0; i < NSectors; i++) { + for (uint32_t i = 0; i < NSectors; i++) { if (!(mTPCSectorMask & (1ul << i))) { if (ptrs.tpcZS) { - for (unsigned int j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { + for (uint32_t j = 0; j < GPUTrackingInOutZS::NENDPOINTS; j++) { tpcZS.slice[i].zsPtr[j] = nullptr; tpcZS.slice[i].nZSPtr[j] = nullptr; tpcZS.slice[i].count[j] = 0; @@ -656,7 +656,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) if (doInputDigitsMC) { tpcDigitsMap.tpcDigitsMC = &tpcDigitsMapMC; } - for (unsigned int i = 0; i < NSectors; i++) { + for (uint32_t i = 0; i < NSectors; i++) { tpcDigitsMap.tpcDigits[i] = inputsClustersDigits->inputDigits[i].data(); tpcDigitsMap.nTPCDigits[i] = inputsClustersDigits->inputDigits[i].size(); if (doInputDigitsMC) { @@ -766,7 +766,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) // ------------------------------ Actual processing ------------------------------ - if ((int)(ptrs.tpcZS != nullptr) + (int)(ptrs.tpcPackedDigits != nullptr && (ptrs.tpcZS == nullptr || ptrs.tpcPackedDigits->tpcDigitsMC == nullptr)) + (int)(ptrs.clustersNative != nullptr) + (int)(ptrs.tpcCompressedClusters != nullptr) != 1) { + if ((int32_t)(ptrs.tpcZS != nullptr) + (int32_t)(ptrs.tpcPackedDigits != nullptr && (ptrs.tpcZS == nullptr || ptrs.tpcPackedDigits->tpcDigitsMC == nullptr)) + (int32_t)(ptrs.clustersNative != nullptr) + (int32_t)(ptrs.tpcCompressedClusters != nullptr) != 1) { throw std::runtime_error("Invalid input for gpu tracking"); } @@ -789,7 +789,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) memcpy((void*)ptrsDump.get(), (const void*)&ptrs, sizeof(ptrs)); } - int retVal = 0; + int32_t retVal = 0; if (mSpecConfig.enableDoublePipeline) { if (!pipelineContext->jobSubmitted) { enqueuePipelinedJob(&ptrs, &outputRegions, pipelineContext.get(), true); @@ -800,8 +800,8 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) pipelineContext->jobFinishedNotify.wait(lk, [context = pipelineContext.get()]() { return context->jobFinished; }); retVal = pipelineContext->jobReturnValue; } else { - // unsigned int threadIndex = pc.services().get().threadIndex; - unsigned int threadIndex = mNextThreadIndex; + // uint32_t threadIndex = pc.services().get().threadIndex; + uint32_t threadIndex = mNextThreadIndex; if (mConfig->configProcessing.doublePipeline) { mNextThreadIndex = (mNextThreadIndex + 1) % 2; } @@ -824,7 +824,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) for (auto const& ref : InputRecordWalker(pc.inputs(), filter)) { auto data = pc.inputs().get>(ref); if (mConfParam->dumpBadTFMode == 1) { - unsigned long size = data.size(); + uint64_t size = data.size(); fwrite(&size, 1, sizeof(size), fp); } fwrite(data.data(), 1, data.size(), fp); @@ -858,7 +858,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) std::unique_ptr tmpEmptyClNative; if (createEmptyOutput) { memset(&ptrs, 0, sizeof(ptrs)); - for (unsigned int i = 0; i < outputRegions.count(); i++) { + for (uint32_t i = 0; i < outputRegions.count(); i++) { if (outputBuffers[i].first) { size_t toSize = 0; if (i == outputRegions.getIndex(outputRegions.compressedClusters)) { @@ -887,7 +887,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) gsl::span spanOutputClusRefs = {ptrs.outputClusRefsTPCO2, ptrs.nOutputClusRefsTPCO2}; gsl::span spanOutputTracksMCTruth = {ptrs.outputTracksTPCO2MC, ptrs.outputTracksTPCO2MC ? ptrs.nOutputTracksTPCO2 : 0}; if (!mConfParam->allocateOutputOnTheFly) { - for (unsigned int i = 0; i < outputRegions.count(); i++) { + for (uint32_t i = 0; i < outputRegions.count(); i++) { if (outputRegions.asArray()[i].ptrBase) { if (outputRegions.asArray()[i].size == 1) { throw std::runtime_error("Preallocated buffer size exceeded"); @@ -924,20 +924,20 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) o2::tpc::ClusterNativeAccess const& accessIndex = *ptrs.clustersNative; if (mSpecConfig.sendClustersPerSector) { // Clusters are shipped by sector, we are copying into per-sector buffers (anyway only for ROOT output) - for (unsigned int i = 0; i < NSectors; i++) { + for (uint32_t i = 0; i < NSectors; i++) { if (mTPCSectorMask & (1ul << i)) { DataHeader::SubSpecificationType subspec = i; clusterOutputSectorHeader.sectorBits = (1ul << i); char* buffer = pc.outputs().make({gDataOriginTPC, "CLUSTERNATIVE", subspec, {clusterOutputSectorHeader}}, accessIndex.nClustersSector[i] * sizeof(*accessIndex.clustersLinear) + sizeof(o2::tpc::ClusterCountIndex)).data(); o2::tpc::ClusterCountIndex* outIndex = reinterpret_cast(buffer); memset(outIndex, 0, sizeof(*outIndex)); - for (int j = 0; j < o2::tpc::constants::MAXGLOBALPADROW; j++) { + for (int32_t j = 0; j < o2::tpc::constants::MAXGLOBALPADROW; j++) { outIndex->nClusters[i][j] = accessIndex.nClusters[i][j]; } memcpy(buffer + sizeof(*outIndex), accessIndex.clusters[i][0], accessIndex.nClustersSector[i] * sizeof(*accessIndex.clustersLinear)); if (mSpecConfig.processMC && accessIndex.clustersMCTruth) { MCLabelContainer cont; - for (unsigned int j = 0; j < accessIndex.nClustersSector[i]; j++) { + for (uint32_t j = 0; j < accessIndex.nClustersSector[i]; j++) { const auto& labels = accessIndex.clustersMCTruth->getLabels(accessIndex.clusterOffset[i][0] + j); for (const auto& label : labels) { cont.addElement(j, label); @@ -1063,7 +1063,7 @@ Options GPURecoWorkflowSpec::options() bool send = mSpecConfig.enableDoublePipeline == 2; char* o2jobid = getenv("O2JOBID"); char* numaid = getenv("NUMAID"); - int chanid = o2jobid ? atoi(o2jobid) : (numaid ? atoi(numaid) : 0); + int32_t chanid = o2jobid ? atoi(o2jobid) : (numaid ? atoi(numaid) : 0); std::string chan = std::string("name=gpu-prepare-channel,type=") + (send ? "push" : "pull") + ",method=" + (send ? "connect" : "bind") + ",address=ipc://@gpu-prepare-channel-" + std::to_string(chanid) + "-{timeslice0},transport=shmem,rateLogging=0"; opts.emplace_back(o2::framework::ConfigParamSpec{"channel-config", o2::framework::VariantType::String, chan, {"Out-of-band channel config"}}); } diff --git a/GPU/Workflow/src/GPUWorkflowTPC.cxx b/GPU/Workflow/src/GPUWorkflowTPC.cxx index fdfd94f430ab7..97bf3aed26368 100644 --- a/GPU/Workflow/src/GPUWorkflowTPC.cxx +++ b/GPU/Workflow/src/GPUWorkflowTPC.cxx @@ -281,14 +281,14 @@ void GPURecoWorkflowSpec::finaliseCCDBTPC(ConcreteDataMatcher& matcher, void* ob mTPCDeadChannelMapCreator->finalizeDeadChannelMap(); mdEdxCalibContainerBufferNew.get()->setDeadChannelMap(mTPCDeadChannelMapCreator->getDeadChannelMap()); LOGP(info, "Updating dead channel map with IDC pad flags: {} / {} dead pads from pad flags / total", - mTPCDeadChannelMapCreator->getDeadChannelMapIDC().getSum(), mTPCDeadChannelMapCreator->getDeadChannelMap().getSum()); + mTPCDeadChannelMapCreator->getDeadChannelMapIDC().getSum(), mTPCDeadChannelMapCreator->getDeadChannelMap().getSum()); } else if (matcher == ConcreteDataMatcher(gDataOriginTPC, "TPCRUNINFO", 0)) { copyCalibsToBuffer(); mTPCDeadChannelMapCreator->loadFEEConfigViaRunInfoTS(mCreationForCalib); mTPCDeadChannelMapCreator->finalizeDeadChannelMap(); mdEdxCalibContainerBufferNew.get()->setDeadChannelMap(mTPCDeadChannelMapCreator->getDeadChannelMap()); LOGP(info, "Updating dead channel map with the FEE info loaded via TPCRUNINFO for creation time {}: {} / {} dead pads from FEE info / total", - mCreationForCalib, mTPCDeadChannelMapCreator->getDeadChannelMapFEE().getSum(), mTPCDeadChannelMapCreator->getDeadChannelMap().getSum()); + mCreationForCalib, mTPCDeadChannelMapCreator->getDeadChannelMapFEE().getSum(), mTPCDeadChannelMapCreator->getDeadChannelMap().getSum()); } else if (mTPCVDriftHelper->accountCCDBInputs(matcher, obj)) { } else if (mCalibObjects.mFastTransformHelper->accountCCDBInputs(matcher, obj)) { } @@ -421,7 +421,7 @@ void GPURecoWorkflowSpec::doTrackTuneTPC(GPUTrackingInOutPointers& ptrs, char* b auto diagInner = trackTune.getCovInnerTotal(scale); auto diagOuter = trackTune.getCovOuterTotal(scale); - for (unsigned int itr = 0; itr < ptrs.nOutputTracksTPCO2; itr++) { + for (uint32_t itr = 0; itr < ptrs.nOutputTracksTPCO2; itr++) { auto& trc = tpcTracks[itr]; if (trackTune.useTPCInnerCorr) { trc.updateParams(trackTune.tpcParInner); diff --git a/GPU/Workflow/src/gpu-reco-workflow.cxx b/GPU/Workflow/src/gpu-reco-workflow.cxx index aef7694ac5de7..5e15dde97a146 100644 --- a/GPU/Workflow/src/gpu-reco-workflow.cxx +++ b/GPU/Workflow/src/gpu-reco-workflow.cxx @@ -38,7 +38,7 @@ using namespace o2::dataformats; using namespace o2::gpu; using CompletionPolicyData = std::vector; static CompletionPolicyData gPolicyData; -static constexpr unsigned long gTpcSectorMask = 0xFFFFFFFFF; +static constexpr uint64_t gTpcSectorMask = 0xFFFFFFFFF; static std::function* gPolicyOrderCheck; static std::shared_ptr gTask; @@ -137,7 +137,7 @@ static const std::unordered_map OutputMap{ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec specs; - std::vector tpcSectors(o2::tpc::Sector::MAXSECTOR); + std::vector tpcSectors(o2::tpc::Sector::MAXSECTOR); std::iota(tpcSectors.begin(), tpcSectors.end(), 0); auto inputType = cfgc.options().get("input-type"); @@ -184,7 +184,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) cfg.runTRDTracking = isEnabled(outputTypes, ioType::TRDTracks); cfg.tpcTriggerHandling = isEnabled(outputTypes, ioType::TPCTriggers) || cfg.caClusterer; cfg.enableDoublePipeline = cfgc.options().get("enableDoublePipeline"); - cfg.tpcDeadMapSources = cfgc.options().get("tpc-deadMap-sources"); + cfg.tpcDeadMapSources = cfgc.options().get("tpc-deadMap-sources"); cfg.runITSTracking = isEnabled(outputTypes, ioType::ITSTracks); cfg.itsOverrBeamEst = isEnabled(inputTypes, ioType::MeanVertex); From 281505dc4d9b2885a74ab4c88fe3135c98d247c6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 15:21:47 +0200 Subject: [PATCH 0315/2205] GPU: use ptrDiff function --- GPU/GPUTracking/Base/GPUParam.cxx | 2 +- GPU/GPUTracking/Base/GPUParam.h | 6 ++-- GPU/GPUTracking/Base/GPUParam.inc | 10 +++--- GPU/GPUTracking/Base/GPUReconstruction.cxx | 38 +++++++++++----------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index 765f55d19b19c..8e2daf1a61490 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -267,7 +267,7 @@ void GPUParam::LoadClusterErrors(bool Print) void GPUParamRTC::setFrom(const GPUParam& param) { - memcpy((char*)this, (char*)¶m, sizeof(param)); + memcpy((void*)this, (void*)¶m, sizeof(param)); } std::string GPUParamRTC::generateRTCCode(const GPUParam& param, bool useConstexpr) diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h index 66f312f8f7dc8..070ac76f58ffb 100644 --- a/GPU/GPUTracking/Base/GPUParam.h +++ b/GPU/GPUTracking/Base/GPUParam.h @@ -101,12 +101,12 @@ struct GPUParam : public internal::GPUParam_t return 0.174533f + par.dAlpha * iSlice; } GPUd() float GetClusterErrorSeeding(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult) const; - GPUd() void GetClusterErrorsSeeding2(char sector, int32_t row, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const; + GPUd() void GetClusterErrorsSeeding2(uint8_t sector, int32_t row, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const; GPUd() float GetSystematicClusterErrorIFC2(float trackX, float trackY, float z, bool sideC) const; - GPUd() float GetSystematicClusterErrorC122(float trackX, float trackY, char sector) const; + GPUd() float GetSystematicClusterErrorC122(float trackX, float trackY, uint8_t sector) const; GPUd() float GetClusterError2(int32_t yz, int32_t type, float zDiff, float angle2, float unscaledMult, float scaledAvgInvCharge, float scaledInvCharge) const; - GPUd() void GetClusterErrors2(char sector, int32_t row, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const; + GPUd() void GetClusterErrors2(uint8_t sector, int32_t row, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const; GPUd() void UpdateClusterError2ByState(int16_t clusterState, float& ErrY2, float& ErrZ2) const; GPUd() float GetUnscaledMult(float time) const; diff --git a/GPU/GPUTracking/Base/GPUParam.inc b/GPU/GPUTracking/Base/GPUParam.inc index c3d1aa837e368..c7c526471d505 100644 --- a/GPU/GPUTracking/Base/GPUParam.inc +++ b/GPU/GPUTracking/Base/GPUParam.inc @@ -47,7 +47,7 @@ GPUdi() void MEM_LG(GPUParam)::Global2Slice(int32_t iSlice, float X, float Y, fl #ifdef GPUCA_TPC_GEOMETRY_O2 MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(uint8_t sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const { const int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); @@ -119,7 +119,7 @@ GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorIFC2(float x, float y, } MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float x, float y, char sector) const +GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float x, float y, uint8_t sector) const { const float dx = x - 83.f; if (dx > occupancyTotal * rec.tpc.sysClusErrorC12Box) { @@ -143,7 +143,7 @@ GPUdi() float MEM_LG(GPUParam)::GetClusterErrorSeeding(int32_t yz, int32_t type, } MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrorsSeeding2(uint8_t sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float& ErrY2, float& ErrZ2) const { int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); @@ -179,7 +179,7 @@ GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorIFC2(float trackX, floa } MEM_CLASS_PRE() -GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float trackX, float trackY, char sector) const +GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float trackX, float trackY, uint8_t sector) const { return 0; } @@ -187,7 +187,7 @@ GPUdi() float MEM_LG(GPUParam)::GetSystematicClusterErrorC122(float trackX, floa #endif // !GPUCA_TPC_GEOMETRY_O2 MEM_CLASS_PRE() -GPUdi() void MEM_LG(GPUParam)::GetClusterErrors2(char sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const +GPUdi() void MEM_LG(GPUParam)::GetClusterErrors2(uint8_t sector, int32_t iRow, float z, float sinPhi, float DzDs, float time, float avgInvCharge, float invCharge, float& ErrY2, float& ErrZ2) const { const int32_t rowType = tpcGeometry.GetROC(iRow); z = CAMath::Abs(tpcGeometry.TPCLength() - CAMath::Abs(z)); diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index a526f11f103da..90fc5216a943d 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -166,8 +166,8 @@ int32_t GPUReconstruction::Init() for (uint32_t i = 0; i < mSlaves.size(); i++) { mSlaves[i]->mDeviceMemoryBase = mDeviceMemoryPermanent; mSlaves[i]->mHostMemoryBase = mHostMemoryPermanent; - mSlaves[i]->mDeviceMemorySize = mDeviceMemorySize - ((char*)mSlaves[i]->mDeviceMemoryBase - (char*)mDeviceMemoryBase); - mSlaves[i]->mHostMemorySize = mHostMemorySize - ((char*)mSlaves[i]->mHostMemoryBase - (char*)mHostMemoryBase); + mSlaves[i]->mDeviceMemorySize = mDeviceMemorySize - ptrDiff(mSlaves[i]->mDeviceMemoryBase, mDeviceMemoryBase); + mSlaves[i]->mHostMemorySize = mHostMemorySize - ptrDiff(mSlaves[i]->mHostMemoryBase, mHostMemoryBase); mSlaves[i]->mHostMemoryPoolEnd = mHostMemoryPoolEnd; mSlaves[i]->mDeviceMemoryPoolEnd = mDeviceMemoryPoolEnd; if (mSlaves[i]->InitDevice()) { @@ -437,7 +437,7 @@ void GPUReconstruction::WriteConstantParams() { if (IsGPU()) { const auto threadContext = GetThreadContext(); - WriteToConstantMemory((char*)&processors()->param - (char*)processors(), ¶m(), sizeof(param()), -1); + WriteToConstantMemory(ptrDiff(&processors()->param, processors()), ¶m(), sizeof(param()), -1); } } @@ -491,7 +491,7 @@ void GPUReconstruction::ComputeReuseMax(GPUProcessor* proc) resMain.mOverrideSize = 0; for (uint32_t i = 0; i < re.res.size(); i++) { GPUMemoryResource& res = mMemoryResources[re.res[i]]; - resMain.mOverrideSize = std::max(resMain.mOverrideSize, (char*)res.SetPointers((void*)1) - (char*)1); + resMain.mOverrideSize = std::max(resMain.mOverrideSize, ptrDiff(res.SetPointers((void*)1), (char*)1)); } } } @@ -545,7 +545,7 @@ size_t GPUReconstruction::AllocateRegisteredMemoryHelper(GPUMemoryResource* res, GPUError("Invalid reuse ptr (%s)", res->mName); throw std::bad_alloc(); } - size_t retVal = (char*)((res->*setPtr)(ptr)) - (char*)(ptr); + size_t retVal = ptrDiff((res->*setPtr)(ptr), ptr); if (retVal > mMemoryResources[res->mReuse].mSize) { GPUError("Insufficient reuse memory %lu < %lu (%s) (%s)", mMemoryResources[res->mReuse].mSize, retVal, res->mName, device); throw std::bad_alloc(); @@ -561,7 +561,7 @@ size_t GPUReconstruction::AllocateRegisteredMemoryHelper(GPUMemoryResource* res, } size_t retVal; if ((res->mType & GPUMemoryResource::MEMORY_STACK) && memorypoolend) { - retVal = (char*)((res->*setPtr)((char*)1)) - (char*)(1); + retVal = ptrDiff((res->*setPtr)((char*)1), (char*)(1)); memorypoolend = (void*)((char*)memorypoolend - GPUProcessor::getAlignmentMod(memorypoolend)); if (retVal < res->mOverrideSize) { retVal = res->mOverrideSize; @@ -569,23 +569,23 @@ size_t GPUReconstruction::AllocateRegisteredMemoryHelper(GPUMemoryResource* res, retVal += GPUProcessor::getAlignment(retVal); memorypoolend = (char*)memorypoolend - retVal; ptr = memorypoolend; - retVal = std::max((char*)((res->*setPtr)(ptr)) - (char*)ptr, res->mOverrideSize); + retVal = std::max(ptrDiff((res->*setPtr)(ptr), ptr), res->mOverrideSize); } else { ptr = memorypool; memorypool = (char*)((res->*setPtr)(ptr)); - retVal = (char*)memorypool - (char*)ptr; + retVal = ptrDiff(memorypool, ptr); if (retVal < res->mOverrideSize) { retVal = res->mOverrideSize; memorypool = (char*)ptr + res->mOverrideSize; } memorypool = (void*)((char*)memorypool + GPUProcessor::getAlignment(memorypool)); } - if (memorypoolend ? (memorypool > memorypoolend) : ((size_t)((char*)memorypool - (char*)memorybase) > memorysize)) { - std::cerr << "Memory pool size exceeded (" << device << ") (" << res->mName << ": " << (memorypoolend ? (memorysize + ((char*)memorypool - (char*)memorypoolend)) : (char*)memorypool - (char*)memorybase) << " < " << memorysize << "\n"; + if (memorypoolend ? (memorypool > memorypoolend) : ((size_t)ptrDiff(memorypool, memorybase) > memorysize)) { + std::cerr << "Memory pool size exceeded (" << device << ") (" << res->mName << ": " << (memorypoolend ? (memorysize + ptrDiff(memorypool, memorypoolend)) : ptrDiff(memorypool, memorybase)) << " < " << memorysize << "\n"; throw std::bad_alloc(); } if (mProcessingSettings.allocDebugLevel >= 2) { - std::cout << "Allocated (" << device << ") " << res->mName << ": " << retVal << " - available: " << (memorypoolend ? ((char*)memorypoolend - (char*)memorypool) : (memorysize - ((char*)memorypool - (char*)memorybase))) << "\n"; + std::cout << "Allocated (" << device << ") " << res->mName << ": " << retVal << " - available: " << (memorypoolend ? ptrDiff(memorypoolend, memorypool) : (memorysize - ptrDiff(memorypool, memorybase))) << "\n"; } return retVal; } @@ -633,7 +633,7 @@ void GPUReconstruction::AllocateRegisteredMemoryInternal(GPUMemoryResource* res, if (control->allocator) { res->mSize = std::max((size_t)res->SetPointers((void*)1) - 1, res->mOverrideSize); res->mPtr = control->allocator(CAMath::nextMultipleOf(res->mSize)); - res->mSize = std::max((char*)res->SetPointers(res->mPtr) - (char*)res->mPtr, res->mOverrideSize); + res->mSize = std::max(ptrDiff(res->SetPointers(res->mPtr), res->mPtr), res->mOverrideSize); if (mProcessingSettings.allocDebugLevel >= 2) { std::cout << "Allocated (from callback) " << res->mName << ": " << res->mSize << "\n"; } @@ -701,12 +701,12 @@ void* GPUReconstruction::AllocateUnmanagedMemory(size_t size, int32_t type) char* retVal; GPUProcessor::computePointerWithAlignment(pool, retVal, size); if (pool > poolend) { - GPUError("Insufficient unmanaged memory: missing %lu bytes", (size_t)((char*)pool - (char*)poolend)); + GPUError("Insufficient unmanaged memory: missing %ld bytes", ptrDiff(pool, poolend)); throw std::bad_alloc(); } UpdateMaxMemoryUsed(); if (mProcessingSettings.allocDebugLevel >= 2) { - std::cout << "Allocated (unmanaged " << (type == GPUMemoryResource::MEMORY_GPU ? "gpu" : "host") << "): " << size << " - available: " << ((char*)poolend - (char*)pool) << "\n"; + std::cout << "Allocated (unmanaged " << (type == GPUMemoryResource::MEMORY_GPU ? "gpu" : "host") << "): " << size << " - available: " << ptrDiff(poolend, pool) << "\n"; } return retVal; } @@ -723,12 +723,12 @@ void* GPUReconstruction::AllocateVolatileDeviceMemory(size_t size) char* retVal; GPUProcessor::computePointerWithAlignment(mDeviceMemoryPool, retVal, size); if (mDeviceMemoryPool > mDeviceMemoryPoolEnd) { - GPUError("Insufficient volatile device memory: missing %lu", (size_t)((char*)mDeviceMemoryPool - (char*)mDeviceMemoryPoolEnd)); + GPUError("Insufficient volatile device memory: missing %ld", ptrDiff(mDeviceMemoryPool, mDeviceMemoryPoolEnd)); throw std::bad_alloc(); } UpdateMaxMemoryUsed(); if (mProcessingSettings.allocDebugLevel >= 2) { - std::cout << "Allocated (volatile GPU): " << size << " - available: " << ((char*)mDeviceMemoryPoolEnd - (char*)mDeviceMemoryPool) << "\n"; + std::cout << "Allocated (volatile GPU): " << size << " - available: " << ptrDiff(mDeviceMemoryPoolEnd, mDeviceMemoryPool) << "\n"; } return retVal; @@ -757,7 +757,7 @@ void GPUReconstruction::ResetRegisteredMemoryPointers(int16_t ires) GPUMemoryResource* res = &mMemoryResources[ires]; if (!(res->mType & GPUMemoryResource::MEMORY_EXTERNAL) && (res->mType & GPUMemoryResource::MEMORY_HOST)) { void* basePtr = res->mReuse >= 0 ? mMemoryResources[res->mReuse].mPtr : res->mPtr; - size_t size = (char*)res->SetPointers(basePtr) - (char*)basePtr; + size_t size = ptrDiff(res->SetPointers(basePtr), basePtr); if (basePtr && size > std::max(res->mSize, res->mOverrideSize)) { std::cerr << "Updated pointers exceed available memory size: " << size << " > " << std::max(res->mSize, res->mOverrideSize) << " - host - " << res->mName << "\n"; throw std::bad_alloc(); @@ -765,7 +765,7 @@ void GPUReconstruction::ResetRegisteredMemoryPointers(int16_t ires) } if (IsGPU() && (res->mType & GPUMemoryResource::MEMORY_GPU)) { void* basePtr = res->mReuse >= 0 ? mMemoryResources[res->mReuse].mPtrDevice : res->mPtrDevice; - size_t size = (char*)res->SetDevicePointers(basePtr) - (char*)basePtr; + size_t size = ptrDiff(res->SetDevicePointers(basePtr), basePtr); if (basePtr && size > std::max(res->mSize, res->mOverrideSize)) { std::cerr << "Updated pointers exceed available memory size: " << size << " > " << std::max(res->mSize, res->mOverrideSize) << " - GPU - " << res->mName << "\n"; throw std::bad_alloc(); @@ -806,7 +806,7 @@ void GPUReconstruction::ReturnVolatileDeviceMemory() mVolatileMemoryStart = nullptr; } if (mProcessingSettings.allocDebugLevel >= 2) { - std::cout << "Freed (volatile GPU) - available: " << ((char*)mDeviceMemoryPoolEnd - (char*)mDeviceMemoryPool) << "\n"; + std::cout << "Freed (volatile GPU) - available: " << ptrDiff(mDeviceMemoryPoolEnd, mDeviceMemoryPool) << "\n"; } } From ce427f7d8e3e63dba1adf882fa3290f8133c50f5 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 20:54:46 +0200 Subject: [PATCH 0316/2205] GPU: Use standard types in TPC clusterizer instead of own uint/ushort/etc. --- .../opencl-common/GPUReconstructionOCL.cl | 2 +- .../GPUTPCCompressionKernels.cxx | 18 +++--- .../Definitions/clusterFinderDefs.h | 15 +---- GPU/GPUTracking/TPCClusterFinder/CfConsts.h | 6 +- GPU/GPUTracking/TPCClusterFinder/CfFragment.h | 2 +- GPU/GPUTracking/TPCClusterFinder/CfUtils.h | 54 ++++++++-------- .../TPCClusterFinder/ClusterAccumulator.cxx | 2 +- .../TPCClusterFinder/ClusterAccumulator.h | 4 +- .../GPUTPCCFChargeMapFiller.cxx | 4 +- .../GPUTPCCFChargeMapFiller.h | 2 +- .../TPCClusterFinder/GPUTPCCFClusterizer.cxx | 46 ++++++------- .../TPCClusterFinder/GPUTPCCFClusterizer.h | 12 ++-- .../GPUTPCCFDeconvolution.cxx | 40 ++++++------ .../TPCClusterFinder/GPUTPCCFDeconvolution.h | 10 +-- .../GPUTPCCFMCLabelFlattener.cxx | 20 +++--- .../GPUTPCCFNoiseSuppression.cxx | 64 +++++++++---------- .../GPUTPCCFNoiseSuppression.h | 14 ++-- .../TPCClusterFinder/GPUTPCCFPeakFinder.cxx | 20 +++--- .../TPCClusterFinder/GPUTPCCFPeakFinder.h | 4 +- .../TPCClusterFinder/GPUTPCClusterFinder.cxx | 4 +- .../GPUTPCClusterFinderDump.cxx | 8 +-- .../TPCClusterFinder/MCLabelAccumulator.cxx | 4 +- .../TPCClusterFinder/MCLabelAccumulator.h | 4 +- .../frontend/GPUDisplayFrontendWayland.cxx | 10 +-- .../display/render/GPUDisplayDraw.cxx | 2 +- .../display/shaders/GPUDisplayShaders.h | 4 +- .../devtools/IrregularSpline2D3D.h | 2 +- 27 files changed, 182 insertions(+), 195 deletions(-) diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl index 6c89b2e6a4710..7905ba8fb7d8f 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl @@ -65,7 +65,7 @@ #define int64_t long #define int32_t int #define int16_t short -#define int8_t char +#define int8_t signed char // Disable assertions since they produce errors in GPU Code #ifdef assert diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx index 79bf98e41ffb9..15888e14eec04 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx @@ -348,13 +348,13 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint8_t* CONSTEXPR const int32_t vec32Elems = CpyVector::Size; CONSTEXPR const int32_t vec16Elems = CpyVector::Size; - if (size >= uint(nThreads * vec128Elems)) { + if (size >= uint32_t(nThreads * vec128Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec64Elems)) { + } else if (size >= uint32_t(nThreads * vec64Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec32Elems)) { + } else if (size >= uint32_t(nThreads * vec32Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec16Elems)) { + } else if (size >= uint32_t(nThreads * vec16Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); @@ -368,11 +368,11 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint16_t CONSTEXPR const int32_t vec64Elems = CpyVector::Size; CONSTEXPR const int32_t vec32Elems = CpyVector::Size; - if (size >= uint(nThreads * vec128Elems)) { + if (size >= uint32_t(nThreads * vec128Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec64Elems)) { + } else if (size >= uint32_t(nThreads * vec64Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec32Elems)) { + } else if (size >= uint32_t(nThreads * vec32Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); @@ -385,9 +385,9 @@ GPUdi() void GPUTPCCompressionGatherKernels::compressorMemcpy(uint32_t CONSTEXPR const int32_t vec128Elems = CpyVector::Size; CONSTEXPR const int32_t vec64Elems = CpyVector::Size; - if (size >= uint(nThreads * vec128Elems)) { + if (size >= uint32_t(nThreads * vec128Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); - } else if (size >= uint(nThreads * vec64Elems)) { + } else if (size >= uint32_t(nThreads * vec64Elems)) { compressorMemcpyVectorised(dst, src, size, nThreads, iThread); } else { compressorMemcpyBasic(dst, src, size, nThreads, iThread); diff --git a/GPU/GPUTracking/Definitions/clusterFinderDefs.h b/GPU/GPUTracking/Definitions/clusterFinderDefs.h index 5a4cfc2023588..a681a176f9b5c 100644 --- a/GPU/GPUTracking/Definitions/clusterFinderDefs.h +++ b/GPU/GPUTracking/Definitions/clusterFinderDefs.h @@ -17,13 +17,6 @@ #include "GPUDef.h" -#ifndef __OPENCL__ -using uchar = uint8_t; -#endif -#ifdef __APPLE__ -using ulong = uint64_t; -#endif - /* #define CHARGEMAP_TIME_MAJOR_LAYOUT */ #define CHARGEMAP_TILING_LAYOUT @@ -53,14 +46,8 @@ using ulong = uint64_t; #define TPC_MAX_FRAGMENT_LEN_HOST 1000 #define TPC_MAX_FRAGMENT_LEN_PADDED(size) ((size) + 2 * GPUCF_PADDING_TIME) -#if 0 -#define DBG_PRINT(msg, ...) printf(msg "\n", __VA_ARGS__) -#else -#define DBG_PRINT(msg, ...) static_cast(0) -#endif - #ifdef GPUCA_GPUCODE -#define CPU_ONLY(x) static_cast(0) +#define CPU_ONLY(x) #define CPU_PTR(x) nullptr #else #define CPU_ONLY(x) x diff --git a/GPU/GPUTracking/TPCClusterFinder/CfConsts.h b/GPU/GPUTracking/TPCClusterFinder/CfConsts.h index 31ad34e9d6dc9..235fc6444e8af 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfConsts.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfConsts.h @@ -70,7 +70,7 @@ GPUconstexpr() tpccf::Delta2 OuterNeighbors[16] = {2, 2}, {1, 2}}; -GPUconstexpr() uchar OuterToInner[16] = +GPUconstexpr() uint8_t OuterToInner[16] = { 0, 0, 0, @@ -90,7 +90,7 @@ GPUconstexpr() uchar OuterToInner[16] = // outer to inner mapping change for the peak counting step, // as the other position is the position of the peak -GPUconstexpr() uchar OuterToInnerInv[16] = +GPUconstexpr() uint8_t OuterToInnerInv[16] = { 1, 0, @@ -153,7 +153,7 @@ GPUconstexpr() tpccf::Delta2 NoiseSuppressionNeighbors[NOISE_SUPPRESSION_NEIGHBO {2, 2}, {2, 3}}; -GPUconstexpr() uint NoiseSuppressionMinima[NOISE_SUPPRESSION_NEIGHBOR_NUM] = +GPUconstexpr() uint32_t NoiseSuppressionMinima[NOISE_SUPPRESSION_NEIGHBOR_NUM] = { (1 << 8) | (1 << 9), (1 << 9), diff --git a/GPU/GPUTracking/TPCClusterFinder/CfFragment.h b/GPU/GPUTracking/TPCClusterFinder/CfFragment.h index dfeed31657c65..ae95bfdc61358 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfFragment.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfFragment.h @@ -104,7 +104,7 @@ struct CfFragment { } private: - GPUd() CfFragment(uint index_, bool hasBacklog_, tpccf::TPCTime start_, tpccf::TPCTime totalSliceLen, tpccf::TPCFragmentTime maxSubSliceLen) + GPUd() CfFragment(uint32_t index_, bool hasBacklog_, tpccf::TPCTime start_, tpccf::TPCTime totalSliceLen, tpccf::TPCFragmentTime maxSubSliceLen) { this->index = index_; this->hasBacklog = hasBacklog_; diff --git a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h index 34ddaacb391a4..2e929ecdcf9be 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h @@ -32,19 +32,19 @@ class CfUtils return (pos.pad() < 2 || pos.pad() >= padsPerRow - 2); } - static GPUdi() bool innerAboveThreshold(uchar aboveThreshold, ushort outerIdx) + static GPUdi() bool innerAboveThreshold(uint8_t aboveThreshold, uint16_t outerIdx) { return aboveThreshold & (1 << cfconsts::OuterToInner[outerIdx]); } - static GPUdi() bool innerAboveThresholdInv(uchar aboveThreshold, ushort outerIdx) + static GPUdi() bool innerAboveThresholdInv(uint8_t aboveThreshold, uint16_t outerIdx) { return aboveThreshold & (1 << cfconsts::OuterToInnerInv[outerIdx]); } - static GPUdi() bool isPeak(uchar peak) { return peak & 0x01; } + static GPUdi() bool isPeak(uint8_t peak) { return peak & 0x01; } - static GPUdi() bool isAboveThreshold(uchar peak) { return peak >> 1; } + static GPUdi() bool isAboveThreshold(uint8_t peak) { return peak >> 1; } static GPUdi() int32_t warpPredicateScan(int32_t pred, int32_t* sum) { @@ -159,14 +159,14 @@ class CfUtils } template - static GPUdi() ushort partition(SharedMemory& smem, ushort ll, bool pred, ushort partSize, ushort* newPartSize) + static GPUdi() uint16_t partition(SharedMemory& smem, uint16_t ll, bool pred, uint16_t partSize, uint16_t* newPartSize) { bool participates = ll < partSize; int32_t part; int32_t lpos = blockPredicateScan(smem, int32_t(!pred && participates), &part); - ushort pos = (participates && !pred) ? lpos : part; + uint16_t pos = (participates && !pred) ? lpos : part; *newPartSize = part; return pos; @@ -175,24 +175,24 @@ class CfUtils template static GPUdi() void blockLoad( const Array2D& map, - uint wgSize, - uint elems, - ushort ll, - uint offset, - uint N, + uint32_t wgSize, + uint32_t elems, + uint16_t ll, + uint32_t offset, + uint32_t N, GPUconstexprref() const tpccf::Delta2* neighbors, const ChargePos* posBcast, GPUgeneric() T* buf) { #if defined(GPUCA_GPUCODE) GPUbarrier(); - ushort x = ll % N; - ushort y = ll / N; + uint16_t x = ll % N; + uint16_t y = ll / N; tpccf::Delta2 d = neighbors[x + offset]; for (uint32_t i = y; i < wgSize; i += (elems / N)) { ChargePos readFrom = posBcast[i]; - uint writeTo = N * i + x; + uint32_t writeTo = N * i + x; buf[writeTo] = map[readFrom.delta(d)]; } GPUbarrier(); @@ -208,7 +208,7 @@ class CfUtils for (uint32_t i = 0; i < N; i++) { tpccf::Delta2 d = neighbors[i + offset]; - uint writeTo = N * ll + i; + uint32_t writeTo = N * ll + i; buf[writeTo] = map[readFrom.delta(d)]; } @@ -219,25 +219,25 @@ class CfUtils template static GPUdi() void condBlockLoad( const Array2D& map, - ushort wgSize, - ushort elems, - ushort ll, - ushort offset, - ushort N, + uint16_t wgSize, + uint16_t elems, + uint16_t ll, + uint16_t offset, + uint16_t N, GPUconstexprref() const tpccf::Delta2* neighbors, const ChargePos* posBcast, - const uchar* aboveThreshold, + const uint8_t* aboveThreshold, GPUgeneric() T* buf) { #if defined(GPUCA_GPUCODE) GPUbarrier(); - ushort y = ll / N; - ushort x = ll % N; + uint16_t y = ll / N; + uint16_t x = ll % N; tpccf::Delta2 d = neighbors[x + offset]; for (uint32_t i = y; i < wgSize; i += (elems / N)) { ChargePos readFrom = posBcast[i]; - uchar above = aboveThreshold[i]; - uint writeTo = N * i + x; + uint8_t above = aboveThreshold[i]; + uint32_t writeTo = N * i + x; T v(0); bool cond = (Inv) ? innerAboveThresholdInv(above, x + offset) : innerAboveThreshold(above, x + offset); @@ -253,13 +253,13 @@ class CfUtils } ChargePos readFrom = posBcast[ll]; - uchar above = aboveThreshold[ll]; + uint8_t above = aboveThreshold[ll]; GPUbarrier(); for (uint32_t i = 0; i < N; i++) { tpccf::Delta2 d = neighbors[i + offset]; - uint writeTo = N * ll + i; + uint32_t writeTo = N * ll + i; T v(0); bool cond = (Inv) ? innerAboveThresholdInv(above, i + offset) : innerAboveThreshold(above, i + offset); diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx index 500b4814df73f..8988126f7a15e 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx @@ -42,7 +42,7 @@ GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::Cl bool wasSplitInPad = mSplitInPad >= param.rec.tpc.cfMinSplitNum; bool isSingleCluster = (mPadSigma == 0) || (mTimeSigma == 0); - uchar flags = 0; + uint8_t flags = 0; flags |= (isEdgeCluster) ? tpc::ClusterNative::flagEdge : 0; flags |= (wasSplitInTime) ? tpc::ClusterNative::flagSplitTime : 0; flags |= (wasSplitInPad) ? tpc::ClusterNative::flagSplitPad : 0; diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h index 3958f6d3aa137..c6a05c46a7642 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h @@ -49,8 +49,8 @@ class ClusterAccumulator float mPadSigma = 0; float mTimeMean = 0; float mTimeSigma = 0; - uchar mSplitInTime = 0; - uchar mSplitInPad = 0; + uint8_t mSplitInTime = 0; + uint8_t mSplitInPad = 0; GPUd() void update(tpccf::Charge, tpccf::Delta2); }; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx index 3b24b8795368c..287dad6f5367f 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.cxx @@ -23,14 +23,14 @@ using namespace GPUCA_NAMESPACE::gpu::tpccf; template <> GPUdii() void GPUTPCCFChargeMapFiller::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { - Array2D indexMap(clusterer.mPindexMap); + Array2D indexMap(clusterer.mPindexMap); fillIndexMapImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer.mPmemory->fragment, clusterer.mPdigits, indexMap, clusterer.mPmemory->counters.nDigitsInFragment); } GPUd() void GPUTPCCFChargeMapFiller::fillIndexMapImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const CfFragment& fragment, const tpc::Digit* digits, - Array2D& indexMap, + Array2D& indexMap, size_t maxDigit) { size_t idx = get_global_id(0); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.h index 63bb0d78e2de4..ffb13dbbb0607 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFChargeMapFiller.h @@ -57,7 +57,7 @@ class GPUTPCCFChargeMapFiller : public GPUKernelTemplate template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); - static GPUd() void fillIndexMapImpl(int32_t, int32_t, int32_t, int32_t, const CfFragment&, const tpc::Digit*, Array2D&, size_t); + static GPUd() void fillIndexMapImpl(int32_t, int32_t, int32_t, int32_t, const CfFragment&, const tpc::Digit*, Array2D&, size_t); static GPUd() void fillFromDigitsImpl(int32_t, int32_t, int32_t, int32_t, processorType&, const CfFragment&, size_t, const tpc::Digit*, ChargePos*, Array2D&); diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx index 4d926e3ddfffa..6399ff34fd9b5 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx @@ -45,13 +45,13 @@ GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int32_t nBlocks, int32_t const ChargePos* filteredPeakPositions, const GPUSettingsRec& calib, MCLabelAccumulator* labelAcc, - uint clusternum, - uint maxClusterPerRow, - uint* clusterInRow, + uint32_t clusternum, + uint32_t maxClusterPerRow, + uint32_t* clusterInRow, tpc::ClusterNative* clusterByRow, - uint* clusterPosInRow) + uint32_t* clusterPosInRow) { - uint idx = get_global_id(0); + uint32_t idx = get_global_id(0); // For certain configurations dummy work items are added, so the total // number of work items is dividable by 64. @@ -93,7 +93,7 @@ GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int32_t nBlocks, int32_t return; } - uint rowIndex = 0; + uint32_t rowIndex = 0; if (clusterByRow != nullptr) { rowIndex = sortIntoBuckets( clusterer, @@ -114,18 +114,18 @@ GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int32_t nBlocks, int32_t GPUdii() void GPUTPCCFClusterizer::updateClusterInner( const GPUSettingsRec& calib, - ushort lid, - ushort N, + uint16_t lid, + uint16_t N, const PackedCharge* buf, const ChargePos& pos, ClusterAccumulator* cluster, MCLabelAccumulator* labelAcc, - uchar* innerAboveThreshold) + uint8_t* innerAboveThreshold) { - uchar aboveThreshold = 0; + uint8_t aboveThreshold = 0; GPUCA_UNROLL(U(), U()) - for (ushort i = 0; i < N; i++) { + for (uint16_t i = 0; i < N; i++) { Delta2 d = cfconsts::InnerNeighbors[i]; PackedCharge p = buf[N * lid + i]; @@ -135,7 +135,7 @@ GPUdii() void GPUTPCCFClusterizer::updateClusterInner( CPU_ONLY( labelAcc->collect(pos.delta(d), q)); - aboveThreshold |= (uchar(q > calib.tpc.cfInnerThreshold) << i); + aboveThreshold |= (uint8_t(q > calib.tpc.cfInnerThreshold) << i); } innerAboveThreshold[lid] = aboveThreshold; @@ -144,17 +144,17 @@ GPUdii() void GPUTPCCFClusterizer::updateClusterInner( } GPUdii() void GPUTPCCFClusterizer::updateClusterOuter( - ushort lid, - ushort N, - ushort M, - ushort offset, + uint16_t lid, + uint16_t N, + uint16_t M, + uint16_t offset, const PackedCharge* buf, const ChargePos& pos, ClusterAccumulator* cluster, MCLabelAccumulator* labelAcc) { GPUCA_UNROLL(U(), U()) - for (ushort i = offset; i < M + offset; i++) { + for (uint16_t i = offset; i < M + offset; i++) { PackedCharge p = buf[N * lid + i]; Delta2 d = cfconsts::OuterNeighbors[i]; @@ -173,11 +173,11 @@ GPUdii() void GPUTPCCFClusterizer::buildCluster( ChargePos pos, ChargePos* posBcast, PackedCharge* buf, - uchar* innerAboveThreshold, + uint8_t* innerAboveThreshold, ClusterAccumulator* myCluster, MCLabelAccumulator* labelAcc) { - ushort ll = get_local_id(0); + uint16_t ll = get_local_id(0); posBcast[ll] = pos; GPUbarrier(); @@ -202,11 +202,11 @@ GPUdii() void GPUTPCCFClusterizer::buildCluster( labelAcc, innerAboveThreshold); - ushort wgSizeHalf = (SCRATCH_PAD_WORK_GROUP_SIZE + 1) / 2; + uint16_t wgSizeHalf = (SCRATCH_PAD_WORK_GROUP_SIZE + 1) / 2; bool inGroup1 = ll < wgSizeHalf; - ushort llhalf = (inGroup1) ? ll : (ll - wgSizeHalf); + uint16_t llhalf = (inGroup1) ? ll : (ll - wgSizeHalf); CfUtils::condBlockLoad( chargeMap, @@ -258,9 +258,9 @@ GPUdii() void GPUTPCCFClusterizer::buildCluster( #endif } -GPUd() uint GPUTPCCFClusterizer::sortIntoBuckets(processorType& clusterer, const tpc::ClusterNative& cluster, uint row, uint maxElemsPerBucket, uint* elemsInBucket, tpc::ClusterNative* buckets) +GPUd() uint32_t GPUTPCCFClusterizer::sortIntoBuckets(processorType& clusterer, const tpc::ClusterNative& cluster, uint32_t row, uint32_t maxElemsPerBucket, uint32_t* elemsInBucket, tpc::ClusterNative* buckets) { - uint index = CAMath::AtomicAdd(&elemsInBucket[row], 1u); + uint32_t index = CAMath::AtomicAdd(&elemsInBucket[row], 1u); if (index < maxElemsPerBucket) { buckets[maxElemsPerBucket * row + index] = cluster; } else { diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h index 5836f69425e30..928a23db7c025 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h @@ -40,7 +40,7 @@ class GPUTPCCFClusterizer : public GPUKernelTemplate struct GPUSharedMemory { ChargePos posBcast[SCRATCH_PAD_WORK_GROUP_SIZE]; PackedCharge buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_BUILD_N]; - uchar innerAboveThreshold[SCRATCH_PAD_WORK_GROUP_SIZE]; + uint8_t innerAboveThreshold[SCRATCH_PAD_WORK_GROUP_SIZE]; }; #ifdef GPUCA_HAVE_O2HEADERS @@ -59,16 +59,16 @@ class GPUTPCCFClusterizer : public GPUKernelTemplate template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int8_t); - static GPUd() void computeClustersImpl(int32_t, int32_t, int32_t, int32_t, processorType&, const CfFragment&, GPUSharedMemory&, const Array2D&, const ChargePos*, const GPUSettingsRec&, MCLabelAccumulator*, uint, uint, uint*, tpc::ClusterNative*, uint*); + static GPUd() void computeClustersImpl(int32_t, int32_t, int32_t, int32_t, processorType&, const CfFragment&, GPUSharedMemory&, const Array2D&, const ChargePos*, const GPUSettingsRec&, MCLabelAccumulator*, uint32_t, uint32_t, uint32_t*, tpc::ClusterNative*, uint32_t*); private: - static GPUd() void updateClusterInner(const GPUSettingsRec&, ushort, ushort, const PackedCharge*, const ChargePos&, ClusterAccumulator*, MCLabelAccumulator*, uchar*); + static GPUd() void updateClusterInner(const GPUSettingsRec&, uint16_t, uint16_t, const PackedCharge*, const ChargePos&, ClusterAccumulator*, MCLabelAccumulator*, uint8_t*); - static GPUd() void updateClusterOuter(ushort, ushort, ushort, ushort, const PackedCharge*, const ChargePos&, ClusterAccumulator*, MCLabelAccumulator*); + static GPUd() void updateClusterOuter(uint16_t, uint16_t, uint16_t, uint16_t, const PackedCharge*, const ChargePos&, ClusterAccumulator*, MCLabelAccumulator*); - static GPUd() void buildCluster(const GPUSettingsRec&, const Array2D&, ChargePos, ChargePos*, PackedCharge*, uchar*, ClusterAccumulator*, MCLabelAccumulator*); + static GPUd() void buildCluster(const GPUSettingsRec&, const Array2D&, ChargePos, ChargePos*, PackedCharge*, uint8_t*, ClusterAccumulator*, MCLabelAccumulator*); - static GPUd() uint sortIntoBuckets(processorType&, const tpc::ClusterNative&, uint, uint, uint*, tpc::ClusterNative*); + static GPUd() uint32_t sortIntoBuckets(processorType&, const tpc::ClusterNative&, uint32_t, uint32_t, uint32_t*, tpc::ClusterNative*); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx index 7444fd4e639a2..5c609a9775bd9 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.cxx @@ -25,15 +25,15 @@ template <> GPUdii() void GPUTPCCFDeconvolution::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); - Array2D isPeakMap(clusterer.mPpeakMap); + Array2D isPeakMap(clusterer.mPpeakMap); GPUTPCCFDeconvolution::deconvolutionImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), smem, isPeakMap, chargeMap, clusterer.mPpositions, clusterer.mPmemory->counters.nPositions); } GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, - const Array2D& peakMap, + const Array2D& peakMap, Array2D& chargeMap, const ChargePos* positions, - const uint digitnum) + const uint32_t digitnum) { SizeT idx = get_global_id(0); @@ -46,10 +46,10 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t int8_t peakCount = (iamPeak) ? 1 : 0; - ushort ll = get_local_id(0); - ushort partId = ll; + uint16_t ll = get_local_id(0); + uint16_t partId = ll; - ushort in3x3 = 0; + uint16_t in3x3 = 0; bool exclude3x3 = iamPeak || !pos.valid(); partId = CfUtils::partition(smem, ll, exclude3x3, SCRATCH_PAD_WORK_GROUP_SIZE, &in3x3); @@ -69,12 +69,12 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t smem.posBcast1, smem.buf); - uchar aboveThreshold = 0; + uint8_t aboveThreshold = 0; if (partId < in3x3) { peakCount = countPeaksInner(partId, smem.buf, &aboveThreshold); } - ushort in5x5 = 0; + uint16_t in5x5 = 0; partId = CfUtils::partition(smem, partId, peakCount > 0 && !exclude3x3, in3x3, &in5x5); if (partId < in5x5) { @@ -83,7 +83,7 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t } GPUbarrier(); - CfUtils::condBlockLoad( + CfUtils::condBlockLoad( peakMap, in5x5, SCRATCH_PAD_WORK_GROUP_SIZE, @@ -117,30 +117,30 @@ GPUdii() void GPUTPCCFDeconvolution::deconvolutionImpl(int32_t nBlocks, int32_t } GPUdi() uint8_t GPUTPCCFDeconvolution::countPeaksInner( - ushort ll, - const uchar* isPeak, - uchar* aboveThreshold) + uint16_t ll, + const uint8_t* isPeak, + uint8_t* aboveThreshold) { uint8_t peaks = 0; GPUCA_UNROLL(U(), U()) - for (uchar i = 0; i < 8; i++) { - uchar p = isPeak[ll * 8 + i]; + for (uint8_t i = 0; i < 8; i++) { + uint8_t p = isPeak[ll * 8 + i]; peaks += CfUtils::isPeak(p); - *aboveThreshold |= uchar(CfUtils::isAboveThreshold(p)) << i; + *aboveThreshold |= uint8_t(CfUtils::isAboveThreshold(p)) << i; } return peaks; } GPUdi() uint8_t GPUTPCCFDeconvolution::countPeaksOuter( - ushort ll, - uchar aboveThreshold, - const uchar* isPeak) + uint16_t ll, + uint8_t aboveThreshold, + const uint8_t* isPeak) { uint8_t peaks = 0; GPUCA_UNROLL(U(), U()) - for (uchar i = 0; i < 16; i++) { - uchar p = isPeak[ll * 16 + i]; + for (uint8_t i = 0; i < 16; i++) { + uint8_t p = isPeak[ll * 16 + i]; peaks += CfUtils::isPeak(p); } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h index 55753f163f482..f3f572646751a 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h @@ -32,8 +32,8 @@ class GPUTPCCFDeconvolution : public GPUKernelTemplate static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDeconvolution); struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 { ChargePos posBcast1[SCRATCH_PAD_WORK_GROUP_SIZE]; - uchar aboveThresholdBcast[SCRATCH_PAD_WORK_GROUP_SIZE]; - uchar buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_COUNT_N]; + uint8_t aboveThresholdBcast[SCRATCH_PAD_WORK_GROUP_SIZE]; + uint8_t buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_COUNT_N]; }; #ifdef GPUCA_HAVE_O2HEADERS @@ -53,10 +53,10 @@ class GPUTPCCFDeconvolution : public GPUKernelTemplate GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void deconvolutionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, Array2D&, const ChargePos*, const uint); + static GPUd() void deconvolutionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, Array2D&, const ChargePos*, const uint32_t); - static GPUdi() uint8_t countPeaksInner(ushort, const uchar*, uchar*); - static GPUdi() uint8_t countPeaksOuter(ushort, uchar, const uchar*); + static GPUdi() uint8_t countPeaksInner(uint16_t, const uint8_t*, uint8_t*); + static GPUdi() uint8_t countPeaksOuter(uint16_t, uint8_t, const uint8_t*); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx index 510c651a8671d..a44bf2f327054 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFMCLabelFlattener.cxx @@ -26,8 +26,8 @@ void GPUTPCCFMCLabelFlattener::setGlobalOffsetsAndAllocate( GPUTPCClusterFinder& cls, GPUTPCLinearLabels& labels) { - uint headerOffset = labels.header.size(); - uint dataOffset = labels.data.size(); + uint32_t headerOffset = labels.header.size(); + uint32_t dataOffset = labels.data.size(); cls.mPlabelsHeaderGlobalOffset = headerOffset; cls.mPlabelsDataGlobalOffset = dataOffset; @@ -48,10 +48,10 @@ GPUd() void GPUTPCCFMCLabelFlattener::Thread GPUd() void GPUTPCCFMCLabelFlattener::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory&, processorType& clusterer, GPUTPCLinearLabels* out) { #if !defined(GPUCA_GPUCODE) - uint row = get_global_id(0); + uint32_t row = get_global_id(0); - uint headerOffset = clusterer.mPlabelsHeaderGlobalOffset; - uint dataOffset = clusterer.mPlabelsDataGlobalOffset; - for (uint r = 0; r < row; r++) { + uint32_t headerOffset = clusterer.mPlabelsHeaderGlobalOffset; + uint32_t dataOffset = clusterer.mPlabelsDataGlobalOffset; + for (uint32_t r = 0; r < row; r++) { headerOffset += clusterer.mPclusterInRow[r]; dataOffset += clusterer.mPlabelsInRow[r]; } auto* labels = clusterer.mPlabelsByRow[row].data.data(); - for (uint c = 0; c < clusterer.mPclusterInRow[row]; c++) { + for (uint32_t c = 0; c < clusterer.mPclusterInRow[row]; c++) { GPUTPCClusterMCInterim& interim = labels[c]; assert(dataOffset + interim.labels.size() <= out->data.size()); out->header[headerOffset] = dataOffset; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx index 9307a53a24d90..ec590bd5d1ab3 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.cxx @@ -25,31 +25,31 @@ template <> GPUdii() void GPUTPCCFNoiseSuppression::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); - Array2D isPeakMap(clusterer.mPpeakMap); + Array2D isPeakMap(clusterer.mPpeakMap); noiseSuppressionImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), smem, clusterer.Param().rec, chargeMap, isPeakMap, clusterer.mPpeakPositions, clusterer.mPmemory->counters.nPeaks, clusterer.mPisPeak); } template <> GPUdii() void GPUTPCCFNoiseSuppression::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { - Array2D isPeakMap(clusterer.mPpeakMap); + Array2D isPeakMap(clusterer.mPpeakMap); updatePeaksImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), clusterer.mPpeakPositions, clusterer.mPisPeak, clusterer.mPmemory->counters.nPeaks, isPeakMap); } GPUdii() void GPUTPCCFNoiseSuppression::noiseSuppressionImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, const GPUSettingsRec& calibration, const Array2D& chargeMap, - const Array2D& peakMap, + const Array2D& peakMap, const ChargePos* peakPositions, - const uint peaknum, - uchar* isPeakPredicate) + const uint32_t peaknum, + uint8_t* isPeakPredicate) { SizeT idx = get_global_id(0); ChargePos pos = peakPositions[CAMath::Min(idx, (SizeT)(peaknum - 1))]; Charge charge = chargeMap[pos].unpack(); - ulong minimas, bigger, peaksAround; + uint64_t minimas, bigger, peaksAround; findMinimaAndPeaks( chargeMap, peakMap, @@ -76,9 +76,9 @@ GPUdii() void GPUTPCCFNoiseSuppression::noiseSuppressionImpl(int32_t nBlocks, in GPUd() void GPUTPCCFNoiseSuppression::updatePeaksImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, const ChargePos* peakPositions, - const uchar* isPeak, - const uint peakNum, - Array2D& peakMap) + const uint8_t* isPeak, + const uint32_t peakNum, + Array2D& peakMap) { SizeT idx = get_global_id(0); @@ -88,7 +88,7 @@ GPUd() void GPUTPCCFNoiseSuppression::updatePeaksImpl(int32_t nBlocks, int32_t n ChargePos pos = peakPositions[idx]; - uchar peak = isPeak[idx]; + uint8_t peak = isPeak[idx]; peakMap[pos] = 0b10 | peak; // if this positions was marked as peak at some point, then its charge must exceed the charge threshold. // So we can just set the bit and avoid rereading the charge @@ -100,28 +100,28 @@ GPUdi() void GPUTPCCFNoiseSuppression::checkForMinima( const float epsilonRelative, PackedCharge other, int32_t pos, - ulong* minimas, - ulong* bigger) + uint64_t* minimas, + uint64_t* bigger) { float r = other.unpack(); - ulong isMinima = (q - r > epsilon) && (float)CAMath::Abs(q - r) / (float)CAMath::Max(q, r) > epsilonRelative; // TODO: Can we assume q > r and get rid of Max/Abs? + uint64_t isMinima = (q - r > epsilon) && (float)CAMath::Abs(q - r) / (float)CAMath::Max(q, r) > epsilonRelative; // TODO: Can we assume q > r and get rid of Max/Abs? *minimas |= (isMinima << pos); - ulong lq = (r > q); + uint64_t lq = (r > q); *bigger |= (lq << pos); } GPUdi() void GPUTPCCFNoiseSuppression::findMinima( const PackedCharge* buf, - const ushort ll, + const uint16_t ll, const int32_t N, int32_t pos, const float q, const float epsilon, const float epsilonRelative, - ulong* minimas, - ulong* bigger) + uint64_t* minimas, + uint64_t* bigger) { GPUCA_UNROLL(U(), U()) for (int32_t i = 0; i < N; i++, pos++) { @@ -132,29 +132,29 @@ GPUdi() void GPUTPCCFNoiseSuppression::findMinima( } GPUdi() void GPUTPCCFNoiseSuppression::findPeaks( - const uchar* buf, - const ushort ll, + const uint8_t* buf, + const uint16_t ll, const int32_t N, int32_t pos, - ulong* peaks) + uint64_t* peaks) { GPUCA_UNROLL(U(), U()) for (int32_t i = 0; i < N; i++, pos++) { - ulong p = CfUtils::isPeak(buf[N * ll + i]); + uint64_t p = CfUtils::isPeak(buf[N * ll + i]); *peaks |= (p << pos); } } GPUdi() bool GPUTPCCFNoiseSuppression::keepPeak( - ulong minima, - ulong peaks) + uint64_t minima, + uint64_t peaks) { bool keepMe = true; GPUCA_UNROLL(U(), U()) for (int32_t i = 0; i < NOISE_SUPPRESSION_NEIGHBOR_NUM; i++) { - bool otherPeak = (peaks & (ulong(1) << i)); + bool otherPeak = (peaks & (uint64_t(1) << i)); bool minimaBetween = (minima & cfconsts::NoiseSuppressionMinima[i]); keepMe &= (!otherPeak || minimaBetween); @@ -165,25 +165,25 @@ GPUdi() bool GPUTPCCFNoiseSuppression::keepPeak( GPUd() void GPUTPCCFNoiseSuppression::findMinimaAndPeaks( const Array2D& chargeMap, - const Array2D& peakMap, + const Array2D& peakMap, const GPUSettingsRec& calibration, float q, const ChargePos& pos, ChargePos* posBcast, PackedCharge* buf, - ulong* minimas, - ulong* bigger, - ulong* peaks) + uint64_t* minimas, + uint64_t* bigger, + uint64_t* peaks) { - ushort ll = get_local_id(0); + uint16_t ll = get_local_id(0); posBcast[ll] = pos; GPUbarrier(); - ushort wgSizeHalf = (SCRATCH_PAD_WORK_GROUP_SIZE + 1) / 2; + uint16_t wgSizeHalf = (SCRATCH_PAD_WORK_GROUP_SIZE + 1) / 2; bool inGroup1 = ll < wgSizeHalf; - ushort llhalf = (inGroup1) ? ll : (ll - wgSizeHalf); + uint16_t llhalf = (inGroup1) ? ll : (ll - wgSizeHalf); *minimas = 0; *bigger = 0; @@ -313,7 +313,7 @@ GPUd() void GPUTPCCFNoiseSuppression::findMinimaAndPeaks( } #endif - uchar* bufp = (uchar*)buf; + uint8_t* bufp = (uint8_t*)buf; /************************************** * Look for peaks diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h index 83f5c062fe08a..fe518a3a96d39 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h @@ -57,19 +57,19 @@ class GPUTPCCFNoiseSuppression : public GPUKernelTemplate GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void noiseSuppressionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const GPUSettingsRec&, const Array2D&, const Array2D&, const ChargePos*, const uint, uchar*); + static GPUd() void noiseSuppressionImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const GPUSettingsRec&, const Array2D&, const Array2D&, const ChargePos*, const uint32_t, uint8_t*); - static GPUd() void updatePeaksImpl(int32_t, int32_t, int32_t, int32_t, const ChargePos*, const uchar*, const uint, Array2D&); + static GPUd() void updatePeaksImpl(int32_t, int32_t, int32_t, int32_t, const ChargePos*, const uint8_t*, const uint32_t, Array2D&); - static GPUdi() void checkForMinima(const float, const float, const float, PackedCharge, int32_t, ulong*, ulong*); + static GPUdi() void checkForMinima(const float, const float, const float, PackedCharge, int32_t, uint64_t*, uint64_t*); - static GPUdi() void findMinima(const PackedCharge*, const ushort, const int32_t, int32_t, const float, const float, const float, ulong*, ulong*); + static GPUdi() void findMinima(const PackedCharge*, const uint16_t, const int32_t, int32_t, const float, const float, const float, uint64_t*, uint64_t*); - static GPUdi() void findPeaks(const uchar*, const ushort, const int32_t, int32_t, ulong*); + static GPUdi() void findPeaks(const uint8_t*, const uint16_t, const int32_t, int32_t, uint64_t*); - static GPUdi() bool keepPeak(ulong, ulong); + static GPUdi() bool keepPeak(uint64_t, uint64_t); - static GPUd() void findMinimaAndPeaks(const Array2D&, const Array2D&, const GPUSettingsRec&, float, const ChargePos&, ChargePos*, PackedCharge*, ulong*, ulong*, ulong*); + static GPUd() void findMinimaAndPeaks(const Array2D&, const Array2D&, const GPUSettingsRec&, float, const ChargePos&, ChargePos*, PackedCharge*, uint64_t*, uint64_t*, uint64_t*); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx index 6e2f67fee0d37..be403c98c4acc 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.cxx @@ -26,7 +26,7 @@ template <> GPUdii() void GPUTPCCFPeakFinder::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); - Array2D isPeakMap(clusterer.mPpeakMap); + Array2D isPeakMap(clusterer.mPpeakMap); findPeaksImpl(get_num_groups(0), get_local_size(0), get_group_id(0), get_local_id(0), smem, chargeMap, clusterer.mPpadIsNoisy, clusterer.mPpositions, clusterer.mPmemory->counters.nPositions, clusterer.Param().rec, *clusterer.GetConstantMem()->calibObjects.tpcPadGain, clusterer.mPisPeak, isPeakMap); } @@ -34,18 +34,18 @@ GPUdii() bool GPUTPCCFPeakFinder::isPeak( GPUSharedMemory& smem, Charge q, const ChargePos& pos, - ushort N, + uint16_t N, const Array2D& chargeMap, const GPUSettingsRec& calib, ChargePos* posBcast, PackedCharge* buf) { - ushort ll = get_local_id(0); + uint16_t ll = get_local_id(0); bool belowThreshold = (q <= calib.tpc.cfQMaxCutoff); - ushort lookForPeaks; - ushort partId = CfUtils::partition( + uint16_t lookForPeaks; + uint16_t partId = CfUtils::partition( smem, ll, belowThreshold, @@ -92,13 +92,13 @@ GPUdii() bool GPUTPCCFPeakFinder::isPeak( GPUd() void GPUTPCCFPeakFinder::findPeaksImpl(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, const Array2D& chargeMap, - const uchar* padHasLostBaseline, + const uint8_t* padHasLostBaseline, const ChargePos* positions, SizeT digitnum, const GPUSettingsRec& calib, const TPCPadGainCalib& gainCorrection, // Only used for globalPad() function - uchar* isPeakPredicate, - Array2D& peakMap) + uint8_t* isPeakPredicate, + Array2D& peakMap) { SizeT idx = get_global_id(0); @@ -111,7 +111,7 @@ GPUd() void GPUTPCCFPeakFinder::findPeaksImpl(int32_t nBlocks, int32_t nThreads, bool hasLostBaseline = padHasLostBaseline[gainCorrection.globalPad(pos.row(), pos.pad())]; charge = (hasLostBaseline) ? 0.f : charge; - uchar peak = isPeak(smem, charge, pos, SCRATCH_PAD_SEARCH_N, chargeMap, calib, smem.posBcast, smem.buf); + uint8_t peak = isPeak(smem, charge, pos, SCRATCH_PAD_SEARCH_N, chargeMap, calib, smem.posBcast, smem.buf); // Exit early if dummy. See comment above. bool iamDummy = (idx >= digitnum); @@ -122,6 +122,6 @@ GPUd() void GPUTPCCFPeakFinder::findPeaksImpl(int32_t nBlocks, int32_t nThreads, isPeakPredicate[idx] = peak; if (pos.valid()) { - peakMap[pos] = (uchar(charge > calib.tpc.cfInnerThreshold) << 1) | peak; + peakMap[pos] = (uint8_t(charge > calib.tpc.cfInnerThreshold) << 1) | peak; } } diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h index 0383e8a4d13e1..c0a263f61eaa6 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h @@ -53,9 +53,9 @@ class GPUTPCCFPeakFinder : public GPUKernelTemplate GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, Args... args); private: - static GPUd() void findPeaksImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, const uchar*, const ChargePos*, tpccf::SizeT, const GPUSettingsRec&, const TPCPadGainCalib&, uchar*, Array2D&); + static GPUd() void findPeaksImpl(int32_t, int32_t, int32_t, int32_t, GPUSharedMemory&, const Array2D&, const uint8_t*, const ChargePos*, tpccf::SizeT, const GPUSettingsRec&, const TPCPadGainCalib&, uint8_t*, Array2D&); - static GPUd() bool isPeak(GPUSharedMemory&, tpccf::Charge, const ChargePos&, ushort, const Array2D&, const GPUSettingsRec&, ChargePos*, PackedCharge*); + static GPUd() bool isPeak(GPUSharedMemory&, tpccf::Charge, const ChargePos&, uint16_t, const Array2D&, const GPUSettingsRec&, ChargePos*, PackedCharge*); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx index a5c44e413bc8d..f8ff6b15465c8 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinder.cxx @@ -159,9 +159,9 @@ void GPUTPCClusterFinder::PrepareMC() assert(mNMaxClusterPerRow > 0); clearMCMemory(); - mPindexMap = new uint[TPCMapMemoryLayout::items(mRec->GetProcessingSettings().overrideClusterizerFragmentLen)]; + mPindexMap = new uint32_t[TPCMapMemoryLayout::items(mRec->GetProcessingSettings().overrideClusterizerFragmentLen)]; mPlabelsByRow = new GPUTPCClusterMCInterimArray[GPUCA_ROW_COUNT]; - mPlabelsInRow = new uint[GPUCA_ROW_COUNT]; + mPlabelsInRow = new uint32_t[GPUCA_ROW_COUNT]; } void GPUTPCClusterFinder::clearMCMemory() diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx index ba52167426137..9b52a0ec94170 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCClusterFinderDump.cxx @@ -37,7 +37,7 @@ void GPUTPCClusterFinder::DumpDigits(std::ostream& out) void GPUTPCClusterFinder::DumpChargeMap(std::ostream& out, std::string_view title) { out << "\nClusterer - " << title << " - Slice " << mISlice << " - Fragment " << mPmemory->fragment.index << "\n"; - Array2D map(mPchargeMap); + Array2D map(mPchargeMap); out << std::hex; @@ -47,7 +47,7 @@ void GPUTPCClusterFinder::DumpChargeMap(std::ostream& out, std::string_view titl for (TPCFragmentTime i = start; i < end; i++) { int32_t zeros = 0; for (GlobalPad j = 0; j < TPC_NUM_OF_PADS; j++) { - ushort q = map[{j, i}]; + uint16_t q = map[{j, i}]; zeros += (q == 0); if (q != 0) { if (zeros > 0) { @@ -71,7 +71,7 @@ void GPUTPCClusterFinder::DumpPeakMap(std::ostream& out, std::string_view title) { out << "\nClusterer - " << title << " - Slice " << mISlice << " - Fragment " << mPmemory->fragment.index << "\n"; - Array2D map(mPpeakMap); + Array2D map(mPpeakMap); out << std::hex; @@ -83,7 +83,7 @@ void GPUTPCClusterFinder::DumpPeakMap(std::ostream& out, std::string_view title) out << i << ":"; for (GlobalPad j = 0; j < TPC_NUM_OF_PADS; j++) { - uchar q = map[{j, i}]; + uint8_t q = map[{j, i}]; zeros += (q == 0); if (q != 0) { if (zeros > 0) { diff --git a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx index f6a8fc44025bc..c68f10d388d3c 100644 --- a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.cxx @@ -32,7 +32,7 @@ void MCLabelAccumulator::collect(const ChargePos& pos, Charge q) return; } - uint index = mIndexMap[pos]; + uint32_t index = mIndexMap[pos]; const auto& labels = mLabels->getLabels(index); @@ -51,7 +51,7 @@ void MCLabelAccumulator::collect(const ChargePos& pos, Charge q) } } -void MCLabelAccumulator::commit(Row row, uint indexInRow, uint maxElemsPerBucket) +void MCLabelAccumulator::commit(Row row, uint32_t indexInRow, uint32_t maxElemsPerBucket) { if (indexInRow >= maxElemsPerBucket || !engaged()) { return; diff --git a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.h b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.h index af4f08f0a349e..53446dd4391ac 100644 --- a/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.h +++ b/GPU/GPUTracking/TPCClusterFinder/MCLabelAccumulator.h @@ -48,10 +48,10 @@ class MCLabelAccumulator bool engaged() const { return mLabels != nullptr && mOutput != nullptr; } - void commit(tpccf::Row, uint, uint); + void commit(tpccf::Row, uint32_t, uint32_t); private: - Array2D mIndexMap; + Array2D mIndexMap; const o2::dataformats::ConstMCLabelContainerView* mLabels = nullptr; GPUTPCClusterMCInterimArray* mOutput = nullptr; diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx index 7233ab1d86e33..b920259a1e70d 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayFrontendWayland.cxx @@ -232,7 +232,7 @@ int32_t GPUDisplayFrontendWayland::FrontendMain() const wl_pointer_listener pointer_listener = {.enter = pointer_enter, .leave = pointer_leave, .motion = pointer_motion, .button = pointer_button, .axis = pointer_axis, .frame = nullptr, .axis_source = nullptr, .axis_stop = nullptr, .axis_discrete = nullptr}; #pragma GCC diagnostic pop - auto keyboard_keymap = [](void* data, wl_keyboard* wl_keyboard, uint format, int32_t fd, uint size) { + auto keyboard_keymap = [](void* data, wl_keyboard* wl_keyboard, uint32_t format, int32_t fd, uint32_t size) { GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; if (me->mXKBkeymap) { xkb_state_unref(me->mXKBstate); @@ -244,9 +244,9 @@ int32_t GPUDisplayFrontendWayland::FrontendMain() munmap(keymap_string, size); close(fd); }; - auto keyboard_enter = [](void* data, wl_keyboard* wl_keyboard, uint serial, wl_surface* surface, wl_array* keys) {}; - auto keyboard_leave = [](void* data, wl_keyboard* wl_keyboard, uint serial, wl_surface* surface) {}; - auto keyboard_key = [](void* data, wl_keyboard* wl_keyboard, uint serial, uint time, uint key, uint state) { + auto keyboard_enter = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, wl_surface* surface, wl_array* keys) {}; + auto keyboard_leave = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, wl_surface* surface) {}; + auto keyboard_key = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; int32_t symbol = me->GetKey(key, state); int32_t keyPress = (symbol >= 'a' && symbol <= 'z') ? symbol + 'A' - 'a' : symbol; @@ -259,7 +259,7 @@ int32_t GPUDisplayFrontendWayland::FrontendMain() me->mKeysShift[keyPress] = false; } }; - auto keyboard_modifiers = [](void* data, wl_keyboard* wl_keyboard, uint serial, uint mods_depressed, uint mods_latched, uint mods_locked, uint group) { + auto keyboard_modifiers = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { GPUDisplayFrontendWayland* me = (GPUDisplayFrontendWayland*)data; xkb_state_update_mask(me->mXKBstate, mods_depressed, mods_latched, mods_locked, 0, 0, group); }; diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx index 18b93a7826ffd..ab7ebf6811766 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -963,7 +963,7 @@ size_t GPUDisplay::DrawGLScene_updateVertexList() totalVertizes += mVertexBuffer[i].size(); } if (totalVertizes > 0xFFFFFFFF) { - throw std::runtime_error("Display vertex count exceeds 32bit uint counter"); + throw std::runtime_error("Display vertex count exceeds 32bit uint32_t counter"); } size_t needMultiVBOSize = mBackend->needMultiVBO(); mUseMultiVBO = needMultiVBOSize && (totalVertizes * sizeof(mVertexBuffer[0][0]) >= needMultiVBOSize); diff --git a/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h b/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h index 5dd99fab38160..ff22006ceb37e 100644 --- a/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h +++ b/GPU/GPUTracking/display/shaders/GPUDisplayShaders.h @@ -126,7 +126,7 @@ void main() static constexpr const char* fieldModelShaderCode = R"( layout(std430, binding = 0) restrict readonly buffer field_config_ssbo { - uint StepCount; + uint32_t StepCount; float StepSize; } field_config; @@ -458,7 +458,7 @@ const float positionScale = 100.0f; void main() { vec3 position = gl_in[0].gl_Position.xyz; - for(uint i = 0; i < field_config.StepCount; ++i) { + for(uint32_t i = 0; i < field_config.StepCount; ++i) { gl_Position = um.ModelViewProj * vec4(position/positionScale, 1.0f); EmitVertex(); const vec3 b_vec = Field(position); diff --git a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h index a13884ef6ee02..9135a991c8fef 100644 --- a/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h +++ b/GPU/TPCFastTransformation/devtools/IrregularSpline2D3D.h @@ -355,7 +355,7 @@ GPUdi() void IrregularSpline2D3D::getSplineVec(const float* correctedData, float float dataV[9 + V::size()]; // dataVvec.scatter( dataV, Vc::SimdArray::IndexType::IndexesFromZero() ); - //dataVvec.scatter(dataV, Vc::SimdArray(Vc::IndexesFromZero)); + // dataVvec.scatter(dataV, Vc::SimdArray(Vc::IndexesFromZero)); dataVvec.store(dataV, Vc::Unaligned); for (uint32_t i = 12; i < 9 + V::size(); i++) { // fill not used part of the vector with 0 From aa60f5e2a858e75a14ad00db34836d3bd256d13d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 21:39:18 +0200 Subject: [PATCH 0317/2205] GPU OpenCL: Use typedef instead of define --- .../Base/opencl-common/GPUReconstructionOCL.cl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl index 7905ba8fb7d8f..42a640579e9e3 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl @@ -58,14 +58,14 @@ #define nullptr NULL #define NULL (0x0) #endif -#define uint64_t unsigned long -#define uint32_t unsigned int -#define uint16_t unsigned short -#define uint8_t unsigned char -#define int64_t long -#define int32_t int -#define int16_t short -#define int8_t signed char +typedef unsigned long uint64_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef signed long int64_t; +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; // Disable assertions since they produce errors in GPU Code #ifdef assert From bdf62924594a8bc63264eba892e79ffc9c489af8 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 22:43:51 +0200 Subject: [PATCH 0318/2205] GPU: fix count of CompressionGatherKernel in timing output --- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 5 ++--- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 8 ++++---- GPU/GPUTracking/Global/GPUChain.h | 4 ++-- GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx | 10 +++++----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index 6fcceded9826d..6bf164c08aa3e 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -357,15 +357,14 @@ GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::insertTimer(uint32_t id, return retVal; } -GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::getTimerById(uint32_t id) +GPUReconstructionCPU::timerMeta* GPUReconstructionCPU::getTimerById(uint32_t id, bool increment) { timerMeta* retVal = nullptr; while (timerFlag.test_and_set()) { - ; } if (mTimers.size() > id && mTimers[id]) { retVal = mTimers[id].get(); - retVal->count++; + retVal->count += increment; } timerFlag.clear(); return retVal; diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index 6ac393b1e2aac..63e0f962fd1f1 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -177,7 +177,7 @@ class GPUReconstructionCPU : public GPUReconstructionKernels - HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0); + HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0, bool increment = true); template HighResTimer& getTimer(const char* name, int32_t num = -1); @@ -186,7 +186,7 @@ class GPUReconstructionCPU : public GPUReconstructionKernels -HighResTimer& GPUReconstructionCPU::getKernelTimer(RecoStep step, int32_t num, size_t addMemorySize) +HighResTimer& GPUReconstructionCPU::getKernelTimer(RecoStep step, int32_t num, size_t addMemorySize, bool increment) { static int32_t id = getNextTimerId(); - timerMeta* timer = getTimerById(id); + timerMeta* timer = getTimerById(id, increment); if (timer == nullptr) { timer = insertTimer(id, GetKernelName(), -1, NSLICES, 0, step); } diff --git a/GPU/GPUTracking/Global/GPUChain.h b/GPU/GPUTracking/Global/GPUChain.h index 65de907d7798a..e65396cbce21a 100644 --- a/GPU/GPUTracking/Global/GPUChain.h +++ b/GPU/GPUTracking/Global/GPUChain.h @@ -190,9 +190,9 @@ class GPUChain } template - HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0) + HighResTimer& getKernelTimer(RecoStep step, int32_t num = 0, size_t addMemorySize = 0, bool increment = true) { - return mRec->getKernelTimer(step, num, addMemorySize); + return mRec->getKernelTimer(step, num, addMemorySize, increment); } template HighResTimer& getTimer(const char* name, int32_t num = -1) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 5f046f797f650..9d27a42720613 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -100,24 +100,24 @@ int32_t GPUChainTracking::RunTPCCompression() switch (ProcessingSettings().tpcCompressionGatherModeKernel) { case 0: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); - getKernelTimer(RecoStep::TPCCompression, 0, outputSize); + getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; case 1: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); - getKernelTimer(RecoStep::TPCCompression, 0, outputSize); + getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; case 2: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); - getKernelTimer(RecoStep::TPCCompression, 0, outputSize); + getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; case 3: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); - getKernelTimer(RecoStep::TPCCompression, 0, outputSize); + getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; case 4: static_assert((nBlocksMulti & 1) && nBlocksMulti >= 3); runKernel(GetGridBlkStep(nBlocksMulti, outputStream, RecoStep::TPCCompression)); - getKernelTimer(RecoStep::TPCCompression, 0, outputSize); + getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; default: GPUError("Invalid compression kernel %d selected.", (int32_t)ProcessingSettings().tpcCompressionGatherModeKernel); From dd74f72f28ecb14884f3e5d84cd419c12a8cbde2 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 8 Oct 2024 10:33:08 +0200 Subject: [PATCH 0319/2205] GPU TPCCF: Fix indentation --- GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx index 6399ff34fd9b5..c051f01a71bf1 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx @@ -29,8 +29,7 @@ template <> GPUdii() void GPUTPCCFClusterizer::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& clusterer, int8_t onlyMC) { Array2D chargeMap(reinterpret_cast(clusterer.mPchargeMap)); - CPU_ONLY( - MCLabelAccumulator labelAcc(clusterer)); + CPU_ONLY(MCLabelAccumulator labelAcc(clusterer)); tpc::ClusterNative* clusterOut = (onlyMC) ? nullptr : clusterer.mPclusterByRow; @@ -132,8 +131,7 @@ GPUdii() void GPUTPCCFClusterizer::updateClusterInner( Charge q = cluster->updateInner(p, d); - CPU_ONLY( - labelAcc->collect(pos.delta(d), q)); + CPU_ONLY(labelAcc->collect(pos.delta(d), q)); aboveThreshold |= (uint8_t(q > calib.tpc.cfInnerThreshold) << i); } @@ -162,8 +160,7 @@ GPUdii() void GPUTPCCFClusterizer::updateClusterOuter( Charge q = cluster->updateOuter(p, d); static_cast(q); // Avoid unused varible warning on GPU. - CPU_ONLY( - labelAcc->collect(pos.delta(d), q)); + CPU_ONLY(labelAcc->collect(pos.delta(d), q)); } } From f41b7b87090a36a3698273b6f03edda241e4f0a6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 8 Oct 2024 13:27:23 +0200 Subject: [PATCH 0320/2205] GPU: Unify GPU kernel error handling code --- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 2 +- GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index 63e0f962fd1f1..0a59c0038437a 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -234,7 +234,7 @@ inline int32_t GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args } double deviceTimerTime = 0.; int32_t retVal = runKernelImplWrapper(gpu_reconstruction_kernels::classArgument(), cpuFallback, deviceTimerTime, std::forward(setup), std::forward(args)...); - if (GPUDebug(GetKernelName(), stream)) { + if (GPUDebug(GetKernelName(), stream, mProcessingSettings.checkKernelFailures)) { throw std::runtime_error("kernel failure"); } if (mProcessingSettings.debugLevel >= 1) { diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu index 9fad6caf5e853..72e5d16006a2f 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDAKernels.cu @@ -81,11 +81,6 @@ int32_t GPUReconstructionCUDABackend::runKernelBackend(const krnlSetupArgsrunKernelBackendInternal(args.s, vals...); }, args.v); } GPUFailedMsg(cudaGetLastError()); - if (mProcessingSettings.checkKernelFailures) { - if (GPUDebug(GetKernelName(), args.s.x.stream, true)) { - throw std::runtime_error("Kernel Failure"); - } - } if (z.ev) { GPUFailedMsg(cudaEventRecord(*(cudaEvent_t*)z.ev, mInternals->Streams[x.stream])); } From e4c0849d21e18d7b1ec9190305c0d4cbdbd6b5cd Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 8 Oct 2024 13:46:27 +0200 Subject: [PATCH 0321/2205] GPU: Switch checkKernelFailures setting to more general serializeGPU --- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 2 +- .../Base/GPUReconstructionDeviceBase.cxx | 14 ++++++++++++ .../Base/GPUReconstructionDeviceBase.h | 2 +- .../Base/cuda/GPUReconstructionCUDA.cu | 22 ++++++------------- .../Base/cuda/GPUReconstructionCUDA.h | 1 - .../opencl-common/GPUReconstructionOCL.cxx | 20 +++++------------ .../Base/opencl-common/GPUReconstructionOCL.h | 1 - GPU/GPUTracking/Definitions/GPUSettingsList.h | 2 +- 8 files changed, 30 insertions(+), 34 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index 0a59c0038437a..ac254221c250c 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -234,7 +234,7 @@ inline int32_t GPUReconstructionCPU::runKernel(krnlSetup&& setup, Args&&... args } double deviceTimerTime = 0.; int32_t retVal = runKernelImplWrapper(gpu_reconstruction_kernels::classArgument(), cpuFallback, deviceTimerTime, std::forward(setup), std::forward(args)...); - if (GPUDebug(GetKernelName(), stream, mProcessingSettings.checkKernelFailures)) { + if (GPUDebug(GetKernelName(), stream, mProcessingSettings.serializeGPU & 1)) { throw std::runtime_error("kernel failure"); } if (mProcessingSettings.debugLevel >= 1) { diff --git a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx index 452a32988dbbb..70eedd0ca86d1 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.cxx @@ -325,3 +325,17 @@ void GPUReconstructionDeviceBase::runConstantRegistrators() mDeviceConstantMemList.emplace_back(list[i]()); } } + +size_t GPUReconstructionDeviceBase::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) +{ + if (!(res->Type() & GPUMemoryResource::MEMORY_GPU)) { + if (mProcessingSettings.debugLevel >= 4) { + GPUInfo("Skipped transfer of non-GPU memory resource: %s", res->Name()); + } + return 0; + } + if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { + GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (int64_t)res->Size()); + } + return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); +} diff --git a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h index 6b32301f44b9c..9746250ea3bd3 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h +++ b/GPU/GPUTracking/Base/GPUReconstructionDeviceBase.h @@ -56,7 +56,7 @@ class GPUReconstructionDeviceBase : public GPUReconstructionCPU virtual const GPUTPCTracker* CPUTracker(int32_t iSlice) { return &processors()->tpcTrackers[iSlice]; } int32_t GPUDebug(const char* state = "UNKNOWN", int32_t stream = -1, bool force = false) override = 0; - size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override = 0; + size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override; size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override = 0; size_t GPUMemCpyAlways(bool onGpu, void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override = 0; diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu index 4a7607d5daf5e..69d18597b5579 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu @@ -519,21 +519,10 @@ size_t GPUReconstructionCUDA::GPUMemCpy(void* dst, const void* src, size_t size, if (ev) { GPUFailedMsg(cudaEventRecord(ev->get(), mInternals->Streams[stream == -1 ? 0 : stream])); } - return size; -} - -size_t GPUReconstructionCUDA::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) -{ - if (!(res->Type() & GPUMemoryResource::MEMORY_GPU)) { - if (mProcessingSettings.debugLevel >= 4) { - GPUInfo("Skipped transfer of non-GPU memory resource: %s", res->Name()); - } - return 0; - } - if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (int64_t)res->Size()); + if (mProcessingSettings.serializeGPU & 2) { + GPUDebug(("GPUMemCpy " + std::to_string(toGPU)).c_str(), stream, true); } - return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); + return size; } size_t GPUReconstructionCUDA::WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream, deviceEvent* ev) @@ -552,6 +541,9 @@ size_t GPUReconstructionCUDA::WriteToConstantMemory(size_t offset, const void* s if (ev && stream != -1) { GPUFailedMsg(cudaEventRecord(ev->get(), mInternals->Streams[stream])); } + if (mProcessingSettings.serializeGPU & 2) { + GPUDebug("WriteToConstantMemory", stream, true); + } return size; } @@ -599,7 +591,7 @@ int32_t GPUReconstructionCUDA::GPUDebug(const char* state, int32_t stream, bool cudaError cuErr; cuErr = cudaGetLastError(); if (cuErr != cudaSuccess) { - GPUError("CUDA Error %s while running kernel (%s) (Stream %d)", cudaGetErrorString(cuErr), state, stream); + GPUError("CUDA Error %s while running (%s) (Stream %d)", cudaGetErrorString(cuErr), state, stream); return (1); } if (!force && mProcessingSettings.debugLevel <= 0) { diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h index 93e2d19071275..b9db625a83f1d 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h @@ -82,7 +82,6 @@ class GPUReconstructionCUDA : public GPUReconstructionKernelscommand_queue[stream == -1 ? 0 : stream], mInternals->mem_gpu, stream == -1, (char*)src - (char*)mDeviceMemoryBase, size, dst, nEvents, evList->getEventList(), ev->getEventList())); } - return size; -} - -size_t GPUReconstructionOCL::TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) -{ - if (!(res->Type() & GPUMemoryResource::MEMORY_GPU)) { - if (mProcessingSettings.debugLevel >= 4) { - GPUInfo("Skipped transfer of non-GPU memory resource: %s", res->Name()); - } - return 0; - } - if (mProcessingSettings.debugLevel >= 3 && (strcmp(res->Name(), "ErrorCodes") || mProcessingSettings.debugLevel >= 4)) { - GPUInfo("Copying to %s: %s - %ld bytes", toGPU ? "GPU" : "Host", res->Name(), (int64_t)res->Size()); + if (mProcessingSettings.serializeGPU & 2) { + GPUDebug(("GPUMemCpy " + std::to_string(toGPU)).c_str(), stream, true); } - return GPUMemCpy(dst, src, res->Size(), stream, toGPU, ev, evList, nEvents); + return size; } size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream, deviceEvent* ev) @@ -434,6 +423,9 @@ size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* sr SynchronizeGPU(); } GPUFailedMsg(clEnqueueWriteBuffer(mInternals->command_queue[stream == -1 ? 0 : stream], mInternals->mem_constant, stream == -1, offset, size, src, 0, nullptr, ev->getEventList())); + if (mProcessingSettings.serializeGPU & 2) { + GPUDebug("WriteToConstantMemory", stream, true); + } return size; } diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h index b74785da42c1d..02ba0469dee2a 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h @@ -50,7 +50,6 @@ class GPUReconstructionOCL : public GPUReconstructionDeviceBase bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) override; size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override; - size_t TransferMemoryInternal(GPUMemoryResource* res, int32_t stream, deviceEvent* ev, deviceEvent* evList, int32_t nEvents, bool toGPU, const void* src, void* dst) override; size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; void ReleaseEvent(deviceEvent ev) override; void RecordMarker(deviceEvent ev, int32_t stream) override; diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 745e519fcc404..960f2fcec3f2c 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -227,7 +227,7 @@ AddOption(trdTrackModelO2, bool, false, "", 0, "Use O2 track model instead of GP AddOption(debugLevel, int32_t, -1, "debug", 'd', "Set debug level (-2 = silent, -1 = autoselect (-2 for O2, 0 for standalone))") AddOption(allocDebugLevel, int32_t, 0, "allocDebug", 0, "Some debug output for memory allocations (without messing with normal debug level)") AddOption(debugMask, int32_t, 262143, "", 0, "Mask for debug output dumps to file") -AddOption(checkKernelFailures, bool, false, "", 0, "Synchronize after each kernel call and identify failing kernels") +AddOption(serializeGPU, int8_t, 0, "", 0, "Synchronize after each kernel call (bit 1) and DMA transfer (bit 2) and identify failures") AddOption(deterministicGPUReconstruction, int32_t, -1, "", 0, "Make CPU and GPU debug output comparable (sort / skip concurrent parts), -1 = automatic if debugLevel >= 6") AddOption(showOutputStat, bool, false, "", 0, "Print some track output statistics") AddOption(runCompressionStatistics, bool, false, "compressionStat", 0, "Run statistics and verification for cluster compression") From 37873b792cf9b4698bdc09e93ac5f8a401e431cb Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 7 Oct 2024 22:44:42 +0200 Subject: [PATCH 0322/2205] Fix printf syntax / improve printf(size_t) usage / simplify syntax for MacOS --- .../TPCSectorCompletionPolicy.h | 4 ++-- Detectors/TPC/workflow/src/ZSSpec.cxx | 2 +- .../TPC/workflow/src/tpc-occupancy-filter.cxx | 5 +++-- Detectors/TPC/workflow/src/tpc-reco-workflow.cxx | 3 ++- GPU/GPUTracking/Base/GPUReconstruction.cxx | 16 ++++++++-------- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 16 ++++++++-------- .../DataCompression/GPUTPCClusterStatistics.cxx | 2 +- .../Global/GPUChainTrackingDebugAndProfiling.cxx | 10 +++++----- GPU/GPUTracking/qa/GPUQA.cxx | 5 +++-- 9 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Detectors/TPC/workflow/readers/include/TPCReaderWorkflow/TPCSectorCompletionPolicy.h b/Detectors/TPC/workflow/readers/include/TPCReaderWorkflow/TPCSectorCompletionPolicy.h index 9f2a8b31dbdba..315737df3ec97 100644 --- a/Detectors/TPC/workflow/readers/include/TPCReaderWorkflow/TPCSectorCompletionPolicy.h +++ b/Detectors/TPC/workflow/readers/include/TPCReaderWorkflow/TPCSectorCompletionPolicy.h @@ -228,7 +228,7 @@ class TPCSectorCompletionPolicy mExternalInputMatchers = arg; } else if constexpr (std::is_same_v**>) { mOrderCheck = arg; - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { mTpcSectorMask = arg; } else { static_assert(framework::always_static_assert_v); @@ -245,7 +245,7 @@ class TPCSectorCompletionPolicy // - They are controlled externally and the external entity can modify them, e.g. after parsing command line arguments. // - They are all matched independently, it is not sufficient that one of them is present for all sectors const std::vector* mExternalInputMatchers = nullptr; - const unsigned long* mTpcSectorMask = nullptr; + const uint64_t* mTpcSectorMask = nullptr; bool mRequireAll = false; }; } // namespace tpc diff --git a/Detectors/TPC/workflow/src/ZSSpec.cxx b/Detectors/TPC/workflow/src/ZSSpec.cxx index 7cabef062c307..ccd59de42f000 100644 --- a/Detectors/TPC/workflow/src/ZSSpec.cxx +++ b/Detectors/TPC/workflow/src/ZSSpec.cxx @@ -66,7 +66,7 @@ DataProcessorSpec getZSEncoderSpec(std::vector const& tpcSectors, bool outR using DigitArray = std::array, NSectors>; struct ProcessAttributes { - std::unique_ptr zsoutput; + std::unique_ptr zsoutput; std::unique_ptr itcorr; std::vector sizes; std::vector tpcSectors; diff --git a/Detectors/TPC/workflow/src/tpc-occupancy-filter.cxx b/Detectors/TPC/workflow/src/tpc-occupancy-filter.cxx index f71d0b837f783..6655cd7588a43 100644 --- a/Detectors/TPC/workflow/src/tpc-occupancy-filter.cxx +++ b/Detectors/TPC/workflow/src/tpc-occupancy-filter.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #include "Algorithm/RangeTokenizer.h" #include "Framework/WorkflowSpec.h" @@ -37,8 +38,8 @@ using namespace o2::framework; using namespace o2::tpc; // Global variable used to transport data to the completion policy -std::vector gPolicyData; -unsigned long gTpcSectorMask = 0xFFFFFFFFF; +static std::vector gPolicyData; +static uint64_t gTpcSectorMask = 0xFFFFFFFFF; // customize the completion policy void customize(std::vector& policies) diff --git a/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx b/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx index 33b9de1143434..c9bf62f974d77 100644 --- a/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx +++ b/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx @@ -35,6 +35,7 @@ #include #include #include +#include // we need a global variable to propagate the type the message dispatching of the // publisher will trigger on. This is dependent on the input type @@ -42,7 +43,7 @@ static o2::framework::Output gDispatchTrigger{"", ""}; // Global variable used to transport data to the completion policy static o2::tpc::reco_workflow::CompletionPolicyData gPolicyData; -static unsigned long gTpcSectorMask = 0xFFFFFFFFF; +static uint64_t gTpcSectorMask = 0xFFFFFFFFF; void customize(std::vector& policies) { diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index 90fc5216a943d..ce71753c81f19 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -74,7 +74,7 @@ constexpr const char* const GPUReconstruction::GEOMETRY_TYPE_NAMES[]; constexpr const char* const GPUReconstruction::IOTYPENAMES[]; constexpr GPUReconstruction::GeometryType GPUReconstruction::geometryType; -static int64_t ptrDiff(void* a, void* b) { return (int64_t)((char*)a - (char*)b); } +static ptrdiff_t ptrDiff(void* a, void* b) { return (char*)a - (char*)b; } GPUReconstruction::GPUReconstruction(const GPUSettingsDeviceBackend& cfg) : mHostConstantMem(new GPUConstantMem), mDeviceBackendSettings(cfg) { @@ -834,9 +834,9 @@ void GPUReconstruction::PopNonPersistentMemory(RecoStep step, uint64_t tag) } if ((mProcessingSettings.debugLevel >= 3 || mProcessingSettings.allocDebugLevel) && (IsGPU() || mProcessingSettings.forceHostMemoryPoolSize)) { if (IsGPU()) { - printf("Allocated Device memory after %30s (%8s): %'13ld (non temporary %'13ld, blocked %'13ld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase), mDeviceMemoryPoolBlocked == nullptr ? 0l : ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolBlocked)); + printf("Allocated Device memory after %30s (%8s): %'13zd (non temporary %'13zd, blocked %'13zd)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase), mDeviceMemoryPoolBlocked ? ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolBlocked) : 0); } - printf("Allocated Host memory after %30s (%8s): %'13ld (non temporary %'13ld, blocked %'13ld)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), ptrDiff(mHostMemoryPool, mHostMemoryBase), mHostMemoryPoolBlocked == nullptr ? 0l : ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolBlocked)); + printf("Allocated Host memory after %30s (%8s): %'13zd (non temporary %'13zd, blocked %'13zd)\n", GPUDataTypes::RECO_STEP_NAMES[getRecoStepNum(step, true)], qTag2Str(std::get<3>(mNonPersistentMemoryStack.back())).c_str(), ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), ptrDiff(mHostMemoryPool, mHostMemoryBase), mHostMemoryPoolBlocked ? ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolBlocked) : 0); printf("%16s", ""); PrintMemoryMax(); } @@ -904,15 +904,15 @@ void GPUReconstruction::UpdateMaxMemoryUsed() void GPUReconstruction::PrintMemoryMax() { - printf("Maximum Memory Allocation: Host %'ld / Device %'ld\n", (int64_t)mHostMemoryUsedMax, (int64_t)mDeviceMemoryUsedMax); + printf("Maximum Memory Allocation: Host %'zu / Device %'zu\n", mHostMemoryUsedMax, mDeviceMemoryUsedMax); } void GPUReconstruction::PrintMemoryOverview() { if (mProcessingSettings.memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) { - printf("Memory Allocation: Host %'ld / %'ld (Permanent %'ld), Device %'ld / %'ld, (Permanent %'ld) %d chunks\n", - ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), (int64_t)mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), - ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), (int64_t)mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), (int32_t)mMemoryResources.size()); + printf("Memory Allocation: Host %'zd / %'zu (Permanent %'zd), Device %'zd / %'zu, (Permanent %'zd) %zu chunks\n", + ptrDiff(mHostMemoryPool, mHostMemoryBase) + ptrDiff((char*)mHostMemoryBase + mHostMemorySize, mHostMemoryPoolEnd), mHostMemorySize, ptrDiff(mHostMemoryPermanent, mHostMemoryBase), + ptrDiff(mDeviceMemoryPool, mDeviceMemoryBase) + ptrDiff((char*)mDeviceMemoryBase + mDeviceMemorySize, mDeviceMemoryPoolEnd), mDeviceMemorySize, ptrDiff(mDeviceMemoryPermanent, mDeviceMemoryBase), mMemoryResources.size()); } } @@ -937,7 +937,7 @@ void GPUReconstruction::PrintMemoryStatistics() } printf("%59s CPU / %9s GPU\n", "", ""); for (auto it = sizes.begin(); it != sizes.end(); it++) { - printf("Allocation %30s %s: Size %'14ld / %'14ld\n", it->first.c_str(), it->second[2] ? "P" : " ", (int64_t)it->second[0], (int64_t)it->second[1]); + printf("Allocation %30s %s: Size %'14zu / %'14zu\n", it->first.c_str(), it->second[2] ? "P" : " ", it->second[0], it->second[1]); } PrintMemoryOverview(); for (uint32_t i = 0; i < mChains.size(); i++) { diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index 6bf164c08aa3e..1acbb99973b43 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -268,9 +268,9 @@ int32_t GPUReconstructionCPU::RunChains() } char bandwidth[256] = ""; if (mTimers[i]->memSize && mStatNEvents && time != 0.) { - snprintf(bandwidth, 256, " (%6.3f GB/s - %'14lu bytes)", mTimers[i]->memSize / time * 1e-9, (uint64_t)(mTimers[i]->memSize / mStatNEvents)); + snprintf(bandwidth, 256, " (%8.3f GB/s - %'14zu bytes - %'14zu per call)", mTimers[i]->memSize / time * 1e-9, mTimers[i]->memSize / mStatNEvents, mTimers[i]->memSize / mStatNEvents / mTimers[i]->count); } - printf("Execution Time: Task (%c %8ux): %50s Time: %'10lu us%s\n", type == 0 ? 'K' : 'C', mTimers[i]->count, mTimers[i]->name.c_str(), (uint64_t)(time * 1000000 / mStatNEvents), bandwidth); + printf("Execution Time: Task (%c %8ux): %50s Time: %'10.0f us%s\n", type == 0 ? 'K' : 'C', mTimers[i]->count, mTimers[i]->name.c_str(), time * 1000000 / mStatNEvents, bandwidth); if (mProcessingSettings.resetTimers) { mTimers[i]->count = 0; mTimers[i]->memSize = 0; @@ -278,14 +278,14 @@ int32_t GPUReconstructionCPU::RunChains() } for (int32_t i = 0; i < GPUDataTypes::N_RECO_STEPS; i++) { if (kernelStepTimes[i] != 0. || mTimersRecoSteps[i].timerTotal.GetElapsedTime() != 0.) { - printf("Execution Time: Step : %11s %38s Time: %'10lu us ( Total Time : %'14lu us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(kernelStepTimes[i] * 1000000 / mStatNEvents), (uint64_t)(mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: Step : %11s %38s Time: %'10.0f us %64s ( Total Time : %'14.0f us)\n", "Tasks", GPUDataTypes::RECO_STEP_NAMES[i], kernelStepTimes[i] * 1000000 / mStatNEvents, "", mTimersRecoSteps[i].timerTotal.GetElapsedTime() * 1000000 / mStatNEvents); } if (mTimersRecoSteps[i].bytesToGPU) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10.0f us (%8.3f GB/s - %'14zu bytes - %'14zu per call)\n", mTimersRecoSteps[i].countToGPU, "DMA to GPU", GPUDataTypes::RECO_STEP_NAMES[i], mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1000000 / mStatNEvents, mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].timerToGPU.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToGPU / mStatNEvents, mTimersRecoSteps[i].bytesToGPU / mTimersRecoSteps[i].countToGPU); } if (mTimersRecoSteps[i].bytesToHost) { - printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10lu us (%6.3f GB/s - %'14lu bytes - %'14lu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], (uint64_t)(mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents), + printf("Execution Time: Step (D %8ux): %11s %38s Time: %'10.0f us (%8.3f GB/s - %'14zu bytes - %'14zu per call)\n", mTimersRecoSteps[i].countToHost, "DMA to Host", GPUDataTypes::RECO_STEP_NAMES[i], mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1000000 / mStatNEvents, mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].timerToHost.GetElapsedTime() * 1e-9, mTimersRecoSteps[i].bytesToHost / mStatNEvents, mTimersRecoSteps[i].bytesToHost / mTimersRecoSteps[i].countToHost); } if (mProcessingSettings.resetTimers) { @@ -299,12 +299,12 @@ int32_t GPUReconstructionCPU::RunChains() } for (int32_t i = 0; i < GPUDataTypes::N_GENERAL_STEPS; i++) { if (mTimersGeneralSteps[i].GetElapsedTime() != 0.) { - printf("Execution Time: General Step : %50s Time: %'10lu us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], (uint64_t)(mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents)); + printf("Execution Time: General Step : %50s Time: %'10.0f us\n", GPUDataTypes::GENERAL_STEP_NAMES[i], mTimersGeneralSteps[i].GetElapsedTime() * 1000000 / mStatNEvents); } } mStatKernelTime = kernelTotal * 1000000 / mStatNEvents; - printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Kernel", (uint64_t)mStatKernelTime, nEventReport.c_str()); - printf("Execution Time: Total : %50s Time: %'10lu us%s\n", "Total Wall", (uint64_t)mStatWallTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10.0f us%s\n", "Total Kernel", mStatKernelTime, nEventReport.c_str()); + printf("Execution Time: Total : %50s Time: %'10.0f us%s\n", "Total Wall", mStatWallTime, nEventReport.c_str()); } else if (GetProcessingSettings().debugLevel >= 0) { GPUInfo("Total Wall Time: %lu us%s", (uint64_t)mStatWallTime, nEventReport.c_str()); } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx index 4490c160b2139..33886f721c5db 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterStatistics.cxx @@ -225,7 +225,7 @@ void GPUTPCClusterStatistics::Finish() GPUInfo("Combined Sigma: %6.4f --> %6.4f (%6.4f%%)", eSigma, eSigmaCombined, eSigma > 1e-3 ? (100. * (eSigma - eSigmaCombined) / eSigma) : 0.f); GPUInfo("Combined Q: %6.4f --> %6.4f (%6.4f%%)", eQ, eQCombined, eQ > 1e-3 ? (100. * (eQ - eQCombined) / eQ) : 0.f); - printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'ld clusters)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, (int64_t)mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); + printf("\nCombined Entropy: %7.4f (Size %'13.0f, %'zu clusters)\nCombined Huffman: %7.4f (Size %'13.0f, %f%%)\n\n", mEntropy / mNTotalClusters, mEntropy, mNTotalClusters, mHuffman / mNTotalClusters, mHuffman, 100. * (mHuffman - mEntropy) / mHuffman); } float GPUTPCClusterStatistics::Analyze(std::vector& p, const char* name, bool count) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index a8c3862ff61c6..af04dd5e0ce93 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -111,7 +111,7 @@ int32_t GPUChainTracking::DoProfile() namespace { struct GPUChainTrackingMemUsage { - void add(uint64_t n, uint64_t bound) + void add(size_t n, size_t bound) { nMax = std::max(nMax, n); maxUse = std::max(n / std::max(bound, 1.), maxUse); @@ -119,9 +119,9 @@ struct GPUChainTrackingMemUsage { nBoundSum += bound; count++; } - uint64_t nMax; - uint64_t nSum = 0; - uint64_t nBoundSum = 0; + size_t nMax; + size_t nSum = 0; + size_t nBoundSum = 0; double maxUse = 0.; uint32_t count = 0; }; @@ -163,7 +163,7 @@ void GPUChainTracking::PrintMemoryStatistics() #endif for (auto& elem : usageMap) { - printf("Mem Usage %-30s : %'14lu / %'14lu (%3.0f%% / %3.0f%% / count %3u / max %'14lu)\n", elem.first.c_str(), elem.second.nSum, elem.second.nBoundSum, 100. * elem.second.nSum / std::max(1lu, elem.second.nBoundSum), 100. * elem.second.maxUse, elem.second.count, elem.second.nMax); + printf("Mem Usage %-30s : %'14zu / %'14zu (%3.0f%% / %3.0f%% / count %3u / max %'14zu)\n", elem.first.c_str(), elem.second.nSum, elem.second.nBoundSum, 100. * elem.second.nSum / std::max(1, elem.second.nBoundSum), 100. * elem.second.maxUse, elem.second.count, elem.second.nMax); } } diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 7ef907838ccf4..59293dbfd1812 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -73,6 +73,7 @@ #include "GPUQAHelper.h" #include #include +#include #include "utils/qconfig.h" #include "utils/timer.h" @@ -2796,10 +2797,10 @@ void GPUQA::PrintClusterCount(int32_t mode, int32_t& num, const char* name, uint createHist(mHistClusterCount[num], name2, name, 1000, 0, mConfig.histMaxNClusters, 1000, 0, 100); } else if (mode == 0) { if (normalization && mConfig.enableLocalOutput) { - printf("\t%35s: %'12lu (%6.2f%%)\n", name, n, 100.f * n / normalization); + printf("\t%35s: %'12" PRIu64 " (%6.2f%%)\n", name, n, 100.f * n / normalization); } if (mConfig.clusterRejectionHistograms) { - float ratio = 100.f * n / std::max(normalization, 1lu); + float ratio = 100.f * n / std::max(normalization, 1); mHistClusterCount[num]->Fill(normalization, ratio, 1); } } From eaba5c299f8cfa21fa04e555fc2d4701223b2c41 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Wed, 9 Oct 2024 10:39:38 +0100 Subject: [PATCH 0323/2205] ctpdev: macro for creating CTP BK counters entry from CCDB. (#13570) * dev:macro for creation of BK entry from CCDB * clang * macro for run list * clang --- .../CTP/include/DataFormatsCTP/Scalers.h | 13 ++++ Detectors/CTP/macro/CMakeLists.txt | 4 + Detectors/CTP/macro/CreateBKForRun.C | 74 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 Detectors/CTP/macro/CreateBKForRun.C diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h index 073cd6a78c24f..eacbadbe9bedc 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h @@ -130,6 +130,19 @@ class CTPRunScalers /// same with absolute timestamp (not orbit) as argument std::pair getRateGivenT(double timestamp, int classindex, int type) const; + /// retrieves integral for class + std::array getIntegralForClass(int i) const + { + return { + mScalerRecordO2[0].scalers[i].classIndex, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].lmBefore - mScalerRecordO2[0].scalers[i].lmBefore, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].lmAfter - mScalerRecordO2[0].scalers[i].lmAfter, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].l0Before - mScalerRecordO2[0].scalers[i].l0Before, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].l0After - mScalerRecordO2[0].scalers[i].l0After, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].l1Before - mScalerRecordO2[0].scalers[i].l1Before, + mScalerRecordO2[mScalerRecordO2.size() - 1].scalers[i].l1After - mScalerRecordO2[0].scalers[i].l1After, + }; + } /// retrieves time boundaries of this scaler object from O2 scalers std::pair getTimeLimit() const { diff --git a/Detectors/CTP/macro/CMakeLists.txt b/Detectors/CTP/macro/CMakeLists.txt index eb78fd89d7aff..96f336c840241 100644 --- a/Detectors/CTP/macro/CMakeLists.txt +++ b/Detectors/CTP/macro/CMakeLists.txt @@ -69,4 +69,8 @@ o2_add_test_root_macro(TestFetcher.C PUBLIC_LINK_LIBRARIES O2::DataFormatsCTP O2::CCDB LABELS ctp) +o2_add_test_root_macro(CreateBKForRun.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsCTP + O2::CCDB + LABELS ctp) diff --git a/Detectors/CTP/macro/CreateBKForRun.C b/Detectors/CTP/macro/CreateBKForRun.C new file mode 100644 index 0000000000000..06ef9eac5f900 --- /dev/null +++ b/Detectors/CTP/macro/CreateBKForRun.C @@ -0,0 +1,74 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include +#include +#include +#endif +using namespace o2::ctp; + +void CreateBKForRun() +{ + std::vector runs = {558124, 558126, 558215, 558217, 558221, 558244, 558247}; + std::string mCCDBPathCTPScalers = "CTP/Calib/Scalers"; + std::string mCCDBPathCTPConfig = "CTP/Config/Config"; + // + std::string filename = "BKcounters.txt"; + std::ofstream outfile(filename); + if (!outfile) { + Error("", "Failed to open file %s", filename.c_str()); + return; + } + auto& ccdbMgr = o2::ccdb::BasicCCDBManager::instance(); + for (auto const& runNumber : runs) { + auto soreor = ccdbMgr.getRunDuration(runNumber); + uint64_t timeStamp = (soreor.second - soreor.first) / 2 + soreor.first; + std::cout << runNumber << " Timestamp:" << timeStamp << std::endl; + // + std::string srun = std::to_string(runNumber); + std::map metadata; + metadata["runNumber"] = srun; + auto ctpscalers = ccdbMgr.getSpecific(mCCDBPathCTPScalers, timeStamp, metadata); + if (ctpscalers == nullptr) { + LOG(info) << "CTPRunScalers not in database, timestamp:" << timeStamp; + } + auto ctpcfg = ccdbMgr.getSpecific(mCCDBPathCTPConfig, timeStamp, metadata); + if (ctpcfg == nullptr) { + LOG(info) << "CTPRunConfig not in database, timestamp:" << timeStamp; + } + // + ctpscalers->convertRawToO2(); + std::vector& ctpcls = ctpcfg->getCTPClasses(); + std::vector clslist = ctpcfg->getTriggerClassList(); + auto times = ctpscalers->getTimeLimit(); + for (size_t i = 0; i < clslist.size(); i++) { + // std::cout << i << " " << ctpcls[i].name ; + std::array cnts = ctpscalers->getIntegralForClass(i); + if (clslist[i] != (int)cnts[0]) { + LOG(fatal) << "cls list incompatible with counters"; + } + std::cout << std::setw(21) << ctpcls[cnts[0]].name; + outfile << runNumber << ", " << ctpcls[i].name << ", " << std::get<1>(times) / 1000; + for (int j = 1; j < 7; j++) { + // std::cout << std::setw(21) << " " << cnts[j]; + std::cout << ", " << cnts[j]; + outfile << ", " << cnts[j]; + } + std::cout << std::endl; + outfile << std::endl; + } + } + // ctpscalers->printFromZero(std::cout); + outfile.close(); +} From 39489be264fc4484961b9154b1877622582efd4d Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 9 Oct 2024 13:40:22 +0200 Subject: [PATCH 0324/2205] CCDB: add getSpecificForRun (#13569) * CCDB: add getSpecificForRun This PR adds a method `getSpecificForRun` to the base CCDB manager class. It is specifically tailored for analysis use in which the reconstruction pass is checked. --- CCDB/include/CCDB/BasicCCDBManager.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/CCDB/include/CCDB/BasicCCDBManager.h b/CCDB/include/CCDB/BasicCCDBManager.h index 5295062de4022..69d9150abcf62 100644 --- a/CCDB/include/CCDB/BasicCCDBManager.h +++ b/CCDB/include/CCDB/BasicCCDBManager.h @@ -115,6 +115,10 @@ class CCDBManagerInstance return getForTimeStamp(path, timestamp); } + /// retrieve an object of type T from CCDB as stored under path and using the timestamp in the middle of the run + metadata. The run number is provided separately to conform to typical analysis use (in which case metadata does not include runNumber) + template + T* getSpecificForRun(std::string const& path, int runNumber, MD metaData = MD()); + /// detect online processing modes (i.e. CCDB objects may be updated in the lifetime of the manager) bool isOnline() const { return mDeplMode == o2::framework::DeploymentMode::OnlineAUX || mDeplMode == o2::framework::DeploymentMode::OnlineDDS || mDeplMode == o2::framework::DeploymentMode::OnlineECS; } @@ -317,6 +321,14 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp) template T* CCDBManagerInstance::getForRun(std::string const& path, int runNumber, bool setRunMetadata) +{ + auto metaData = setRunMetadata ? MD{{"runNumber", std::to_string(runNumber)}} : MD{}; + mMetaData = metaData; + return getSpecificForRun(path, runNumber, metaData); +} + +template +T* CCDBManagerInstance::getSpecificForRun(std::string const& path, int runNumber, MD metaData) { auto [start, stop] = getRunDuration(runNumber); if (start < 0 || stop < 0) { @@ -325,8 +337,7 @@ T* CCDBManagerInstance::getForRun(std::string const& path, int runNumber, bool s } return nullptr; } - mMetaData = setRunMetadata ? MD{{"runNumber", std::to_string(runNumber)}} : MD{}; - return getForTimeStamp(path, start / 2 + stop / 2); + return getSpecific(path, start / 2 + stop / 2, metaData); } class BasicCCDBManager : public CCDBManagerInstance From 015c38a47f26643366dc73c2938f70fd60265a92 Mon Sep 17 00:00:00 2001 From: Ruben Shahoyan Date: Wed, 9 Oct 2024 13:59:58 +0200 Subject: [PATCH 0325/2205] Pass CCDB Headers together with binary blob (#13575) --- CCDB/include/CCDB/CcdbApi.h | 15 ++++++ CCDB/src/CcdbApi.cxx | 26 ++++++++- Framework/CCDBSupport/src/CCDBHelpers.cxx | 4 ++ .../Core/include/Framework/DataRefUtils.h | 1 + Framework/Core/src/DataRefUtils.cxx | 53 ++++++++++++++++++- 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/CCDB/include/CCDB/CcdbApi.h b/CCDB/include/CCDB/CcdbApi.h index ea396a5b49402..9ba8869fb7de3 100644 --- a/CCDB/include/CCDB/CcdbApi.h +++ b/CCDB/include/CCDB/CcdbApi.h @@ -392,6 +392,9 @@ class CcdbApi //: public DatabaseInterface // Loads files from alien and cvmfs into given destination. bool loadLocalContentToMemory(o2::pmr::vector& dest, std::string& url) const; + // add annotated flattened headers in the end of the blob + static void appendFlatHeader(o2::pmr::vector& dest, const std::map& headers); + // the failure to load the file to memory is signaled by 0 size and non-0 capacity static bool isMemoryFileInvalid(const o2::pmr::vector& v) { return v.size() == 0 && v.capacity() > 0; } template @@ -610,6 +613,16 @@ class CcdbApi //: public DatabaseInterface return getSnapshotDir(topdir, path) + '/' + sfile; } + template // can be either std::map or std::multimap + static size_t getFlatHeaderSize(const MAP& Headers) + { + size_t hsize = sizeof(int) + sizeof(FlatHeaderAnnot); // annotation size + for (auto& h : Headers) { + hsize += h.first.length() + h.second.length() + 2; // 2*(string_buffer + terminating null character) + } + return hsize; + } + // tmp helper and single point of entry for a CURL perform call // helps to switch between easy handle perform and multi handles in a single place CURLcode CURL_perform(CURL* handle) const; @@ -632,6 +645,8 @@ class CcdbApi //: public DatabaseInterface size_t mCurlTimeoutDownload = 15; // download timeout in seconds, can be configured via ALICEO2_CCDB_CURL_TIMEOUT_DOWNLOAD, updated according to the deployment mode size_t mCurlTimeoutUpload = 15; // upload timeout in seconds, can be configured via ALICEO2_CCDB_CURL_TIMEOUT_UPLOAD, updated according to the deployment mode + static constexpr char FlatHeaderAnnot[] = "$HEADER$"; // annotation for flat header + ClassDefNV(CcdbApi, 1); }; diff --git a/CCDB/src/CcdbApi.cxx b/CCDB/src/CcdbApi.cxx index a17458a33e5e6..3b622b87e7e7b 100644 --- a/CCDB/src/CcdbApi.cxx +++ b/CCDB/src/CcdbApi.cxx @@ -1687,12 +1687,15 @@ void CcdbApi::scheduleDownload(RequestContext& requestContext, size_t* requestCo ho.counter++; try { if (chunk.capacity() < chunk.size() + realsize) { + // estimate headers size when converted to annotated text string + const char hannot[] = "header"; + size_t hsize = getFlatHeaderSize(ho.header); auto cl = ho.header.find("Content-Length"); if (cl != ho.header.end()) { size_t sizeFromHeader = std::stol(cl->second); - sz = std::max(chunk.size() * (sizeFromHeader ? 1 : 2) + realsize, sizeFromHeader); + sz = hsize + std::max(chunk.size() * (sizeFromHeader ? 1 : 2) + realsize, sizeFromHeader); } else { - sz = std::max(chunk.size() * 2, chunk.size() + realsize); + sz = hsize + std::max(chunk.size() * 2, chunk.size() + realsize); // LOGP(debug, "SIZE IS NOT IN HEADER, allocate {}", sz); } chunk.reserve(sz); @@ -1885,6 +1888,25 @@ void CcdbApi::loadFileToMemory(o2::pmr::vector& dest, std::string const& p vectoredLoadFileToMemory(contexts); } +void CcdbApi::appendFlatHeader(o2::pmr::vector& dest, const std::map& headers) +{ + size_t hsize = getFlatHeaderSize(headers), cnt = dest.size(); + dest.resize(cnt + hsize); + auto addString = [&dest, &cnt](const std::string& s) { + for (char c : s) { + dest[cnt++] = c; + } + dest[cnt++] = 0; + }; + + for (auto& h : headers) { + addString(h.first); + addString(h.second); + } + *reinterpret_cast(&dest[cnt]) = hsize; // store size + std::memcpy(&dest[cnt + sizeof(int)], FlatHeaderAnnot, sizeof(FlatHeaderAnnot)); // annotate the flattened headers map +} + void CcdbApi::navigateSourcesAndLoadFile(RequestContext& requestContext, int& fromSnapshot, size_t* requestCounter) const { LOGP(debug, "loadFileToMemory {} ETag=[{}]", requestContext.path, requestContext.etag); diff --git a/Framework/CCDBSupport/src/CCDBHelpers.cxx b/Framework/CCDBSupport/src/CCDBHelpers.cxx index 6c510ad189ac5..ab1a21e263eb0 100644 --- a/Framework/CCDBSupport/src/CCDBHelpers.cxx +++ b/Framework/CCDBSupport/src/CCDBHelpers.cxx @@ -260,6 +260,7 @@ auto populateCacheWith(std::shared_ptr const& helper, helper->mapURL2UUID[path].cacheMiss++; helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); helper->mapURL2UUID[path].maxSize = std::max(v.size(), helper->mapURL2UUID[path].maxSize); + api.appendFlatHeader(v, headers); auto cacheId = allocator.adoptContainer(output, std::move(v), DataAllocator::CacheStrategy::Always, header::gSerializationMethodCCDB); helper->mapURL2DPLCache[path] = cacheId; O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "populateCacheWith", "Caching %{public}s for %{public}s (DPL id %" PRIu64 ")", path.data(), headers["ETag"].data(), cacheId.value); @@ -273,6 +274,7 @@ auto populateCacheWith(std::shared_ptr const& helper, helper->mapURL2UUID[path].cacheMiss++; helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); helper->mapURL2UUID[path].maxSize = std::max(v.size(), helper->mapURL2UUID[path].maxSize); + api.appendFlatHeader(v, headers); auto cacheId = allocator.adoptContainer(output, std::move(v), DataAllocator::CacheStrategy::Always, header::gSerializationMethodCCDB); helper->mapURL2DPLCache[path] = cacheId; O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "populateCacheWith", "Caching %{public}s for %{public}s (DPL id %" PRIu64 ")", path.data(), headers["ETag"].data(), cacheId.value); @@ -395,6 +397,7 @@ AlgorithmSpec CCDBHelpers::fetchFromCCDB() helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); helper->mapURL2UUID[path].maxSize = std::max(v.size(), helper->mapURL2UUID[path].maxSize); newOrbitResetTime = getOrbitResetTime(v); + api.appendFlatHeader(v, headers); auto cacheId = allocator.adoptContainer(output, std::move(v), DataAllocator::CacheStrategy::Always, header::gSerializationMethodNone); helper->mapURL2DPLCache[path] = cacheId; O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "fetchFromCCDB", "Caching %{public}s for %{public}s (DPL id %" PRIu64 ")", path.data(), headers["ETag"].data(), cacheId.value); @@ -405,6 +408,7 @@ AlgorithmSpec CCDBHelpers::fetchFromCCDB() helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); helper->mapURL2UUID[path].maxSize = std::max(v.size(), helper->mapURL2UUID[path].maxSize); newOrbitResetTime = getOrbitResetTime(v); + api.appendFlatHeader(v, headers); auto cacheId = allocator.adoptContainer(output, std::move(v), DataAllocator::CacheStrategy::Always, header::gSerializationMethodNone); helper->mapURL2DPLCache[path] = cacheId; O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "fetchFromCCDB", "Caching %{public}s for %{public}s (DPL id %" PRIu64 ")", path.data(), headers["ETag"].data(), cacheId.value); diff --git a/Framework/Core/include/Framework/DataRefUtils.h b/Framework/Core/include/Framework/DataRefUtils.h index 264533def326d..c63b06357b8ed 100644 --- a/Framework/Core/include/Framework/DataRefUtils.h +++ b/Framework/Core/include/Framework/DataRefUtils.h @@ -179,6 +179,7 @@ struct DataRefUtils { } // Decode a CCDB object using the CcdbApi. static void* decodeCCDB(DataRef const& ref, std::type_info const& info); + static std::map extractCCDBHeaders(DataRef const& ref); static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef& ref) { diff --git a/Framework/Core/src/DataRefUtils.cxx b/Framework/Core/src/DataRefUtils.cxx index 239aba95aa3ce..b32c47387e69a 100644 --- a/Framework/Core/src/DataRefUtils.cxx +++ b/Framework/Core/src/DataRefUtils.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. #include +#include #include "Framework/DataRefUtils.h" #include "Framework/RuntimeError.h" #include "Framework/Logger.h" @@ -80,11 +81,29 @@ void* DataRefUtils::decodeCCDB(DataRef const& ref, std::type_info const& tinfo) Int_t previousErrorLevel = gErrorIgnoreLevel; gErrorIgnoreLevel = kFatal; auto* dh = o2::header::get(ref.header); - TMemFile memFile("name", const_cast(ref.payload), dh->payloadSize, "READ"); + const char* buff = const_cast(ref.payload); + size_t flSize = dh->payloadSize; + // does it have a flattened headers map attached in the end? + constexpr char FlatHeaderAnnot[] = "$HEADER$"; + constexpr int Offset = sizeof(int) + sizeof(FlatHeaderAnnot); + int headerSize = 0; + LOGP(debug, "DHPayloadSize={}>{} Ref:{}/{} Cmp {}:{}", dh->payloadSize, Offset, dh->dataOrigin.as(), dh->dataDescription.as(), std::string{buff + dh->payloadSize - sizeof(FlatHeaderAnnot)}, std::string{FlatHeaderAnnot}); + + if (dh->payloadSize >= Offset && + !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) { + headerSize = *reinterpret_cast(buff + dh->payloadSize - Offset); + } + if (headerSize <= 0) { + LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize); + } + TMemFile memFile("name", const_cast(ref.payload), dh->payloadSize - headerSize, "READ"); gErrorIgnoreLevel = previousErrorLevel; if (memFile.IsZombie()) { return nullptr; } + + extractCCDBHeaders(ref); + TClass* tcl = TClass::GetClass(tinfo); result = extractFromTFile(memFile, tcl, "ccdb_object"); if (!result) { @@ -94,4 +113,36 @@ void* DataRefUtils::decodeCCDB(DataRef const& ref, std::type_info const& tinfo) return result; } +std::map DataRefUtils::extractCCDBHeaders(DataRef const& ref) +{ + auto* dh = o2::header::get(ref.header); + const char* buff = const_cast(ref.payload); + // does it have a flattened headers map attached in the end? + constexpr char FlatHeaderAnnot[] = "$HEADER$"; + constexpr int Offset = sizeof(int) + sizeof(FlatHeaderAnnot); + int headerSize = 0, ss0 = 0; + if (dh->payloadSize >= Offset && !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) { + headerSize = *reinterpret_cast(buff + dh->payloadSize - Offset); + } + if (headerSize <= 0) { + LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize); + } + buff += dh->payloadSize - headerSize; // jump to the start of flattened header + headerSize -= Offset; + const char* str0 = &buff[ss0++]; + std::map res; + while (ss0 < headerSize) { + if (buff[ss0++] == 0) { + if (!str0) { + str0 = &buff[ss0]; // new key string is found + } else { + res.emplace(std::string(str0), std::string(&buff[ss0])); // new value string found, add key value to the map + LOGP(debug, "Header{} {}:{}", res.size(), std::string(str0), std::string(&buff[ss0])); + str0 = nullptr; + } + } + } + return res; +} + } // namespace o2::framework From ff3f5b328a4506d6f233faf4863f5f54a7e1dab3 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 9 Oct 2024 16:31:49 +0200 Subject: [PATCH 0326/2205] TOF digitizer: Ability to process events happening before timeframe start (#13572) Relates to https://its.cern.ch/jira/browse/O2-5395 This commit makes sure that TOF digitization treats correctly events happening before timeframe start: - cut away hits from events much before first readout frame - allow to pickup hits from events happening just before the first readout frame (due to time of flight) some slight code reorganization: - introduce a getReadoutWindow function for reuse - introduce a constant for maximal time of flight of hits --- .../TOF/base/include/TOFBase/WindowFiller.h | 4 ++-- .../include/TOFSimulation/Digitizer.h | 8 +++++++ .../include/TOFSimulation/TOFSimParams.h | 2 ++ Detectors/TOF/simulation/src/Digitizer.cxx | 23 +++++++++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Detectors/TOF/base/include/TOFBase/WindowFiller.h b/Detectors/TOF/base/include/TOFBase/WindowFiller.h index 054e1353b7670..77827ee5e7057 100644 --- a/Detectors/TOF/base/include/TOFBase/WindowFiller.h +++ b/Detectors/TOF/base/include/TOFBase/WindowFiller.h @@ -104,8 +104,8 @@ class WindowFiller protected: // info TOF timewindow - uint64_t mReadoutWindowCurrent = 0; - InteractionRecord mFirstIR{0, 0}; // reference IR (1st IR of the timeframe) + uint64_t mReadoutWindowCurrent = 0; // keeps track of current readout window + InteractionRecord mFirstIR{0, 0}; // reference IR (1st IR of the timeframe) InteractionTimeRecord mEventTime; bool mContinuous = true; diff --git a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h index feb35c769d6ba..15a71b9e57c1f 100644 --- a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h +++ b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h @@ -83,6 +83,14 @@ class Digitizer : public WindowFiller void setEffBoundary2(float val) { mEffBoundary2 = val; } void setEffBoundary3(float val) { mEffBoundary3 = val; } + // determines the readout window id, given a time in nanoseconds (relative + // to orbit-reset) + uint64_t getReadoutWindow(double timeNS) const + { + // event time shifted by 2 BC as safe margin before to change current readout window to account for decalibration + return uint64_t((timeNS - Geo::BC_TIME * (Geo::OVERLAP_IN_BC + 2)) * Geo::READOUTWINDOW_INV); + } + private: // parameters Int_t mMode; diff --git a/Detectors/TOF/simulation/include/TOFSimulation/TOFSimParams.h b/Detectors/TOF/simulation/include/TOFSimulation/TOFSimParams.h index de67cabfce474..e36fb275ff55b 100644 --- a/Detectors/TOF/simulation/include/TOFSimulation/TOFSimParams.h +++ b/Detectors/TOF/simulation/include/TOFSimulation/TOFSimParams.h @@ -33,6 +33,8 @@ struct TOFSimParams : public o2::conf::ConfigurableParamHelper { float eff_boundary2 = 0.833; // efficiency in the pad border float eff_boundary3 = 0.1; // efficiency in mBound3 + float max_hit_time = 1000.; // time cutoff for hits (time of flight); default 1us + O2ParamDef(TOFSimParams, "TOFSimParams"); }; diff --git a/Detectors/TOF/simulation/src/Digitizer.cxx b/Detectors/TOF/simulation/src/Digitizer.cxx index d8ef99ae1bd22..f44c40808af93 100644 --- a/Detectors/TOF/simulation/src/Digitizer.cxx +++ b/Detectors/TOF/simulation/src/Digitizer.cxx @@ -69,6 +69,7 @@ void Digitizer::init() { // set first readout window in MC production getting + // orbitFirstSampled corresponds to the start of the concrete timeframe (it is set in O2DPG productions) mReadoutWindowCurrent = uint64_t(o2::raw::HBFUtils::Instance().orbitFirstSampled) * Geo::NWINDOW_IN_ORBIT; // method to initialize the parameters neede to digitize and the array of strip objects containing @@ -91,12 +92,21 @@ void Digitizer::init() int Digitizer::process(const std::vector* hits, std::vector* digits) { + const double max_hit_time = TOFSimParams::Instance().max_hit_time; + // hits array of TOF hits for a given simulated event // digits passed from external to be filled, in continuous readout mode we will push it on mDigitsPerTimeFrame vector of vectors of digits // printf("process event time = %f with %ld hits\n",mEventTime.getTimeNS(),hits->size()); - uint64_t readoutwindow = uint64_t((mEventTime.getTimeNS() - Geo::BC_TIME * (Geo::OVERLAP_IN_BC + 2)) * Geo::READOUTWINDOW_INV); // event time shifted by 2 BC as safe margin before to change current readout window to account for decalibration + uint64_t readoutwindow = getReadoutWindow(mEventTime.getTimeNS()); + + // determines the maximal readout window difference to a preceding RO which can still affect the current readout window + int max_readout_diff = int(max_hit_time * Geo::READOUTWINDOW_INV) + 1; + // early return based on events happening earlier than MAX_READOUT_DIFF away from current RO frame + if (readoutwindow < mReadoutWindowCurrent && mReadoutWindowCurrent - readoutwindow > max_readout_diff) { + return 0; + } if (mContinuous && readoutwindow > mReadoutWindowCurrent) { // if we are moving in future readout windows flush previous ones (only for continuous readout mode) digits->clear(); @@ -110,9 +120,18 @@ int Digitizer::process(const std::vector* hits, std::vector* dig for (auto& hit : *hits) { // TODO: put readout window counting/selection // neglect very slow particles (low energy neutrons) - if (hit.GetTime() > 1000) { // 1 mus + if (hit.GetTime() > max_hit_time) { // 1 mus + continue; + } + + // discard hits arriving before the minimum readout window + auto hit_ro_window = getReadoutWindow(double(hit.GetTime()) + mEventTime.getTimeNS() /*+ Geo::LATENCYWINDOW*/); + + // discard hits arriving too early + if (hit_ro_window < mReadoutWindowCurrent) { continue; } + processHit(hit, mEventTime.getTimeOffsetWrtBC() + Geo::LATENCYWINDOW); } // end loop over hits From 81baf9197272761a3228c7cd7ea53f8bb8dc9bdd Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 3 Oct 2024 18:55:19 +0200 Subject: [PATCH 0327/2205] TPC digi: Cut digits arriving before timeframe/readout start Relates to https://its.cern.ch/jira/browse/O2-5395 and should allow to treat correctly events coming before the timeframe start to reduce the startup effect in MC. --- .../include/TPCSimulation/SAMPAProcessing.h | 4 ++++ Detectors/TPC/simulation/src/Digitizer.cxx | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Detectors/TPC/simulation/include/TPCSimulation/SAMPAProcessing.h b/Detectors/TPC/simulation/include/TPCSimulation/SAMPAProcessing.h index e9df76ef052fd..be40c8652ad61 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/SAMPAProcessing.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/SAMPAProcessing.h @@ -258,6 +258,10 @@ inline float SAMPAProcessing::getZfromTimeBin(float timeBin, Side s) const inline TimeBin SAMPAProcessing::getTimeBinFromTime(float time) const { + if (time < 0.f) { + // protection and convention for negative times (otherwise overflow) + return 0; + } return static_cast(time / mEleParam->ZbinWidth); } diff --git a/Detectors/TPC/simulation/src/Digitizer.cxx b/Detectors/TPC/simulation/src/Digitizer.cxx index 15cc86edaecab..cb865d9f7f752 100644 --- a/Detectors/TPC/simulation/src/Digitizer.cxx +++ b/Detectors/TPC/simulation/src/Digitizer.cxx @@ -111,6 +111,12 @@ void Digitizer::process(const std::vector& hits, } const float absoluteTime = eleTime + mTDriftOffset + (mEventTime - mOutputDigitTimeOffset); /// in us + /// the absolute time needs to be within the readout limits + /// (otherwise negative times would all be accumulated in the 0-th timebin further below) + if (!(absoluteTime >= 0 /* && absoluteTime <= timeframelength */)) { + continue; + } + /// Attachment if (electronTransport.isElectronAttachment(driftTime)) { continue; @@ -217,9 +223,14 @@ void Digitizer::setUseSCDistortions(std::string_view finp) void Digitizer::setStartTime(double time) { + // this is setting the first timebin index for the digit container + // note that negative times w.r.t start of timeframe/data-taking == mOutputDigitTimeOffset + // will yield the 0-th bin (due to casting logic in sampaProcessing) SAMPAProcessing& sampaProcessing = SAMPAProcessing::instance(); sampaProcessing.updateParameters(mVDrift); - mDigitContainer.setStartTime(sampaProcessing.getTimeBinFromTime(time - mOutputDigitTimeOffset)); + const auto timediff = time - mOutputDigitTimeOffset; + const auto starttimebin = sampaProcessing.getTimeBinFromTime(timediff); + mDigitContainer.setStartTime(starttimebin); } void Digitizer::setLumiScaleFactor() From f0723d732f1643dade9b73aa1a6a4eefb7e29db0 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 10 Oct 2024 01:50:19 +0200 Subject: [PATCH 0328/2205] RDHUtils::printRDH will log 1 line only --- Detectors/Raw/src/RDHUtils.cxx | 35 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/Detectors/Raw/src/RDHUtils.cxx b/Detectors/Raw/src/RDHUtils.cxx index b021e98945ae7..d4ef416108bad 100644 --- a/Detectors/Raw/src/RDHUtils.cxx +++ b/Detectors/Raw/src/RDHUtils.cxx @@ -26,48 +26,39 @@ using namespace o2::header; void RDHUtils::printRDH(const RAWDataHeaderV4& rdh) { std::bitset<32> trb(rdh.triggerType); - LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x Packet:%-3d MemSize:%-4d OffsNext:%-4d prio.:%d BL:%-5d HS:%-2d HV:%d", - int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), int(rdh.packetCounter), int(rdh.memorySize), - int(rdh.offsetToNext), int(rdh.priority), int(rdh.blockLength), int(rdh.headerSize), int(rdh.version)); - LOGF(info, "HBOrb:%-9u TrOrb:%-9u Trg:%32s HBBC:%-4d TrBC:%-4d Page:%-5d Stop:%d Par:%-5d DetFld:0x%04x", // + LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x HBOrb:%-9u TrOrb:%-9u Trg:%32s HBBC:%-4d TrBC:%-4d Packet:%-3d Page:%-5d Stop:%d Par:%-5d DetFld:0x%04x MemSize:%-4d OffsNext:%-4d prio.:%d BL:%-5d HS:%-2d HV:%d", + int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), rdh.heartbeatOrbit, rdh.triggerOrbit, trb.to_string().c_str(), int(rdh.heartbeatBC), int(rdh.triggerBC), - int(rdh.pageCnt), int(rdh.stop), int(rdh.par), int(rdh.detectorField)); + int(rdh.packetCounter), int(rdh.pageCnt), int(rdh.stop), int(rdh.par), int(rdh.detectorField), int(rdh.memorySize), + int(rdh.offsetToNext), int(rdh.priority), int(rdh.blockLength), int(rdh.headerSize), int(rdh.version)); } //_________________________________________________ void RDHUtils::printRDH(const RAWDataHeaderV5& rdh) { std::bitset<32> trb(rdh.triggerType); - LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x Packet:%-3d MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", - int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), int(rdh.packetCounter), int(rdh.memorySize), + LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x Orbit:%-9u BC:%-4d Stop:%d Page:%-5d Packet:%-3d Trg:%32s Par:%-5d DetFld:0x%04x MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", + int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), rdh.orbit, int(rdh.bunchCrossing), int(rdh.stop), int(rdh.pageCnt), + int(rdh.packetCounter), trb.to_string().c_str(), int(rdh.detectorPAR), int(rdh.detectorField), int(rdh.memorySize), int(rdh.offsetToNext), int(rdh.priority), int(rdh.headerSize), int(rdh.version)); - LOGF(info, "Orbit:%-9u BC:%-4d Stop:%d Page:%-5d Trg:%32s Par:%-5d DetFld:0x%04x", - rdh.orbit, int(rdh.bunchCrossing), int(rdh.stop), int(rdh.pageCnt), trb.to_string().c_str(), - int(rdh.detectorPAR), int(rdh.detectorField)); } //_________________________________________________ void RDHUtils::printRDH(const RAWDataHeaderV7& rdh) { std::bitset<32> trb(rdh.triggerType); - LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x SrcID:%s[%d] Packet:%-3d MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", - int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), DAQID::DAQtoO2(rdh.sourceID).str, int(rdh.sourceID), int(rdh.packetCounter), - int(rdh.memorySize), int(rdh.offsetToNext), int(rdh.priority), int(rdh.headerSize), int(rdh.version)); - LOGF(info, "Orbit:%-9u BC:%-4d DataFormat:%-2d Stop:%d Page:%-5d Trg:%32s Par:%-5d DetFld:0x%04x", - rdh.orbit, int(rdh.bunchCrossing), int(rdh.dataFormat), int(rdh.stop), int(rdh.pageCnt), trb.to_string().c_str(), - int(rdh.detectorPAR), int(rdh.detectorField)); + LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x SrcID:%s[%d] Orbit:%-9u BC:%-4d DataFormat:%-2d Stop:%d Page:%-5d Packet:%-3d Trg:%32s Par:%-5d DetFld:0x%04x MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", + int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), DAQID::DAQtoO2(rdh.sourceID).str, int(rdh.sourceID), rdh.orbit, int(rdh.bunchCrossing), int(rdh.dataFormat), int(rdh.stop), int(rdh.pageCnt), int(rdh.packetCounter), + trb.to_string().c_str(), int(rdh.detectorPAR), int(rdh.detectorField), int(rdh.memorySize), int(rdh.offsetToNext), int(rdh.priority), int(rdh.headerSize), int(rdh.version)); } //_________________________________________________ void RDHUtils::printRDH(const RAWDataHeaderV6& rdh) { std::bitset<32> trb(rdh.triggerType); - LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x SrcID:%s[%d] Packet:%-3d MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", - int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), DAQID::DAQtoO2(rdh.sourceID).str, int(rdh.sourceID), int(rdh.packetCounter), - int(rdh.memorySize), int(rdh.offsetToNext), int(rdh.priority), int(rdh.headerSize), int(rdh.version)); - LOGF(info, "Orbit:%-9u BC:%-4d Stop:%d Page:%-5d Trg:%32s Par:%-5d DetFld:0x%04x", - rdh.orbit, int(rdh.bunchCrossing), int(rdh.stop), int(rdh.pageCnt), trb.to_string().c_str(), - int(rdh.detectorPAR), int(rdh.detectorField)); + LOGF(info, "EP:%d CRU:0x%04x Link:%-3d FEEID:0x%04x SrcID:%s[%d] Orbit:%-9u BC:%-4d Stop:%d Page:%-5d Packet:%-3d Trg:%32s Par:%-5d DetFld:0x%04x MemSize:%-5d OffsNext:%-5d prio.:%d HS:%-2d HV:%d", + int(rdh.endPointID), int(rdh.cruID), int(rdh.linkID), int(rdh.feeId), DAQID::DAQtoO2(rdh.sourceID).str, int(rdh.sourceID), rdh.orbit, int(rdh.bunchCrossing), int(rdh.stop), int(rdh.pageCnt), + int(rdh.packetCounter), trb.to_string().c_str(), int(rdh.detectorPAR), int(rdh.detectorField), int(rdh.memorySize), int(rdh.offsetToNext), int(rdh.priority), int(rdh.headerSize), int(rdh.version)); } //_________________________________________________ From 6d80cc39919c2e34a9ec061a390bd4e9133a2ca7 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 10 Oct 2024 01:50:47 +0200 Subject: [PATCH 0329/2205] Make ITS/MFT raw data logging more informative --- .../reconstruction/include/ITSMFTReconstruction/GBTLink.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h index 62e0f82299a1f..8683bb2b102d7 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/GBTLink.h @@ -155,7 +155,7 @@ struct GBTLink { long offs = sizeof(RDH); char* ptrR = ((char*)ptr) + sizeof(RDH); while (offs < szd) { - const o2::itsmft::GBTWord* w = reinterpret_cast(ptrR); + const GBTWord* w = reinterpret_cast(ptrR); std::string com = fmt::format(" | FeeID:{:#06x} offs: {:6} ", feeID, offs); if (w->isData()) { com += "data word"; @@ -164,12 +164,12 @@ struct GBTLink { } else if (w->isDataTrailer()) { com += "data trailer"; } else if (w->isTriggerWord()) { - com += "trigger word"; + const GBTTrigger* trw = (const GBTTrigger*)w; + com += fmt::format("trigger word bc:{} orbit:{} noData:{} int:{} cont:{}", trw->bc, trw->orbit, trw->noData, trw->internal, trw->continuation); } else if (w->isDiagnosticWord()) { com += "diag word"; } else if (w->isCalibrationWord()) { - com += "calib word"; - com += fmt::format(" #{}", ((const GBTCalibration*)w)->calibCounter); + com += fmt::format("calib word count:{:5} data:{:#08x}", ((const GBTCalibration*)w)->calibCounter, ((const GBTCalibration*)w)->calibUserField); } else if (w->isCableDiagnostic()) { com += "cable diag word"; } else if (w->isStatus()) { From 887a58e1e603a6a53e174cd9f5cddc3da9c05f0e Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:01:22 +0200 Subject: [PATCH 0330/2205] DPL: add separate getter for DataRef Will simplify splitting of the large get<> method using concepts. --- .../Core/include/Framework/InputRecord.h | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Framework/Core/include/Framework/InputRecord.h b/Framework/Core/include/Framework/InputRecord.h index 3e7efb83efd25..449e55fc7fcbc 100644 --- a/Framework/Core/include/Framework/InputRecord.h +++ b/Framework/Core/include/Framework/InputRecord.h @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -206,6 +207,28 @@ class InputRecord } return this->getByPos(pos, part); } + + template + requires std::is_convertible_v + DataRef getRef(R binding, int part = 0) const + { + return getDataRefByString(binding, part); + } + + template + requires requires(R r) { r.c_str(); } + DataRef getRef(R binding, int part = 0) const + { + return getDataRefByString(binding.c_str(), part); + } + + template + requires std::is_convertible_v + DataRef getRef(R ref, int part = 0) const + { + return ref; + } + /// Get the object of specified type T for the binding R. /// If R is a string like object, we look up by name the InputSpec and /// return the data associated to the given label. @@ -220,20 +243,7 @@ class InputRecord template decltype(auto) get(R binding, int part = 0) const { - DataRef ref{nullptr, nullptr}; - using decayed = std::decay_t; - - // Get the actual dataref - if constexpr (std::is_same_v || - std::is_same_v) { - ref = getDataRefByString(binding, part); - } else if constexpr (std::is_same_v) { - ref = getDataRefByString(binding.c_str(), part); - } else if constexpr (std::is_same_v) { - ref = binding; - } else { - static_assert(always_static_assert_v, "Unknown binding type"); - } + DataRef ref = getRef(binding, part); using PointerLessValueT = std::remove_pointer_t; From 349454171c44d9220eed17cb4721101fedad2add Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:41:42 +0200 Subject: [PATCH 0331/2205] DPL: do not deserialise metadata unless requested --- Framework/Core/src/DataRefUtils.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Framework/Core/src/DataRefUtils.cxx b/Framework/Core/src/DataRefUtils.cxx index b32c47387e69a..d3710a6234642 100644 --- a/Framework/Core/src/DataRefUtils.cxx +++ b/Framework/Core/src/DataRefUtils.cxx @@ -102,8 +102,6 @@ void* DataRefUtils::decodeCCDB(DataRef const& ref, std::type_info const& tinfo) return nullptr; } - extractCCDBHeaders(ref); - TClass* tcl = TClass::GetClass(tinfo); result = extractFromTFile(memFile, tcl, "ccdb_object"); if (!result) { From b3c6c348c820c4a0aad768771a4b26eaab42108b Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 9 Oct 2024 21:45:15 +0200 Subject: [PATCH 0332/2205] DPL: add helper method to retrieve and cache CCDB metadata --- .../Core/include/Framework/InputRecord.h | 47 +++++++++++++++++++ .../Core/include/Framework/ObjectCache.h | 7 +++ 2 files changed, 54 insertions(+) diff --git a/Framework/Core/include/Framework/InputRecord.h b/Framework/Core/include/Framework/InputRecord.h index 449e55fc7fcbc..49b8ad70438a7 100644 --- a/Framework/Core/include/Framework/InputRecord.h +++ b/Framework/Core/include/Framework/InputRecord.h @@ -40,6 +40,10 @@ namespace o2::framework { +// Wrapper class to get CCDB metadata +struct CCDBMetadataExtractor { +}; + struct InputSpec; class InputSpan; class CallbackService; @@ -464,6 +468,49 @@ class InputRecord } } + template + std::map& get(R binding, int part = 0) const + requires std::same_as + { + auto ref = getRef(binding, part); + auto header = DataRefUtils::getHeader(ref); + auto payloadSize = DataRefUtils::getPayloadSize(ref); + auto method = header->payloadSerializationMethod; + if (method != header::gSerializationMethodCCDB) { + throw runtime_error("Attempt to extract metadata from a non-CCDB serialised message"); + } + // This is to support deserialising objects from CCDB. Contrary to what happens for + // other objects, those objects are most likely long lived, so we + // keep around an instance of the associated object and deserialise it only when + // it's updated. + auto id = ObjectCache::Id::fromRef(ref); + ConcreteDataMatcher matcher{header->dataOrigin, header->dataDescription, header->subSpecification}; + // If the matcher does not have an entry in the cache, deserialise it + // and cache the deserialised object at the given id. + auto path = fmt::format("{}", DataSpecUtils::describe(matcher)); + LOGP(debug, "{}", path); + auto& cache = mRegistry.get(); + auto cacheEntry = cache.matcherToMetadataId.find(path); + if (cacheEntry == cache.matcherToMetadataId.end()) { + cache.matcherToMetadataId.insert(std::make_pair(path, id)); + cache.idToMetadata[id] = extractCCDBHeaders(ref); + LOGP(info, "Caching CCDB metadata {}: {}", id.value, path); + return cache.idToMetadata[id]; + } + auto& oldId = cacheEntry->second; + // The id in the cache is the same, let's simply return it. + if (oldId.value == id.value) { + LOGP(debug, "Returning cached CCDB metatada {}: {}", id.value, path); + return cache.idToMetadata[id]; + } + // The id in the cache is different. Let's destroy the old cached entry + // and create a new one. + LOGP(info, "Replacing cached entry {} with {} for {}", oldId.value, id.value, path); + cache.idToObject[id] = extracCCDBMetadata(ref); + oldId.value = id.value; + return cache.idToObject[id]; + } + /// Helper method to be used to check if a given part of the InputRecord is present. [[nodiscard]] bool isValid(std::string const& s) const { diff --git a/Framework/Core/include/Framework/ObjectCache.h b/Framework/Core/include/Framework/ObjectCache.h index 22120a216092f..a6873aec8a1ac 100644 --- a/Framework/Core/include/Framework/ObjectCache.h +++ b/Framework/Core/include/Framework/ObjectCache.h @@ -13,6 +13,7 @@ #include "Framework/DataRef.h" #include +#include namespace o2::framework { @@ -46,6 +47,12 @@ struct ObjectCache { /// A map from a CacheId (which is the void* ptr of the previous map). /// to an actual (type erased) pointer to the deserialised object. std::unordered_map idToObject; + + /// A cache to the deserialised metadata + /// We keep it separate because we want to avoid that looking up + /// the metadata also pollutes the object cache. + std::unordered_map matcherToMetadataId; + std::unordered_map, Id::hash_fn> idToMetadata; }; } // namespace o2::framework From 9a6e661aa7715d33c17b5a9c98d295bd0043e3ff Mon Sep 17 00:00:00 2001 From: swenzel Date: Wed, 9 Oct 2024 16:20:12 +0200 Subject: [PATCH 0333/2205] Improve AggregatedRunInfo: prioritize use of CTP/Calib/FirstRunOrbit use CTP/Calib/FirstRunOrbit when available. Otherwise fallback to RunInformation. --- .../Parameters/src/AggregatedRunInfo.cxx | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index 77c8a332c13b2..9e3d86177ff4a 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -48,7 +48,39 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2:: int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) - orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; + orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle + orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; + + // fetch SOR directly from CTP entry on CCDB + bool oldFatalState = ccdb.getFatalWhenNull(); + ccdb.setFatalWhenNull(false); + auto ctp_first_run_orbit = ccdb.getForTimeStamp>("CTP/Calib/FirstRunOrbit", run_mid_timestamp); + ccdb.setFatalWhenNull(oldFatalState); + if (ctp_first_run_orbit && ctp_first_run_orbit->size() >= 3) { + // if we have CTP first run orbit available, we should use it + + // int64_t creation_time = (*ctp_first_run_orbit)[0]; + int64_t ctp_run_number = (*ctp_first_run_orbit)[1]; + int64_t ctp_orbitSOR = (*ctp_first_run_orbit)[2]; + + if (ctp_run_number != runnumber) { + LOG(error) << "AggregatedRunInfo: run number inconsistency found (asked: " << runnumber << " vs CTP found: " << ctp_run_number << ")"; + } + + // overwrite orbitSOR + if (ctp_orbitSOR != orbitSOR) { + LOG(warn) << "The calculated orbitSOR " << orbitSOR << " differs from CTP orbitSOR " << ctp_orbitSOR; + // reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc. + + // so we need to adjust the SOR timings to be consistent + auto sor_new = (int64_t)((tsOrbitReset + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); + if (sor_new != sor) { + LOG(warn) << "Adjusting SOR from " << sor << " to " << sor_new; + sor = sor_new; + } + } + orbitSOR = ctp_orbitSOR; + } return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; } From 27014995d7ee9689a64424f5c95493b7c94c4f74 Mon Sep 17 00:00:00 2001 From: noferini <9963644+noferini@users.noreply.github.com> Date: Thu, 10 Oct 2024 09:37:12 +0200 Subject: [PATCH 0334/2205] assure TOF code uses std::abs everywhere --- Detectors/GlobalTracking/src/MatchTOF.cxx | 50 +++++++++---------- .../src/TOFEventTimeChecker.cxx | 8 +-- Detectors/TOF/base/src/EventTimeMaker.cxx | 8 +-- Detectors/TOF/base/src/Geo.cxx | 14 +++--- Detectors/TOF/base/src/Utils.cxx | 24 ++++----- Detectors/TOF/calibration/src/CalibTOF.cxx | 14 +++--- .../calibration/src/TOFChannelCalibrator.cxx | 6 +-- .../TOF/prototyping/findTOFclusterFromLabel.C | 13 ++++- .../reconstruction/src/CosmicProcessor.cxx | 6 +-- Detectors/TOF/simulation/src/Digitizer.cxx | 14 +++--- macro/checkTOFMatching.C | 19 +++++-- macro/compareTOFClusters.C | 18 +++---- 12 files changed, 108 insertions(+), 86 deletions(-) diff --git a/Detectors/GlobalTracking/src/MatchTOF.cxx b/Detectors/GlobalTracking/src/MatchTOF.cxx index 2db453b0f62be..9bb741ee4443f 100644 --- a/Detectors/GlobalTracking/src/MatchTOF.cxx +++ b/Detectors/GlobalTracking/src/MatchTOF.cxx @@ -192,15 +192,15 @@ void MatchTOF::run(const o2::globaltracking::RecoContainer& inp, unsigned long f bct0--; } float tof = matchingPair.getSignal() - bct0 * Geo::BC_TIME_INPS; - if (abs(tof - matchingPair.getLTIntegralOut().getTOF(2)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(3)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(4)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(0)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(1)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(5)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(6)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(7)) < 600) { - } else if (abs(tof - matchingPair.getLTIntegralOut().getTOF(8)) < 600) { + if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(2)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(3)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(4)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(0)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(1)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(5)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(6)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(7)) < 600) { + } else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(8)) < 600) { } else { // no pion, kaon, proton, electron, muon, deuteron, triton, 3He, 4He matchingPair.setFakeMatch(); } @@ -557,7 +557,7 @@ void MatchTOF::propagateTPCTracks(int sec) } if (trc.getX() < o2::constants::geom::XTPCOuterRef - 1.) { - if (!propagateToRefXWithoutCov(trc, o2::constants::geom::XTPCOuterRef, 10, mBz) || TMath::Abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagat> + if (!propagateToRefXWithoutCov(trc, o2::constants::geom::XTPCOuterRef, 10, mBz) || std::abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagat> mNotPropagatedToTOF[trkType::UNCONS]++; continue; } @@ -566,7 +566,7 @@ void MatchTOF::propagateTPCTracks(int sec) o2::base::Propagator::Instance()->estimateLTFast(intLT0, trc); // the "rough" propagation worked; now we can propagate considering also the cov matrix - if (!propagateToRefX(trc, mXRef, 2, intLT0)) { // || TMath::Abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix w> + if (!propagateToRefX(trc, mXRef, 2, intLT0)) { // || std::abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix w> mNotPropagatedToTOF[trkType::UNCONS]++; continue; } @@ -603,7 +603,7 @@ void MatchTOF::propagateConstrTracks(int sec) } // the "rough" propagation worked; now we can propagate considering also the cov matrix - if (!propagateToRefX(trc, mXRef, 2, intLT0) || TMath::Abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked;> + if (!propagateToRefX(trc, mXRef, 2, intLT0) || std::abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked;> mNotPropagatedToTOF[trkType::CONSTR]++; continue; } @@ -706,7 +706,7 @@ void MatchTOF::addTPCSeed(const o2::tpc::TrackTPC& _tr, o2::dataformats::GlobalT // compute track length up to now mLTinfos[sector][trkType::UNCONS].emplace_back(intLT0); float vz0 = _tr.getZAt(0, mBz); - if (abs(vz0) > 9000) { + if (std::abs(vz0) > 9000) { vz0 = _tr.getZ() - _tr.getX() * _tr.getTgl(); } mVZtpcOnly[sector].push_back(vz0); @@ -727,14 +727,14 @@ void MatchTOF::addTPCSeed(const o2::tpc::TrackTPC& _tr, o2::dataformats::GlobalT } if (trc.getX() < o2::constants::geom::XTPCOuterRef - 1.) { - if (!propagateToRefX(trc, o2::constants::geom::XTPCOuterRef, 10, intLT0) || TMath::Abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked; CHECK: can it happ + if (!propagateToRefX(trc, o2::constants::geom::XTPCOuterRef, 10, intLT0) || std::abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked; CHECK: can it happ mNotPropagatedToTOF[trkType::UNCONS]++; return; } } // the "rough" propagation worked; now we can propagate considering also the cov matrix - if (!propagateToRefX(trc, mXRef, 2, intLT0)) { // || TMath::Abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked; CHECK: can it happen that it does not if the prop> + if (!propagateToRefX(trc, mXRef, 2, intLT0)) { // || std::abs(trc.getZ()) > Geo::MAXHZTOF) { // we check that the propagation with the cov matrix worked; CHECK: can it happen that it does not if the prop> mNotPropagatedToTOF[trkType::UNCONS]++; return; } @@ -1411,10 +1411,10 @@ void MatchTOF::doMatchingForTPC(int sec) } if (mMatchParams->applyPIDcutTPConly) { // for TPC only tracks allowing possibility to apply a PID cut - if (abs(tof - trkLTInt[ibc][iPropagation].getTOF(2)) < 2000) { // pion hypotesis - } else if (abs(tof - trkLTInt[ibc][iPropagation].getTOF(3)) < 2000) { // kaon hypoteis - } else if (abs(tof - trkLTInt[ibc][iPropagation].getTOF(4)) < 2000) { // proton hypotesis - } else { // reject matching + if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(2)) < 2000) { // pion hypotesis + } else if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(3)) < 2000) { // kaon hypoteis + } else if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(4)) < 2000) { // proton hypotesis + } else { // reject matching continue; } } @@ -1518,7 +1518,7 @@ int MatchTOF::findFITIndex(int bc, const gsl::span& FI if (mHasFillScheme && !mFillScheme[ir.bc]) { continue; } - bool quality = (fabs(FITRecPoints[i].getCollisionTime(0)) < 1000 && fabs(FITRecPoints[i].getVertex()) < 1000); + bool quality = (std::abs(FITRecPoints[i].getCollisionTime(0)) < 1000 && std::abs(FITRecPoints[i].getVertex()) < 1000); if (bestQuality && !quality) { // if current has no good quality and the one previoulsy selected has -> discard the current one continue; } @@ -1596,7 +1596,7 @@ void MatchTOF::BestMatches(std::vector& match float timeNew = TOFClusWork[matchingPair.getTOFClIndex()].getTime() - deltaT; float timeOld = TOFClusWork[prevMatching.getTOFClIndex()].getTime(); - if (fabs(timeNew - timeOld) < 200) { + if (std::abs(timeNew - timeOld) < 200) { // update time information averaging the two (the second one corrected for the difference in the track length) prevMatching.setSignal((timeNew + timeOld) * 0.5); prevMatching.setChi2(0); // flag such cases with chi2 equal to zero @@ -1820,7 +1820,7 @@ bool MatchTOF::propagateToRefX(o2::track::TrackParCov& trc, float xRef, float st refReached = true; // we reached the 371cm reference } istep++; - if (fabs(trc.getY()) > trc.getX() * tanHalfSector) { // we are still in the same sector + if (std::abs(trc.getY()) > trc.getX() * tanHalfSector) { // we are still in the same sector // we need to rotate the track to go to the new sector //Printf("propagateToRefX: changing sector"); auto alphaNew = o2::math_utils::angle2Alpha(trc.getPhiPos()); @@ -1860,7 +1860,7 @@ bool MatchTOF::propagateToRefXWithoutCov(const o2::track::TrackParCov& trc, floa refReached = true; // we reached the 371cm reference } istep++; - if (fabs(trcNoCov.getY()) > trcNoCov.getX() * tanHalfSector) { // we are still in the same sector + if (std::abs(trcNoCov.getY()) > trcNoCov.getX() * tanHalfSector) { // we are still in the same sector // we need to rotate the track to go to the new sector //Printf("propagateToRefX: changing sector"); auto alphaNew = o2::math_utils::angle2Alpha(trcNoCov.getPhiPos()); @@ -1877,7 +1877,7 @@ bool MatchTOF::propagateToRefXWithoutCov(const o2::track::TrackParCov& trc, floa // if (std::abs(trc.getSnp()) > MAXSNP) Printf("propagateToRefX: condition on snp not ok, returning false"); //Printf("propagateToRefX: snp of teh track is %f (--> %f grad)", trcNoCov.getSnp(), TMath::ASin(trcNoCov.getSnp())*TMath::RadToDeg()); - return refReached && std::abs(trcNoCov.getSnp()) < 0.95 && TMath::Abs(trcNoCov.getZ()) < Geo::MAXHZTOF; // Here we need to put MAXSNP + return refReached && std::abs(trcNoCov.getSnp()) < 0.95 && std::abs(trcNoCov.getZ()) < Geo::MAXHZTOF; // Here we need to put MAXSNP } //______________________________________________ @@ -1900,7 +1900,7 @@ void MatchTOF::updateTimeDependentParams() mTPCBin2Z = mTPCTBinMUS * mTPCVDrift; mBz = o2::base::Propagator::Instance()->getNominalBz(); - mMaxInvPt = abs(mBz) > 0.1 ? 1. / (abs(mBz) * 0.05) : 999.; + mMaxInvPt = std::abs(mBz) > 0.1 ? 1. / (std::abs(mBz) * 0.05) : 999.; const auto& trackTune = TrackTuneParams::Instance(); float scale = mTPCCorrMapsHelper->getInstLumiCTP(); diff --git a/Detectors/GlobalTrackingWorkflow/src/TOFEventTimeChecker.cxx b/Detectors/GlobalTrackingWorkflow/src/TOFEventTimeChecker.cxx index eb212f2507786..3d8b36043ddeb 100644 --- a/Detectors/GlobalTrackingWorkflow/src/TOFEventTimeChecker.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/TOFEventTimeChecker.cxx @@ -266,10 +266,10 @@ void TOFEventTimeChecker::processEvent(std::vector& tracks) float betaexpPr = mL / mExpPr * cinv; //Mass - float mass = mP / beta * TMath::Sqrt(TMath::Abs(1 - beta * beta)); - float massexpPi = mP / betaexpPi * TMath::Sqrt(TMath::Abs(1 - betaexpPi * betaexpPi)); - float massexpKa = mP / betaexpKa * TMath::Sqrt(TMath::Abs(1 - betaexpKa * betaexpKa)); - float massexpPr = mP / betaexpPr * TMath::Sqrt(TMath::Abs(1 - betaexpPr * betaexpPr)); + float mass = mP / beta * TMath::Sqrt(std::abs(1 - beta * beta)); + float massexpPi = mP / betaexpPi * TMath::Sqrt(std::abs(1 - betaexpPi * betaexpPi)); + float massexpKa = mP / betaexpKa * TMath::Sqrt(std::abs(1 - betaexpKa * betaexpKa)); + float massexpPr = mP / betaexpPr * TMath::Sqrt(std::abs(1 - betaexpPr * betaexpPr)); if (massexpPi < 0.13) { // remove wrong track lengths continue; diff --git a/Detectors/TOF/base/src/EventTimeMaker.cxx b/Detectors/TOF/base/src/EventTimeMaker.cxx index 802be496ae495..132bd26fcfe52 100644 --- a/Detectors/TOF/base/src/EventTimeMaker.cxx +++ b/Detectors/TOF/base/src/EventTimeMaker.cxx @@ -152,7 +152,7 @@ void computeEvTime(const std::vector& tracks, const std::vector< } float err = evtime.mTrackTimes[i] - averageBest; err *= sqrt(evtime.mWeights[i]); - err = fabs(err); + err = std::abs(err); if (err > errworse) { errworse = err; worse = i; @@ -293,7 +293,7 @@ int getStartTimeInSet(const std::vector& tracks, std::vector& tracks, std::vector errworse) { errworse = err; worse = itrk; @@ -404,7 +404,7 @@ int getStartTimeInSetFast(const std::vector& tracks, std::vector const eventTimeTrack& ctrack = tracks[trackInSet[itrk]]; float err = ctrack.mSignal - ctrack.expTimes[hypo[itrk]] - averageBest; err /= ctrack.expSigma[hypo[itrk]]; - err = fabs(err); + err = std::abs(err); if (err > errworse) { errworse = err; worse = itrk; diff --git a/Detectors/TOF/base/src/Geo.cxx b/Detectors/TOF/base/src/Geo.cxx index 655addbb3007e..c76e6b4d83943 100644 --- a/Detectors/TOF/base/src/Geo.cxx +++ b/Detectors/TOF/base/src/Geo.cxx @@ -773,10 +773,10 @@ Int_t Geo::fromPlateToStrip(Float_t* pos, Int_t iplate, Int_t isector) step[2] = -getGeoDistances(isector, iplate, istrip); translate(posLoc2[0], posLoc2[1], posLoc2[2], step); - if (fabs(posLoc2[1]) > 10) { + if (std::abs(posLoc2[1]) > 10) { continue; } - if (fabs(posLoc2[2]) > 10) { + if (std::abs(posLoc2[2]) > 10) { continue; } @@ -788,8 +788,8 @@ Int_t Geo::fromPlateToStrip(Float_t* pos, Int_t iplate, Int_t isector) rotateToStrip(posLoc2, iplate, istrip, isector); - if ((TMath::Abs(posLoc2[0]) <= STRIPLENGTH * 0.5) && (TMath::Abs(posLoc2[1]) <= HSTRIPY * 0.5) && - (TMath::Abs(posLoc2[2]) <= WCPCBZ * 0.5)) { + if ((std::abs(posLoc2[0]) <= STRIPLENGTH * 0.5) && (std::abs(posLoc2[1]) <= HSTRIPY * 0.5) && + (std::abs(posLoc2[2]) <= WCPCBZ * 0.5)) { step[0] = -0.5 * NPADX * XPAD; step[1] = 0.; step[2] = -0.5 * NPADZ * ZPAD; @@ -891,11 +891,11 @@ Int_t Geo::getPlate(const Float_t* pos) Float_t zLocal = pos[2]; Float_t deltaRhoLoc = (RMAX - RMIN) * 0.5 - MODULEWALLTHICKNESS + yLocal; - Float_t deltaZetaLoc = TMath::Abs(zLocal); + Float_t deltaZetaLoc = std::abs(zLocal); Float_t deltaRHOmax = 0.; - if (TMath::Abs(zLocal) >= EXTERINTERMODBORDER1 && TMath::Abs(zLocal) <= EXTERINTERMODBORDER2) { + if (std::abs(zLocal) >= EXTERINTERMODBORDER1 && std::abs(zLocal) <= EXTERINTERMODBORDER2) { deltaRhoLoc -= LENGTHEXINMODBORDER; deltaZetaLoc = EXTERINTERMODBORDER2 - deltaZetaLoc; deltaRHOmax = (RMAX - RMIN) * 0.5 - MODULEWALLTHICKNESS - 2. * LENGTHEXINMODBORDER; // old 5.35, new 4.8 @@ -913,7 +913,7 @@ Int_t Geo::getPlate(const Float_t* pos) iPlate = 3; } } - } else if (TMath::Abs(zLocal) >= INTERCENTRMODBORDER1 && TMath::Abs(zLocal) <= INTERCENTRMODBORDER2) { + } else if (std::abs(zLocal) >= INTERCENTRMODBORDER1 && std::abs(zLocal) <= INTERCENTRMODBORDER2) { deltaRhoLoc -= LENGTHINCEMODBORDERD; deltaZetaLoc = deltaZetaLoc - INTERCENTRMODBORDER1; deltaRHOmax = (RMAX - RMIN) * 0.5 - MODULEWALLTHICKNESS - 2. * LENGTHINCEMODBORDERD; // old 0.39, new 0.2 diff --git a/Detectors/TOF/base/src/Utils.cxx b/Detectors/TOF/base/src/Utils.cxx index 265cb0247b544..36fc3d2d61c6f 100644 --- a/Detectors/TOF/base/src/Utils.cxx +++ b/Detectors/TOF/base/src/Utils.cxx @@ -143,20 +143,20 @@ double Utils::subtractInteractionBC(double time, int& mask, bool subLatency) if (deltaCBC >= -8 && deltaCBC < 8) { mask += (1 << (deltaCBC + 8)); // fill bc candidates } - if (abs(deltaCBC) < dbc) { + if (std::abs(deltaCBC) < dbc) { bcc = bc - deltaCBC; dbcSigned = deltaCBC; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } - if (abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit) + if (std::abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit) bcc = bc - deltaCBC - o2::constants::lhc::LHCMaxBunches; dbcSigned = deltaCBC + o2::constants::lhc::LHCMaxBunches; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } - if (abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0) + if (std::abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0) bcc = bc - deltaCBC + o2::constants::lhc::LHCMaxBunches; dbcSigned = deltaCBC - o2::constants::lhc::LHCMaxBunches; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } } if (dbcSigned >= -8 && dbcSigned < 8) { @@ -192,20 +192,20 @@ float Utils::subtractInteractionBC(float time, int& mask, bool subLatency) if (deltaCBC >= -8 && deltaCBC < 8) { mask += (1 << (deltaCBC + 8)); // fill bc candidates } - if (abs(deltaCBC) < dbc) { + if (std::abs(deltaCBC) < dbc) { bcc = bc - deltaCBC; dbcSigned = deltaCBC; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } - if (abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit) + if (std::abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit) bcc = bc - deltaCBC - o2::constants::lhc::LHCMaxBunches; dbcSigned = deltaCBC + o2::constants::lhc::LHCMaxBunches; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } - if (abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0) + if (std::abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0) bcc = bc - deltaCBC + o2::constants::lhc::LHCMaxBunches; dbcSigned = deltaCBC - o2::constants::lhc::LHCMaxBunches; - dbc = abs(dbcSigned); + dbc = std::abs(dbcSigned); } } if (dbcSigned >= -8 && dbcSigned < 8) { diff --git a/Detectors/TOF/calibration/src/CalibTOF.cxx b/Detectors/TOF/calibration/src/CalibTOF.cxx index 52fdd5ebd8e02..1b1bb94f19e07 100644 --- a/Detectors/TOF/calibration/src/CalibTOF.cxx +++ b/Detectors/TOF/calibration/src/CalibTOF.cxx @@ -212,7 +212,7 @@ void CalibTOF::run(int flag, int sector) int channelInSector = (ipad + ich) % o2::tof::Geo::NPADSXSECTOR; mTimeSlewingObj->setFractionUnderPeak(sector, channelInSector, fractionUnderPeak); - mTimeSlewingObj->setSigmaPeak(sector, channelInSector, abs(funcChOffset->GetParameter(2))); + mTimeSlewingObj->setSigmaPeak(sector, channelInSector, std::abs(funcChOffset->GetParameter(2))); // now fill 2D histo for time-slewing using current channel offset @@ -237,7 +237,7 @@ void CalibTOF::run(int flag, int sector) int istrip = ((ich + ipad) / o2::tof::Geo::NPADS) % o2::tof::Geo::NSTRIPXSECTOR; gTimeVsTot->SetName(Form("pad_%02d_%02d_%02d", sector, istrip, ipad % o2::tof::Geo::NPADS)); gTimeVsTot->Write(); - // histoChTimeSlewingTemp->Write(Form("histoChTimeSlewingTemp_%02d_%02d_%02d", sector, istrip, ipad%o2::tof::Geo::NPADS)); // no longer written since it produces a very large output + // histoChTimeSlewingTemp->Write(Form("histoChTimeSlewingTemp_%02d_%02d_%02d", sector, istrip, ipad%o2::tof::Geo::NPADS)); // no longer written since it produces a very large output } } else if (flag & kChannelOffset) { mTimeSlewingObj->addTimeSlewingInfo(ich + ipad, 0, mCalibChannelOffset[ich + ipad]); @@ -603,8 +603,8 @@ Int_t CalibTOF::FitPeak(TF1* fitFunc, TH1* h, Float_t startSigma, Float_t nSigma /* refit with better range */ for (Int_t i = 0; i < 3; i++) { fitCent = fitFunc->GetParameter(1); - fitMin = fitCent - nSigmaMin * abs(fitFunc->GetParameter(2)); - fitMax = fitCent + nSigmaMax * abs(fitFunc->GetParameter(2)); + fitMin = fitCent - nSigmaMin * std::abs(fitFunc->GetParameter(2)); + fitMax = fitCent + nSigmaMax * std::abs(fitFunc->GetParameter(2)); if (fitMin < -12500) { fitMin = -12500; } @@ -735,9 +735,9 @@ void CalibTOF::flagProblematics() hsigmapeak->Fit(fFuncSigma, "WWq0"); hfractionpeak->Fit(fFuncFraction, "WWq0"); - sigmaMin = fFuncSigma->GetParameter(1) - mNsigmaSigmaProblematicCut * abs(fFuncSigma->GetParameter(2)); - sigmaMax = fFuncSigma->GetParameter(1) + mNsigmaSigmaProblematicCut * abs(fFuncSigma->GetParameter(3)); - fractionMin = fFuncFraction->GetParameter(1) - mNsigmaFractionProblematicCut * abs(fFuncFraction->GetParameter(2)); + sigmaMin = fFuncSigma->GetParameter(1) - mNsigmaSigmaProblematicCut * std::abs(fFuncSigma->GetParameter(2)); + sigmaMax = fFuncSigma->GetParameter(1) + mNsigmaSigmaProblematicCut * std::abs(fFuncSigma->GetParameter(3)); + fractionMin = fFuncFraction->GetParameter(1) - mNsigmaFractionProblematicCut * std::abs(fFuncFraction->GetParameter(2)); for (int k = 0; k < o2::tof::Geo::NPADX; k++) { ipad = 48 * iz + k; diff --git a/Detectors/TOF/calibration/src/TOFChannelCalibrator.cxx b/Detectors/TOF/calibration/src/TOFChannelCalibrator.cxx index fbaa555013f9c..c0568125b8d5e 100644 --- a/Detectors/TOF/calibration/src/TOFChannelCalibrator.cxx +++ b/Detectors/TOF/calibration/src/TOFChannelCalibrator.cxx @@ -627,7 +627,7 @@ void TOFChannelCalibrator::finalizeSlotWithCosmics(Slot& slot) mFitCal->Fill(ich, localFitter.GetParameter(ichLocal)); #endif ts.setFractionUnderPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, fracUnderPeak[ichLocal]); - ts.setSigmaPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, abs(std::sqrt(localFitter.GetCovarianceMatrixElement(ichLocal, ichLocal)))); + ts.setSigmaPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, std::abs(std::sqrt(localFitter.GetCovarianceMatrixElement(ichLocal, ichLocal)))); } } // end loop strips @@ -783,12 +783,12 @@ void TOFChannelCalibrator::finalizeSlotWithTracks(Slot& slot) fractionUnderPeak = entriesInChannel > 0 ? c->integral(ich, intmin, intmax) / entriesInChannel : 0; // now we need to store the results in the TimeSlewingObject ts.setFractionUnderPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, fractionUnderPeak); - ts.setSigmaPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, abs(fitValues[2])); + ts.setSigmaPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, std::abs(fitValues[2])); int tobeused = o2::tof::Utils::getMaxUsedChannel(ich); fitValues[1] += tobeused * o2::tof::Geo::BC_TIME_INPS; // adjust by adding the right BC - if (abs(fitValues[1]) > mRange) { + if (std::abs(fitValues[1]) > mRange) { ts.setFractionUnderPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, -1); ts.setSigmaPeak(ich / Geo::NPADSXSECTOR, ich % Geo::NPADSXSECTOR, 99999); } diff --git a/Detectors/TOF/prototyping/findTOFclusterFromLabel.C b/Detectors/TOF/prototyping/findTOFclusterFromLabel.C index 67ed487ecebc1..cacf9fbbfd50d 100644 --- a/Detectors/TOF/prototyping/findTOFclusterFromLabel.C +++ b/Detectors/TOF/prototyping/findTOFclusterFromLabel.C @@ -1,3 +1,14 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + #if !defined(__CLING__) || defined(__ROOTCLING__) #include "TFile.h" #include "TTree.h" @@ -95,7 +106,7 @@ void findTOFclusterFromLabel(int trackID, int eventID = 0, int sourceID = 0) for (int i = 0; i < mcArr->size(); ++i) { const auto& mcTrack = (*mcArr)[i]; if (i == trackID) { - Printf("Particle %d: pdg = %d, pT = %f, px = %f, py = %f, pz = %f, vx = %f, vy = %f, vz = %f", i, mcTrack.GetPdgCode(), TMath::Abs(mcTrack.GetStartVertexMomentumX() * mcTrack.GetStartVertexMomentumX() + mcTrack.GetStartVertexMomentumY() * mcTrack.GetStartVertexMomentumY()), mcTrack.GetStartVertexMomentumX(), mcTrack.GetStartVertexMomentumY(), mcTrack.GetStartVertexMomentumZ(), mcTrack.GetStartVertexCoordinatesX(), mcTrack.GetStartVertexCoordinatesY(), mcTrack.GetStartVertexCoordinatesZ()); + Printf("Particle %d: pdg = %d, pT = %f, px = %f, py = %f, pz = %f, vx = %f, vy = %f, vz = %f", i, mcTrack.GetPdgCode(), std::abs(mcTrack.GetStartVertexMomentumX() * mcTrack.GetStartVertexMomentumX() + mcTrack.GetStartVertexMomentumY() * mcTrack.GetStartVertexMomentumY()), mcTrack.GetStartVertexMomentumX(), mcTrack.GetStartVertexMomentumY(), mcTrack.GetStartVertexMomentumZ(), mcTrack.GetStartVertexCoordinatesX(), mcTrack.GetStartVertexCoordinatesY(), mcTrack.GetStartVertexCoordinatesZ()); } } diff --git a/Detectors/TOF/reconstruction/src/CosmicProcessor.cxx b/Detectors/TOF/reconstruction/src/CosmicProcessor.cxx index 886435c299265..eb2f6ea9eec9e 100644 --- a/Detectors/TOF/reconstruction/src/CosmicProcessor.cxx +++ b/Detectors/TOF/reconstruction/src/CosmicProcessor.cxx @@ -103,7 +103,7 @@ void CosmicProcessor::process(DigitDataReader& reader, bool fill) for (int j = i + 1; j < ndig2; j++) { auto& dig2 = (*array)[j]; int64_t bc2 = int64_t(dig2.getBC()) - bc1; - if (labs(bc2) > bcdist) { + if (std::abs(bc2) > bcdist) { continue; } @@ -126,7 +126,7 @@ void CosmicProcessor::process(DigitDataReader& reader, bool fill) float lt2 = pos2[0] * pos2[0] + pos2[1] * pos2[1]; float l = sqrt(lt2 + pos2[2] * pos2[2]); - if (!trackFound && lt2 < 40000 && fabs(dtime) < 10000) { + if (!trackFound && lt2 < 40000 && std::abs(dtime) < 10000) { mCosmicTrackTemp.emplace_back(ch2, pos2or[0], pos2or[1], pos2or[2], dtime, tot2); } @@ -139,7 +139,7 @@ void CosmicProcessor::process(DigitDataReader& reader, bool fill) dtime -= l * 33.356409; // corrected for pad distance assuiming muonn downward - if (fabs(dtime) > thr) { + if (std::abs(dtime) > thr) { continue; } diff --git a/Detectors/TOF/simulation/src/Digitizer.cxx b/Detectors/TOF/simulation/src/Digitizer.cxx index f44c40808af93..50ea2c194616c 100644 --- a/Detectors/TOF/simulation/src/Digitizer.cxx +++ b/Detectors/TOF/simulation/src/Digitizer.cxx @@ -302,8 +302,8 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, tot = 0; } - Float_t xborder = Geo::XPAD * 0.5 - TMath::Abs(x); - Float_t zborder = Geo::ZPAD * 0.5 - TMath::Abs(z); + Float_t xborder = Geo::XPAD * 0.5 - std::abs(x); + Float_t zborder = Geo::ZPAD * 0.5 - std::abs(z); Float_t border = TMath::Min(xborder, zborder); Float_t timewalkX = x * mTimeWalkeSlope; @@ -326,7 +326,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, // Decalibrate float tsCorr = mCalibApi->getTimeDecalibration(channel, tot); - if (TMath::Abs(tsCorr) > 200E3) { // accept correction up to 200 ns + if (std::abs(tsCorr) > 200E3) { // accept correction up to 200 ns LOG(error) << "Wrong de-calibration correction for ch = " << channel << ", tot = " << tot << " (Skip it)"; return; } @@ -483,10 +483,10 @@ Float_t Digitizer::getCharge(Float_t eDep) //______________________________________________________________________ Bool_t Digitizer::isFired(Float_t x, Float_t z, Float_t charge) { - if (TMath::Abs(x) > Geo::XPAD * 0.5 + 0.3) { + if (std::abs(x) > Geo::XPAD * 0.5 + 0.3) { return kFALSE; } - if (TMath::Abs(z) > Geo::ZPAD * 0.5 + 0.3) { + if (std::abs(z) > Geo::ZPAD * 0.5 + 0.3) { return kFALSE; } @@ -505,7 +505,7 @@ Bool_t Digitizer::isFired(Float_t x, Float_t z, Float_t charge) //______________________________________________________________________ Float_t Digitizer::getEffX(Float_t x) { - Float_t xborder = Geo::XPAD * 0.5 - TMath::Abs(x); + Float_t xborder = Geo::XPAD * 0.5 - std::abs(x); if (xborder > 0) { if (xborder > mBound1) { @@ -532,7 +532,7 @@ Float_t Digitizer::getEffX(Float_t x) //______________________________________________________________________ Float_t Digitizer::getEffZ(Float_t z) { - Float_t zborder = Geo::ZPAD * 0.5 - TMath::Abs(z); + Float_t zborder = Geo::ZPAD * 0.5 - std::abs(z); if (zborder > 0) { if (zborder > mBound1) { diff --git a/macro/checkTOFMatching.C b/macro/checkTOFMatching.C index ed6a2355bdd94..7e5e84431c220 100644 --- a/macro/checkTOFMatching.C +++ b/macro/checkTOFMatching.C @@ -1,3 +1,14 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + #if !defined(__CLING__) || defined(__ROOTCLING__) #include "TFile.h" #include "TF1.h" @@ -111,7 +122,7 @@ void checkTOFMatching(bool batchMode = true) // loop over tracks for (uint i = 0; i < mTracksArrayInp->size(); i++) { o2::dataformats::TrackTPCITS trackITSTPC = mTracksArrayInp->at(i); - if (TMath::Abs(trackITSTPC.getEta()) < 0.9) { + if (std::abs(trackITSTPC.getEta()) < 0.9) { htrack->Fill(trackITSTPC.getPt()); if (trackITSTPC.getPt() > 0.5) { htrack_t->Fill(trackITSTPC.getTimeMUS().getTimeStamp()); @@ -287,7 +298,7 @@ void checkTOFMatching(bool batchMode = true) #endif bool bMatched = kFALSE; for (uint ilabel = 0; ilabel < labelsTOF.size(); ilabel++) { - if ((abs(labelsTPC.getTrackID()) == labelsTOF[ilabel].getTrackID() && labelsTPC.getEventID() == labelsTOF[ilabel].getEventID() && labelsTPC.getSourceID() == labelsTOF[ilabel].getSourceID()) || (labelsITS.getTrackID() == labelsTOF[ilabel].getTrackID() && labelsITS.getEventID() == labelsTOF[ilabel].getEventID() && labelsITS.getSourceID() == labelsTOF[ilabel].getSourceID())) { + if ((std::abs(labelsTPC.getTrackID()) == labelsTOF[ilabel].getTrackID() && labelsTPC.getEventID() == labelsTOF[ilabel].getEventID() && labelsTPC.getSourceID() == labelsTOF[ilabel].getSourceID()) || (labelsITS.getTrackID() == labelsTOF[ilabel].getTrackID() && labelsITS.getEventID() == labelsTOF[ilabel].getEventID() && labelsITS.getSourceID() == labelsTOF[ilabel].getSourceID())) { nGoodMatches++; bMatched = kTRUE; break; @@ -325,7 +336,7 @@ void checkTOFMatching(bool batchMode = true) } } - if (TMath::Abs(trackITSTPC.getEta()) < 0.9) { + if (std::abs(trackITSTPC.getEta()) < 0.9) { htof->Fill(trackITSTPC.getPt()); if (bMatched) htofGood->Fill(trackITSTPC.getPt()); @@ -350,7 +361,7 @@ void checkTOFMatching(bool batchMode = true) const auto idxTPCcheck = trackITSTPC.getRefTPC(); const auto idxITScheck = trackITSTPC.getRefITS(); const auto& labelsTPCcheck = (*mcTPC)[idxTPCcheck.getIndex()]; - if (abs(labelsTPCcheck.getTrackID()) == trackIdTOF && labelsTPCcheck.getEventID() == eventIdTOF && labelsTPCcheck.getSourceID() == sourceIdTOF) { + if (std::abs(labelsTPCcheck.getTrackID()) == trackIdTOF && labelsTPCcheck.getEventID() == eventIdTOF && labelsTPCcheck.getSourceID() == sourceIdTOF) { #ifdef DEBUG LOGF(info, "The TPC track that should have been matched to TOF is number %d", i); #endif diff --git a/macro/compareTOFClusters.C b/macro/compareTOFClusters.C index 07029215e9dee..778a5a2be5dd5 100644 --- a/macro/compareTOFClusters.C +++ b/macro/compareTOFClusters.C @@ -68,17 +68,17 @@ bool compareTOFClusters(std::string inpName1 = "tofclustersOr.root", std::string clstatus = false; } - if (TMath::Abs(cl1.getTimeRaw() - cl2.getTimeRaw()) > 1E-6) { + if (std::abs(cl1.getTimeRaw() - cl2.getTimeRaw()) > 1E-6) { printf("cluster %d - Different Raw Times %lf != %lf \n", i, cl1.getTimeRaw(), cl2.getTimeRaw()); clstatus = false; } - if (TMath::Abs(cl1.getTime() - cl2.getTime()) > 1E-6) { + if (std::abs(cl1.getTime() - cl2.getTime()) > 1E-6) { printf("cluster %d - Different Calbrated Times %lf != %lf \n", i, cl1.getTime(), cl2.getTime()); clstatus = false; } - if (TMath::Abs(cl1.getTot() - cl2.getTot()) > 1E-6) { + if (std::abs(cl1.getTot() - cl2.getTot()) > 1E-6) { printf("cluster %d - Different ToTs %f != %f \n", i, cl1.getTot(), cl2.getTot()); clstatus = false; } @@ -93,32 +93,32 @@ bool compareTOFClusters(std::string inpName1 = "tofclustersOr.root", std::string clstatus = false; } - if (TMath::Abs(cl1.getX() - cl2.getX()) > 1E-6) { + if (std::abs(cl1.getX() - cl2.getX()) > 1E-6) { printf("cluster %d - Different X positions %lf != %lf \n", i, cl1.getX(), cl2.getX()); clstatus = false; } - if (TMath::Abs(cl1.getY() - cl2.getY()) > 1E-6) { + if (std::abs(cl1.getY() - cl2.getY()) > 1E-6) { printf("cluster %d - Different Y positions %lf != %lf \n", i, cl1.getY(), cl2.getY()); clstatus = false; } - if (TMath::Abs(cl1.getZ() - cl2.getZ()) > 1E-6) { + if (std::abs(cl1.getZ() - cl2.getZ()) > 1E-6) { printf("cluster %d - Different Z positions %lf != %lf \n", i, cl1.getZ(), cl2.getZ()); clstatus = false; } - if (TMath::Abs(cl1.getSigmaY2() - cl2.getSigmaY2()) > 1E-6) { + if (std::abs(cl1.getSigmaY2() - cl2.getSigmaY2()) > 1E-6) { printf("cluster %d - Different Y2 sigmas %lf != %lf \n", i, cl1.getSigmaY2(), cl2.getSigmaY2()); clstatus = false; } - if (TMath::Abs(cl1.getSigmaZ2() - cl2.getSigmaZ2()) > 1E-6) { + if (std::abs(cl1.getSigmaZ2() - cl2.getSigmaZ2()) > 1E-6) { printf("cluster %d - Different Z2 sigmas %lf != %lf \n", i, cl1.getSigmaZ2(), cl2.getSigmaZ2()); clstatus = false; } - if (TMath::Abs(cl1.getSigmaYZ() - cl2.getSigmaYZ()) > 1E-6) { + if (std::abs(cl1.getSigmaYZ() - cl2.getSigmaYZ()) > 1E-6) { printf("cluster %d - Different YZ sigmas %lf != %lf \n", i, cl1.getSigmaYZ(), cl2.getSigmaYZ()); clstatus = false; } From 2a47fa09dede85a75fa2d50f99df8c2e6f5abd80 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:30:14 +0200 Subject: [PATCH 0335/2205] DPL: allow customising DataProcessingStats intervals In particular, this allows setting a minimum value for online metrics. --- .../Core/include/Framework/DataProcessingStats.h | 11 ++++++++++- Framework/Core/src/CommonServices.cxx | 11 +++++++---- Framework/Core/src/DataProcessingStats.cxx | 14 ++++++++------ Framework/Core/src/DeviceSpecHelpers.cxx | 1 + Framework/Core/src/runDataProcessing.cxx | 1 + .../Core/test/test_ComputingQuotaEvaluator.cxx | 2 +- Framework/Core/test/test_DataProcessingStats.cxx | 12 ++++++------ Framework/Core/test/test_DataRelayer.cxx | 2 +- 8 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Framework/Core/include/Framework/DataProcessingStats.h b/Framework/Core/include/Framework/DataProcessingStats.h index 286df61ba1464..ec96bf8e9973c 100644 --- a/Framework/Core/include/Framework/DataProcessingStats.h +++ b/Framework/Core/include/Framework/DataProcessingStats.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -69,8 +70,16 @@ enum struct ProcessingStatsId : short { /// Helper struct to hold statistics about the data processing happening. struct DataProcessingStats { + // Parameters for the default behaviour + struct DefaultConfig { + int64_t minOnlinePublishInterval = 0; + }; + + DefaultConfig config = {}; + DataProcessingStats(std::function getRealtimeBase, - std::function getTimestamp); + std::function getTimestamp, + DefaultConfig config); constexpr static ServiceKind service_kind = ServiceKind::Global; constexpr static unsigned short MAX_METRICS = 1 << 15; diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index 9192cbd0c965d..bc750181d54e2 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -715,14 +715,14 @@ o2::framework::ServiceSpec O2_SIGNPOST_EVENT_EMIT(data_processor_context, cid, "oldest_possible_timeslice", "Queueing oldest possible timeslice %" PRIu64 " propagation for execution.", (uint64_t)oldestPossibleOutput.timeslice.value); AsyncQueueHelpers::post( - queue, AsyncTask{ .timeslice = TimesliceId{oldestPossibleTimeslice}, - .id = decongestion.oldestPossibleTimesliceTask, + queue, AsyncTask{ .timeslice = TimesliceId{oldestPossibleTimeslice}, + .id = decongestion.oldestPossibleTimesliceTask, .debounce = -1, .callback = decongestionCallback} .user(DecongestionContext{.ref = services, .oldestPossibleOutput = oldestPossibleOutput})); if (decongestion.orderedCompletionPolicyActive) { AsyncQueueHelpers::post( - queue, AsyncTask{.timeslice = TimesliceId{oldestPossibleOutput.timeslice.value},.id = decongestion.oldestPossibleTimesliceTask, .debounce = -1, + queue, AsyncTask{.timeslice = TimesliceId{oldestPossibleOutput.timeslice.value},.id = decongestion.oldestPossibleTimesliceTask, .debounce = -1, .callback = decongestionCallbackOrdered} .user({.ref = services, .oldestPossibleOutput = oldestPossibleOutput})); } }, @@ -867,8 +867,11 @@ o2::framework::ServiceSpec CommonServices::dataProcessingStats() clock_gettime(CLOCK_REALTIME, &now); uv_update_time(state.loop); uint64_t offset = now.tv_sec * 1000 - uv_now(state.loop); + DataProcessingStats::DefaultConfig config = { + .minOnlinePublishInterval = std::stoi(options.GetProperty("dpl-stats-min-online-publishing-interval").c_str()) * 1000}; auto* stats = new DataProcessingStats(TimingHelpers::defaultRealtimeBaseConfigurator(offset, state.loop), - TimingHelpers::defaultCPUTimeConfigurator(state.loop)); + TimingHelpers::defaultCPUTimeConfigurator(state.loop), + config); auto& runningWorkflow = services.get(); // It makes no sense to update the stats more often than every 5s diff --git a/Framework/Core/src/DataProcessingStats.cxx b/Framework/Core/src/DataProcessingStats.cxx index 920f4d7c7addb..3b02a0aacdd70 100644 --- a/Framework/Core/src/DataProcessingStats.cxx +++ b/Framework/Core/src/DataProcessingStats.cxx @@ -11,21 +11,20 @@ #include "Framework/DataProcessingStats.h" #include "Framework/RuntimeError.h" -#include "Framework/ServiceRegistryRef.h" -#include "Framework/DeviceState.h" #include "Framework/Logger.h" #include -#include #include -#include +#include namespace o2::framework { DataProcessingStats::DataProcessingStats(std::function getRealtimeBase_, - std::function getTimestamp_) + std::function getTimestamp_, + DefaultConfig config_) : getTimestamp(getTimestamp_), - getRealtimeBase(getRealtimeBase_) + getRealtimeBase(getRealtimeBase_), + config(config_) { getRealtimeBase(realTimeBase, initialTimeOffset); } @@ -269,6 +268,9 @@ void DataProcessingStats::registerMetric(MetricSpec const& spec) metricSpecs[spec.metricId] = spec; metricsNames[spec.metricId] = spec.name; metrics[spec.metricId] = spec.defaultValue; + if (metricSpecs[spec.metricId].scope == Scope::Online) { + metricSpecs[spec.metricId].minPublishInterval = std::max(metricSpecs[spec.metricId].minPublishInterval, config.minOnlinePublishInterval); + } int64_t currentTime = getTimestamp(realTimeBase, initialTimeOffset); updateInfos[spec.metricId] = UpdateInfo{currentTime, currentTime}; updated[spec.metricId] = spec.sendInitialValue; diff --git a/Framework/Core/src/DeviceSpecHelpers.cxx b/Framework/Core/src/DeviceSpecHelpers.cxx index d1fad2bb66f8b..f2644ed66ba08 100644 --- a/Framework/Core/src/DeviceSpecHelpers.cxx +++ b/Framework/Core/src/DeviceSpecHelpers.cxx @@ -1753,6 +1753,7 @@ boost::program_options::options_description DeviceSpecHelpers::getForwardedDevic ("configuration,cfg", bpo::value(), "configuration connection string") // ("driver-client-backend", bpo::value(), "driver connection string") // ("monitoring-backend", bpo::value(), "monitoring connection string") // + ("dpl-stats-min-online-publishing-interval", bpo::value(), "minimum flushing interval for online metrics (in s)") // ("infologger-mode", bpo::value(), "O2_INFOLOGGER_MODE override") // ("infologger-severity", bpo::value(), "minimun FairLogger severity which goes to info logger") // ("dpl-tracing-flags", bpo::value(), "pipe separated list of events to trace") // diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index d4d0c836aa925..58e669e127f03 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -1049,6 +1049,7 @@ int doChild(int argc, char** argv, ServiceRegistry& serviceRegistry, ConfigParamsHelper::populateBoostProgramOptions(optsDesc, spec.options, gHiddenDeviceOptions); char const* defaultSignposts = getenv("DPL_SIGNPOSTS"); optsDesc.add_options()("monitoring-backend", bpo::value()->default_value("default"), "monitoring backend info") // + ("dpl-stats-min-online-publishing-interval", bpo::value()->default_value("0"), "minimum flushing interval for online metrics (in s)") // ("driver-client-backend", bpo::value()->default_value(defaultDriverClient), "backend for device -> driver communicataon: stdout://: use stdout, ws://: use websockets") // ("infologger-severity", bpo::value()->default_value(""), "minimum FairLogger severity to send to InfoLogger") // ("dpl-tracing-flags", bpo::value()->default_value(""), "pipe `|` separate list of events to be traced") // diff --git a/Framework/Core/test/test_ComputingQuotaEvaluator.cxx b/Framework/Core/test/test_ComputingQuotaEvaluator.cxx index 26b41a3791485..92fedcfe78614 100644 --- a/Framework/Core/test/test_ComputingQuotaEvaluator.cxx +++ b/Framework/Core/test/test_ComputingQuotaEvaluator.cxx @@ -75,7 +75,7 @@ TEST_CASE("TestComputingQuotaEvaluator") }; DataProcessingStats stats(TimingHelpers::defaultRealtimeBaseConfigurator(0, uv_default_loop()), - TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop())); + TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop()), {}); ServiceRegistry registry; ServiceRegistryRef ref(registry); diff --git a/Framework/Core/test/test_DataProcessingStats.cxx b/Framework/Core/test/test_DataProcessingStats.cxx index c23b7fe0436d5..5f14ead966dc0 100644 --- a/Framework/Core/test/test_DataProcessingStats.cxx +++ b/Framework/Core/test/test_DataProcessingStats.cxx @@ -30,7 +30,7 @@ using namespace o2::framework; TEST_CASE("DataProcessingStats") { DataProcessingStats stats(TimingHelpers::defaultRealtimeBaseConfigurator(0, uv_default_loop()), - TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop())); + TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop()), {}); o2::framework::clean_all_runtime_errors(); stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric}); @@ -190,7 +190,7 @@ TEST_CASE("DataProcessingStatsOutOfOrder") int64_t value[] = {0, 1000, 999, 998}; return base + value[count++] - offset; }; - DataProcessingStats stats(realtimeTime, cpuTime); + DataProcessingStats stats(realtimeTime, cpuTime, {}); // Notice this will consume one value in the cpuTime. stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric}); stats.updateStats({DummyMetric, DataProcessingStats::Op::Set, 2}); @@ -222,7 +222,7 @@ TEST_CASE("DataProcessingStatsInstantaneousRate") // I want to push deltas since the last update and have the immediate time // averaged being stored. - DataProcessingStats stats(realtimeConfigurator, cpuTimeConfigurator); + DataProcessingStats stats(realtimeConfigurator, cpuTimeConfigurator, {}); stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric, .kind = DataProcessingStats::Kind::Rate}); REQUIRE(stats.updateInfos[DummyMetric].timestamp == 0); REQUIRE(stats.updateInfos[DummyMetric].lastPublished == 0); @@ -265,7 +265,7 @@ TEST_CASE("DataProcessingStatsCumulativeRate") // I want to push deltas since the last update and have the immediate time // averaged being stored. - DataProcessingStats stats(realtimeConfigurator, cpuTimeConfigurator); + DataProcessingStats stats(realtimeConfigurator, cpuTimeConfigurator, {}); stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric, .kind = DataProcessingStats::Kind::Rate}); REQUIRE(stats.updateInfos[DummyMetric].timestamp == 1000); REQUIRE(stats.updateInfos[DummyMetric].lastPublished == 1000); @@ -310,7 +310,7 @@ TEST_CASE("DataProcessingStatsPublishing") // I want to push deltas since the last update and have the immediate time // averaged being stored. - DataProcessingStats stats(realtimeTimestamp, cpuTimeTimestamp); + DataProcessingStats stats(realtimeTimestamp, cpuTimeTimestamp, {}); stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric, .minPublishInterval = 5000}); stats.registerMetric({.name = "dummy_metric2", .metricId = DummyMetric2, .minPublishInterval = 2000}); REQUIRE(stats.updateInfos[DummyMetric].timestamp == 1000); @@ -355,7 +355,7 @@ TEST_CASE("DataProcessingStatsPublishingRepeated") // I want to push deltas since the last update and have the immediate time // averaged being stored. - DataProcessingStats stats(realtimeTimestamp, cpuTimeTimestamp); + DataProcessingStats stats(realtimeTimestamp, cpuTimeTimestamp, {}); stats.registerMetric({.name = "dummy_metric", .metricId = DummyMetric, .minPublishInterval = 3000, .maxRefreshLatency = 9000}); REQUIRE(stats.updateInfos[DummyMetric].timestamp == 1000); REQUIRE(stats.updateInfos[DummyMetric].lastPublished == 1000); diff --git a/Framework/Core/test/test_DataRelayer.cxx b/Framework/Core/test/test_DataRelayer.cxx index ec5d48fbd78da..64a1827820638 100644 --- a/Framework/Core/test/test_DataRelayer.cxx +++ b/Framework/Core/test/test_DataRelayer.cxx @@ -48,7 +48,7 @@ TEST_CASE("DataRelayer") TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop())); DataProcessingStats stats( TimingHelpers::defaultRealtimeBaseConfigurator(0, uv_default_loop()), - TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop())); + TimingHelpers::defaultCPUTimeConfigurator(uv_default_loop()), {}); int quickUpdateInterval = 1; using MetricSpec = DataProcessingStats::MetricSpec; std::vector specs{ From e9240044a933a019c45557fe633e58ba2667a858 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 10 Oct 2024 14:45:37 +0200 Subject: [PATCH 0336/2205] Ship GRPECS as part of AggregatedRunInfo; cleanup * provide also the GRPECS as part of the struct * use CTP info only when run number is consistent --- .../DataFormatsParameters/AggregatedRunInfo.h | 3 ++ .../Parameters/src/AggregatedRunInfo.cxx | 33 ++++++++++--------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h index dc93ad46cc167..ddcb6e3c8471d 100644 --- a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -22,6 +22,8 @@ namespace o2::parameters { +class GRPECSObject; + /// Composite struct where one may collect important global properties of data "runs" /// aggregated from various sources (GRPECS, RunInformation CCDB entries, etc.). /// Also offers the authoritative algorithms to collect these information for easy reuse @@ -36,6 +38,7 @@ struct AggregatedRunInfo { int64_t orbitEOR; // orbit when run ends after orbit reset // we may have pointers to actual data source objects GRPECS, ... + o2::parameters::GRPECSObject* grpECS = nullptr; // pointer to GRPECSobject (fetched during struct building) // fills and returns AggregatedRunInfo for a given run number. static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index 9e3d86177ff4a..bc836cd2e394b 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -63,24 +63,25 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2:: int64_t ctp_run_number = (*ctp_first_run_orbit)[1]; int64_t ctp_orbitSOR = (*ctp_first_run_orbit)[2]; - if (ctp_run_number != runnumber) { - LOG(error) << "AggregatedRunInfo: run number inconsistency found (asked: " << runnumber << " vs CTP found: " << ctp_run_number << ")"; - } - - // overwrite orbitSOR - if (ctp_orbitSOR != orbitSOR) { - LOG(warn) << "The calculated orbitSOR " << orbitSOR << " differs from CTP orbitSOR " << ctp_orbitSOR; - // reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc. - - // so we need to adjust the SOR timings to be consistent - auto sor_new = (int64_t)((tsOrbitReset + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); - if (sor_new != sor) { - LOG(warn) << "Adjusting SOR from " << sor << " to " << sor_new; - sor = sor_new; + if (ctp_run_number == runnumber) { + // overwrite orbitSOR + if (ctp_orbitSOR != orbitSOR) { + LOG(warn) << "The calculated orbitSOR " << orbitSOR << " differs from CTP orbitSOR " << ctp_orbitSOR; + // reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc. + + // so we need to adjust the SOR timings to be consistent + auto sor_new = (int64_t)((tsOrbitReset + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); + if (sor_new != sor) { + LOG(warn) << "Adjusting SOR from " << sor << " to " << sor_new; + sor = sor_new; + } } + orbitSOR = ctp_orbitSOR; + } else { + LOG(error) << "AggregatedRunInfo: run number inconsistency found (asked: " << runnumber << " vs CTP found: " << ctp_run_number << ")"; + LOG(error) << " ... not using CTP info"; } - orbitSOR = ctp_orbitSOR; } - return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR}; + return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR, grpecs}; } From 1ff58c417622029b5789d1cc696117cb8a78782a Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 10 Oct 2024 16:50:46 +0200 Subject: [PATCH 0337/2205] Update AggregatedRunInfo.h --- .../include/DataFormatsParameters/AggregatedRunInfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h index ddcb6e3c8471d..d4f434db059c5 100644 --- a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -38,7 +38,7 @@ struct AggregatedRunInfo { int64_t orbitEOR; // orbit when run ends after orbit reset // we may have pointers to actual data source objects GRPECS, ... - o2::parameters::GRPECSObject* grpECS = nullptr; // pointer to GRPECSobject (fetched during struct building) + const o2::parameters::GRPECSObject* grpECS = nullptr; // pointer to GRPECSobject (fetched during struct building) // fills and returns AggregatedRunInfo for a given run number. static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); From 63b85d483e00c7115328417a3bd2171ad5eeff3d Mon Sep 17 00:00:00 2001 From: Fabio Catalano Date: Thu, 10 Oct 2024 15:48:24 +0200 Subject: [PATCH 0338/2205] Add DsStar (433) to physics constants --- Common/Constants/include/CommonConstants/PhysicsConstants.h | 2 ++ Common/Constants/include/CommonConstants/make_pdg_header.py | 1 + 2 files changed, 3 insertions(+) diff --git a/Common/Constants/include/CommonConstants/PhysicsConstants.h b/Common/Constants/include/CommonConstants/PhysicsConstants.h index 64c4ac9c6635e..10351c965af3a 100644 --- a/Common/Constants/include/CommonConstants/PhysicsConstants.h +++ b/Common/Constants/include/CommonConstants/PhysicsConstants.h @@ -48,6 +48,7 @@ enum Pdg { kDPlus = 411, kDS = 431, kDSBar = -431, + kDSStar = 433, kDS1 = 10433, kDS2Star = 435, kDStar = 413, @@ -95,6 +96,7 @@ constexpr double MassDMinus = 1.86966; constexpr double MassDPlus = 1.86966; constexpr double MassDS = 1.96835; constexpr double MassDSBar = 1.96835; +constexpr double MassDSStar = 2.1122; constexpr double MassDS1 = 2.53511; constexpr double MassDS2Star = 2.5691; constexpr double MassDStar = 2.01026; diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index fc62474eafa65..b71bff40b0011 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -103,6 +103,7 @@ class Pdg(Enum): kDPlus = 411 kDS = 431 kDSBar = -431 + kDSStar = 433 kDS1 = 10433 kDS2Star = 435 kDStar = 413 From 6fbc0f9a60fcf3163718e25eb913171d6324cb50 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Fri, 11 Oct 2024 13:36:28 +0200 Subject: [PATCH 0339/2205] add ITS sensors to parallel world (#13163) * add possibility to use TGeo parallel world navigation * add virtual interface that allows detector to add volumes to parallel world * implement ITS parallel world --- .../DetectorsCommonDataFormats/AlignParam.h | 4 +- Detectors/Base/CMakeLists.txt | 2 + .../Base/include/DetectorsBase/Detector.h | 3 ++ .../include/DetectorsBase/GeometryManager.h | 4 +- .../DetectorsBase/GeometryManagerParam.h | 31 ++++++++++++ Detectors/Base/src/Detector.cxx | 4 ++ Detectors/Base/src/DetectorsBaseLinkDef.h | 1 + Detectors/Base/src/GeometryManager.cxx | 4 +- Detectors/Base/src/GeometryManagerParam.cxx | 13 +++++ .../ITSMFT/ITS/simulation/CMakeLists.txt | 4 +- .../include/ITSSimulation/Detector.h | 3 ++ .../include/ITSSimulation/ITSSimParam.h | 34 +++++++++++++ .../ITSMFT/ITS/simulation/src/Detector.cxx | 49 +++++++++++++++++++ .../ITSMFT/ITS/simulation/src/ITSSimParam.cxx | 13 +++++ .../ITS/simulation/src/ITSSimulationLinkDef.h | 1 + Steer/src/O2MCApplication.cxx | 23 +++++++++ 16 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 Detectors/Base/include/DetectorsBase/GeometryManagerParam.h create mode 100644 Detectors/Base/src/GeometryManagerParam.cxx create mode 100644 Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSSimParam.h create mode 100644 Detectors/ITSMFT/ITS/simulation/src/ITSSimParam.cxx diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/AlignParam.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/AlignParam.h index 74610264336be..c4e702c6ae27e 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/AlignParam.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/AlignParam.h @@ -136,7 +136,7 @@ class AlignParam ClassDefNV(AlignParam, 1); }; -} -} +} // namespace detectors +} // namespace o2 #endif diff --git a/Detectors/Base/CMakeLists.txt b/Detectors/Base/CMakeLists.txt index 952dc9e865693..934a112ea2062 100644 --- a/Detectors/Base/CMakeLists.txt +++ b/Detectors/Base/CMakeLists.txt @@ -14,6 +14,7 @@ o2_add_library(DetectorsBase src/GeometryManager.cxx src/MaterialManager.cxx src/MaterialManagerParam.cxx + src/GeometryManagerParam.cxx src/Propagator.cxx src/MatLayerCyl.cxx src/MatLayerCylSet.cxx @@ -51,6 +52,7 @@ o2_target_root_dictionary(DetectorsBase include/DetectorsBase/GeometryManager.h include/DetectorsBase/MaterialManager.h include/DetectorsBase/MaterialManagerParam.h + include/DetectorsBase/GeometryManagerParam.h include/DetectorsBase/Propagator.h include/DetectorsBase/Ray.h include/DetectorsBase/MatCell.h diff --git a/Detectors/Base/include/DetectorsBase/Detector.h b/Detectors/Base/include/DetectorsBase/Detector.h index 1432d93c53821..f1744086d6a05 100644 --- a/Detectors/Base/include/DetectorsBase/Detector.h +++ b/Detectors/Base/include/DetectorsBase/Detector.h @@ -106,6 +106,9 @@ class Detector : public FairDetector /// declare alignable volumes of detector virtual void addAlignableVolumes() const; + /// fill parallel geometry with sensitive volumes of detector + virtual void fillParallelWorld() const; + /// Sets per wrapper volume parameters virtual void defineWrapperVolume(Int_t id, Double_t rmin, Double_t rmax, Double_t zspan); diff --git a/Detectors/Base/include/DetectorsBase/GeometryManager.h b/Detectors/Base/include/DetectorsBase/GeometryManager.h index 96998187cca63..ad1d77b10f49a 100644 --- a/Detectors/Base/include/DetectorsBase/GeometryManager.h +++ b/Detectors/Base/include/DetectorsBase/GeometryManager.h @@ -86,8 +86,7 @@ class GeometryManager : public TObject double meanZ = 0.; // mean Z: sum(x_i*Z_i)/sum(x_i) [adimensional] double meanZ2A = 0.; // Z/A mean: sum(x_i*Z_i/A_i)/sum(x_i) [adimensional] double length = -1.; // length: sum(x_i) [cm] - int nCross = 0; - ; // number of boundary crosses + int nCross = 0; // number of boundary crosses MatBudgetExt() = default; ~MatBudgetExt() = default; @@ -132,6 +131,7 @@ class GeometryManager : public TObject /// detector geometry. The output global matrix is stored in 'm'. /// Returns kFALSE in case TGeo has not been initialized or the volume path is not valid. static Bool_t getOriginalMatrixFromPath(const char* path, TGeoHMatrix& m); + private: /// sensitive volume identifier composed from (det_ID< { + bool useParallelWorld = false; + bool usePwGeoBVH = false; + bool usePwCaching = false; + + O2ParamDef(GeometryManagerParam, "GeometryManagerParam"); +}; + +} // namespace o2 + +#endif /* DETECTORS_BASE_INCLUDE_GEOMETRYMANAGERPARAM_H_ */ diff --git a/Detectors/Base/src/Detector.cxx b/Detectors/Base/src/Detector.cxx index f2b790ffccd5b..d2be9237f6f13 100644 --- a/Detectors/Base/src/Detector.cxx +++ b/Detectors/Base/src/Detector.cxx @@ -171,6 +171,10 @@ void Detector::addAlignableVolumes() const LOG(warning) << "Alignable volumes are not yet defined for " << GetName(); } +void Detector::fillParallelWorld() const +{ +} + int Detector::registerSensitiveVolumeAndGetVolID(TGeoVolume const* vol) { // register this volume with FairRoot diff --git a/Detectors/Base/src/DetectorsBaseLinkDef.h b/Detectors/Base/src/DetectorsBaseLinkDef.h index bb1aa42c66718..bd76e9bfbe2e4 100644 --- a/Detectors/Base/src/DetectorsBaseLinkDef.h +++ b/Detectors/Base/src/DetectorsBaseLinkDef.h @@ -26,6 +26,7 @@ #pragma link C++ class o2::base::GeometryManager::MatBudgetExt + ; #pragma link C++ class o2::base::MaterialManager + ; #pragma link C++ class o2::MaterialManagerParam + ; +#pragma link C++ class o2::GeometryManagerParam + ; #pragma link C++ class o2::base::SimFieldUtils + ; #pragma link C++ class o2::base::Ray + ; diff --git a/Detectors/Base/src/GeometryManager.cxx b/Detectors/Base/src/GeometryManager.cxx index 885cff7a73588..c5e7e8e47e731 100644 --- a/Detectors/Base/src/GeometryManager.cxx +++ b/Detectors/Base/src/GeometryManager.cxx @@ -12,8 +12,8 @@ /// \file GeometryManager.cxx /// \brief Implementation of the GeometryManager class -#include // for LOG -#include // for TIter +#include // for LOG +#include // for TIter #include #include // for TGeoHMatrix #include // for TGeoNode diff --git a/Detectors/Base/src/GeometryManagerParam.cxx b/Detectors/Base/src/GeometryManagerParam.cxx new file mode 100644 index 0000000000000..e3c3ff3d687a7 --- /dev/null +++ b/Detectors/Base/src/GeometryManagerParam.cxx @@ -0,0 +1,13 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "DetectorsBase/GeometryManagerParam.h" +O2ParamImpl(o2::GeometryManagerParam); diff --git a/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt b/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt index 78a93bdc7232d..51ade8bab6bcc 100644 --- a/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/simulation/CMakeLists.txt @@ -13,6 +13,7 @@ o2_add_library(ITSSimulation SOURCES src/V11Geometry.cxx src/V1Layer.cxx src/V3Layer.cxx src/Detector.cxx src/V3Services.cxx src/V3Cage.cxx src/DescriptorInnerBarrelITS2.cxx src/ITSDataSimulator.cxx + src/ITSSimParam.cxx PUBLIC_LINK_LIBRARIES O2::ITSBase O2::ITSMFTSimulation ROOT::Physics $<$:O2::ITS3Base> $<$:O2::ITS3Simulation>) @@ -24,7 +25,8 @@ o2_target_root_dictionary(ITSSimulation include/ITSSimulation/V3Cage.h include/ITSSimulation/V11Geometry.h include/ITSSimulation/V3Services.h - include/ITSSimulation/DescriptorInnerBarrelITS2.h) + include/ITSSimulation/DescriptorInnerBarrelITS2.h + include/ITSSimulation/ITSSimParam.h) o2_data_file(COPY data DESTINATION Detectors/ITS/simulation) diff --git a/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/Detector.h b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/Detector.h index c48f0f942d29c..57301ac4babd0 100644 --- a/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/Detector.h +++ b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/Detector.h @@ -159,6 +159,9 @@ class Detector : public o2::base::DetImpl /// Add alignable top volumes void addAlignableVolumes() const override; + /// Add ITS chip volumes to parallel world geometry + void fillParallelWorld() const override; + /// Add alignable Layer volumes /// \param lr layer number /// \param parent path of the parent volume diff --git a/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSSimParam.h b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSSimParam.h new file mode 100644 index 0000000000000..231b9294136b0 --- /dev/null +++ b/Detectors/ITSMFT/ITS/simulation/include/ITSSimulation/ITSSimParam.h @@ -0,0 +1,34 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef DETECTORS_BASE_INCLUDE_ITSSIMPARAM_H_ +#define DETECTORS_BASE_INCLUDE_ITSSIMPARAM_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2 +{ +namespace its +{ + +struct ITSSimParam : public o2::conf::ConfigurableParamHelper { + bool addMetalToPW = true; + bool addSensorToPW = true; + bool addChipToPW = true; + + O2ParamDef(ITSSimParam, "ITSSimParam"); +}; + +} // namespace its +} // namespace o2 + +#endif /* DETECTORS_BASE_INCLUDE_ITSSIMPARAM_H_ */ diff --git a/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx b/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx index 9a93c72ee0760..bf2e997794ee4 100644 --- a/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx +++ b/Detectors/ITSMFT/ITS/simulation/src/Detector.cxx @@ -20,6 +20,7 @@ #include "ITSSimulation/V3Layer.h" #include "ITSSimulation/V3Services.h" #include "ITSSimulation/V3Cage.h" +#include "ITSSimulation/ITSSimParam.h" #include "DetectorsBase/Stack.h" #include "SimulationDataFormat/TrackReference.h" @@ -41,6 +42,7 @@ #include "TVirtualMC.h" // for gMC, TVirtualMC #include "TVirtualMCStack.h" // for TVirtualMCStack #include "TFile.h" // for TVirtualMCStack +#include "TGeoParallelWorld.h" #include // for NULL, snprintf #include @@ -1308,6 +1310,53 @@ void Detector::defineSensitiveVolumes() } } +void Detector::fillParallelWorld() const +{ + TGeoParallelWorld* pw = gGeoManager->GetParallelWorld(); + if (pw == nullptr) { + LOG(error) << "Parallel world was not created"; + return; + } + auto& param = ITSSimParam::Instance(); + + for (int iL{0}; iL < mNumberLayers; ++iL) { + auto const layer = mGeometry[iL]; + int nhbarrels = layer->getNumberOfHalfBarrelsPerParent(); + int nstaves = layer->getNumberOfStavesPerParent(); + int nhstaves = layer->getNumberOfHalfStavesPerParent(); + int nmodules = layer->getNumberOfModulesPerParent(); + int nchips = layer->getNumberOfChipsPerParent(); + + for (int iHB{0}; iHB < nhbarrels; ++iHB) { + for (int iS{0}; iS < nstaves; ++iS) { + for (int iHS{nhstaves > 0 ? 0 : -1}; iHS < nhstaves; ++iHS) { + for (int iM{nmodules > 0 ? 0 : -1}; iM < nmodules; ++iM) { + for (int iC{0}; iC < nchips; ++iC) { + TString sname = GeometryTGeo::composeSymNameChip(iL, iHB, iS, iHS, iM, iC); + TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(sname); + auto path = pne->GetTitle(); + + if (param.addMetalToPW) { + TString metalPath = Form("%s/MetalStack_1", path); + gGeoManager->MakePhysicalNode(metalPath); + pw->AddNode(metalPath); + } + if (param.addSensorToPW) { + TString sensorPath = Form("%s/ITSUSensor%d_1", path, iL); + gGeoManager->MakePhysicalNode(sensorPath); + pw->AddNode(sensorPath); + } + if (param.addChipToPW) { + pw->AddNode(path); + } + } + } + } + } + } + } +} + Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos, const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus) diff --git a/Detectors/ITSMFT/ITS/simulation/src/ITSSimParam.cxx b/Detectors/ITSMFT/ITS/simulation/src/ITSSimParam.cxx new file mode 100644 index 0000000000000..564e9942a26d5 --- /dev/null +++ b/Detectors/ITSMFT/ITS/simulation/src/ITSSimParam.cxx @@ -0,0 +1,13 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ITSSimulation/ITSSimParam.h" +O2ParamImpl(o2::its::ITSSimParam); diff --git a/Detectors/ITSMFT/ITS/simulation/src/ITSSimulationLinkDef.h b/Detectors/ITSMFT/ITS/simulation/src/ITSSimulationLinkDef.h index 92e10577b6abf..bd4ce228deb1b 100644 --- a/Detectors/ITSMFT/ITS/simulation/src/ITSSimulationLinkDef.h +++ b/Detectors/ITSMFT/ITS/simulation/src/ITSSimulationLinkDef.h @@ -23,5 +23,6 @@ #pragma link C++ class o2::its::Detector + ; #pragma link C++ class o2::its::DescriptorInnerBarrelITS2 + ; #pragma link C++ class o2::base::DetImpl < o2::its::Detector> + ; +#pragma link C++ class o2::its::ITSSimParam + ; #endif diff --git a/Steer/src/O2MCApplication.cxx b/Steer/src/O2MCApplication.cxx index e06faaf26bd63..ed4735b21b46a 100644 --- a/Steer/src/O2MCApplication.cxx +++ b/Steer/src/O2MCApplication.cxx @@ -9,6 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include + #include #include #include @@ -33,6 +35,8 @@ #include #include #include "SimConfig/GlobalProcessCutSimParam.h" +#include "DetectorsBase/GeometryManagerParam.h" +#include namespace o2 { @@ -186,6 +190,25 @@ bool O2MCApplicationBase::MisalignGeometry() auto alignedgeomfile = o2::base::NameConf::getAlignedGeomFileName(confref.getOutPrefix()); gGeoManager->Export(alignedgeomfile.c_str()); + auto& param = o2::GeometryManagerParam::Instance(); + + // fill parallel world geometry if activated + if (param.useParallelWorld) { + TGeoParallelWorld* pw = gGeoManager->CreateParallelWorld("priority_sensors"); + if (param.usePwGeoBVH) { + pw->SetAccelerationMode(TGeoParallelWorld::AccelerationMode::kBVH); + } + if (param.usePwCaching) { + TGeoNavigator::SetPWSafetyCaching(true); + } + for (auto det : listDetectors) { + if (dynamic_cast(det)) { + ((o2::base::Detector*)det)->fillParallelWorld(); + } + } + gGeoManager->SetUseParallelWorldNav(true); + } + // return original return value of misalignment procedure return true; } From 80195a0bfb613aead4a06bc1541c0a024465ab76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Tich=C3=A1k?= <53997499+justonedev1@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:41:33 +0200 Subject: [PATCH 0340/2205] [QC-1176] added tools to QC to check whether objects is mergeable (#13472) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added tools to QC to check whether objects is mergeable * fix copyright, fix comment --------- Co-authored-by: Michal Tichák --- Utilities/Mergers/CMakeLists.txt | 5 +- Utilities/Mergers/include/Mergers/Mergeable.h | 52 +++++++++++++++++++ Utilities/Mergers/src/Mergeable.cxx | 36 +++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 Utilities/Mergers/include/Mergers/Mergeable.h create mode 100644 Utilities/Mergers/src/Mergeable.cxx diff --git a/Utilities/Mergers/CMakeLists.txt b/Utilities/Mergers/CMakeLists.txt index 26d9c79c69aab..43a22dd395996 100644 --- a/Utilities/Mergers/CMakeLists.txt +++ b/Utilities/Mergers/CMakeLists.txt @@ -12,8 +12,9 @@ # FIXME: the LinkDef should not be in the public area o2_add_library(Mergers - SOURCES src/MergerAlgorithm.cxx src/IntegratingMerger.cxx src/MergerInfrastructureBuilder.cxx - src/MergerBuilder.cxx src/FullHistoryMerger.cxx src/ObjectStore.cxx + SOURCES src/FullHistoryMerger.cxx src/IntegratingMerger.cxx src/Mergeable.cxx + src/MergerAlgorithm.cxx src/MergerBuilder.cxx src/MergerInfrastructureBuilder.cxx + src/ObjectStore.cxx PUBLIC_LINK_LIBRARIES O2::Framework AliceO2::InfoLogger) o2_target_root_dictionary( diff --git a/Utilities/Mergers/include/Mergers/Mergeable.h b/Utilities/Mergers/include/Mergers/Mergeable.h new file mode 100644 index 0000000000000..12facadb455ea --- /dev/null +++ b/Utilities/Mergers/include/Mergers/Mergeable.h @@ -0,0 +1,52 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ALICEO2_MERGERS_H +#define ALICEO2_MERGERS_H + +/// \file Mergeable.h +/// \brief Mergeable concept. +/// +/// \author Michal Tichak, michal.tichak@cern.ch + +#include + +class TObject; +class TH1; +class TCollection; +class TObjArray; +class TH1; +class TTree; +class THnBase; +class TEfficiency; +class TGraph; +class TCanvas; + +namespace o2::mergers +{ + +class MergeInterface; + +template +constexpr bool IsDerivedFrom = (std::derived_from || ...); + +// \brief Concept to be used to test if some parameter is mergeable +// +// \parameter T type to be restricted +template +concept Mergeable = IsDerivedFrom, mergers::MergeInterface, TCollection, TH1, TTree, TGraph, TEfficiency, THnBase>; + +// \brief runtime check whether TObject is mergeable +bool isMergeable(TObject* obj); + +} // namespace o2::mergers + +#endif diff --git a/Utilities/Mergers/src/Mergeable.cxx b/Utilities/Mergers/src/Mergeable.cxx new file mode 100644 index 0000000000000..4963240025e1b --- /dev/null +++ b/Utilities/Mergers/src/Mergeable.cxx @@ -0,0 +1,36 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include +#include +#include "Mergers/MergeInterface.h" +#include "Mergers/Mergeable.h" + +namespace o2::mergers +{ + +bool isMergeable(TObject* obj) +{ + return obj->InheritsFrom(mergers::MergeInterface::Class()) || + obj->InheritsFrom(TCollection::Class()) || + obj->InheritsFrom(TH1::Class()) || + obj->InheritsFrom(THnBase::Class()) || + obj->InheritsFrom(TTree::Class()) || + obj->InheritsFrom(TGraph::Class()) || + obj->InheritsFrom(TEfficiency::Class()); +} + +} // namespace o2::mergers From c7b07de879e88bf432e3a1836421d44b203931cb Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 10 Oct 2024 17:54:37 +0200 Subject: [PATCH 0341/2205] Fix fetching CCDB metadata, extend ccdbRunDependent behaviour ccdbParamSpec run-dependence flag changed from bool to int. The new convension is: ccdbParamSpec(path) : not run-depndent ccdbParamSpec(path, 1) : run-dependent object with usual timestamp and runNumber requested via metadata ccdbParamSpec(path, 2) : run-dependent object with runNumber used instead of timestamp. So, the entry like RCT/Info/RunInformation should be requested by passing 2. --- Framework/CCDBSupport/src/CCDBHelpers.cxx | 23 ++++++++++++------- .../Core/include/Framework/CCDBParamSpec.h | 4 ++-- .../Core/include/Framework/InputRecord.h | 6 ++--- Framework/Core/src/CCDBParamSpec.cxx | 8 +++---- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Framework/CCDBSupport/src/CCDBHelpers.cxx b/Framework/CCDBSupport/src/CCDBHelpers.cxx index ab1a21e263eb0..29d446403e1c8 100644 --- a/Framework/CCDBSupport/src/CCDBHelpers.cxx +++ b/Framework/CCDBSupport/src/CCDBHelpers.cxx @@ -198,6 +198,7 @@ auto populateCacheWith(std::shared_ptr const& helper, auto sid = _o2_signpost_id_t{(int64_t)timingInfo.timeslice}; O2_SIGNPOST_START(ccdb, sid, "populateCacheWith", "Starting to populate cache with CCDB objects"); for (auto& route : helper->routes) { + int64_t timestampToUse = timestamp; O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "populateCacheWith", "Fetching object for route %{public}s", DataSpecUtils::describe(route.matcher).data()); objCnt++; auto concrete = DataSpecUtils::asConcreteDataMatcher(route.matcher); @@ -212,8 +213,14 @@ auto populateCacheWith(std::shared_ptr const& helper, for (auto& meta : route.matcher.metadata) { if (meta.name == "ccdb-path") { path = meta.defaultValue.get(); - } else if (meta.name == "ccdb-run-dependent" && meta.defaultValue.get() == true) { - metadata["runNumber"] = dtc.runNumber; + } else if (meta.name == "ccdb-run-dependent" && meta.defaultValue.get() > 0) { + if (meta.defaultValue.get() == 1) { + metadata["runNumber"] = dtc.runNumber; + } else if (meta.defaultValue.get() == 2) { + timestampToUse = std::stoi(dtc.runNumber); + } else { + LOGP(fatal, "Undefined run-dependent option {} for spec {}/{}/{}", meta.defaultValue.get(), concrete.origin.as(), concrete.description.as(), int(concrete.subSpec)); + } } else if (isPrefix(ccdbMetadataPrefix, meta.name)) { std::string key = meta.name.substr(ccdbMetadataPrefix.size()); auto value = meta.defaultValue.get(); @@ -232,7 +239,7 @@ auto populateCacheWith(std::shared_ptr const& helper, uint64_t cachePopulatedAt = url2uuid->second.cachePopulatedAt; // If timestamp is before the time the element was cached or after the claimed validity, we need to check validity, again // when online. - bool cacheExpired = (validUntil <= timestamp) || (timestamp <= cachePopulatedAt); + bool cacheExpired = (validUntil <= timestampToUse) || (timestamp < cachePopulatedAt); checkValidity = (std::abs(int(timingInfo.tfCounter - url2uuid->second.lastCheckedTF)) >= chRate) && (isOnline || cacheExpired); } else { checkValidity = true; // never skip check if the cache is empty @@ -242,10 +249,10 @@ auto populateCacheWith(std::shared_ptr const& helper, const auto& api = helper->getAPI(path); if (checkValidity && (!api.isSnapshotMode() || etag.empty())) { // in the snapshot mode the object needs to be fetched only once - LOGP(detail, "Loading {} for timestamp {}", path, timestamp); - api.loadFileToMemory(v, path, metadata, timestamp, &headers, etag, helper->createdNotAfter, helper->createdNotBefore); + LOGP(detail, "Loading {} for timestamp {}", path, timestampToUse); + api.loadFileToMemory(v, path, metadata, timestampToUse, &headers, etag, helper->createdNotAfter, helper->createdNotBefore); if ((headers.count("Error") != 0) || (etag.empty() && v.empty())) { - LOGP(fatal, "Unable to find object {}/{}", path, timestamp); + LOGP(fatal, "Unable to find object {}/{}", path, timestampToUse); // FIXME: I should send a dummy message. continue; } @@ -256,7 +263,7 @@ auto populateCacheWith(std::shared_ptr const& helper, helper->mapURL2UUID[path].lastCheckedTF = timingInfo.tfCounter; if (etag.empty()) { helper->mapURL2UUID[path].etag = headers["ETag"]; // update uuid - helper->mapURL2UUID[path].cachePopulatedAt = timestamp; + helper->mapURL2UUID[path].cachePopulatedAt = timestampToUse; helper->mapURL2UUID[path].cacheMiss++; helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); helper->mapURL2UUID[path].maxSize = std::max(v.size(), helper->mapURL2UUID[path].maxSize); @@ -269,7 +276,7 @@ auto populateCacheWith(std::shared_ptr const& helper, if (v.size()) { // but should be overridden by fresh object // somewhere here pruneFromCache should be called helper->mapURL2UUID[path].etag = headers["ETag"]; // update uuid - helper->mapURL2UUID[path].cachePopulatedAt = timestamp; + helper->mapURL2UUID[path].cachePopulatedAt = timestampToUse; helper->mapURL2UUID[path].cacheValidUntil = headers["Cache-Valid-Until"].empty() ? 0 : std::stoul(headers["Cache-Valid-Until"]); helper->mapURL2UUID[path].cacheMiss++; helper->mapURL2UUID[path].minSize = std::min(v.size(), helper->mapURL2UUID[path].minSize); diff --git a/Framework/Core/include/Framework/CCDBParamSpec.h b/Framework/Core/include/Framework/CCDBParamSpec.h index d627f12b40985..9f2c3b69ae458 100644 --- a/Framework/Core/include/Framework/CCDBParamSpec.h +++ b/Framework/Core/include/Framework/CCDBParamSpec.h @@ -23,9 +23,9 @@ struct CCDBMetadata { }; ConfigParamSpec ccdbPathSpec(std::string const& path); -ConfigParamSpec ccdbRunDependent(bool defaultValue = true); +ConfigParamSpec ccdbRunDependent(int defaultValue = 1); // <1: not run-dependent, 1: run-dependent object with usual timestamp, 2: run-dependent object with runNumber used instead of timestamp -std::vector ccdbParamSpec(std::string const& path, bool runDependent, std::vector metadata = {}, int qrate = 0); +std::vector ccdbParamSpec(std::string const& path, int runDependent, std::vector metadata = {}, int qrate = 0); /// Helper to create an InputSpec which will read from a CCDB /// Notice that those input specs have some convetions for their metadata: /// diff --git a/Framework/Core/include/Framework/InputRecord.h b/Framework/Core/include/Framework/InputRecord.h index 49b8ad70438a7..0c9f36d00c634 100644 --- a/Framework/Core/include/Framework/InputRecord.h +++ b/Framework/Core/include/Framework/InputRecord.h @@ -493,7 +493,7 @@ class InputRecord auto cacheEntry = cache.matcherToMetadataId.find(path); if (cacheEntry == cache.matcherToMetadataId.end()) { cache.matcherToMetadataId.insert(std::make_pair(path, id)); - cache.idToMetadata[id] = extractCCDBHeaders(ref); + cache.idToMetadata[id] = DataRefUtils::extractCCDBHeaders(ref); LOGP(info, "Caching CCDB metadata {}: {}", id.value, path); return cache.idToMetadata[id]; } @@ -506,9 +506,9 @@ class InputRecord // The id in the cache is different. Let's destroy the old cached entry // and create a new one. LOGP(info, "Replacing cached entry {} with {} for {}", oldId.value, id.value, path); - cache.idToObject[id] = extracCCDBMetadata(ref); + cache.idToMetadata[id] = DataRefUtils::extractCCDBHeaders(ref); oldId.value = id.value; - return cache.idToObject[id]; + return cache.idToMetadata[id]; } /// Helper method to be used to check if a given part of the InputRecord is present. diff --git a/Framework/Core/src/CCDBParamSpec.cxx b/Framework/Core/src/CCDBParamSpec.cxx index 718c4b162de2a..de588444f4f1c 100644 --- a/Framework/Core/src/CCDBParamSpec.cxx +++ b/Framework/Core/src/CCDBParamSpec.cxx @@ -21,9 +21,9 @@ ConfigParamSpec ccdbPathSpec(std::string const& path) return ConfigParamSpec{"ccdb-path", VariantType::String, path, {fmt::format("Path in CCDB ({})", path)}, ConfigParamKind::kGeneric}; } -ConfigParamSpec ccdbRunDependent(bool defaultValue) +ConfigParamSpec ccdbRunDependent(int defaultValue) { - return ConfigParamSpec{"ccdb-run-dependent", VariantType::Bool, defaultValue, {"Give object for specific run number"}, ConfigParamKind::kGeneric}; + return ConfigParamSpec{"ccdb-run-dependent", VariantType::Int, defaultValue, {"Give object for specific run number"}, ConfigParamKind::kGeneric}; } ConfigParamSpec ccdbQueryRateSpec(int r) @@ -45,11 +45,11 @@ std::vector ccdbParamSpec(std::string const& path, std::vector< return ccdbParamSpec(path, false, metadata, qrate); } -std::vector ccdbParamSpec(std::string const& path, bool runDependent, std::vector metadata, int qrate) +std::vector ccdbParamSpec(std::string const& path, int runDependent, std::vector metadata, int qrate) { // Add here CCDB objecs which should be considered run dependent std::vector result{ccdbPathSpec(path)}; - if (runDependent) { + if (runDependent > 0) { result.push_back(ccdbRunDependent(runDependent)); } if (qrate != 0) { From 81e6fd9d47f259f5cdf1f0c6bc66c256be34989b Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 10 Oct 2024 17:55:50 +0200 Subject: [PATCH 0342/2205] add separate method to extract run-duration from RCT info headers --- CCDB/include/CCDB/BasicCCDBManager.h | 2 +- CCDB/src/BasicCCDBManager.cxx | 45 +++++++++++++++------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/CCDB/include/CCDB/BasicCCDBManager.h b/CCDB/include/CCDB/BasicCCDBManager.h index 69d9150abcf62..678bedf24e551 100644 --- a/CCDB/include/CCDB/BasicCCDBManager.h +++ b/CCDB/include/CCDB/BasicCCDBManager.h @@ -194,7 +194,7 @@ class CCDBManagerInstance /// On error it fatals (if fatal == true) or else returns the pair -1, -1. std::pair getRunDuration(int runnumber, bool fatal = true); static std::pair getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal = true); - + static std::pair getRunDuration(const MD& headers); std::string getSummaryString() const; size_t getFetchedSize() const { return mFetchedSize; } diff --git a/CCDB/src/BasicCCDBManager.cxx b/CCDB/src/BasicCCDBManager.cxx index 0fe72c88fcb46..bcf88554578c1 100644 --- a/CCDB/src/BasicCCDBManager.cxx +++ b/CCDB/src/BasicCCDBManager.cxx @@ -32,44 +32,47 @@ void CCDBManagerInstance::reportFatal(std::string_view err) LOG(fatal) << err; } -std::pair CCDBManagerInstance::getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal) +std::pair CCDBManagerInstance::getRunDuration(const std::map& headers) { - auto response = api.retrieveHeaders("RCT/Info/RunInformation", std::map(), runnumber); - if (response.size() != 0) { + if (headers.size() != 0) { std::string report{}; - auto strt = response.find("STF"); - auto stop = response.find("ETF"); - long valStrt = (strt == response.end()) ? -1L : boost::lexical_cast(strt->second); - long valStop = (stop == response.end()) ? -1L : boost::lexical_cast(stop->second); + auto strt = headers.find("STF"); + auto stop = headers.find("ETF"); + long valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast(strt->second); + long valStop = (stop == headers.end()) ? -1L : boost::lexical_cast(stop->second); if (valStrt < 0 || valStop < 0) { report += "Missing STF/EFT -> use SOX/EOX;"; - strt = response.find("SOX"); - valStrt = (strt == response.end()) ? -1L : boost::lexical_cast(strt->second); + strt = headers.find("SOX"); + valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast(strt->second); if (valStrt < 1) { report += fmt::format(" Missing/invalid SOX -> use SOR"); - strt = response.find("SOR"); - valStrt = (strt == response.end()) ? -1L : boost::lexical_cast(strt->second); + strt = headers.find("SOR"); + valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast(strt->second); } - stop = response.find("EOX"); - valStop = (stop == response.end()) ? -1L : boost::lexical_cast(stop->second); + stop = headers.find("EOX"); + valStop = (stop == headers.end()) ? -1L : boost::lexical_cast(stop->second); if (valStop < 1) { report += fmt::format(" | Missing/invalid EOX -> use EOR"); - stop = response.find("EOR"); - valStop = (stop == response.end()) ? -1L : boost::lexical_cast(stop->second); + stop = headers.find("EOR"); + valStop = (stop == headers.end()) ? -1L : boost::lexical_cast(stop->second); } if (!report.empty()) { LOGP(warn, "{}", report); } } - if (valStrt > 0 && valStop >= valStrt) { - return std::make_pair(valStrt, valStop); - } + return std::make_pair(valStrt, valStop); } - // failure - if (fatal) { + return std::make_pair(-1L, -1L); +} + +std::pair CCDBManagerInstance::getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal) +{ + auto headers = api.retrieveHeaders("RCT/Info/RunInformation", std::map(), runnumber); + auto response = getRunDuration(headers); + if ((response.first <= 0 || response.second < response.first) && fatal) { LOG(fatal) << "Empty, missing or invalid response from query to RCT/Info/RunInformation for run " << runnumber; } - return std::make_pair(-1L, -1L); + return response; } std::pair CCDBManagerInstance::getRunDuration(int runnumber, bool fatal) From 0b6360d348099e9cb00a172c2067ef30f41e84b1 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 11 Oct 2024 12:30:12 +0200 Subject: [PATCH 0343/2205] Factor out AggregatedRunInfo creation to use it in GRPGeomHelper --- .../DataFormatsParameters/AggregatedRunInfo.h | 15 ++--- .../Parameters/src/AggregatedRunInfo.cxx | 56 +++++++++---------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h index d4f434db059c5..e509be97a14fa 100644 --- a/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h +++ b/DataFormats/Parameters/include/DataFormatsParameters/AggregatedRunInfo.h @@ -29,19 +29,20 @@ class GRPECSObject; /// Also offers the authoritative algorithms to collect these information for easy reuse /// across various algorithms (anchoredMC, analysis, ...) struct AggregatedRunInfo { - int runNumber; // run number - int64_t sor; // best known timestamp for the start of run - int64_t eor; // best known timestamp for end of run - int64_t orbitsPerTF; // number of orbits per TF - int64_t orbitReset; // timestamp of orbit reset before run - int64_t orbitSOR; // orbit when run starts after orbit reset - int64_t orbitEOR; // orbit when run ends after orbit reset + int runNumber = 0; // run number + int64_t sor = 0; // best known timestamp for the start of run + int64_t eor = 0; // best known timestamp for end of run + int64_t orbitsPerTF = 0; // number of orbits per TF + int64_t orbitReset = 0; // timestamp of orbit reset before run + int64_t orbitSOR = 0; // orbit when run starts after orbit reset + int64_t orbitEOR = 0; // orbit when run ends after orbit reset // we may have pointers to actual data source objects GRPECS, ... const o2::parameters::GRPECSObject* grpECS = nullptr; // pointer to GRPECSobject (fetched during struct building) // fills and returns AggregatedRunInfo for a given run number. static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber); + static AggregatedRunInfo buildAggregatedRunInfo(int runnumber, long sorMS, long eorMS, long orbitResetMUS, const o2::parameters::GRPECSObject* grpecs, const std::vector* ctfFirstRunOrbitVec); }; } // namespace o2::parameters diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index bc836cd2e394b..2bd508256c1bf 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -41,47 +41,43 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2:: std::map metadata; metadata["runNumber"] = Form("%d", runnumber); auto grpecs = ccdb.getSpecific("GLO/Config/GRPECS", run_mid_timestamp, metadata); - auto nOrbitsPerTF = grpecs->getNHBFPerTF(); - - // calculate SOR orbit - int64_t orbitSOR = (sor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; - int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; - - // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) - orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle - orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; - - // fetch SOR directly from CTP entry on CCDB bool oldFatalState = ccdb.getFatalWhenNull(); ccdb.setFatalWhenNull(false); - auto ctp_first_run_orbit = ccdb.getForTimeStamp>("CTP/Calib/FirstRunOrbit", run_mid_timestamp); + auto ctp_first_run_orbit = ccdb.getForTimeStamp>("CTP/Calib/FirstRunOrbit", run_mid_timestamp); ccdb.setFatalWhenNull(oldFatalState); - if (ctp_first_run_orbit && ctp_first_run_orbit->size() >= 3) { - // if we have CTP first run orbit available, we should use it - - // int64_t creation_time = (*ctp_first_run_orbit)[0]; - int64_t ctp_run_number = (*ctp_first_run_orbit)[1]; - int64_t ctp_orbitSOR = (*ctp_first_run_orbit)[2]; + return buildAggregatedRunInfo(runnumber, sor, eor, tsOrbitReset, grpecs, ctp_first_run_orbit); +} - if (ctp_run_number == runnumber) { - // overwrite orbitSOR +o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(int runnumber, long sorMS, long eorMS, long orbitResetMUS, const o2::parameters::GRPECSObject* grpecs, const std::vector* ctfFirstRunOrbitVec) +{ + auto nOrbitsPerTF = grpecs->getNHBFPerTF(); + // calculate SOR/EOR orbits + int64_t orbitSOR = (sorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; + int64_t orbitEOR = (eorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; + // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) + orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle + orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; + if (ctfFirstRunOrbitVec && ctfFirstRunOrbitVec->size() >= 3) { // if we have CTP first run orbit available, we should use it + int64_t creation_timeIGNORED = (*ctfFirstRunOrbitVec)[0]; // do not use CTP start of run time! + int64_t ctp_run_number = (*ctfFirstRunOrbitVec)[1]; + int64_t ctp_orbitSOR = (*ctfFirstRunOrbitVec)[2]; + if (creation_timeIGNORED == -1 && ctp_run_number == -1 && ctp_orbitSOR == -1) { + LOGP(warn, "Default dummy CTP/Calib/FirstRunOrbit was provide, ignoring"); + } else if (ctp_run_number == runnumber) { // overwrite orbitSOR if (ctp_orbitSOR != orbitSOR) { - LOG(warn) << "The calculated orbitSOR " << orbitSOR << " differs from CTP orbitSOR " << ctp_orbitSOR; + LOGP(warn, "The calculated orbitSOR {} differs from CTP orbitSOR {}", orbitSOR, ctp_orbitSOR); // reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc. - // so we need to adjust the SOR timings to be consistent - auto sor_new = (int64_t)((tsOrbitReset + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); - if (sor_new != sor) { - LOG(warn) << "Adjusting SOR from " << sor << " to " << sor_new; - sor = sor_new; + auto sor_new = (int64_t)((orbitResetMUS + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); + if (sor_new != sorMS) { + LOGP(warn, "Adjusting SOR from {} to {}", sorMS, sor_new); + sorMS = sor_new; } } orbitSOR = ctp_orbitSOR; } else { - LOG(error) << "AggregatedRunInfo: run number inconsistency found (asked: " << runnumber << " vs CTP found: " << ctp_run_number << ")"; - LOG(error) << " ... not using CTP info"; + LOGP(error, "AggregatedRunInfo: run number inconsistency found (asked: {} vs CTP found: {}, ignoring", runnumber, ctp_run_number); } } - - return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR, grpecs}; + return AggregatedRunInfo{runnumber, sorMS, eorMS, nOrbitsPerTF, orbitResetMUS, orbitSOR, orbitEOR, grpecs}; } From b4ffc319d4a46d457769fe69bc1694ac87442b86 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 11 Oct 2024 12:31:34 +0200 Subject: [PATCH 0344/2205] AggregatedRunInfo can be requested via GRPGeomHelper To do this, request it after creating auto ggRequest = std::make_shared(...) as ggRequest->requireAggregateRunInfo(inputs); Then, in the task, once the GRPGeomHelper::checkUpdates was called, one can access AggregatedRunInfo as const auto& rInfo = GGCCDBRequest.getAggregatedRunInfo() TODO: filling of AggregatedRunInfo requires CTP/Calib/FirstRunOrbit which is populated only starting from 15 Aug 2023. Need to retrofit it for all runs and also for special non-anchored MC range. --- .../include/DetectorsBase/GRPGeomHelper.h | 12 +++++-- Detectors/Base/src/GRPGeomHelper.cxx | 32 ++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Detectors/Base/include/DetectorsBase/GRPGeomHelper.h b/Detectors/Base/include/DetectorsBase/GRPGeomHelper.h index 663f09702c638..ec1f9a91c3f20 100644 --- a/Detectors/Base/include/DetectorsBase/GRPGeomHelper.h +++ b/Detectors/Base/include/DetectorsBase/GRPGeomHelper.h @@ -22,6 +22,7 @@ #include "DataFormatsParameters/GRPLHCIFData.h" #include "DataFormatsParameters/GRPECSObject.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/AggregatedRunInfo.h" namespace o2::framework { @@ -92,6 +93,7 @@ struct GRPGeomRequest { Ideal, Alignments }; + bool askAggregateRunInfo = false; bool askGRPECS = false; bool askGRPLHCIF = false; bool askGRPMagField = false; @@ -105,6 +107,7 @@ struct GRPGeomRequest { GRPGeomRequest() = delete; GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF, bool GRPMagField, bool askMatLUT, GeomRequest geom, std::vector& inputs, bool askOnce = false, bool needPropD = false, std::string detMaskString = "all"); + void requireAggregateRunInfo(std::vector& inputs); void addInput(const o2::framework::InputSpec&& isp, std::vector& inputs); }; @@ -121,14 +124,16 @@ class GRPGeomHelper } void setRequest(std::shared_ptr req); bool finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj); - void checkUpdates(o2::framework::ProcessingContext& pc) const; + void checkUpdates(o2::framework::ProcessingContext& pc); auto getAlignment(o2::detectors::DetID det) const { return mAlignments[det]; } auto getMatLUT() const { return mMatLUT; } auto getGRPECS() const { return mGRPECS; } auto getGRPLHCIF() const { return mGRPLHCIF; } auto getGRPMagField() const { return mGRPMagField; } - auto getOrbitResetTimeMS() const { return mOrbitResetTimeMS; } + auto getOrbitResetTimeMS() const { return mOrbitResetTimeMUS / 1000; } + auto getOrbitResetTimeMUS() const { return mOrbitResetTimeMUS; } + const o2::parameters::AggregatedRunInfo& getAggregatedRunInfo() const { return mAggregatedRunInfo; } static int getNHBFPerTF(); private: @@ -141,7 +146,8 @@ class GRPGeomHelper const o2::parameters::GRPECSObject* mGRPECS = nullptr; const o2::parameters::GRPLHCIFData* mGRPLHCIF = nullptr; const o2::parameters::GRPMagField* mGRPMagField = nullptr; - long mOrbitResetTimeMS = 0; // orbit reset time in milliseconds + o2::parameters::AggregatedRunInfo mAggregatedRunInfo{}; + long mOrbitResetTimeMUS = 0; // orbit reset time in microseconds }; } // namespace base diff --git a/Detectors/Base/src/GRPGeomHelper.cxx b/Detectors/Base/src/GRPGeomHelper.cxx index 3e949412f8aa2..2a76e52b3679e 100644 --- a/Detectors/Base/src/GRPGeomHelper.cxx +++ b/Detectors/Base/src/GRPGeomHelper.cxx @@ -63,7 +63,7 @@ GRPGeomRequest::GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF, addInput({"orbitReset", "CTP", "ORBITRESET", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/OrbitReset")}, inputs); } if (askGRPECS) { - addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", true)}, inputs); // Run dependent !!! + addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", 1)}, inputs); // Run dependent !!! } if (askGRPLHCIF) { addInput({"grplhcif", "GLO", "GRPLHCIF", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPLHCIF")}, inputs); @@ -73,6 +73,22 @@ GRPGeomRequest::GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF, } } +void GRPGeomRequest::requireAggregateRunInfo(std::vector& inputs) +{ + askAggregateRunInfo = true; + // require dependencies + if (!askGRPECS) { + askGRPECS = true; + addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", 1)}, inputs); + } + if (!askTime) { + askTime = true; + addInput({"orbitReset", "CTP", "ORBITRESET", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/OrbitReset")}, inputs); + } + addInput({"RCTRunInfo", "RCT", "RunInfo", 0, Lifetime::Condition, ccdbParamSpec("RCT/Info/RunInformation", 2)}, inputs); + addInput({"CTPRunOrbit", "CTP", "RunOrbit", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/FirstRunOrbit")}, inputs); // TODO: should become run-depenendent (1) object +} + void GRPGeomRequest::addInput(const o2::framework::InputSpec&& isp, std::vector& inputs) { if (std::find(inputs.begin(), inputs.end(), isp) == inputs.end()) { @@ -124,8 +140,8 @@ bool GRPGeomHelper::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) return true; } if (mRequest->askTime && matcher == ConcreteDataMatcher("CTP", "ORBITRESET", 0)) { - mOrbitResetTimeMS = (*(std::vector*)obj)[0] / 1000; - LOG(info) << "orbit reset time updated to " << mOrbitResetTimeMS; + mOrbitResetTimeMUS = (*(std::vector*)obj)[0]; + LOG(info) << "orbit reset time updated to " << mOrbitResetTimeMUS; return true; } if (mRequest->askMatLUT && matcher == ConcreteDataMatcher("GLO", "MATLUT", 0)) { @@ -159,7 +175,7 @@ bool GRPGeomHelper::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) return false; } -void GRPGeomHelper::checkUpdates(ProcessingContext& pc) const +void GRPGeomHelper::checkUpdates(ProcessingContext& pc) { // request input just to trigger finaliseCCDB if there was an update @@ -225,6 +241,14 @@ void GRPGeomHelper::checkUpdates(ProcessingContext& pc) const } } } + if (mRequest->askAggregateRunInfo) { + const auto hmap = pc.inputs().get("RCTRunInfo"); // metadata only! + auto rl = o2::ccdb::BasicCCDBManager::getRunDuration(hmap); + auto ctfFirstRunOrbitVec = pc.inputs().get*>("CTPRunOrbit"); + mAggregatedRunInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(pc.services().get().runNumber, rl.first, rl.second, mOrbitResetTimeMUS, mGRPECS, ctfFirstRunOrbitVec.get()); + LOGP(debug, "Extracted AggregateRunInfo: runNumber:{}, sor:{}, eor:{}, orbitsPerTF:{}, orbitReset:{}, orbitSOR:{}, orbitEOR:{}", + mAggregatedRunInfo.runNumber, mAggregatedRunInfo.sor, mAggregatedRunInfo.eor, mAggregatedRunInfo.orbitsPerTF, mAggregatedRunInfo.orbitReset, mAggregatedRunInfo.orbitSOR, mAggregatedRunInfo.orbitEOR); + } } } From 260d9da4ead78bb086790b686e8092b60be82f01 Mon Sep 17 00:00:00 2001 From: pillot Date: Mon, 14 Oct 2024 11:04:22 +0200 Subject: [PATCH 0345/2205] skip digits produced before the beginning of the TF (#13589) --- Detectors/MUON/MCH/Simulation/CMakeLists.txt | 1 + Detectors/MUON/MCH/Simulation/src/Digitizer.cxx | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Detectors/MUON/MCH/Simulation/CMakeLists.txt b/Detectors/MUON/MCH/Simulation/CMakeLists.txt index 57cf85ef0c502..b7e92fbb28087 100644 --- a/Detectors/MUON/MCH/Simulation/CMakeLists.txt +++ b/Detectors/MUON/MCH/Simulation/CMakeLists.txt @@ -21,6 +21,7 @@ o2_add_library(MCHSimulation PUBLIC_LINK_LIBRARIES O2::DataFormatsMCH O2::DetectorsBase O2::DetectorsPassive + O2::DetectorsRaw O2::MCHBase O2::MCHGeometryCreator O2::MCHMappingInterface diff --git a/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx b/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx index 29a1b7023ebcc..8461aecdae16b 100644 --- a/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx +++ b/Detectors/MUON/MCH/Simulation/src/Digitizer.cxx @@ -11,6 +11,7 @@ #include "MCHSimulation/Digitizer.h" +#include "DetectorsRaw/HBFUtils.h" #include "MCHSimulation/DigitizerParam.h" namespace o2::mch @@ -56,11 +57,14 @@ size_t Digitizer::digitize(std::vector& rofs, nPileup += d.second->digitize(irDigitsAndLabels); } - // fill the external containers + // fill the external containers, skipping digits produced before the beginning of the TF + auto firstTFOrbit = o2::raw::HBFUtils::Instance().getFirstSampledTFIR().orbit; for (const auto& [ir, digitsAndLabels] : irDigitsAndLabels) { - rofs.emplace_back(ROFRecord(ir, digits.size(), digitsAndLabels.first.size())); - digits.insert(digits.end(), digitsAndLabels.first.begin(), digitsAndLabels.first.end()); - labels.mergeAtBack(digitsAndLabels.second); + if (ir.orbit >= firstTFOrbit) { + rofs.emplace_back(ROFRecord(ir, digits.size(), digitsAndLabels.first.size())); + digits.insert(digits.end(), digitsAndLabels.first.begin(), digitsAndLabels.first.end()); + labels.mergeAtBack(digitsAndLabels.second); + } } return nPileup; From 8e75aa1fe2bca1581fa813f0a9a62071b2326dd7 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 14 Oct 2024 18:23:54 +0200 Subject: [PATCH 0346/2205] Modify CCDB headers check to account for CCDBSerialized<> access of non-CCDB objects --- Framework/Core/src/DataRefUtils.cxx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Framework/Core/src/DataRefUtils.cxx b/Framework/Core/src/DataRefUtils.cxx index d3710a6234642..f092429d9c5a0 100644 --- a/Framework/Core/src/DataRefUtils.cxx +++ b/Framework/Core/src/DataRefUtils.cxx @@ -93,7 +93,7 @@ void* DataRefUtils::decodeCCDB(DataRef const& ref, std::type_info const& tinfo) !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) { headerSize = *reinterpret_cast(buff + dh->payloadSize - Offset); } - if (headerSize <= 0) { + if (headerSize < 0) { LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize); } TMemFile memFile("name", const_cast(ref.payload), dh->payloadSize - headerSize, "READ"); @@ -119,16 +119,21 @@ std::map DataRefUtils::extractCCDBHeaders(DataRef cons constexpr char FlatHeaderAnnot[] = "$HEADER$"; constexpr int Offset = sizeof(int) + sizeof(FlatHeaderAnnot); int headerSize = 0, ss0 = 0; + std::map res; if (dh->payloadSize >= Offset && !std::strncmp(buff + dh->payloadSize - sizeof(FlatHeaderAnnot), FlatHeaderAnnot, sizeof(FlatHeaderAnnot))) { headerSize = *reinterpret_cast(buff + dh->payloadSize - Offset); + } else { // header was not added + LOGP(warn, "CCDB headers were not added to condition object blob, returning dummy header map"); + return res; } - if (headerSize <= 0) { + + if (headerSize < 0) { LOGP(fatal, "Anomalous flattened header size {} extracted", headerSize); } + buff += dh->payloadSize - headerSize; // jump to the start of flattened header headerSize -= Offset; const char* str0 = &buff[ss0++]; - std::map res; while (ss0 < headerSize) { if (buff[ss0++] == 0) { if (!str0) { From 91d4cee764a0a4f51e041da985aacaaa4959aae0 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 11 Oct 2024 09:57:38 +0200 Subject: [PATCH 0347/2205] GPU: Add tpcApplyCFCutsAtDecoding option to apply cluster cuts of CF during CTF decoding --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/GPUTracking/Global/GPUChain.h | 7 +- GPU/GPUTracking/Global/GPUChainTracking.cxx | 10 ++- .../Global/GPUChainTrackingCompression.cxx | 68 ++++++++++++++----- .../GPUChainTrackingDebugAndProfiling.cxx | 4 +- 5 files changed, 64 insertions(+), 26 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 960f2fcec3f2c..bcb568d893007 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -285,6 +285,7 @@ AddOption(tpcSingleSector, int32_t, -1, "", 0, "Restrict TPC processing to a sin AddOption(tpcDownscaledEdx, uint8_t, 0, "", 0, "If != 0, downscale dEdx processing (if enabled) to x %") AddOption(tpcMaxAttachedClustersPerSectorRow, uint32_t, 51000, "", 0, "Maximum number of TPC attached clusters which can be decoded per SectorRow") AddOption(tpcUseOldCPUDecoding, bool, false, "", 0, "Enable old CPU-based TPC decoding") +AddOption(tpcApplyCFCutsAtDecoding, bool, false, "", 0, "Apply cluster cuts from clusterization during decoding of compressed clusters") AddOption(RTCcacheFolder, std::string, "./rtccache/", "", 0, "Folder in which the cache file is stored") AddOption(RTCprependCommand, std::string, "", "", 0, "Prepend RTC compilation commands by this string") AddOption(RTCoverrideArchitecture, std::string, "", "", 0, "Override arhcitecture part of RTC compilation command line") diff --git a/GPU/GPUTracking/Global/GPUChain.h b/GPU/GPUTracking/Global/GPUChain.h index e65396cbce21a..7a36355bf843d 100644 --- a/GPU/GPUTracking/Global/GPUChain.h +++ b/GPU/GPUTracking/Global/GPUChain.h @@ -59,31 +59,30 @@ class GPUChain const GPUParam& GetParam() const { return mRec->mHostConstantMem->param; } const GPUSettingsGRP& GetGRPSettings() const { return mRec->mGRPSettings; } - const GPUSettingsDeviceBackend& GetDeviceBackendSettings() const { return mRec->mDeviceBackendSettings; } - const GPUSettingsProcessing& GetProcessingSettings() const { return mRec->mProcessingSettings; } const GPUCalibObjectsConst& calib() const { return processors()->calibObjects; } GPUReconstruction* rec() { return mRec; } const GPUReconstruction* rec() const { return mRec; } inline const GPUConstantMem* GetProcessors() { return mRec->processors(); } + // Make functions from GPUReconstruction*** available GPUReconstruction::RecoStepField GetRecoSteps() const { return mRec->GetRecoSteps(); } GPUReconstruction::RecoStepField GetRecoStepsGPU() const { return mRec->GetRecoStepsGPU(); } GPUReconstruction::InOutTypeField GetRecoStepsInputs() const { return mRec->GetRecoStepsInputs(); } GPUReconstruction::InOutTypeField GetRecoStepsOutputs() const { return mRec->GetRecoStepsOutputs(); } + inline const GPUSettingsDeviceBackend& GetDeviceBackendSettings() const { return mRec->mDeviceBackendSettings; } + inline const GPUSettingsProcessing& GetProcessingSettings() const { return mRec->mProcessingSettings; } protected: GPUReconstructionCPU* mRec; GPUChain(GPUReconstruction* rec) : mRec((GPUReconstructionCPU*)rec) {} int32_t GetThread(); - // Make functions from GPUReconstruction*** available inline GPUConstantMem* processors() { return mRec->processors(); } inline GPUConstantMem* processorsShadow() { return mRec->mProcessorsShadow; } inline GPUConstantMem* processorsDevice() { return mRec->mDeviceConstantMem; } inline GPUParam& param() { return mRec->param(); } inline const GPUConstantMem* processors() const { return mRec->processors(); } - inline GPUSettingsProcessing& ProcessingSettings() { return mRec->mProcessingSettings; } inline void SynchronizeStream(int32_t stream) { mRec->SynchronizeStream(stream); } inline void SynchronizeEvents(deviceEvent* evList, int32_t nEvents = 1) { mRec->SynchronizeEvents(evList, nEvents); } inline void SynchronizeEventAndRelease(deviceEvent& ev, bool doGPU = true) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index d6fd370b3b330..528c683944ef1 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -309,7 +309,7 @@ bool GPUChainTracking::ValidateSettings() GPUError("Must use external output for double pipeline mode"); return false; } - if (ProcessingSettings().tpcCompressionGatherMode == 1) { + if (GetProcessingSettings().tpcCompressionGatherMode == 1) { GPUError("Double pipeline incompatible to compression mode 1"); return false; } @@ -318,7 +318,11 @@ bool GPUChainTracking::ValidateSettings() return false; } } - if ((GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCCompression) && !(GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCCompression) && (ProcessingSettings().tpcCompressionGatherMode == 1 || ProcessingSettings().tpcCompressionGatherMode == 3)) { + if ((GetRecoSteps() & GPUDataTypes::RecoStep::TPCDecompression) && GetProcessingSettings().tpcApplyCFCutsAtDecoding && !GetProcessingSettings().tpcUseOldCPUDecoding) { + GPUError("tpcApplyCFCutsAtDecoding currently requires tpcUseOldCPUDecoding"); + return false; + } + if ((GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCCompression) && !(GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCCompression) && (GetProcessingSettings().tpcCompressionGatherMode == 1 || GetProcessingSettings().tpcCompressionGatherMode == 3)) { GPUError("Invalid tpcCompressionGatherMode for compression on CPU"); return false; } @@ -888,7 +892,7 @@ int32_t GPUChainTracking::RunChainFinalize() if (GetProcessingSettings().eventDisplay->getDisplayControl() == 2) { mDisplayRunning = false; GetProcessingSettings().eventDisplay->DisplayExit(); - ProcessingSettings().eventDisplay = nullptr; + const_cast(GetProcessingSettings()).eventDisplay = nullptr; // TODO: fixme - eventDisplay should probably not be put into ProcessingSettings in the first place return (2); } GetProcessingSettings().eventDisplay->setDisplayControl(0); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 9d27a42720613..7d5ee7e3410fd 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -40,7 +40,7 @@ int32_t GPUChainTracking::RunTPCCompression() RecordMarker(mEvents->single, 0); } - if (ProcessingSettings().tpcCompressionGatherMode == 3) { + if (GetProcessingSettings().tpcCompressionGatherMode == 3) { mRec->AllocateVolatileDeviceMemory(0); // make future device memory allocation volatile } SetupGPUProcessor(&Compressor, true); @@ -73,19 +73,19 @@ int32_t GPUChainTracking::RunTPCCompression() Compressor.mOutputFlat->set(outputSize, *Compressor.mOutput); char* hostFlatPtr = (char*)Compressor.mOutput->qTotU; // First array as allocated in GPUTPCCompression::SetPointersCompressedClusters size_t copySize = 0; - if (ProcessingSettings().tpcCompressionGatherMode == 3) { + if (GetProcessingSettings().tpcCompressionGatherMode == 3) { CompressorShadow.mOutputA = Compressor.mOutput; copySize = AllocateRegisteredMemory(Compressor.mMemoryResOutputGPU); // We overwrite Compressor.mOutput with the allocated output pointers on the GPU } const o2::tpc::CompressedClustersPtrs* P = nullptr; HighResTimer* gatherTimer = nullptr; int32_t outputStream = 0; - if (ProcessingSettings().doublePipeline) { + if (GetProcessingSettings().doublePipeline) { SynchronizeStream(OutputStream()); // Synchronize output copies running in parallel from memory that might be released, only the following async copy from stacked memory is safe after the chain finishes. outputStream = OutputStream(); } - if (ProcessingSettings().tpcCompressionGatherMode >= 2) { - if (ProcessingSettings().tpcCompressionGatherMode == 2) { + if (GetProcessingSettings().tpcCompressionGatherMode >= 2) { + if (GetProcessingSettings().tpcCompressionGatherMode == 2) { void* devicePtr = mRec->getGPUPointer(Compressor.mOutputFlat); if (devicePtr != Compressor.mOutputFlat) { CompressedClustersPtrs& ptrs = *Compressor.mOutput; // We need to update the ptrs with the gpu-mapped version of the host address space @@ -97,7 +97,7 @@ int32_t GPUChainTracking::RunTPCCompression() TransferMemoryResourcesToGPU(myStep, &Compressor, outputStream); constexpr uint32_t nBlocksDefault = 2; constexpr uint32_t nBlocksMulti = 1 + 2 * 200; - switch (ProcessingSettings().tpcCompressionGatherModeKernel) { + switch (GetProcessingSettings().tpcCompressionGatherModeKernel) { case 0: runKernel(GetGridBlkStep(nBlocksDefault, outputStream, RecoStep::TPCCompression)); getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); @@ -120,10 +120,10 @@ int32_t GPUChainTracking::RunTPCCompression() getKernelTimer(RecoStep::TPCCompression, 0, outputSize, false); break; default: - GPUError("Invalid compression kernel %d selected.", (int32_t)ProcessingSettings().tpcCompressionGatherModeKernel); + GPUError("Invalid compression kernel %d selected.", (int32_t)GetProcessingSettings().tpcCompressionGatherModeKernel); return 1; } - if (ProcessingSettings().tpcCompressionGatherMode == 3) { + if (GetProcessingSettings().tpcCompressionGatherMode == 3) { RecordMarker(mEvents->stream[outputStream], outputStream); char* deviceFlatPts = (char*)Compressor.mOutput->qTotU; if (GetProcessingSettings().doublePipeline) { @@ -138,9 +138,9 @@ int32_t GPUChainTracking::RunTPCCompression() } } else { int8_t direction = 0; - if (ProcessingSettings().tpcCompressionGatherMode == 0) { + if (GetProcessingSettings().tpcCompressionGatherMode == 0) { P = &CompressorShadow.mPtrs; - } else if (ProcessingSettings().tpcCompressionGatherMode == 1) { + } else if (GetProcessingSettings().tpcCompressionGatherMode == 1) { P = &Compressor.mPtrs; direction = -1; gatherTimer = &getTimer("GPUTPCCompression_GatherOnCPU", 0); @@ -184,11 +184,11 @@ int32_t GPUChainTracking::RunTPCCompression() GPUMemCpyAlways(myStep, O->timeA, P->timeA, O->nTracks * sizeof(O->timeA[0]), outputStream, direction); GPUMemCpyAlways(myStep, O->padA, P->padA, O->nTracks * sizeof(O->padA[0]), outputStream, direction); } - if (ProcessingSettings().tpcCompressionGatherMode == 1) { + if (GetProcessingSettings().tpcCompressionGatherMode == 1) { gatherTimer->Stop(); } mIOPtrs.tpcCompressedClusters = Compressor.mOutputFlat; - if (ProcessingSettings().tpcCompressionGatherMode == 3) { + if (GetProcessingSettings().tpcCompressionGatherMode == 3) { SynchronizeEventAndRelease(mEvents->stream[outputStream]); mRec->ReturnVolatileDeviceMemory(); } @@ -209,18 +209,52 @@ int32_t GPUChainTracking::RunTPCDecompression() if (GetProcessingSettings().tpcUseOldCPUDecoding) { const auto& threadContext = GetThreadContext(); TPCClusterDecompressor decomp; - auto allocator = [this](size_t size) { + auto allocatorFinal = [this](size_t size) { this->mInputsHost->mNClusterNative = this->mInputsShadow->mNClusterNative = size; this->AllocateRegisteredMemory(this->mInputsHost->mResourceClusterNativeOutput, this->mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); return this->mInputsHost->mPclusterNativeOutput; }; - auto& gatherTimer = getTimer("TPCDecompression", 0); - gatherTimer.Start(); - if (decomp.decompress(mIOPtrs.tpcCompressedClusters, *mClusterNativeAccess, allocator, param(), GetProcessingSettings().deterministicGPUReconstruction)) { + std::unique_ptr tmpBuffer; + auto allocatorTmp = [&tmpBuffer](size_t size) { + return ((tmpBuffer = std::make_unique(size))).get(); + }; + auto& decompressTimer = getTimer("TPCDecompression", 0); + auto allocatorUse = GetProcessingSettings().tpcApplyCFCutsAtDecoding ? std::function{allocatorTmp} : std::function{allocatorFinal}; + decompressTimer.Start(); + if (decomp.decompress(mIOPtrs.tpcCompressedClusters, *mClusterNativeAccess, allocatorUse, param(), GetProcessingSettings().deterministicGPUReconstruction)) { GPUError("Error decompressing clusters"); return 1; } - gatherTimer.Stop(); + if (GetProcessingSettings().tpcApplyCFCutsAtDecoding) { + ClusterNative* outputBuffer; + for (int32_t iPhase = 0; iPhase < 2; iPhase++) { + uint32_t countTotal = 0; + for (uint32_t iSector = 0; iSector < GPUCA_NSLICES; iSector++) { + for (uint32_t iRow = 0; iRow < GPUCA_ROW_COUNT; iRow++) { + uint32_t count = 0; + for (uint32_t k = 0; k < mClusterNativeAccess->nClusters[iSector][iRow]; k++) { + const ClusterNative& cl = mClusterNativeAccess->clusters[iSector][iRow][k]; + bool keep = cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff && (cl.sigmaPadPacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime); + count += keep; + countTotal += keep; + if (iPhase) { + outputBuffer[countTotal] = cl; + } + } + if (iPhase) { + mClusterNativeAccess->nClusters[iSector][iRow] = count; + } + } + } + if (iPhase) { + mClusterNativeAccess->clustersLinear = outputBuffer; + mClusterNativeAccess->setOffsetPtrs(); + } else { + outputBuffer = allocatorFinal(countTotal); + } + } + } + decompressTimer.Stop(); mIOPtrs.clustersNative = mClusterNativeAccess.get(); if (mRec->IsGPU()) { AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeBuffer); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index af04dd5e0ce93..82b9bb5ada373 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -206,7 +206,7 @@ void GPUChainTracking::PrintOutputStat() { int32_t nTracks = 0, nAttachedClusters = 0, nAttachedClustersFitted = 0, nAdjacentClusters = 0; uint32_t nCls = GetProcessingSettings().doublePipeline ? mIOPtrs.clustersNative->nClustersTotal : GetTPCMerger().NMaxClusters(); - if (ProcessingSettings().createO2Output > 1) { + if (GetProcessingSettings().createO2Output > 1) { nTracks = mIOPtrs.nOutputTracksTPCO2; nAttachedClusters = mIOPtrs.nMergedTrackHits; } else { @@ -244,7 +244,7 @@ void GPUChainTracking::PrintOutputStat() } snprintf(trdText, 1024, " - TRD Tracker reconstructed %d tracks (%d tracklets)", nTRDTracks, nTRDTracklets); } - GPUInfo("Output Tracks: %d (%d / %d / %d / %d clusters (fitted / attached / adjacent / total) - %s format)%s", nTracks, nAttachedClustersFitted, nAttachedClusters, nAdjacentClusters, nCls, ProcessingSettings().createO2Output > 1 ? "O2" : "GPU", trdText); + GPUInfo("Output Tracks: %d (%d / %d / %d / %d clusters (fitted / attached / adjacent / total) - %s format)%s", nTracks, nAttachedClustersFitted, nAttachedClusters, nAdjacentClusters, nCls, GetProcessingSettings().createO2Output > 1 ? "O2" : "GPU", trdText); } void GPUChainTracking::SanityCheck() From 63d8c5b461e3d2917d3e49d02cb69d253e832215 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 14 Oct 2024 21:04:32 +0200 Subject: [PATCH 0348/2205] GPU: Fix missing headers --- GPU/GPUTracking/Definitions/GPULogging.h | 2 ++ GPU/GPUTracking/display/GPUDisplayInterface.cxx | 1 + 2 files changed, 3 insertions(+) diff --git a/GPU/GPUTracking/Definitions/GPULogging.h b/GPU/GPUTracking/Definitions/GPULogging.h index eff71f0fb5178..f3c6c019f593b 100644 --- a/GPU/GPUTracking/Definitions/GPULogging.h +++ b/GPU/GPUTracking/Definitions/GPULogging.h @@ -34,6 +34,7 @@ #define GPUError(...) #define GPUFatal(...) #elif defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE_DEVICE) && !defined(GPUCA_NO_FMT) + #include #include #define GPUInfo(string, ...) \ { \ @@ -54,6 +55,7 @@ #elif defined(GPUCA_STANDALONE) || defined(GPUCA_GPUCODE_DEVICE) || (defined(GPUCA_ALIROOT_LIB) && defined(GPUCA_GPUCODE) && defined(__cplusplus) && __cplusplus < 201703L) // For standalone / CUDA / HIP, we just use printf, which should be available // Temporarily, we also have to handle CUDA on AliRoot with O2 defaults due to ROOT / CUDA incompatibilities + #include #define GPUInfo(string, ...) \ { \ printf(string "\n", ##__VA_ARGS__); \ diff --git a/GPU/GPUTracking/display/GPUDisplayInterface.cxx b/GPU/GPUTracking/display/GPUDisplayInterface.cxx index 53090bb345821..12b7b96540f79 100644 --- a/GPU/GPUTracking/display/GPUDisplayInterface.cxx +++ b/GPU/GPUTracking/display/GPUDisplayInterface.cxx @@ -19,6 +19,7 @@ #include #include #include +#include using namespace GPUCA_NAMESPACE::gpu; From ce79769296f1373e3287df3400c0d72be94d99c7 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 14 Oct 2024 15:57:31 +0200 Subject: [PATCH 0349/2205] Add GPUTPCClusterFilter class to remove TPC clusters in generic way for cluster studies --- GPU/GPUTracking/CMakeLists.txt | 1 + GPU/GPUTracking/Debug/GPUTPCClusterFilter.cxx | 31 ++++++++++++++++ GPU/GPUTracking/Debug/GPUTPCClusterFilter.h | 36 +++++++++++++++++++ GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + .../Global/GPUChainTrackingCompression.cxx | 8 +++-- 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 GPU/GPUTracking/Debug/GPUTPCClusterFilter.cxx create mode 100644 GPU/GPUTracking/Debug/GPUTPCClusterFilter.h diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index a4ca1f126f013..c4c891ff229f3 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -94,6 +94,7 @@ set(SRCS_NO_CINT Global/GPUErrors.cxx Merger/GPUTPCGMMergerGPU.cxx Debug/GPUROOTDumpCore.cxx + Debug/GPUTPCClusterFilter.cxx utils/timer.cxx) set(SRCS_NO_H SliceTracker/GPUTPCTrackerDump.cxx diff --git a/GPU/GPUTracking/Debug/GPUTPCClusterFilter.cxx b/GPU/GPUTracking/Debug/GPUTPCClusterFilter.cxx new file mode 100644 index 0000000000000..cdd0e4879f949 --- /dev/null +++ b/GPU/GPUTracking/Debug/GPUTPCClusterFilter.cxx @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUTPCClusterFilter.cxx +/// \author David Rohr + +#include "GPUTPCClusterFilter.h" +#include "DataFormatsTPC/ClusterNative.h" + +using namespace o2::gpu; + +GPUTPCClusterFilter::GPUTPCClusterFilter(const o2::tpc::ClusterNativeAccess& clusters) +{ + // Could initialize private variables based on the clusters here +} + +bool GPUTPCClusterFilter::filter(uint32_t sector, uint32_t row, o2::tpc::ClusterNative& cl) +{ + // Return true to keep the cluster, false to drop it. + // May change cluster properties by modifying the cl reference. + // Note that this function might be called multiple times for the same cluster, in which case the final modified cl reference goes into the output clusters. + return true; +} diff --git a/GPU/GPUTracking/Debug/GPUTPCClusterFilter.h b/GPU/GPUTracking/Debug/GPUTPCClusterFilter.h new file mode 100644 index 0000000000000..908f78fd23b9a --- /dev/null +++ b/GPU/GPUTracking/Debug/GPUTPCClusterFilter.h @@ -0,0 +1,36 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUTPCClusterFilter.h +/// \author David Rohr + +#ifndef GPUTPCCLUSTERFILTER_H +#define GPUTPCCLUSTERFILTER_H + +#include + +namespace o2::tpc +{ +struct ClusterNativeAccess; +struct ClusterNative; +} // namespace o2::tpc + +namespace o2::gpu +{ +class GPUTPCClusterFilter +{ + public: + GPUTPCClusterFilter(const o2::tpc::ClusterNativeAccess& clusters); + bool filter(uint32_t sector, uint32_t row, o2::tpc::ClusterNative& cl); +}; +} // namespace o2::gpu + +#endif diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index bcb568d893007..a879d64b4d9f4 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -286,6 +286,7 @@ AddOption(tpcDownscaledEdx, uint8_t, 0, "", 0, "If != 0, downscale dEdx processi AddOption(tpcMaxAttachedClustersPerSectorRow, uint32_t, 51000, "", 0, "Maximum number of TPC attached clusters which can be decoded per SectorRow") AddOption(tpcUseOldCPUDecoding, bool, false, "", 0, "Enable old CPU-based TPC decoding") AddOption(tpcApplyCFCutsAtDecoding, bool, false, "", 0, "Apply cluster cuts from clusterization during decoding of compressed clusters") +AddOption(tpcApplyDebugClusterFilter, bool, false, "", 0, "Apply custom cluster filter of GPUTPCClusterFilter class") AddOption(RTCcacheFolder, std::string, "./rtccache/", "", 0, "Folder in which the cache file is stored") AddOption(RTCprependCommand, std::string, "", "", 0, "Prepend RTC compilation commands by this string") AddOption(RTCoverrideArchitecture, std::string, "", "", 0, "Override arhcitecture part of RTC compilation command line") diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 7d5ee7e3410fd..f9157355c2b7f 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -21,6 +21,7 @@ #ifdef GPUCA_HAVE_O2HEADERS #include "GPUTPCCFChainContext.h" #include "TPCClusterDecompressor.h" +#include "GPUTPCClusterFilter.h" #endif #include "utils/strtag.h" @@ -226,6 +227,7 @@ int32_t GPUChainTracking::RunTPCDecompression() return 1; } if (GetProcessingSettings().tpcApplyCFCutsAtDecoding) { + GPUTPCClusterFilter clusterFilter(*mClusterNativeAccess); ClusterNative* outputBuffer; for (int32_t iPhase = 0; iPhase < 2; iPhase++) { uint32_t countTotal = 0; @@ -233,8 +235,10 @@ int32_t GPUChainTracking::RunTPCDecompression() for (uint32_t iRow = 0; iRow < GPUCA_ROW_COUNT; iRow++) { uint32_t count = 0; for (uint32_t k = 0; k < mClusterNativeAccess->nClusters[iSector][iRow]; k++) { - const ClusterNative& cl = mClusterNativeAccess->clusters[iSector][iRow][k]; - bool keep = cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff && (cl.sigmaPadPacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime); + ClusterNative cl = mClusterNativeAccess->clusters[iSector][iRow][k]; + bool keep = cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff; + keep = keep && (cl.sigmaPadPacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime); + keep = keep && (!GetProcessingSettings().tpcApplyDebugClusterFilter || clusterFilter.filter(iSector, iRow, cl)); count += keep; countTotal += keep; if (iPhase) { From 415a7b54fb85b5b324f9eb4ec3727b4c5e513588 Mon Sep 17 00:00:00 2001 From: Evgeny Kryshen Date: Mon, 14 Oct 2024 15:48:44 +0300 Subject: [PATCH 0350/2205] Custom orbit shifts for runs <=LHC22m --- .../Parameters/src/AggregatedRunInfo.cxx | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index 2bd508256c1bf..94a658a433e74 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -17,6 +17,7 @@ #include "DataFormatsParameters/GRPECSObject.h" #include "CommonConstants/LHCConstants.h" #include "Framework/Logger.h" +#include using namespace o2::parameters; @@ -57,6 +58,80 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(int // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; + // temporary map of orbit shifts for runs <=LHC22m (while waiting for complete run list from CTP/Calib/FirstRunOrbit) + std::map mapOrbitShift; + mapOrbitShift[517619] = 109; + mapOrbitShift[517620] = 109; + mapOrbitShift[517623] = 109; + mapOrbitShift[517677] = 127; + mapOrbitShift[517678] = 127; + mapOrbitShift[517679] = 127; + mapOrbitShift[517685] = 127; + mapOrbitShift[517690] = 127; + mapOrbitShift[517693] = 127; + mapOrbitShift[517737] = 127; + mapOrbitShift[517748] = 127; + mapOrbitShift[517751] = 127; + mapOrbitShift[517753] = 127; + mapOrbitShift[517758] = 127; + mapOrbitShift[517767] = 127; + mapOrbitShift[518541] = 40; + mapOrbitShift[518543] = 92; + mapOrbitShift[518546] = 124; + mapOrbitShift[518547] = 47; + mapOrbitShift[519041] = 59; + mapOrbitShift[519043] = 59; + mapOrbitShift[519045] = 59; + mapOrbitShift[519497] = 86; + mapOrbitShift[519498] = 86; + mapOrbitShift[519499] = 86; + mapOrbitShift[519502] = 86; + mapOrbitShift[519503] = 86; + mapOrbitShift[519504] = 86; + mapOrbitShift[519506] = 86; + mapOrbitShift[519507] = 86; + mapOrbitShift[519903] = 62; + mapOrbitShift[519904] = 62; + mapOrbitShift[519905] = 62; + mapOrbitShift[519906] = 62; + mapOrbitShift[520259] = 76; + mapOrbitShift[520294] = 76; + mapOrbitShift[520471] = 46; + mapOrbitShift[520472] = 46; + mapOrbitShift[520473] = 46; + mapOrbitShift[523142] = 127; + mapOrbitShift[523148] = 127; + mapOrbitShift[523182] = 127; + mapOrbitShift[523186] = 127; + mapOrbitShift[523298] = 28; + mapOrbitShift[523306] = 28; + mapOrbitShift[523308] = 28; + mapOrbitShift[523309] = 28; + mapOrbitShift[523397] = 110; + mapOrbitShift[523399] = 110; + mapOrbitShift[523401] = 110; + mapOrbitShift[523441] = 117; + mapOrbitShift[523541] = 103; + mapOrbitShift[523559] = 103; + mapOrbitShift[523669] = 39; + mapOrbitShift[523671] = 39; + mapOrbitShift[523677] = 39; + mapOrbitShift[523728] = 113; + mapOrbitShift[523731] = 113; + mapOrbitShift[523779] = 41; + mapOrbitShift[523783] = 41; + mapOrbitShift[523786] = 41; + mapOrbitShift[523788] = 41; + mapOrbitShift[523789] = 41; + mapOrbitShift[523792] = 41; + mapOrbitShift[523797] = 41; + mapOrbitShift[523821] = 36; + mapOrbitShift[523897] = 38; + if (mapOrbitShift.find(runnumber) != mapOrbitShift.end()) { + orbitSOR += mapOrbitShift[runnumber]; + orbitEOR += mapOrbitShift[runnumber]; + } + if (ctfFirstRunOrbitVec && ctfFirstRunOrbitVec->size() >= 3) { // if we have CTP first run orbit available, we should use it int64_t creation_timeIGNORED = (*ctfFirstRunOrbitVec)[0]; // do not use CTP start of run time! int64_t ctp_run_number = (*ctfFirstRunOrbitVec)[1]; From 34eb6f4a96cbbb6f4808cd49abb2b25321a5cfc7 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 15 Oct 2024 22:52:18 +0200 Subject: [PATCH 0351/2205] ITS GPU: Make threads and blocks configurable from CLI (#13596) --- .../GPU/ITStrackingGPU/TimeFrameGPU.h | 1 - .../GPU/ITStrackingGPU/TrackingKernels.h | 4 +- .../ITS/tracking/GPU/cuda/TimeFrameGPU.cu | 21 ---------- .../tracking/GPU/cuda/TrackerTraitsGPU.cxx | 9 ++-- .../ITS/tracking/GPU/cuda/TrackingKernels.cu | 8 ++-- .../tracking/GPU/cuda/VertexerTraitsGPU.cxx | 1 + .../ITS/tracking/GPU/cuda/VertexingKernels.cu | 41 +++++++++++++------ .../include/ITStracking/TrackingConfigParam.h | 22 +++------- .../ITS/tracking/src/TrackingConfigParam.cxx | 4 +- .../ITSMFT/ITS/tracking/src/TrackingLinkDef.h | 4 +- .../ITSMFT/ITS/tracking/src/Vertexer.cxx | 2 +- 11 files changed, 53 insertions(+), 64 deletions(-) diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h index 12a5f877c0135..73955be325ff7 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h @@ -184,7 +184,6 @@ class TimeFrameGPU : public TimeFrame void registerHostMemory(const int); void unregisterHostMemory(const int); void initialise(const int, const TrackingParameters&, const int, IndexTableUtils* utils = nullptr, const TimeFrameGPUParameters* pars = nullptr); - void initialiseHybrid(const int, const TrackingParameters&, const int, IndexTableUtils* utils = nullptr, const TimeFrameGPUParameters* pars = nullptr); void initDevice(IndexTableUtils*, const TrackingParameters& trkParam, const TimeFrameGPUParameters&, const int, const int); void initDeviceSAFitting(); void loadTrackingFrameInfoDevice(const int); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h index e96125bdd3bc7..cc74456bbb1aa 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h @@ -59,6 +59,8 @@ void trackSeedHandler(CellSeed* trackSeeds, float maxChi2ClusterAttachment, float maxChi2NDF, const o2::base::Propagator* propagator, - const o2::base::PropagatorF::MatCorrType matCorrType); + const o2::base::PropagatorF::MatCorrType matCorrType, + const int nBlocks, + const int nThreads); } // namespace o2::its #endif // ITSTRACKINGGPU_TRACKINGKERNELS_H_ diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu index ff9ef6c80b9a3..05edc847f1e05 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu @@ -362,27 +362,6 @@ void TimeFrameGPU::initialise(const int iteration, const int maxLayers, IndexTableUtils* utils, const TimeFrameGPUParameters* gpuParam) -{ - mGpuStreams.resize(mGpuParams.nTimeFrameChunks); - mHostNTracklets.resize((nLayers - 1) * mGpuParams.nTimeFrameChunks, 0); - mHostNCells.resize((nLayers - 2) * mGpuParams.nTimeFrameChunks, 0); - - auto init = [&]() -> void { - this->initDevice(utils, trkParam, *gpuParam, maxLayers, iteration); - }; - std::thread t1{init}; - RANGE("tf_cpu_initialisation", 1); - o2::its::TimeFrame::initialise(iteration, trkParam, maxLayers); - // registerHostMemory(maxLayers); - t1.join(); -} - -template -void TimeFrameGPU::initialiseHybrid(const int iteration, - const TrackingParameters& trkParam, - const int maxLayers, - IndexTableUtils* utils, - const TimeFrameGPUParameters* gpuParam) { mGpuStreams.resize(mGpuParams.nTimeFrameChunks); o2::its::TimeFrame::initialise(iteration, trkParam, maxLayers); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx index 7f1d6812bc6cd..ac8b3f87b874c 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx @@ -20,6 +20,7 @@ #include "ITStrackingGPU/TrackerTraitsGPU.h" #include "ITStrackingGPU/TrackingKernels.h" +#include "ITStracking/TrackingConfigParam.h" namespace o2::its { @@ -28,7 +29,7 @@ constexpr int UnusedIndex{-1}; template void TrackerTraitsGPU::initialiseTimeFrame(const int iteration) { - mTimeFrameGPU->initialiseHybrid(iteration, mTrkParams[iteration], nLayers); + mTimeFrameGPU->initialise(iteration, mTrkParams[iteration], nLayers); mTimeFrameGPU->loadTrackingFrameInfoDevice(iteration); } @@ -397,7 +398,7 @@ void TrackerTraitsGPU::findRoads(const int iteration) } mTimeFrameGPU->createTrackITSExtDevice(trackSeeds); mTimeFrameGPU->loadTrackSeedsDevice(trackSeeds); - + auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); trackSeedHandler( mTimeFrameGPU->getDeviceTrackSeeds(), // CellSeed* trackSeeds, mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), // TrackingFrameInfo** foundTrackingFrameInfo, @@ -408,7 +409,9 @@ void TrackerTraitsGPU::findRoads(const int iteration) mTrkParams[0].MaxChi2ClusterAttachment, // float maxChi2ClusterAttachment, mTrkParams[0].MaxChi2NDF, // float maxChi2NDF, mTimeFrameGPU->getDevicePropagator(), // const o2::base::Propagator* propagator - mCorrType); // o2::base::PropagatorImpl::MatCorrType + mCorrType, // o2::base::PropagatorImpl::MatCorrType + conf.nBlocks, + conf.nThreads); mTimeFrameGPU->downloadTrackITSExtDevice(trackSeeds); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index 2374e7b8d04a2..60683e5fea30b 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -717,9 +717,11 @@ void trackSeedHandler(CellSeed* trackSeeds, float maxChi2ClusterAttachment, float maxChi2NDF, const o2::base::Propagator* propagator, - const o2::base::PropagatorF::MatCorrType matCorrType) + const o2::base::PropagatorF::MatCorrType matCorrType, + const int nBlocks, + const int nThreads) { - gpu::fitTrackSeedsKernel<<<20, 256>>>( + gpu::fitTrackSeedsKernel<<>>( trackSeeds, // CellSeed* trackSeeds, foundTrackingFrameInfo, // TrackingFrameInfo** foundTrackingFrameInfo, tracks, // o2::its::TrackITSExt* tracks, @@ -734,4 +736,4 @@ void trackSeedHandler(CellSeed* trackSeeds, gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); } -} // namespace o2::its +} // namespace o2::its \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx index 0e03dd0f25ce4..a26d52b2961c3 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexerTraitsGPU.cxx @@ -37,6 +37,7 @@ void VertexerTraitsGPU::initialise(const TrackingParameters& trackingParams, con { mTimeFrameGPU->initialise(0, trackingParams, 3, &mIndexTableUtils, &mTfGPUParams); } + void VertexerTraitsGPU::updateVertexingParameters(const std::vector& vrtPar, const TimeFrameGPUParameters& tfPar) { mVrtParams = vrtPar; diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu index 9e99687c3be6a..2ba4471ef61e5 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/VertexingKernels.cu @@ -39,8 +39,23 @@ void trackletFinderHandler(const Cluster* clustersNextLayer, // 0 2 const unsigned int startRofId, const unsigned int rofSize, const float phiCut, - const size_t maxTrackletsPerCluster) + const unsigned int maxTrackletsPerCluster, + const int nBlocks, + const int nThreads) { + gpu::trackleterKernelMultipleRof<<>>( + clustersNextLayer, // const Cluster* clustersNextLayer, // 0 2 + clustersCurrentLayer, // const Cluster* clustersCurrentLayer, // 1 1 + sizeNextLClusters, // const int* sizeNextLClusters, + sizeCurrentLClusters, // const int* sizeCurrentLClusters, + nextIndexTables, // const int* nextIndexTables, + Tracklets, // Tracklet* Tracklets, + foundTracklets, // int* foundTracklets, + utils, // const IndexTableUtils* utils, + startRofId, // const unsigned int startRofId, + rofSize, // const unsigned int rofSize, + phiCut, // const float phiCut, + maxTrackletsPerCluster); // const unsigned int maxTrackletsPerCluster = 1e2 } /* GPUd() float smallestAngleDifference(float a, float b) @@ -96,7 +111,7 @@ GPUd() void printOnBlock(const unsigned int bId, const char* str, Args... args) } } -GPUg() void printBufferOnThread(const int* v, size_t size, const int len = 150, const unsigned int tId = 0) +GPUg() void printBufferOnThread(const int* v, unsigned int size, const int len = 150, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { for (int i{0}; i < size; ++i) { @@ -109,7 +124,7 @@ GPUg() void printBufferOnThread(const int* v, size_t size, const int len = 150, } } -GPUg() void printBufferOnThreadF(const float* v, size_t size, const unsigned int tId = 0) +GPUg() void printBufferOnThreadF(const float* v, unsigned int size, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { printf("vector :"); @@ -127,7 +142,7 @@ GPUg() void resetTrackletsKernel(Tracklet* tracklets, const int nTracklets) } } -GPUg() void dumpFoundTrackletsKernel(const Tracklet* tracklets, const int* nTracklet, const size_t nClustersMiddleLayer, const int maxTrackletsPerCluster) +GPUg() void dumpFoundTrackletsKernel(const Tracklet* tracklets, const int* nTracklet, const unsigned int nClustersMiddleLayer, const int maxTrackletsPerCluster) { for (int iCurrentLayerClusterIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentLayerClusterIndex < nClustersMiddleLayer; iCurrentLayerClusterIndex += blockDim.x * gridDim.x) { const int stride{iCurrentLayerClusterIndex * maxTrackletsPerCluster}; @@ -160,7 +175,7 @@ GPUg() void trackleterKernelSingleRof( int* foundTracklets, const IndexTableUtils* utils, const short rofId, - const size_t maxTrackletsPerCluster = 1e2) + const unsigned int maxTrackletsPerCluster = 1e2) { const int phiBins{utils->getNphiBins()}; const int zBins{utils->getNzBins()}; @@ -168,7 +183,7 @@ GPUg() void trackleterKernelSingleRof( for (int iCurrentLayerClusterIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentLayerClusterIndex < sizeCurrentLClusters; iCurrentLayerClusterIndex += blockDim.x * gridDim.x) { if (iCurrentLayerClusterIndex < sizeCurrentLClusters) { unsigned int storedTracklets{0}; - const size_t stride{iCurrentLayerClusterIndex * maxTrackletsPerCluster}; + const unsigned int stride{iCurrentLayerClusterIndex * maxTrackletsPerCluster}; const Cluster& currentCluster = clustersCurrentLayer[iCurrentLayerClusterIndex]; const int4 selectedBinsRect{VertexerTraits::getBinsRect(currentCluster, (int)Mode, 0.f, 50.f, phiCut / 2, *utils)}; if (selectedBinsRect.x != 0 || selectedBinsRect.y != 0 || selectedBinsRect.z != 0 || selectedBinsRect.w != 0) { @@ -218,7 +233,7 @@ GPUg() void trackleterKernelMultipleRof( const short startRofId, const short rofSize, const float phiCut, - const size_t maxTrackletsPerCluster = 1e2) + const unsigned int maxTrackletsPerCluster = 1e2) { const int phiBins{utils->getNphiBins()}; const int zBins{utils->getNzBins()}; @@ -235,7 +250,7 @@ GPUg() void trackleterKernelMultipleRof( // single rof loop on layer1 clusters for (int iCurrentLayerClusterIndex = threadIdx.x; iCurrentLayerClusterIndex < nClustersCurrentLayerRof; iCurrentLayerClusterIndex += blockDim.x) { unsigned int storedTracklets{0}; - const size_t stride{iCurrentLayerClusterIndex * maxTrackletsPerCluster}; + const unsigned int stride{iCurrentLayerClusterIndex * maxTrackletsPerCluster}; const Cluster& currentCluster = clustersCurrentLayerRof[iCurrentLayerClusterIndex]; const int4 selectedBinsRect{VertexerTraits::getBinsRect(currentCluster, (int)Mode, 0.f, 50.f, phiCut / 2, *utils)}; if (selectedBinsRect.x != 0 || selectedBinsRect.y != 0 || selectedBinsRect.z != 0 || selectedBinsRect.w != 0) { @@ -276,7 +291,7 @@ template GPUg() void trackletSelectionKernelSingleRof( const Cluster* clusters0, const Cluster* clusters1, - const size_t nClustersMiddleLayer, + const unsigned int nClustersMiddleLayer, Tracklet* tracklets01, Tracklet* tracklets12, const int* nFoundTracklet01, @@ -436,7 +451,7 @@ GPUg() void computeCentroidsKernel( Line* lines, int* nFoundLines, int* nExclusiveFoundLines, - const size_t nClustersMiddleLayer, + const unsigned int nClustersMiddleLayer, float* centroids, const float lowHistX, const float highHistX, @@ -446,7 +461,7 @@ GPUg() void computeCentroidsKernel( { const int nLines = nExclusiveFoundLines[nClustersMiddleLayer - 1] + nFoundLines[nClustersMiddleLayer - 1]; const int maxIterations{nLines * (nLines - 1) / 2}; - for (size_t currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < maxIterations; currentThreadIndex += blockDim.x * gridDim.x) { + for (unsigned int currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < maxIterations; currentThreadIndex += blockDim.x * gridDim.x) { int iFirstLine = currentThreadIndex / nLines; int iSecondLine = currentThreadIndex % nLines; // All unique pairs @@ -496,7 +511,7 @@ GPUg() void computeZCentroidsKernel( const int binOpeningX, const int binOpeningY) { - for (size_t currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < nLines; currentThreadIndex += blockDim.x * gridDim.x) { + for (unsigned int currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < nLines; currentThreadIndex += blockDim.x * gridDim.x) { if (tmpVtX[0].value || tmpVtX[1].value) { float tmpX{lowHistX + tmpVtX[0].key * binSizeHistX + binSizeHistX / 2}; int sumWX{tmpVtX[0].value}; @@ -543,7 +558,7 @@ GPUg() void computeVertexKernel( const int minContributors, const int binOpeningZ) { - for (size_t currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < binOpeningZ; currentThreadIndex += blockDim.x * gridDim.x) { + for (unsigned int currentThreadIndex = blockIdx.x * blockDim.x + threadIdx.x; currentThreadIndex < binOpeningZ; currentThreadIndex += blockDim.x * gridDim.x) { if (currentThreadIndex == 0) { if (tmpVertexBins[2].value > 1 && (tmpVertexBins[0].value || tmpVertexBins[1].value)) { float z{lowHistZ + tmpVertexBins[2].key * binSizeHistZ + binSizeHistZ / 2}; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h index ee0ee633a3721..fe5e52bd6277a 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h @@ -55,7 +55,6 @@ struct VertexerParamConfig : public o2::conf::ConfigurableParamHelper { - // Use TGeo for mat. budget bool useMatCorrTGeo = false; bool useFastMaterial = false; @@ -89,24 +88,13 @@ struct TrackerParamConfig : public o2::conf::ConfigurableParamHelper { +struct ITSGpuTrackingParamConfig : public o2::conf::ConfigurableParamHelper { // GPU-specific parameters - size_t tmpCUBBufferSize = 1e5; // In average in pp events there are required 4096 bytes - size_t maxTrackletsPerCluster = 1e2; - size_t clustersPerLayerCapacity = 2.5e5; - size_t clustersPerROfCapacity = 1.5e3; - // size_t trackletsCapacity = maxTrackletsPerCluster * clustersPerLayerCapacity; - size_t validatedTrackletsCapacity = 1e5; - size_t cellsLUTsize = validatedTrackletsCapacity; - size_t maxNeighboursSize = 1e4; - size_t neighboursLUTsize = maxNeighboursSize; - size_t maxRoadPerRofSize = 5e2; // pp! - size_t maxLinesCapacity = 1e2; - size_t maxVerticesCapacity = 5e4; - size_t nTimeFramePartitions = 3; - int maxGPUMemoryGB = -1; + unsigned int tmpCUBBufferSize = 1e5; // In average in pp events there are required 4096 bytes + int nBlocks = 20; + int nThreads = 256; - O2ParamDef(GpuRecoParamConfig, "ITSGpuRecoParam"); + O2ParamDef(ITSGpuTrackingParamConfig, "ITSGpuTrackingParam"); }; } // namespace its diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingConfigParam.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingConfigParam.cxx index 4e67f919ac005..33edd140dd234 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingConfigParam.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingConfigParam.cxx @@ -18,10 +18,10 @@ namespace its { static auto& sVertexerParamITS = o2::its::VertexerParamConfig::Instance(); static auto& sCATrackerParamITS = o2::its::TrackerParamConfig::Instance(); -static auto& sGpuRecoParamITS = o2::its::GpuRecoParamConfig::Instance(); +static auto& sGpuRecoParamITS = o2::its::ITSGpuTrackingParamConfig::Instance(); O2ParamImpl(o2::its::VertexerParamConfig); O2ParamImpl(o2::its::TrackerParamConfig); -O2ParamImpl(o2::its::GpuRecoParamConfig); +O2ParamImpl(o2::its::ITSGpuTrackingParamConfig); } // namespace its } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h b/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h index f388943726b82..b06a4fd7d7d62 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h @@ -30,7 +30,7 @@ #pragma link C++ class o2::its::TrackerParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::TrackerParamConfig> + ; -#pragma link C++ class o2::its::GpuRecoParamConfig + ; -#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::GpuRecoParamConfig> + ; +#pragma link C++ class o2::its::ITSGpuTrackingParamConfig + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::ITSGpuTrackingParamConfig> + ; #endif diff --git a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx index 69d1ac9e7547c..4eaddc8385b8a 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx @@ -104,7 +104,7 @@ void Vertexer::getGlobalConfiguration() { auto& vc = o2::its::VertexerParamConfig::Instance(); vc.printKeyValues(true, true); - auto& grc = o2::its::GpuRecoParamConfig::Instance(); + auto& grc = o2::its::ITSGpuTrackingParamConfig::Instance(); // This is odd: we override only the parameters for the first iteration. // Variations for the next iterations are set in the trackingInterfrace. From 272bf86351e3610c4d93911531424117b31357f3 Mon Sep 17 00:00:00 2001 From: Paul Buehler Date: Wed, 16 Oct 2024 17:32:32 +0200 Subject: [PATCH 0352/2205] include PWG-UD converters (#13597) --- scripts/datamodel-doc/inputCard.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/datamodel-doc/inputCard.xml b/scripts/datamodel-doc/inputCard.xml index 5d0133cab6de4..10a453b84b4f5 100644 --- a/scripts/datamodel-doc/inputCard.xml +++ b/scripts/datamodel-doc/inputCard.xml @@ -479,7 +479,7 @@ - TableProducer/CMakeLists.txt + TableProducer/CMakeLists.txt, TableProducer/Converters/CMakeLists.txt @@ -492,7 +492,7 @@ - TableProducer/*.cxx + TableProducer/*.cxx, TableProducer/Converters/*.cxx From ac0f3f675dbfb8e594548bac92117ce5b27958d1 Mon Sep 17 00:00:00 2001 From: noferini <9963644+noferini@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:47:02 +0200 Subject: [PATCH 0353/2205] adding extra margin for sync TOF dia calibs --- Detectors/TOF/calibration/src/TOFDiagnosticCalibrator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/TOF/calibration/src/TOFDiagnosticCalibrator.cxx b/Detectors/TOF/calibration/src/TOFDiagnosticCalibrator.cxx index 7c0c929f9c380..9a4118dbba493 100644 --- a/Detectors/TOF/calibration/src/TOFDiagnosticCalibrator.cxx +++ b/Detectors/TOF/calibration/src/TOFDiagnosticCalibrator.cxx @@ -44,7 +44,7 @@ void TOFDiagnosticCalibrator::finalizeSlot(Slot& slot) auto flName = o2::ccdb::CcdbApi::generateFileName(clName); uint64_t startingMS = slot.getStartTimeMS() - 10000; // start 10 seconds before - uint64_t stoppingMS = slot.getEndTimeMS() + 10000; // stop 10 seconds after + uint64_t stoppingMS = slot.getEndTimeMS() + 600000; // stop 10 minutes after mccdbInfoVector.emplace_back("TOF/Calib/Diagnostic", clName, flName, md, startingMS, stoppingMS); mDiagnosticVector.emplace_back(*diag); } From 280edb55d36ac8b8ee19121b31e080d85eb49397 Mon Sep 17 00:00:00 2001 From: Simone Ragoni <47641042+siragoni@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:51:59 +0200 Subject: [PATCH 0354/2205] [EMCAL-539,EMCAL-696,EMCAL-697] FIT-CTP-EMCAL trigger simulation (#13227) * First implementation of the EMCAL CTP inputs * Added DigitizerTRU initialization * Suppressed verbosity, introduced CTPinputs * Enum for EMCAL triggers, introduced switch trigger sim * Enabling trigger simulation from CCDB * IR couts * Minimised couts * FastOr masking prototype from CCDB * Fixes to masking logic * Interaction rate check --- Detectors/CTP/simulation/src/Digitizer.cxx | 16 +- Detectors/EMCAL/simulation/CMakeLists.txt | 2 +- .../include/EMCALSimulation/DigitizerTRU.h | 18 ++ .../EMCALSimulation/LZEROElectronics.h | 7 + .../EMCAL/simulation/src/DigitizerTRU.cxx | 77 ++++++- .../src/DigitsWriteoutBufferTRU.cxx | 3 + .../EMCAL/simulation/src/LZEROElectronics.cxx | 28 ++- .../EMCALWorkflow/EMCALDigitizerSpec.h | 5 + .../EMCAL/workflow/src/EMCALDigitizerSpec.cxx | 201 +++++++++++++++++- 9 files changed, 335 insertions(+), 22 deletions(-) diff --git a/Detectors/CTP/simulation/src/Digitizer.cxx b/Detectors/CTP/simulation/src/Digitizer.cxx index 7a16483594400..7f8c00a0ace69 100644 --- a/Detectors/CTP/simulation/src/Digitizer.cxx +++ b/Detectors/CTP/simulation/src/Digitizer.cxx @@ -43,6 +43,7 @@ std::vector Digitizer::process(const gsl::span std::vector digits; for (auto const& hits : predigits) { std::bitset inpmaskcoll = 0; + auto currentIR = hits.first; for (auto const inp : hits.second) { switch (inp->detector) { case o2::detectors::DetID::FT0: { @@ -81,7 +82,7 @@ std::vector Digitizer::process(const gsl::span std::bitset emcMBaccept; emcMBaccept.set(CTP_NINPUTS - 1, 1); inpmaskcoll |= emcMBaccept; - } else { + } // else { // needs to be done always, remove else for (auto const& ctpinp : det2ctpinp[o2::detectors::DetID::EMC]) { uint64_t mask = inpmaskdebug & detInputName2Mask[ctpinp.name]; // uint64_t mask = (inp->inputsMask).to_ullong() & detInputName2Mask[ctpinp.name]; @@ -89,9 +90,9 @@ std::vector Digitizer::process(const gsl::span inpmaskcoll |= std::bitset(ctpinp.inputMask); } } - } - LOG(info) << "EMC input mask:" << inpmaskcoll; - break; + // } + // LOG(info) << "EMC input mask:" << inpmaskcoll << " with IR = " << currentIR.bc << ", orbit = " << currentIR.orbit; + break; } case o2::detectors::DetID::PHS: { for (auto const& ctpinp : det2ctpinp[o2::detectors::DetID::PHS]) { @@ -132,7 +133,8 @@ std::vector Digitizer::process(const gsl::span data.CTPInputMask = inpmaskcoll; data.CTPClassMask = classmask; digits.emplace_back(data); - LOG(info) << "Trigger-Event " << data.intRecord.bc << " " << data.intRecord.orbit << " Input mask:" << inpmaskcoll; + LOG(info) << "Trigger-Event " << data.intRecord.bc << " " << data.intRecord.orbit << " Input mask:" << inpmaskcoll << " with IR = " << data.intRecord.bc << ", orbit = " << data.intRecord.orbit; + // LOG(info) << "Trigger-Event " << data.intRecord.bc << " " << data.intRecord.orbit << " Class mask:" << data.CTPClassMask << " with IR = " << data.intRecord.bc << ", orbit = " << data.intRecord.orbit; } } return std::move(digits); @@ -160,12 +162,12 @@ void Digitizer::calculateClassMask(const std::bitset ctpinpmask, st classmask |= tcl.classMask; LOG(info) << "adding MBA:" << tcl.name; } - } else { + } // else { // EMCAL rare triggers - physical trigger input // class identification can be handled like in the case of the other // classes as EMCAL trigger input is required classmask |= tcl.classMask; - } + // } } } else { if ((ctpinpmask.to_ullong() & tcl.descriptor->getInputsMask()) == tcl.descriptor->getInputsMask()) { diff --git a/Detectors/EMCAL/simulation/CMakeLists.txt b/Detectors/EMCAL/simulation/CMakeLists.txt index 5402d9145f1d8..c08bc8c53c69b 100644 --- a/Detectors/EMCAL/simulation/CMakeLists.txt +++ b/Detectors/EMCAL/simulation/CMakeLists.txt @@ -13,7 +13,7 @@ o2_add_library(EMCALSimulation SOURCES src/Detector.cxx src/Digitizer.cxx src/DigitizerTRU.cxx src/SDigitizer.cxx src/DigitsWriteoutBuffer.cxx src/DigitsWriteoutBufferTRU.cxx src/LZEROElectronics.cxx src/TRUElectronics.cxx src/DigitsVectorStream.cxx src/SpaceFrame.cxx src/SimParam.cxx src/LabeledDigit.cxx src/RawWriter.cxx - PUBLIC_LINK_LIBRARIES ROOT::TreePlayer O2::EMCALBase O2::DetectorsBase O2::SimConfig O2::SimulationDataFormat O2::Headers O2::DetectorsRaw O2::EMCALReconstruction O2::DataFormatsCTP) + PUBLIC_LINK_LIBRARIES ROOT::TreePlayer O2::EMCALBase O2::DetectorsBase O2::SimConfig O2::SimulationDataFormat O2::Headers O2::DetectorsRaw O2::EMCALReconstruction O2::EMCALCalib O2::DataFormatsCTP) o2_target_root_dictionary(EMCALSimulation HEADERS include/EMCALSimulation/Detector.h diff --git a/Detectors/EMCAL/simulation/include/EMCALSimulation/DigitizerTRU.h b/Detectors/EMCAL/simulation/include/EMCALSimulation/DigitizerTRU.h index 80cae94b94199..1a29176b8e9cc 100644 --- a/Detectors/EMCAL/simulation/include/EMCALSimulation/DigitizerTRU.h +++ b/Detectors/EMCAL/simulation/include/EMCALSimulation/DigitizerTRU.h @@ -31,6 +31,7 @@ #include "SimulationDataFormat/MCTruthContainer.h" #include "DataFormatsEMCAL/TriggerRecord.h" #include "CommonUtils/TreeStreamRedirector.h" +#include "EMCALCalib/FeeDCS.h" namespace o2 { @@ -40,6 +41,7 @@ class TreeStreamRedirector; } namespace emcal { +class FeeDCS; /// \class DigitizerTRU /// \brief EMCAL DigitizerTRU, digitizes with the help of a temporary description based upon a pol9*Heavyside @@ -79,6 +81,13 @@ class DigitizerTRU /// Sets geometry for trigger mapping void setGeometry(o2::emcal::Geometry* gm) { mGeometry = gm; } + /// Sets FEE DCS for the masking of the fastOrs + void setFEE(o2::emcal::FeeDCS* fees) { mFeeDCS = fees; } + + /// Sets the masked fastOrs from the CCDB in the LZERO + void setMaskedFastOrsInLZERO(); + void printMaskedFastOrsInLZERO(); + void setWindowStartTime(int time) { mTimeWindowStart = time; } void setDebugStreaming(bool doStreaming) { mEnableDebugStreaming = doStreaming; } @@ -101,12 +110,20 @@ class DigitizerTRU /// Getter for debug mode bool isDebugMode() { return mEnableDebugStreaming; } + /// Getter for triggers + const std::vector& getTriggerInputs() { return LZERO.getTriggerInputs(); } + /// Getter for patches std::vector getPatchesVector() { return patchesFromAllTRUs; } /// raw pointers used here to allow interface with TF1 static double rawResponseFunction(double* x, double* par); + /// Utility functions obtained from QC for EMC + int GetTRUIndexFromSTUIndex(Int_t id, Int_t detector); + int GetChannelForMaskRun2(int mask, int bitnumber, bool onethirdsm); + std::vector GetAbsFastORIndexFromMask(); + private: short mEventTimeOffset = 0; ///< event time difference from trigger time (in number of bins) bool mSmearEnergy = true; ///< do time and energy smearing @@ -134,6 +151,7 @@ class DigitizerTRU std::unique_ptr mDebugStream = nullptr; // std::unique_ptr mDebugStreamPatch = nullptr; bool mEnableDebugStreaming = false; + o2::emcal::FeeDCS* mFeeDCS; ///< EMCAL FEE DCS ClassDefNV(DigitizerTRU, 1); }; diff --git a/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h b/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h index b0ddb2c7b114b..c894a542e44fe 100644 --- a/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h +++ b/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h @@ -39,6 +39,8 @@ namespace emcal /// \param mLastTimesumAllFastOrs Vector of tuples with TRU ID, FastOrID with STU indexing, and their last Timesums struct EMCALTriggerInputs { o2::InteractionRecord mInterRecord; ///< Last known interaction record + int mTriggeredTRU; ///< Trigger TRU + std::vector mTriggeredPatches; ///< Trigger patches, in local STU indexing std::vector> mLastTimesumAllFastOrs; ///< TRU ID, FastOrID with STU indexing, and its last Timesum }; @@ -76,6 +78,10 @@ class LZEROElectronics /// Sets geometry for trigger mapping void setGeometry(o2::emcal::Geometry* gm) { mGeometry = gm; } + /// Sets the masked fastOrs from the CCDB in the LZERO + void setMaskedFastOrs(std::vector maskedfastors) { mMaskedFastOrs = maskedfastors; } + void printMaskedFastOrs(); + /// Set Threshold for LZERO algorithm /// \param threshold LZERO algorithm threshold void setThreshold(double threshold) { mThreshold = threshold; } @@ -131,6 +137,7 @@ class LZEROElectronics // const SimParam* mSimParam = nullptr; ///< SimParam object std::vector mTriggers; ///< Triggers to be sent out std::vector mTriggersPatch; ///< Triggers to be sent out + std::vector mMaskedFastOrs; ///< Masked fastOrs from CCDB bool mSimulateNoiseDigits = true; ///< simulate noise digits // TriggerMappingV2* mTriggerMap = nullptr; ///< Trigger map to properly assign an absolute FastOr to TRU FastOr Geometry* mGeometry = nullptr; ///< EMCAL geometry diff --git a/Detectors/EMCAL/simulation/src/DigitizerTRU.cxx b/Detectors/EMCAL/simulation/src/DigitizerTRU.cxx index 4bb2e51dd6991..7f0da790eff8c 100644 --- a/Detectors/EMCAL/simulation/src/DigitizerTRU.cxx +++ b/Detectors/EMCAL/simulation/src/DigitizerTRU.cxx @@ -12,6 +12,7 @@ #include "EMCALSimulation/DigitizerTRU.h" #include "EMCALSimulation/SimParam.h" #include "EMCALSimulation/DigitsWriteoutBuffer.h" +#include "EMCALCalib/FeeDCS.h" #include "DataFormatsEMCAL/Digit.h" #include "EMCALBase/Hit.h" #include "MathUtils/Cartesian.h" @@ -436,4 +437,78 @@ void DigitizerTRU::finish() if (isDebugMode() == true) { endDebugStream(); } -} \ No newline at end of file +} +//______________________________________________________________________ +int DigitizerTRU::GetTRUIndexFromSTUIndex(Int_t id, Int_t detector) +{ + Int_t kEMCAL = 0; + Int_t kDCAL = 1; + + if ((id > 31 && detector == kEMCAL) || (id > 13 && detector == kDCAL) || id < 0) { + return -1; // Error Condition + } + + if (detector == kEMCAL) { + return id; + } else if (detector == kDCAL) { + return 32 + ((int)(id / 4) * 6) + ((id % 4 < 2) ? (id % 4) : (id % 4 + 2)); + } + return -1; +} +//______________________________________________________________________ +int DigitizerTRU::GetChannelForMaskRun2(int mask, int bitnumber, bool onethirdsm) +{ + if (onethirdsm) { + return mask * 16 + bitnumber; + } + const int kChannelMap[6][16] = {{8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47}, // Channels in mask0 + {56, 57, 58, 59, 68, 69, 70, 71, 80, 81, 82, 83, 92, 93, 94, 95}, // Channels in mask1 + {4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43}, // Channels in mask2 + {52, 53, 54, 55, 64, 65, 66, 67, 76, 77, 78, 79, 88, 89, 90, 91}, // Channels in mask3 + {0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39}, // Channels in mask4 + {48, 49, 50, 51, 60, 61, 62, 63, 72, 73, 74, 75, 84, 85, 86, 87}}; // Channels in mask5 + return kChannelMap[mask][bitnumber]; +} +//______________________________________________________________________ +std::vector DigitizerTRU::GetAbsFastORIndexFromMask() +{ + TriggerMappingV2 mTriggerMap(mGeometry); + std::vector maskedfastors; + int itru = 0; + for (Int_t i = 0; i < 46; i++) { + int localtru = itru % 32, detector = itru >= 32 ? 1 : 0, + globaltru = GetTRUIndexFromSTUIndex(localtru, detector); + bool onethirdsm = ((globaltru >= 30 && globaltru < 32) || (globaltru >= 50 && globaltru < 52)); + for (int ipos = 0; ipos < 6; ipos++) { + auto regmask = mFeeDCS->getTRUDCS(i).getMaskReg(ipos); + std::bitset<16> bitsregmask(regmask); + for (int ibit = 0; ibit < 16; ibit++) { + if (bitsregmask.test(ibit)) { + auto channel = GetChannelForMaskRun2(ipos, ibit, onethirdsm); + int absfastor = mTriggerMap.getAbsFastORIndexFromIndexInTRU(globaltru, channel); + maskedfastors.push_back(absfastor); + } + } + } + itru++; + } + return maskedfastors; +} +//______________________________________________________________________ +void DigitizerTRU::setMaskedFastOrsInLZERO() +{ + auto maskedFastOrs = GetAbsFastORIndexFromMask(); + LOG(info) << "======================================"; + LOG(info) << "== PRINT MASK COMPUTED IN DIGITIZER =="; + int counter = 0; + for (auto fastOr : maskedFastOrs) { + LOG(info) << "fastOr masked (number, ID) = (" << counter << ", " << fastOr; + counter += 1; + } + LZERO.setMaskedFastOrs(maskedFastOrs); +} +//______________________________________________________________________ +void DigitizerTRU::printMaskedFastOrsInLZERO() +{ + LZERO.printMaskedFastOrs(); +} diff --git a/Detectors/EMCAL/simulation/src/DigitsWriteoutBufferTRU.cxx b/Detectors/EMCAL/simulation/src/DigitsWriteoutBufferTRU.cxx index e261fba8d0e9d..8b642b2c767eb 100644 --- a/Detectors/EMCAL/simulation/src/DigitsWriteoutBufferTRU.cxx +++ b/Detectors/EMCAL/simulation/src/DigitsWriteoutBufferTRU.cxx @@ -56,6 +56,7 @@ void DigitsWriteoutBufferTRU::fillOutputContainer(bool isEndOfTimeFrame, Interac // LZERO.updatePatchesADC(patches); // LZERO.peakFinderOnAllPatches(patches); // } + LOG(debug) << "DIG TRU fillOutputContainer in DigitsWriteoutBufferTRU: LOW IR"; mCurrentInteractionRecord = nextInteractionRecord; clear(); @@ -94,6 +95,8 @@ void DigitsWriteoutBufferTRU::fillOutputContainer(bool isEndOfTimeFrame, Interac } } reserve(15); + + LOG(debug) << "DIG TRU fillOutputContainer in DigitsWriteoutBufferTRU: HIGH IR"; } } //________________________________________________________ diff --git a/Detectors/EMCAL/simulation/src/LZEROElectronics.cxx b/Detectors/EMCAL/simulation/src/LZEROElectronics.cxx index 997bc9efabc88..672c9c5b1ca89 100644 --- a/Detectors/EMCAL/simulation/src/LZEROElectronics.cxx +++ b/Detectors/EMCAL/simulation/src/LZEROElectronics.cxx @@ -113,13 +113,11 @@ void LZEROElectronics::fill(const std::deque& digitl // At the end of the loop run the peak finder // Ship to LONEElectronics in case a peak is found // Entire logic limited to timebin by timebin -> effectively implementing time scan - counterDigitTimeBin++; for (auto& [fastor, digitsList] : *digitsTimeBin.mDigitMap) { // Digit loop // The peak finding algorithm is run after getting out of the loop! - if (digitsList.size() == 0) { continue; } @@ -154,7 +152,10 @@ void LZEROElectronics::fill(const std::deque& digitl auto whichFastOr = std::get<1>(mTriggerMap.convertFastORIndexTRUtoSTU(whichTRU, whichFastOrTRU)); auto& patchTRU = patchesFromAllTRUs[whichTRU]; auto& fastOrPatchTRU = patchTRU.mFastOrs[whichFastOr]; - fastOrPatchTRU.updateADC(summedDigit.getAmplitudeADC()); + // fastOrPatchTRU.updateADC(summedDigit.getAmplitudeADC()); + if (std::find(mMaskedFastOrs.begin(), mMaskedFastOrs.end(), fastor) != mMaskedFastOrs.end()) { + fastOrPatchTRU.updateADC(summedDigit.getAmplitudeADC()); + } digIndex++; } @@ -172,13 +173,21 @@ void LZEROElectronics::fill(const std::deque& digitl // It accounts for the difference in times between L0a, L0b, and then there will be a L1 and L1b delay // There is 1BC uncertainty on the trigger readout due to steps in the interaction between CTP and detector simulations bool foundPeak = false; + int counterWhichTRU = 0; + int triggeredTRU = -1; + std::vector triggeredPatches; for (auto& patches : patchesFromAllTRUs) { updatePatchesADC(patches); bool foundPeakCurrentTRU = peakFinderOnAllPatches(patches); auto firedPatches = getFiredPatches(patches); + if (foundPeakCurrentTRU == true && foundPeak == false) { + triggeredTRU = counterWhichTRU; + triggeredPatches = firedPatches; + } if (foundPeakCurrentTRU) { foundPeak = true; } + counterWhichTRU += 1; } if (foundPeak == true) { @@ -187,6 +196,8 @@ void LZEROElectronics::fill(const std::deque& digitl EMCALTriggerInputs TriggerInputsForL1; if (foundPeak) { TriggerInputsForL1.mInterRecord = record; + TriggerInputsForL1.mTriggeredTRU = triggeredTRU; + TriggerInputsForL1.mTriggeredPatches = triggeredPatches; int whichTRU = 0; for (auto& patches : patchesFromAllTRUs) { int whichFastOr = 0; @@ -228,3 +239,14 @@ void LZEROElectronics::fill(const std::deque& digitl } } } +//________________________________________________________ +void LZEROElectronics::printMaskedFastOrs() +{ + LOG(info) << "==============================="; + LOG(info) << "== PRINT MASK SAVED IN LZERO =="; + int counter = 0; + for (auto fastOr : mMaskedFastOrs) { + LOG(info) << "fastOr masked (number, ID) = (" << counter << ", " << fastOr; + counter += 1; + } +} diff --git a/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h b/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h index fe58dd75bdbde..ee50dfb03bb6d 100644 --- a/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h +++ b/Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h @@ -23,6 +23,7 @@ #include "EMCALSimulation/SDigitizer.h" #include "SimulationDataFormat/MCTruthContainer.h" #include +#include "EMCALSimulation/DigitizerTRU.h" class TChain; @@ -90,6 +91,10 @@ class DigitizerSpec final : public o2::base::BaseDPLDigitizer, public o2::framew std::vector mSimChains; o2::ctp::CTPConfiguration* mCTPConfig; ///< CTP configuration o2::steer::MCKinematicsReader* mcReader; ///< reader to access MC collision information + + DigitizerTRU mDigitizerTRU; ///< Digitizer object TRU + o2::emcal::SDigitizer mSumDigitizerTRU; ///< Summed digitizer TRU + bool mRunDigitizerTRU = true; ///< Run Digitizer TRU? }; /// \brief Create new digitizer spec diff --git a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx index 8690956650664..5de966d1b6a4c 100644 --- a/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx +++ b/Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx @@ -53,11 +53,17 @@ void DigitizerSpec::initDigitizerTask(framework::InitContext& ctx) // init digitizer mSumDigitizer.setGeometry(geom); + mSumDigitizerTRU.setGeometry(geom); + mDigitizerTRU.setGeometry(geom); if (ctx.options().get("debug-stream")) { mDigitizer.setDebugStreaming(true); + mDigitizerTRU.setDebugStreaming(true); } // mDigitizer.init(); + if (ctx.options().get("disable-dig-tru")) { + mRunDigitizerTRU = false; + } mFinished = false; } @@ -80,6 +86,7 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) o2::emcal::SimParam::Instance().printKeyValues(true, true); mDigitizer.flush(); + mDigitizerTRU.flush(); // read collision context from input auto context = ctx.inputs().get("collisioncontext"); @@ -104,6 +111,86 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) TStopwatch timer; timer.Start(); + auto& eventParts = context->getEventParts(); + + // ------------------------------ + // For the TRIGGER Simulation + // ------------------------------ + // Load the masked fastOr + // This impact the acceptance + // of the detector, and thus the + // overall efficiency of the L0 + if (mCalibHandler) { + mDigitizerTRU.setFEE(mCalibHandler->getFEEDCS()); + mDigitizerTRU.setMaskedFastOrsInLZERO(); + } + + // ------------------------------ + // TRIGGER Simulation + // ------------------------------ + // 1. Run SDigitizer separate loop -> map of vector of SDigits + // 2. Run Trigger simulation chain (Digitizer -> Digits writeout buffer -> L0 Simulation) + // 3. Run Loop SDigits -> Digits, set live only if the trigger is accepted. + // + // loop over all composite collisions given from context + // (aka loop over all the interaction records) + int collisionN = 0; + for (int collID = 0; collID < timesview.size(); ++collID) { + + if (mRunDigitizerTRU == false) { + break; + } + + if (intRate < 10000.) { + break; + } + + collisionN++; + + mDigitizerTRU.setEventTime(timesview[collID]); + + // for each collision, loop over the constituents event and source IDs + // (background signal merging is basically taking place here) + for (auto& part : eventParts[collID]) { + + mSumDigitizerTRU.setCurrEvID(part.entryID); + mSumDigitizerTRU.setCurrSrcID(part.sourceID); + + // get the hits for this event and this source + mHits.clear(); + context->retrieveHits(mSimChains, "EMCHit", part.sourceID, part.entryID, &mHits); + + // LOG(info) << "DIG TRU For collision " << collID << " eventID " << part.entryID << " found " << mHits.size() << " hits "; + + // std::vector summedLabeledDigits = mSumDigitizerTRU.process(mHits); + // std::vector summedDigits; + // for (auto labeledsummeddigit : summedLabeledDigits) { + // summedDigits.push_back(labeledsummeddigit.getDigit()); + // } + + std::vector summedLabeledDigits; + std::vector summedDigits; + if (mRunSDitizer) { + summedLabeledDigits = mSumDigitizerTRU.process(mHits); + for (auto labeledsummeddigit : summedLabeledDigits) { + summedDigits.push_back(labeledsummeddigit.getDigit()); + } + } else { + for (auto& hit : mHits) { + summedDigits.emplace_back(hit.GetDetectorID(), hit.GetEnergyLoss(), hit.GetTime()); + } + } + + // call actual digitization procedure + mDigitizerTRU.process(summedDigits); + } + } + mDigitizerTRU.printMaskedFastOrsInLZERO(); + mDigitizerTRU.finish(); + // Result of the trigger simulation + // -> Set of BCs with triggering patches + auto emcalTriggers = mDigitizerTRU.getTriggerInputs(); + // Load FIT triggers if not running in self-triggered mode std::vector mbtriggers; if (mRequireCTPInput) { @@ -178,18 +265,78 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) LOG(info) << " CALLING EMCAL DIGITIZATION "; o2::dataformats::MCTruthContainer labelAccum; - auto& eventParts = context->getEventParts(); + // auto& eventParts = context->getEventParts(); + std::vector>> acceptedTriggers; + enum EMCALTriggerBits { kMB, + kEMC, + kDMC }; // EMCAL trigger bits enum for CTP inputs + TRandom3 mRandomGenerator(std::chrono::high_resolution_clock::now().time_since_epoch().count()); // loop over all composite collisions given from context // (aka loop over all the interaction records) for (int collID = 0; collID < timesview.size(); ++collID) { - bool trigger = true; // Default: Self-triggered mode - all collisions treated as trigger + + std::bitset<5> trigger{0x1}; // Default: Self-triggered mode - all collisions treated as trigger if (mRequireCTPInput) { + // ==================================================== // check if we have a trigger input from CTP - trigger = (std::find(mbtriggers.begin(), mbtriggers.end(), timesview[collID]) != mbtriggers.end()); + // Simulated L0 and downsampling + // 2 cases -> Check from CTP config + // 1) EMCAL trigger active -> MB downsampled + // - Accept the event in 2 conditions + // + MB downsampling (first condition) -> Set trigger bit kTVXinEMC + // + EMCAL L0 trigger -> Set bit EMCAL L0 + // Always test both, set trigger 0x1 -> EMBA, 0x2 -> 0EMC, 0x4 -> 0DCMX, 0 -> No trigger + // 2) EMCAL triggers not active + // . - Old logics kept, no downscaling, pure busy + // ---------------------------------------------------- + // PRNG for downscaling check + auto mbtrigger = std::find(mbtriggers.begin(), mbtriggers.end(), timesview[collID]); + if (mbtrigger != mbtriggers.end()) { + + // ============================ + // retrieve downscaling from + // configuration of CTP classes + int downscaling = 0; + for (const auto& trg : mCTPConfig->getCTPClasses()) { + if (trg.cluster->maskCluster[o2::detectors::DetID::EMC]) { + // Class triggering EMCAL cluster + downscaling = trg.downScale; + } + } + if (mRandomGenerator.Uniform(0., 1) < downscaling) { + // accept as minimum bias + trigger.set(EMCALTriggerBits::kMB, true); + } + // check for LO triggers in 12 BCs + for (auto emcalTrigger : emcalTriggers) { + auto bcTimingOfEmcalTrigger = emcalTrigger.mInterRecord.bc; + auto bcTimingOfMBTrigger = (*mbtrigger).bc; + if (std::abs(bcTimingOfEmcalTrigger - bcTimingOfMBTrigger) < 12) { + if (emcalTrigger.mTriggeredTRU < 32) { + trigger.set(EMCALTriggerBits::kEMC, true); + } else { + trigger.set(EMCALTriggerBits::kDMC, true); + } + } + } + + } else { + // No trigger active + // Set busy + trigger.set(EMCALTriggerBits::kMB, false); + } + } + // Bitset + // Trigger sim: Select event + if (!trigger.any()) { + continue; } + // Trigger sim: Prepare CTP input digit + acceptedTriggers.push_back(std::make_tuple(timesview[collID], trigger)); + LOG(debug) << "EMCAL TRU simulation: Sending trg = " << trigger << " to CTP"; - mDigitizer.setEventTime(timesview[collID], trigger); + mDigitizer.setEventTime(timesview[collID], trigger.any()); if (!mDigitizer.isLive()) { continue; @@ -244,14 +391,28 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) ctx.outputs().snapshot(Output{"EMC", "ROMode", 0}, roMode); // Create CTP digits std::vector triggerinputs; - for (auto& trg : mDigitizer.getTriggerRecords()) { - // covert TriggerRecord into CTP trigger digit + // for (auto& trg : mDigitizer.getTriggerRecords()) { + // // covert TriggerRecord into CTP trigger digit + // o2::ctp::CTPInputDigit nextdigit; + // nextdigit.intRecord = trg.getBCData(); + // nextdigit.detector = o2::detectors::DetID::EMC; + // // Set min. bias accept trigger (input 0) as fake trigger + // // Other inputs will be added once available + // nextdigit.inputsMask.set(0); + // triggerinputs.push_back(nextdigit); + // } + for (auto& trg : acceptedTriggers) { + // convert TriggerRecord into CTP trigger digit o2::ctp::CTPInputDigit nextdigit; - nextdigit.intRecord = trg.getBCData(); + nextdigit.intRecord = std::get<0>(trg); nextdigit.detector = o2::detectors::DetID::EMC; - // Set min. bias accept trigger (input 0) as fake trigger - // Other inputs will be added once available - nextdigit.inputsMask.set(0); + // nextdigit.inputsMask = std::get<1>(trg); + for (size_t i = 0; i < nextdigit.inputsMask.size(); i++) { + if (std::get<1>(trg)[i] != 0) { + nextdigit.inputsMask.set(i); + } + } + LOG(debug) << "EMCAL TRU simulation: assigned = " << nextdigit.inputsMask << " as nextdigit for CTP, with IR = " << nextdigit.intRecord.bc << ", orbit = " << nextdigit.intRecord.orbit; triggerinputs.push_back(nextdigit); } ctx.outputs().snapshot(Output{"EMC", "TRIGGERINPUT", 0}, triggerinputs); @@ -266,6 +427,7 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx) void DigitizerSpec::configure() { mDigitizer.init(); + mDigitizerTRU.init(); } void DigitizerSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) @@ -276,6 +438,23 @@ void DigitizerSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, vo if (matcher == o2::framework::ConcreteDataMatcher("CTP", "CTPCONFIG", 0)) { std::cout << "Loading CTP configuration" << std::endl; mCTPConfig = reinterpret_cast(obj); + for (const auto& trg : mCTPConfig->getCTPClasses()) { + if (trg.cluster->maskCluster[o2::detectors::DetID::EMC]) { + // Class triggering EMCAL cluster + LOG(debug) << "ENABLING Trigger simulation, found trigger class for EMCAL cluster: " << trg.name << " with input mask " << std::bitset<64>(trg.descriptor->getInputsMask()); + for (const auto& [det, ctpinputs] : mCTPConfig->getDet2InputMap()) { + if (!(det == o2::detectors::DetID::EMC)) { + continue; + } + // if the detector ID is EMC AND the input mask is not empty, run the trigger simulation + for (const auto& input : ctpinputs) { + if (input.inputMask != 0) { + mRunDigitizerTRU = true; + } + } + } + } + } } } @@ -301,6 +480,7 @@ o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool require if (useccdb) { calibloader = std::make_shared(); calibloader->enableSimParams(true); + calibloader->enableFEEDCS(true); calibloader->defineInputSpecs(inputs); } if (requireCTPInput) { @@ -316,6 +496,7 @@ o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool require AlgorithmSpec{o2::framework::adaptFromTask(calibloader, requireCTPInput)}, Options{ {"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}}, + {"disable-dig-tru", VariantType::Bool, false, {"Disable TRU digitisation"}}, {"debug-stream", VariantType::Bool, false, {"Enable debug streaming"}}} // I can't use VariantType::Bool as it seems to have a problem }; From 2295e53becf214bcb4e4274feae8ed5e097ad71c Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Tue, 15 Oct 2024 13:43:01 +0200 Subject: [PATCH 0355/2205] TPC: adding check for SACs at endOfStream --- .../include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h index 7638076f5563f..adc43ee6d0258 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h @@ -201,7 +201,7 @@ class TPCFourierTransformAggregatorSpec : public o2::framework::Task void endOfStream(o2::framework::EndOfStreamContext& ec) final { - if (!mDisableScaler) { + if (!mDisableScaler && !mProcessSACs) { makeTPCScaler(ec.outputs(), true); } ec.services().get().readyToQuit(QuitRequest::Me); From fe6fa35ec06f16e91448ba9bd48b0c4f9c75bbd3 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 17 Oct 2024 13:53:53 +0200 Subject: [PATCH 0356/2205] Update LZEROElectronics.h const and reference correctness --- .../simulation/include/EMCALSimulation/LZEROElectronics.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h b/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h index c894a542e44fe..4927515b7691c 100644 --- a/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h +++ b/Detectors/EMCAL/simulation/include/EMCALSimulation/LZEROElectronics.h @@ -79,7 +79,7 @@ class LZEROElectronics void setGeometry(o2::emcal::Geometry* gm) { mGeometry = gm; } /// Sets the masked fastOrs from the CCDB in the LZERO - void setMaskedFastOrs(std::vector maskedfastors) { mMaskedFastOrs = maskedfastors; } + void setMaskedFastOrs(std::vector const& maskedfastors) { mMaskedFastOrs = maskedfastors; } void printMaskedFastOrs(); /// Set Threshold for LZERO algorithm @@ -110,7 +110,7 @@ class LZEROElectronics /// Getter for the pattern of peaks found by the LZERO algorithm /// \param p TRUElectronics object - const std::vector& getFiredPatches(TRUElectronics& p) const + const std::vector& getFiredPatches(TRUElectronics const& p) const { return p.mFiredPatches; } From 397ca53d46bd251e1259d1f4dd8e48954390f582 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 17 Oct 2024 11:01:17 +0200 Subject: [PATCH 0357/2205] DPL: speedup homogeneous_apply_ref Adding the requires statement should reduce greatly work done by the compiler to build and then optimise out the if constexprs. --- .../include/Framework/StructToTuple.h | 122 ++++++++++++++++-- 1 file changed, 109 insertions(+), 13 deletions(-) diff --git a/Framework/Foundation/include/Framework/StructToTuple.h b/Framework/Foundation/include/Framework/StructToTuple.h index becf22d01b8fe..c600e33883a74 100644 --- a/Framework/Foundation/include/Framework/StructToTuple.h +++ b/Framework/Foundation/include/Framework/StructToTuple.h @@ -163,13 +163,19 @@ consteval auto brace_constructible_size(auto... Members) return std::array{DPL_FENUM_##d##0(l, p, )}; \ } -template -auto homogeneous_apply_refs(L l, T&& object) +template +consteval int nested_brace_constructible_size() { using type = std::decay_t; constexpr int nesting = B ? 1 : 0; - constexpr unsigned long numElements = brace_constructible_size() - nesting; - static_assert(numElements < 99, "Too many elements in the struct"); + return brace_constructible_size() - nesting; +} + +template () / 10> + requires(D == 9) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); // clang-format off if DPL_HOMOGENEOUS_APPLY_ENTRY (9, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (9, 8) @@ -181,7 +187,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (9, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (9, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (9) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 8) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 6) @@ -191,7 +207,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (8, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (8) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 7) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 6) @@ -201,7 +227,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (7, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (7) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 6) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 6) @@ -211,7 +247,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (6, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (6) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 5) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 6) @@ -221,7 +267,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (5, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (5) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 4) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 6) @@ -231,7 +287,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (4, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (4) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 3) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 6) @@ -241,7 +307,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (3, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (3) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 2) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 6) @@ -251,7 +327,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (2, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (2) - else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 1) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 9) else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 8) else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 7) else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 6) @@ -261,7 +347,17 @@ auto homogeneous_apply_refs(L l, T&& object) else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 2) else if DPL_HOMOGENEOUS_APPLY_ENTRY (1, 1) else if DPL_HOMOGENEOUS_APPLY_ENTRY_TENS (1) - else if DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (9) + else { return std::array(); } + // clang-format on +} + +template () / 10> + requires(D == 0) +auto homogeneous_apply_refs(L l, T&& object) +{ + constexpr int numElements = nested_brace_constructible_size(); + // clang-format off + if DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (9) else if DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (8) else if DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (7) else if DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (6) From f86edb47870f94bf32796fc0f3a4a58756429b07 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 18 Oct 2024 00:42:46 +0200 Subject: [PATCH 0358/2205] Fix broken --max-tf option of ReaderDriver --- Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx index f8fd91418c04e..d02d321201936 100644 --- a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx @@ -75,7 +75,7 @@ void ReadeDriverSpec::run(ProcessingContext& pc) LOGP(debug, "OUTVEC {}/{}", v.back().getMin().asString(), v.back().getMax().asString()); } count++; - if ((HBFINI::LastIRFrameIndex == -1 && count == HBFINI::NTFs) || (v.size() && v.back().isLast())) { + if ((HBFINI::LastIRFrameIndex == -1 && count == mNTF) || (v.size() && v.back().isLast())) { pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); } From 0a2bcda49fd636d1701357a663b1b056cd1efcc6 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:38:07 +0200 Subject: [PATCH 0359/2205] DPL analysis: hide internal symbols --- .../Core/include/Framework/AnalysisTask.h | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/Framework/Core/include/Framework/AnalysisTask.h b/Framework/Core/include/Framework/AnalysisTask.h index 9d623adcf2bd3..ea57b643fadb2 100644 --- a/Framework/Core/include/Framework/AnalysisTask.h +++ b/Framework/Core/include/Framework/AnalysisTask.h @@ -60,6 +60,7 @@ static constexpr bool is_enumeration_v> = true; // Helper struct which builds a DataProcessorSpec from // the contents of an AnalysisTask... +namespace { struct AnalysisDataProcessorBuilder { template static ConfigParamSpec getSpec() @@ -374,6 +375,7 @@ struct AnalysisDataProcessorBuilder { std::invoke(processingFunction, task, g, std::get(at)...); } }; +} struct SetDefaultProcesses { std::vector> map; @@ -385,8 +387,9 @@ struct TaskName { std::string value; }; +namespace { template -auto getTaskNameSetProcesses(TaskName first, SetDefaultProcesses second, A... args) +auto getTaskNameSetProcesses(std::string& outputName, TaskName first, SetDefaultProcesses second, A... args) { auto task = std::make_shared(std::forward(args)...); for (auto& setting : second.map) { @@ -396,11 +399,12 @@ auto getTaskNameSetProcesses(TaskName first, SetDefaultProcesses second, A... ar }, *task.get()); } - return std::make_tuple(first.value, task); + outputName = first.value; + return task; } template -auto getTaskNameSetProcesses(SetDefaultProcesses first, TaskName second, A... args) +auto getTaskNameSetProcesses(std::string& outputName, SetDefaultProcesses first, TaskName second, A... args) { auto task = std::make_shared(std::forward(args)...); for (auto& setting : first.map) { @@ -410,11 +414,12 @@ auto getTaskNameSetProcesses(SetDefaultProcesses first, TaskName second, A... ar }, *task.get()); } - return std::make_tuple(second.value, task); + outputName = second.value; + return task; } template -auto getTaskNameSetProcesses(SetDefaultProcesses first, A... args) +auto getTaskNameSetProcesses(std::string& outputName, SetDefaultProcesses first, A... args) { auto task = std::make_shared(std::forward(args)...); for (auto& setting : first.map) { @@ -425,40 +430,27 @@ auto getTaskNameSetProcesses(SetDefaultProcesses first, A... args) *task.get()); } auto type_name_str = type_name(); - std::string name = type_to_task_name(type_name_str); - return std::make_tuple(name, task); + outputName = type_to_task_name(type_name_str); + return task; } template -auto getTaskNameSetProcesses(TaskName first, A... args) +auto getTaskNameSetProcesses(std::string& outputName, TaskName first, A... args) { auto task = std::make_shared(std::forward(args)...); - return std::make_tuple(first.value, task); + outputName = first.value; + return task; } template -auto getTaskNameSetProcesses(A... args) +auto getTaskNameSetProcesses(std::string& outputName, A... args) { auto task = std::make_shared(std::forward(args)...); auto type_name_str = type_name(); - std::string name = type_to_task_name(type_name_str); - return std::make_tuple(name, task); -} - -template -auto getTaskName(TaskName first, A... args) -{ - auto task = std::make_shared(std::forward(args)...); - return std::make_tuple(first.value, task); + outputName = type_to_task_name(type_name_str); + return task; } -template -auto getTaskName(A... args) -{ - auto task = std::make_shared(std::forward(args)...); - auto type_name_str = type_name(); - std::string name = type_to_task_name(type_name_str); - return std::make_tuple(name, task); } /// Adaptor to make an AlgorithmSpec from a o2::framework::Task @@ -468,7 +460,8 @@ DataProcessorSpec adaptAnalysisTask(ConfigContext const& ctx, Args&&... args) { TH1::AddDirectory(false); - auto [name_str, task] = getTaskNameSetProcesses(args...); + std::string name_str; + auto task = getTaskNameSetProcesses(name_str, args...); auto suffix = ctx.options().get("workflow-suffix"); if (!suffix.empty()) { From bdec6715ae6d645e03c44cc90f99e930f1cacbc8 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Wed, 16 Oct 2024 15:30:18 +0200 Subject: [PATCH 0360/2205] MID: skip digits produced before the beginning of the TF --- Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx index 1dbd392fb9f73..bb83e0b7e8c41 100644 --- a/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx @@ -20,6 +20,7 @@ #include "Framework/Task.h" #include "Steer/HitProcessingManager.h" // for DigitizationContext #include "DetectorsBase/BaseDPLDigitizer.h" +#include "DetectorsRaw/HBFUtils.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsMID/ROFRecord.h" @@ -83,6 +84,8 @@ class MIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer context->initSimChains(o2::detectors::DetID::MID, mSimChains); auto& irecords = context->getEventRecords(); + auto firstTFOrbit = o2::raw::HBFUtils::Instance().getFirstSampledTFIR().orbit; + auto& eventParts = context->getEventParts(); std::vector digits, digitsAccum; std::vector rofRecords; @@ -93,6 +96,11 @@ class MIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer for (int collID = 0; collID < irecords.size(); ++collID) { // for each collision, loop over the constituents event and source IDs // (background signal merging is basically taking place here) + + // Skip digits produced before the first orbit + if (irecords[collID].orbit < firstTFOrbit) { + continue; + } auto firstEntry = digitsAccum.size(); for (auto& part : eventParts[collID]) { mDigitizer->setEventID(part.entryID); From 852be0a3874b30b10517799000eb416dee5c7c48 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Thu, 17 Oct 2024 16:31:54 +0200 Subject: [PATCH 0361/2205] Account for the electronics delay in the simulated digits It was accounted for only in the raw data so far. --- Steer/DigitizerWorkflow/CMakeLists.txt | 1 + Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Steer/DigitizerWorkflow/CMakeLists.txt b/Steer/DigitizerWorkflow/CMakeLists.txt index 00ed662a75d39..78f91144bf854 100644 --- a/Steer/DigitizerWorkflow/CMakeLists.txt +++ b/Steer/DigitizerWorkflow/CMakeLists.txt @@ -51,6 +51,7 @@ o2_add_executable(digitizer-workflow O2::MCHDigitFiltering O2::MFTSimulation O2::MIDSimulation + O2::MIDRaw O2::PHOSSimulation O2::CPVSimulation O2::TOFSimulation diff --git a/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx index bb83e0b7e8c41..ced70fa8a0f97 100644 --- a/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/MIDDigitizerSpec.cxx @@ -31,6 +31,7 @@ #include "MIDSimulation/ChamberResponse.h" #include "MIDSimulation/ChamberEfficiencyResponse.h" #include "MIDSimulation/Geometry.h" +#include "MIDRaw/ElectronicsDelay.h" #include "DataFormatsMID/MCLabel.h" using namespace o2::framework; @@ -84,7 +85,9 @@ class MIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer context->initSimChains(o2::detectors::DetID::MID, mSimChains); auto& irecords = context->getEventRecords(); - auto firstTFOrbit = o2::raw::HBFUtils::Instance().getFirstSampledTFIR().orbit; + auto firstTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); + auto delay = InteractionRecord(mElectronicsDelay.localToBC, 0); + auto firstTimeTF = InteractionTimeRecord(firstTF + delay, 0); auto& eventParts = context->getEventParts(); std::vector digits, digitsAccum; @@ -98,7 +101,7 @@ class MIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer // (background signal merging is basically taking place here) // Skip digits produced before the first orbit - if (irecords[collID].orbit < firstTFOrbit) { + if (irecords[collID] < firstTimeTF) { continue; } auto firstEntry = digitsAccum.size(); @@ -144,6 +147,7 @@ class MIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer std::vector mSimChains; // RS: at the moment using hardcoded flag for continuos readout o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::CONTINUOUS; // readout mode + ElectronicsDelay mElectronicsDelay; // Electronics delay }; o2::framework::DataProcessorSpec getMIDDigitizerSpec(int channel, bool mctruth) From bfa4f1e320833dcf7861d75803b26a9592fcce49 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 17 Oct 2024 18:42:55 +0200 Subject: [PATCH 0362/2205] TRD digi / O2-5395: Trivial collision cut --- Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx index 1cd145a6c2e36..5d010b050e8b1 100644 --- a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx @@ -32,6 +32,7 @@ #include "TRDSimulation/Digitizer.h" #include "TRDSimulation/Detector.h" // for the Hit type #include "TRDSimulation/TRDSimParams.h" +#include "DetectorsRaw/HBFUtils.h" #include using namespace o2::framework; @@ -92,6 +93,8 @@ class TRDDPLDigitizerTask : public o2::base::BaseDPLDigitizer size_t currTrig = 0; // from which collision is the current TRD trigger (only needed for debug information) bool firstEvent = true; // Flag for the first event processed + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + TStopwatch timer; timer.Start(); // loop over all composite collisions given from context @@ -100,6 +103,16 @@ class TRDDPLDigitizerTask : public o2::base::BaseDPLDigitizer LOGF(debug, "Collision %lu out of %lu at %.1f ns started processing. Current pileup container size: %lu. Current number of digits accumulated: %lu", collID, irecords.size(), irecords[collID].getTimeNS(), mDigitizer.getPileupSignals().size(), digitsAccum.size()); currentTime = irecords[collID]; + + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (currentTime < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } + // Trigger logic implemented here bool isNewTrigger = true; // flag newly accepted readout trigger if (firstEvent) { From bdde90491b05acd2505b67be723eda13033be949 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 18 Oct 2024 09:56:01 +0200 Subject: [PATCH 0363/2205] DPL: move byteswapping helpers to Endian.h --- Framework/Core/src/TableTreeHelpers.cxx | 48 ------------------ .../Foundation/include/Framework/Endian.h | 49 +++++++++++++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index 14e4a43ea6cba..ebddcf300461a 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -128,54 +128,6 @@ BranchToColumn::BranchToColumn(TBranch* branch, bool VLA, std::string name, EDat } } -template -inline T doSwap(T) -{ - static_assert(always_static_assert_v, "Unsupported type"); -} - -template <> -inline uint16_t doSwap(uint16_t x) -{ - return swap16_(x); -} - -template <> -inline uint32_t doSwap(uint32_t x) -{ - return swap32_(x); -} - -template <> -inline uint64_t doSwap(uint64_t x) -{ - return swap64_(x); -} - -template -void doSwapCopy_(void* dest, void* source, int size) noexcept -{ - auto tdest = static_cast(dest); - auto tsrc = static_cast(source); - for (auto i = 0; i < size; ++i) { - tdest[i] = doSwap(tsrc[i]); - } -} - -void swapCopy(unsigned char* dest, char* source, int size, int typeSize) noexcept -{ - switch (typeSize) { - case 1: - return (void)std::memcpy(dest, source, size); - case 2: - return doSwapCopy_(dest, source, size); - case 4: - return doSwapCopy_(dest, source, size); - case 8: - return doSwapCopy_(dest, source, size); - } -} - std::pair, std::shared_ptr> BranchToColumn::read(TBuffer* buffer) { auto totalEntries = mBranch->GetEntries(); diff --git a/Framework/Foundation/include/Framework/Endian.h b/Framework/Foundation/include/Framework/Endian.h index 9749eaf084c6f..a8fee915ee340 100644 --- a/Framework/Foundation/include/Framework/Endian.h +++ b/Framework/Foundation/include/Framework/Endian.h @@ -12,6 +12,9 @@ #ifndef O2_FRAMEWORK_ENDIAN_H_ #define O2_FRAMEWORK_ENDIAN_H_ +#include +#include +#include // Lookup file for __BYTE_ORDER #ifdef __APPLE__ #include @@ -29,4 +32,50 @@ #define O2_HOST_BYTE_ORDER __BYTE_ORDER #define O2_BIG_ENDIAN __BIG_ENDIAN #define O2_LITTLE_ENDIAN __LITTLE_ENDIAN + + +template + requires std::same_as +inline uint16_t doSwap(uint16_t x) +{ + return swap16_(x); +} + +template + requires std::same_as +inline uint32_t doSwap(uint32_t x) +{ + return swap32_(x); +} + +template + requires std::same_as +inline uint64_t doSwap(uint64_t x) +{ + return swap64_(x); +} + +template +inline void doSwapCopy_(void* dest, void* source, int size) noexcept +{ + auto tdest = static_cast(dest); + auto tsrc = static_cast(source); + for (auto i = 0; i < size; ++i) { + tdest[i] = doSwap(tsrc[i]); + } +} + +inline void swapCopy(unsigned char* dest, char* source, int size, int typeSize) noexcept +{ + switch (typeSize) { + case 1: + return (void)std::memcpy(dest, source, size); + case 2: + return doSwapCopy_(dest, source, size); + case 4: + return doSwapCopy_(dest, source, size); + case 8: + return doSwapCopy_(dest, source, size); + } +} #endif // O2_FRAMEWORK_ENDIAN_H_ From 6c54a70c5c27dfde5624a4678db8182b5f7736da Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 15 Oct 2024 15:07:12 +0200 Subject: [PATCH 0364/2205] GPU: tpcApplyDebugClusterFilter is applied also during Clusterization --- GPU/GPUTracking/Base/GPUReconstruction.cxx | 2 +- GPU/GPUTracking/Global/GPUChainTracking.cxx | 4 ++ GPU/GPUTracking/Global/GPUChainTracking.h | 1 + .../Global/GPUChainTrackingClusterizer.cxx | 46 +++++++++++++------ .../Global/GPUChainTrackingCompression.cxx | 32 +------------ .../GPUChainTrackingDebugAndProfiling.cxx | 43 +++++++++++++++++ 6 files changed, 82 insertions(+), 46 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index ce71753c81f19..632bf0f331f31 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -300,7 +300,7 @@ int32_t GPUReconstruction::InitPhaseBeforeDevice() if (!(mRecoSteps.stepsGPUMask & RecoStep::TPCMerging) || !param().rec.tpc.mergerReadFromTrackerDirectly) { mProcessingSettings.fullMergerOnGPU = false; } - if (mProcessingSettings.debugLevel > 3 || !mProcessingSettings.fullMergerOnGPU || mProcessingSettings.deterministicGPUReconstruction) { + if (mProcessingSettings.debugLevel > 3 || !IsGPU() || !mProcessingSettings.fullMergerOnGPU || mProcessingSettings.deterministicGPUReconstruction) { mProcessingSettings.delayedOutput = false; } if (!mProcessingSettings.fullMergerOnGPU && (GetRecoStepsGPU() & RecoStep::TPCMerging)) { diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 528c683944ef1..319e57d99fd0e 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -326,6 +326,10 @@ bool GPUChainTracking::ValidateSettings() GPUError("Invalid tpcCompressionGatherMode for compression on CPU"); return false; } + if (GetProcessingSettings().tpcApplyDebugClusterFilter == 1 && (GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding || GetProcessingSettings().delayedOutput || GetProcessingSettings().runMC)) { + GPUError("tpcApplyDebugClusterFilter cannot be used with GPU clusterization or with delayedOutput for GPU or with MC labels"); + return false; + } if (GetRecoSteps() & RecoStep::TRDTracking) { if (GetProcessingSettings().trdTrackModelO2 && (GetProcessingSettings().createO2Output == 0 || param().rec.tpc.nWaysOuter == 0 || (GetMatLUT() == nullptr && !GetProcessingSettings().willProvideO2PropagatorLate))) { GPUError("TRD tracking can only run on O2 TPC tracks if createO2Output is enabled (%d), nWaysOuter is set (%d), and matBudLUT is available (0x%p)", (int32_t)GetProcessingSettings().createO2Output, (int32_t)param().rec.tpc.nWaysOuter, (void*)GetMatLUT()); diff --git a/GPU/GPUTracking/Global/GPUChainTracking.h b/GPU/GPUTracking/Global/GPUChainTracking.h index b222d6180bdf2..11443b52504e2 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.h +++ b/GPU/GPUTracking/Global/GPUChainTracking.h @@ -312,6 +312,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega #endif void RunTPCTrackingMerger_MergeBorderTracks(int8_t withinSlice, int8_t mergeMode, GPUReconstruction::krnlDeviceType deviceType); void RunTPCTrackingMerger_Resolve(int8_t useOrigTrackParam, int8_t mergeAll, GPUReconstruction::krnlDeviceType deviceType); + void RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* clusters, std::function allocator, bool applyClusterCuts); std::atomic_flag mLockAtomicOutputBuffer = ATOMIC_FLAG_INIT; std::mutex mMutexUpdateCalib; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index 79804a7f5ffab..af7cc03369afc 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -617,7 +617,9 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } size_t nClsTotal = 0; - ClusterNativeAccess* tmpNative = mClusterNativeAccess.get(); + ClusterNativeAccess* tmpNativeAccess = mClusterNativeAccess.get(); + ClusterNative* tmpNativeClusters = nullptr; + std::unique_ptr tmpNativeClusterBuffer; // setup MC Labels bool propagateMCLabels = GetProcessingSettings().runMC && processors()->ioPtrs.tpcPackedDigits && processors()->ioPtrs.tpcPackedDigits->tpcDigitsMC; @@ -635,7 +637,13 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (mWaitForFinalInputs) { GPUFatal("Cannot use waitForFinalInput callback without delayed output"); } - AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + if (!GetProcessingSettings().tpcApplyDebugClusterFilter) { + AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + tmpNativeClusters = mInputsHost->mPclusterNativeOutput; + } else { + tmpNativeClusterBuffer = std::make_unique(mInputsHost->mNClusterNative); + tmpNativeClusters = tmpNativeClusterBuffer.get(); + } } GPUTPCLinearLabels mcLinearLabels; @@ -892,7 +900,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) bool anyLaneHasData = false; for (int32_t lane = 0; lane < maxLane; lane++) { uint32_t iSlice = iSliceBase + lane; - std::fill(&tmpNative->nClusters[iSlice][0], &tmpNative->nClusters[iSlice][0] + MAXGLOBALPADROW, 0); + std::fill(&tmpNativeAccess->nClusters[iSlice][0], &tmpNativeAccess->nClusters[iSlice][0] + MAXGLOBALPADROW, 0); if (doGPU) { SynchronizeStream(lane); } @@ -914,9 +922,9 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) GPUMemCpyAlways(RecoStep::TPCClusterFinding, (void*)&mInputsShadow->mPclusterNativeBuffer[nClsTotal], (const void*)&clustererShadow.mPclusterByRow[j * clusterer.mNMaxClusterPerRow], sizeof(mIOPtrs.clustersNative->clustersLinear[0]) * clusterer.mPclusterInRow[j], mRec->NStreams() - 1, -2); } } else if (buildNativeHost) { - GPUMemCpyAlways(RecoStep::TPCClusterFinding, (void*)&mInputsHost->mPclusterNativeOutput[nClsTotal], (const void*)&clustererShadow.mPclusterByRow[j * clusterer.mNMaxClusterPerRow], sizeof(mIOPtrs.clustersNative->clustersLinear[0]) * clusterer.mPclusterInRow[j], mRec->NStreams() - 1, false); + GPUMemCpyAlways(RecoStep::TPCClusterFinding, (void*)&tmpNativeClusters[nClsTotal], (const void*)&clustererShadow.mPclusterByRow[j * clusterer.mNMaxClusterPerRow], sizeof(mIOPtrs.clustersNative->clustersLinear[0]) * clusterer.mPclusterInRow[j], mRec->NStreams() - 1, false); } - tmpNative->nClusters[iSlice][j] += clusterer.mPclusterInRow[j]; + tmpNativeAccess->nClusters[iSlice][j] += clusterer.mPclusterInRow[j]; nClsTotal += clusterer.mPclusterInRow[j]; } if (transferRunning[lane]) { @@ -944,9 +952,9 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } if (buildNativeHost && buildNativeGPU && anyLaneHasData) { if (GetProcessingSettings().delayedOutput) { - mOutputQueue.emplace_back(outputQueueEntry{(void*)((char*)&mInputsHost->mPclusterNativeOutput[nClsFirst] - (char*)&mInputsHost->mPclusterNativeOutput[0]), &mInputsShadow->mPclusterNativeBuffer[nClsFirst], (nClsTotal - nClsFirst) * sizeof(mInputsHost->mPclusterNativeOutput[nClsFirst]), RecoStep::TPCClusterFinding}); + mOutputQueue.emplace_back(outputQueueEntry{(void*)((char*)&tmpNativeClusters[nClsFirst] - (char*)&tmpNativeClusters[0]), &mInputsShadow->mPclusterNativeBuffer[nClsFirst], (nClsTotal - nClsFirst) * sizeof(tmpNativeClusters[0]), RecoStep::TPCClusterFinding}); } else { - GPUMemCpy(RecoStep::TPCClusterFinding, (void*)&mInputsHost->mPclusterNativeOutput[nClsFirst], (const void*)&mInputsShadow->mPclusterNativeBuffer[nClsFirst], (nClsTotal - nClsFirst) * sizeof(mInputsHost->mPclusterNativeOutput[0]), mRec->NStreams() - 1, false); + GPUMemCpy(RecoStep::TPCClusterFinding, (void*)&tmpNativeClusters[nClsFirst], (const void*)&mInputsShadow->mPclusterNativeBuffer[nClsFirst], (nClsTotal - nClsFirst) * sizeof(tmpNativeClusters[0]), mRec->NStreams() - 1, false); } } @@ -1004,16 +1012,26 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (buildNativeHost && buildNativeGPU && GetProcessingSettings().delayedOutput) { mInputsHost->mNClusterNative = mInputsShadow->mNClusterNative = nClsTotal; AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + tmpNativeClusters = mInputsHost->mPclusterNativeOutput; for (uint32_t i = outputQueueStart; i < mOutputQueue.size(); i++) { - mOutputQueue[i].dst = (char*)mInputsHost->mPclusterNativeOutput + (size_t)mOutputQueue[i].dst; + mOutputQueue[i].dst = (char*)tmpNativeClusters + (size_t)mOutputQueue[i].dst; } } if (buildNativeHost) { - tmpNative->clustersLinear = mInputsHost->mPclusterNativeOutput; - tmpNative->clustersMCTruth = mcLabelsConstView; - tmpNative->setOffsetPtrs(); - mIOPtrs.clustersNative = tmpNative; + tmpNativeAccess->clustersLinear = tmpNativeClusters; + tmpNativeAccess->clustersMCTruth = mcLabelsConstView; + tmpNativeAccess->setOffsetPtrs(); + mIOPtrs.clustersNative = tmpNativeAccess; + if (GetProcessingSettings().tpcApplyDebugClusterFilter) { + auto allocator = [this, &tmpNativeClusters](size_t size) { + this->mInputsHost->mNClusterNative = size; + this->AllocateRegisteredMemory(this->mInputsHost->mResourceClusterNativeOutput, this->mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + return (tmpNativeClusters = this->mInputsHost->mPclusterNativeOutput); + }; + RunTPCClusterFilter(tmpNativeAccess, allocator, false); + nClsTotal = tmpNativeAccess->nClustersTotal; + } } if (!mWaitForFinalInputs) { @@ -1037,11 +1055,11 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (buildNativeHost && (GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4)) { for (uint32_t i = 0; i < NSLICES; i++) { for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { - std::sort(&mInputsHost->mPclusterNativeOutput[tmpNative->clusterOffset[i][j]], &mInputsHost->mPclusterNativeOutput[tmpNative->clusterOffset[i][j] + tmpNative->nClusters[i][j]]); + std::sort(&tmpNativeClusters[tmpNativeAccess->clusterOffset[i][j]], &tmpNativeClusters[tmpNativeAccess->clusterOffset[i][j] + tmpNativeAccess->nClusters[i][j]]); } } if (buildNativeGPU) { - GPUMemCpy(RecoStep::TPCClusterFinding, (void*)mInputsShadow->mPclusterNativeBuffer, (const void*)mInputsHost->mPclusterNativeOutput, nClsTotal * sizeof(mInputsHost->mPclusterNativeOutput[0]), -1, true); + GPUMemCpy(RecoStep::TPCClusterFinding, (void*)mInputsShadow->mPclusterNativeBuffer, (const void*)tmpNativeClusters, nClsTotal * sizeof(tmpNativeClusters[0]), -1, true); } } mRec->MemoryScalers()->nTPCHits = nClsTotal; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index f9157355c2b7f..c0679c090c20c 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -21,7 +21,6 @@ #ifdef GPUCA_HAVE_O2HEADERS #include "GPUTPCCFChainContext.h" #include "TPCClusterDecompressor.h" -#include "GPUTPCClusterFilter.h" #endif #include "utils/strtag.h" @@ -227,36 +226,7 @@ int32_t GPUChainTracking::RunTPCDecompression() return 1; } if (GetProcessingSettings().tpcApplyCFCutsAtDecoding) { - GPUTPCClusterFilter clusterFilter(*mClusterNativeAccess); - ClusterNative* outputBuffer; - for (int32_t iPhase = 0; iPhase < 2; iPhase++) { - uint32_t countTotal = 0; - for (uint32_t iSector = 0; iSector < GPUCA_NSLICES; iSector++) { - for (uint32_t iRow = 0; iRow < GPUCA_ROW_COUNT; iRow++) { - uint32_t count = 0; - for (uint32_t k = 0; k < mClusterNativeAccess->nClusters[iSector][iRow]; k++) { - ClusterNative cl = mClusterNativeAccess->clusters[iSector][iRow][k]; - bool keep = cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff; - keep = keep && (cl.sigmaPadPacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || !(cl.getFlags() & ClusterNative::flagSingle) || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime); - keep = keep && (!GetProcessingSettings().tpcApplyDebugClusterFilter || clusterFilter.filter(iSector, iRow, cl)); - count += keep; - countTotal += keep; - if (iPhase) { - outputBuffer[countTotal] = cl; - } - } - if (iPhase) { - mClusterNativeAccess->nClusters[iSector][iRow] = count; - } - } - } - if (iPhase) { - mClusterNativeAccess->clustersLinear = outputBuffer; - mClusterNativeAccess->setOffsetPtrs(); - } else { - outputBuffer = allocatorFinal(countTotal); - } - } + RunTPCClusterFilter(mClusterNativeAccess.get(), allocatorFinal, true); } decompressTimer.Stop(); mIOPtrs.clustersNative = mClusterNativeAccess.get(); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index 82b9bb5ada373..7a4aa73ae13d1 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -18,9 +18,15 @@ #include #include #include + #ifdef GPUCA_TRACKLET_CONSTRUCTOR_DO_PROFILE #include "bitmapfile.h" #endif + +#ifdef GPUCA_HAVE_O2HEADERS +#include "GPUTPCClusterFilter.h" +#endif + #define PROFILE_MAX_SIZE (100 * 1024 * 1024) using namespace GPUCA_NAMESPACE::gpu; @@ -292,3 +298,40 @@ void GPUChainTracking::SanityCheck() } #endif } + +void GPUChainTracking::RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* clusters, std::function allocator, bool applyClusterCuts) +{ + GPUTPCClusterFilter clusterFilter(*clusters); + o2::tpc::ClusterNative* outputBuffer; + for (int32_t iPhase = 0; iPhase < 2; iPhase++) { + uint32_t countTotal = 0; + for (uint32_t iSector = 0; iSector < GPUCA_NSLICES; iSector++) { + for (uint32_t iRow = 0; iRow < GPUCA_ROW_COUNT; iRow++) { + uint32_t count = 0; + for (uint32_t k = 0; k < clusters->nClusters[iSector][iRow]; k++) { + o2::tpc::ClusterNative cl = clusters->clusters[iSector][iRow][k]; + bool keep = true; + if (applyClusterCuts) { + keep = keep && cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff; + keep = keep && (!(cl.getFlags() & o2::tpc::ClusterNative::flagSingle) || ((cl.sigmaPadPacked || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime))); + } + keep = keep && (!GetProcessingSettings().tpcApplyDebugClusterFilter || clusterFilter.filter(iSector, iRow, cl)); + if (iPhase && keep) { + outputBuffer[countTotal] = cl; + } + count += keep; + countTotal += keep; + } + if (iPhase) { + clusters->nClusters[iSector][iRow] = count; + } + } + } + if (iPhase) { + clusters->clustersLinear = outputBuffer; + clusters->setOffsetPtrs(); + } else { + outputBuffer = allocator(countTotal); + } + } +} From 88c1e45b7b3fedd5271fa72be23b8e216a37abf3 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 17 Oct 2024 20:51:40 +0200 Subject: [PATCH 0365/2205] GPU Standalone Benchmark: Apply forceGPUType only if GPU was requested --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 4 ++-- GPU/GPUTracking/Standalone/Benchmark/standalone.cxx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index a879d64b4d9f4..be843b01610e8 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -462,8 +462,8 @@ EndConfig() // Settings for the standalone benchmark BeginConfig(GPUSettingsStandalone, configStandalone) -AddOption(runGPU, bool, true, "", 'g', "Use GPU for processing", message("GPU processing: %s")) -AddOptionSet(runGPU, bool, false, "", 'c', "Use CPU for processing", message("CPU enabled")) +AddOption(runGPU, uint8_t, 1, "", 'g', "Use GPU for processing", message("GPU processing enabled"), set(2)) +AddOptionSet(runGPU, uint8_t, 0, "", 'c', "Use CPU for processing", message("CPU enabled")) AddOption(gpuType, std::string, "AUTO", "", 0, "GPU type (CUDA / HIP / OCL / OCL2) or CPU or AUTO") AddOption(runGPUforce, bool, true, "", 0, "Force usage of the specified GPU device type, no CPU fallback") AddOption(noprompt, bool, true, "", 0, "Do prompt for keypress before exiting") diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index d907de6567826..ad4c20a9d1700 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -268,7 +268,7 @@ int32_t ReadConfiguration(int argc, char** argv) } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) { configStandalone.gpuType = "OCL"; } else { - if (configStandalone.runGPUforce) { + if (configStandalone.runGPU > 1 && configStandalone.runGPUforce) { printf("No GPU backend / device found, running on CPU is disabled due to runGPUforce\n"); return 1; } From 1a25adac30f4ff6c622c3fea6a0248c0df359191 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 17 Oct 2024 20:52:02 +0200 Subject: [PATCH 0366/2205] GPU Standalone: Add GPUCA_BUILD_DEBUG_SANITIZE build option --- GPU/GPUTracking/Standalone/CMakeLists.txt | 5 ++++- GPU/GPUTracking/Standalone/cmake/config.cmake | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Standalone/CMakeLists.txt b/GPU/GPUTracking/Standalone/CMakeLists.txt index f7ff04700418d..fd5f812facf06 100644 --- a/GPU/GPUTracking/Standalone/CMakeLists.txt +++ b/GPU/GPUTracking/Standalone/CMakeLists.txt @@ -49,7 +49,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(GPUCA_BUILD_DEBUG) - set(CMAKE_CXX_FLAGS "-O0 -ggdb") # -fsanitize=address,undefined -fno-sanitize=vptr + set(CMAKE_CXX_FLAGS "-O0 -ggdb") + if (GPUCA_BUILD_DEBUG_SANITIZE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize=vptr") + endif() set(CMAKE_BUILD_TYPE DEBUG) else() set(CMAKE_CXX_FLAGS "-O3 -march=native -ggdb -minline-all-stringops -funroll-loops -fno-stack-protector") diff --git a/GPU/GPUTracking/Standalone/cmake/config.cmake b/GPU/GPUTracking/Standalone/cmake/config.cmake index 2dd5d2e6fd27e..29f908c538af7 100644 --- a/GPU/GPUTracking/Standalone/cmake/config.cmake +++ b/GPU/GPUTracking/Standalone/cmake/config.cmake @@ -29,6 +29,7 @@ set(GPUCA_BUILD_EVENT_DISPLAY_QT 1) set(GPUCA_CONFIG_GL3W 0) set(GPUCA_CONFIG_O2 1) set(GPUCA_BUILD_DEBUG 0) +set(GPUCA_BUILD_DEBUG_SANITIZE 0) set(GPUCA_NO_FAST_MATH 0) #set(GPUCA_CUDA_GCCBIN c++-13) #set(GPUCA_OPENCL_CLANGBIN clang-18) From 8eb3898be2d9fe956dd2b24d32ce43f3679d0917 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 17 Oct 2024 20:52:47 +0200 Subject: [PATCH 0367/2205] GPU Standalone: Don't require literals of the option type in default config option list --- GPU/GPUTracking/utils/qconfig.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/utils/qconfig.cxx b/GPU/GPUTracking/utils/qconfig.cxx index aadd4622a1497..cd6267179c844 100644 --- a/GPU/GPUTracking/utils/qconfig.cxx +++ b/GPU/GPUTracking/utils/qconfig.cxx @@ -170,12 +170,14 @@ struct qConfigType { settings.max = maxval.v; } static inline void qProcessSetting(qConfigSettings& settings, qmessage_t msg) { settings.message = msg.v; } - static inline void qProcessSetting(qConfigSettings& settings, qset_t set) + template + static inline void qProcessSetting(qConfigSettings& settings, qset_t set) { settings.doSet = true; settings.set = set.v; } - static inline void qProcessSetting(qConfigSettings& settings, qdef_t set) + template + static inline void qProcessSetting(qConfigSettings& settings, qdef_t set) { settings.doDefault = true; settings.set = set.v; From 3d639ddaae0cd073f94265319a17eb5d8db06db7 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 17 Oct 2024 21:08:29 +0200 Subject: [PATCH 0368/2205] calculate run 1st orbit only when not available from CCDB --- .../Parameters/src/AggregatedRunInfo.cxx | 109 +++--------------- 1 file changed, 18 insertions(+), 91 deletions(-) diff --git a/DataFormats/Parameters/src/AggregatedRunInfo.cxx b/DataFormats/Parameters/src/AggregatedRunInfo.cxx index 94a658a433e74..22ce362b5d85a 100644 --- a/DataFormats/Parameters/src/AggregatedRunInfo.cxx +++ b/DataFormats/Parameters/src/AggregatedRunInfo.cxx @@ -53,106 +53,33 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(int { auto nOrbitsPerTF = grpecs->getNHBFPerTF(); // calculate SOR/EOR orbits - int64_t orbitSOR = (sorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; - int64_t orbitEOR = (eorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; - // adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0) - orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle - orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; - // temporary map of orbit shifts for runs <=LHC22m (while waiting for complete run list from CTP/Calib/FirstRunOrbit) - std::map mapOrbitShift; - mapOrbitShift[517619] = 109; - mapOrbitShift[517620] = 109; - mapOrbitShift[517623] = 109; - mapOrbitShift[517677] = 127; - mapOrbitShift[517678] = 127; - mapOrbitShift[517679] = 127; - mapOrbitShift[517685] = 127; - mapOrbitShift[517690] = 127; - mapOrbitShift[517693] = 127; - mapOrbitShift[517737] = 127; - mapOrbitShift[517748] = 127; - mapOrbitShift[517751] = 127; - mapOrbitShift[517753] = 127; - mapOrbitShift[517758] = 127; - mapOrbitShift[517767] = 127; - mapOrbitShift[518541] = 40; - mapOrbitShift[518543] = 92; - mapOrbitShift[518546] = 124; - mapOrbitShift[518547] = 47; - mapOrbitShift[519041] = 59; - mapOrbitShift[519043] = 59; - mapOrbitShift[519045] = 59; - mapOrbitShift[519497] = 86; - mapOrbitShift[519498] = 86; - mapOrbitShift[519499] = 86; - mapOrbitShift[519502] = 86; - mapOrbitShift[519503] = 86; - mapOrbitShift[519504] = 86; - mapOrbitShift[519506] = 86; - mapOrbitShift[519507] = 86; - mapOrbitShift[519903] = 62; - mapOrbitShift[519904] = 62; - mapOrbitShift[519905] = 62; - mapOrbitShift[519906] = 62; - mapOrbitShift[520259] = 76; - mapOrbitShift[520294] = 76; - mapOrbitShift[520471] = 46; - mapOrbitShift[520472] = 46; - mapOrbitShift[520473] = 46; - mapOrbitShift[523142] = 127; - mapOrbitShift[523148] = 127; - mapOrbitShift[523182] = 127; - mapOrbitShift[523186] = 127; - mapOrbitShift[523298] = 28; - mapOrbitShift[523306] = 28; - mapOrbitShift[523308] = 28; - mapOrbitShift[523309] = 28; - mapOrbitShift[523397] = 110; - mapOrbitShift[523399] = 110; - mapOrbitShift[523401] = 110; - mapOrbitShift[523441] = 117; - mapOrbitShift[523541] = 103; - mapOrbitShift[523559] = 103; - mapOrbitShift[523669] = 39; - mapOrbitShift[523671] = 39; - mapOrbitShift[523677] = 39; - mapOrbitShift[523728] = 113; - mapOrbitShift[523731] = 113; - mapOrbitShift[523779] = 41; - mapOrbitShift[523783] = 41; - mapOrbitShift[523786] = 41; - mapOrbitShift[523788] = 41; - mapOrbitShift[523789] = 41; - mapOrbitShift[523792] = 41; - mapOrbitShift[523797] = 41; - mapOrbitShift[523821] = 36; - mapOrbitShift[523897] = 38; - if (mapOrbitShift.find(runnumber) != mapOrbitShift.end()) { - orbitSOR += mapOrbitShift[runnumber]; - orbitEOR += mapOrbitShift[runnumber]; - } - + int64_t orbitSOR = -1; if (ctfFirstRunOrbitVec && ctfFirstRunOrbitVec->size() >= 3) { // if we have CTP first run orbit available, we should use it int64_t creation_timeIGNORED = (*ctfFirstRunOrbitVec)[0]; // do not use CTP start of run time! int64_t ctp_run_number = (*ctfFirstRunOrbitVec)[1]; int64_t ctp_orbitSOR = (*ctfFirstRunOrbitVec)[2]; if (creation_timeIGNORED == -1 && ctp_run_number == -1 && ctp_orbitSOR == -1) { - LOGP(warn, "Default dummy CTP/Calib/FirstRunOrbit was provide, ignoring"); - } else if (ctp_run_number == runnumber) { // overwrite orbitSOR - if (ctp_orbitSOR != orbitSOR) { - LOGP(warn, "The calculated orbitSOR {} differs from CTP orbitSOR {}", orbitSOR, ctp_orbitSOR); - // reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc. - // so we need to adjust the SOR timings to be consistent - auto sor_new = (int64_t)((orbitResetMUS + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); - if (sor_new != sorMS) { - LOGP(warn, "Adjusting SOR from {} to {}", sorMS, sor_new); - sorMS = sor_new; - } - } + LOGP(warn, "Default dummy CTP/Calib/FirstRunOrbit was provides, ignoring"); + } else if (ctp_run_number == runnumber) { orbitSOR = ctp_orbitSOR; + auto sor_new = (int64_t)((orbitResetMUS + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.); + if (sor_new != sorMS) { + LOGP(warn, "Adjusting SOR from {} to {}", sorMS, sor_new); + sorMS = sor_new; + } } else { LOGP(error, "AggregatedRunInfo: run number inconsistency found (asked: {} vs CTP found: {}, ignoring", runnumber, ctp_run_number); } } + int64_t orbitEOR = (eorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; + if (runnumber > 523897) { // condition was introduced starting from LHC22o + orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF; + } + if (orbitSOR < 0) { // extract from SOR + orbitSOR = (sorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS; + if (runnumber > 523897) { + orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; + } + } return AggregatedRunInfo{runnumber, sorMS, eorMS, nOrbitsPerTF, orbitResetMUS, orbitSOR, orbitEOR, grpecs}; } From 831cf1fe564eb9270b271a222e7f74ef83b8613e Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 17 Oct 2024 00:11:53 +0200 Subject: [PATCH 0369/2205] Fix ITS L2G matrix generation Account for the difference between ITS chip and epitaxial layer matrices --- .../Align/include/Align/AlignableSensorITS.h | 2 ++ Detectors/Align/include/Align/Controller.h | 1 + Detectors/Align/src/AlignableSensorITS.cxx | 35 +++++++++++++++++++ .../ITS/base/include/ITSBase/GeometryTGeo.h | 2 +- 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Detectors/Align/include/Align/AlignableSensorITS.h b/Detectors/Align/include/Align/AlignableSensorITS.h index 8070869bd8c7b..7769eb6aa22f3 100644 --- a/Detectors/Align/include/Align/AlignableSensorITS.h +++ b/Detectors/Align/include/Align/AlignableSensorITS.h @@ -36,6 +36,8 @@ class AlignableSensorITS final : public AlignableSensor AlignableSensorITS(const char* name, int vid, int iid, Controller* ctr); ~AlignableSensorITS() final = default; void prepareMatrixT2L() final; + void prepareMatrixL2G(bool reco = false) final; + void prepareMatrixL2GIdeal() final; // protected: // diff --git a/Detectors/Align/include/Align/Controller.h b/Detectors/Align/include/Align/Controller.h index abbb051be138a..96ee2e4fcf418 100644 --- a/Detectors/Align/include/Align/Controller.h +++ b/Detectors/Align/include/Align/Controller.h @@ -282,6 +282,7 @@ class Controller final : public TObject int getDebugOutputLevel() const { return mDebugOutputLevel; } void setDebugOutputLevel(int i) { mDebugOutputLevel = i; } void setDebugStream(o2::utils::TreeStreamRedirector* d) { mDBGOut = d; } + o2::utils::TreeStreamRedirector* getDebugStream() { return mDBGOut; } void setTPCParam(const o2::gpu::GPUParam* par) { mTPCParam = par; } const o2::gpu::GPUParam* getTPCParam() const { return mTPCParam; } diff --git a/Detectors/Align/src/AlignableSensorITS.cxx b/Detectors/Align/src/AlignableSensorITS.cxx index d3fe5476ecbbc..b4480a25bc740 100644 --- a/Detectors/Align/src/AlignableSensorITS.cxx +++ b/Detectors/Align/src/AlignableSensorITS.cxx @@ -66,5 +66,40 @@ void AlignableSensorITS::prepareMatrixT2L() setMatrixT2L(t2l); } +void AlignableSensorITS::prepareMatrixL2G(bool reco) +{ + // Note that for ITS2 it is NOT the same as GeometryManager::getMatrix() (i.e. that of the alignable volule) + // since we need the matrix of epitaxial layer and not the whole chip + auto geom = o2::its::GeometryTGeo::Instance(); + const auto* m = geom->extractMatrixSensor(getVolID()); + if (!m) { + LOGP(fatal, "Failed on :GeometryTGeo::extractMatrixSensor({})", getVolID()); + } + reco ? setMatrixL2GReco(*m) : setMatrixL2G(*m); +} + +void AlignableSensorITS::prepareMatrixL2GIdeal() +{ + // Note that for ITS2 it is NOT the same as GeometryManager::getOriginalMatrix (i.e. that of the alignable volule) + // since we need the matrix of epitaxial layer and not the whole chip + auto geom = o2::its::GeometryTGeo::Instance(); + TGeoHMatrix mtmp; + if (!base::GeometryManager::getOriginalMatrix(getSymName(), mtmp)) { // this is chip ideal matrix, not that of the epitaxial layer + LOG(fatal) << "Failed to find ideal L2G matrix for " << getSymName(); + } + // we have to apply to it the difference between the aligner epitaxial layer matrix and that of the chip + const auto* malgSens = geom->extractMatrixSensor(getVolID()); + if (!malgSens) { + LOGP(fatal, "Failed on :GeometryTGeo::extractMatrixSensor({})", getVolID()); + } + const auto* malgChip = geom->getMatrix(getVolID()); + // correct chip original matrix by the difference between aligneg chip and sensor matrices + // Sens_ideal = Chip_ideal * Chip_aligned^-1 * Sens_aligned + auto chAlignInv = malgChip->Inverse(); + chAlignInv.Multiply(*malgSens); + mtmp.Multiply(chAlignInv); + setMatrixL2GIdeal(mtmp); +} + } // namespace align } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/base/include/ITSBase/GeometryTGeo.h b/Detectors/ITSMFT/ITS/base/include/ITSBase/GeometryTGeo.h index 6172a02286abd..fcdc978fa64f0 100644 --- a/Detectors/ITSMFT/ITS/base/include/ITSBase/GeometryTGeo.h +++ b/Detectors/ITSMFT/ITS/base/include/ITSBase/GeometryTGeo.h @@ -338,7 +338,6 @@ class GeometryTGeo : public o2::itsmft::GeometryTGeo TString getMatrixPath(int index) const; - protected: /// Get the transformation matrix of the SENSOR (not necessary the same as the chip) /// for a given chip 'index' by quering the TGeoManager TGeoHMatrix* extractMatrixSensor(int index) const; @@ -349,6 +348,7 @@ class GeometryTGeo : public o2::itsmft::GeometryTGeo // get sensor tracking frame alpha and x void extractSensorXAlpha(int isn, float& x, float& alp); + protected: /// This routine computes the layer number a given the chip index /// \param int index The chip index number, starting from zero. /// \param int indexInLr The chip index inside a layer, starting from zero. From 3abc51fefb91a2ca61020acf678e5acf249cb7db Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 19 Oct 2024 18:32:20 +0200 Subject: [PATCH 0370/2205] Do not init TPC refitter if TPC is not requested --- .../study/src/TrackingStudy.cxx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx index fd90475a4c670..e2ccfd88566fe 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx @@ -143,15 +143,15 @@ void TrackingStudySpec::run(ProcessingContext& pc) o2::globaltracking::RecoContainer recoData; recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions - - mTPCRefitter = std::make_unique(&recoData.inputsTPCclusters->clusterIndex, &mTPCCorrMapsLoader, o2::base::Propagator::Instance()->getNominalBz(), - recoData.getTPCTracksClusterRefs().data(), 0, recoData.clusterShMapTPC.data(), recoData.occupancyMapTPC.data(), - recoData.occupancyMapTPC.size(), nullptr, o2::base::Propagator::Instance()); - mTPCRefitter->setTrackReferenceX(900); // disable propagation after refit by setting reference to value > 500 - mNTPCOccBinLength = mTPCRefitter->getParam()->rec.tpc.occupancyMapTimeBins; - mTBinClOccBef.clear(); - mTBinClOccAft.clear(); - + if (recoData.inputsTPCclusters) { + mTPCRefitter = std::make_unique(&recoData.inputsTPCclusters->clusterIndex, &mTPCCorrMapsLoader, o2::base::Propagator::Instance()->getNominalBz(), + recoData.getTPCTracksClusterRefs().data(), 0, recoData.clusterShMapTPC.data(), recoData.occupancyMapTPC.data(), + recoData.occupancyMapTPC.size(), nullptr, o2::base::Propagator::Instance()); + mTPCRefitter->setTrackReferenceX(900); // disable propagation after refit by setting reference to value > 500 + mNTPCOccBinLength = mTPCRefitter->getParam()->rec.tpc.occupancyMapTimeBins; + mTBinClOccBef.clear(); + mTBinClOccAft.clear(); + } // prepare TPC occupancy data if (mNTPCOccBinLength > 1 && recoData.occupancyMapTPC.size()) { mNTPCOccBinLengthInv = 1. / mNTPCOccBinLength; From 050a0723641796e357745bed41b983f19ca840f6 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:37:35 +0200 Subject: [PATCH 0371/2205] DPL: use constraint rather than static_assert --- Framework/Core/include/Framework/DataAllocator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/DataAllocator.h b/Framework/Core/include/Framework/DataAllocator.h index d746031ad58c5..0f1030c44ca86 100644 --- a/Framework/Core/include/Framework/DataAllocator.h +++ b/Framework/Core/include/Framework/DataAllocator.h @@ -144,8 +144,8 @@ class DataAllocator using DataDescription = o2::header::DataDescription; using SubSpecificationType = o2::header::DataHeader::SubSpecificationType; template + requires std::is_fundamental_v struct UninitializedVector { - static_assert(std::is_fundamental::value, "UninitializedVector only allowed for fundamental types"); using value_type = T; }; From 183a577c42b13ac2dc9e5d266c4e86cd5b3cedad Mon Sep 17 00:00:00 2001 From: rmunzer <97919772+rmunzer@users.noreply.github.com> Date: Sun, 20 Oct 2024 23:36:52 +0200 Subject: [PATCH 0372/2205] Add default option for zdc_digits_reco (#13607) * Add default option for zdc_digits_reco * Add SYNCRAWMODE as condition for ZDC default parameters * Update dpl-workflow.sh - fix newlines --------- Co-authored-by: David Rohr --- prodtests/full-system-test/dpl-workflow.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/prodtests/full-system-test/dpl-workflow.sh b/prodtests/full-system-test/dpl-workflow.sh index de812ecbf6ca0..4811c0970131c 100755 --- a/prodtests/full-system-test/dpl-workflow.sh +++ b/prodtests/full-system-test/dpl-workflow.sh @@ -351,6 +351,7 @@ if has_processing_step MUON_SYNC_RECO; then fi [[ $RUNTYPE == "COSMICS" ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow:-} ]] && CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow="MFTTracking.FullClusterScan=true" fi +[[ $SYNCRAWMODE == 1 ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_zdc_digits_reco:-} ]] && CONFIG_EXTRA_PROCESS_o2_zdc_digits_reco='RecoParamZDC.tdc_calib[9]=1;RecoParamZDC.tdc_calib[0]=1;RecoParamZDC.tdc_calib[8]=1;RecoParamZDC.tdc_calib[1]=1;RecoParamZDC.tdc_calib[3]=1;RecoParamZDC.tdc_calib[6]=1;RecoParamZDC.tdc_calib[5]=1;RecoParamZDC.tdc_calib[4]=1;RecoParamZDC.tdc_calib[2]=1;RecoParamZDC.tdc_calib[7]=1;RecoParamZDC.energy_calib[13]=1;RecoParamZDC.energy_calib[12]=1;RecoParamZDC.energy_calib[11]=1;RecoParamZDC.energy_calib[6]=1;RecoParamZDC.energy_calib[25]=1;RecoParamZDC.energy_calib[14]=1;RecoParamZDC.energy_calib[20]=1;RecoParamZDC.energy_calib[5]=1;RecoParamZDC.energy_calib[0]=1;RecoParamZDC.energy_calib[19]=1;RecoParamZDC.tower_calib[1]=1;RecoParamZDC.tower_calib[2]=1;RecoParamZDC.tower_calib[3]=1;RecoParamZDC.tower_calib[4]=1;RecoParamZDC.tower_calib[24]=1;RecoParamZDC.tower_calib[21]=1;RecoParamZDC.tower_calib[22]=1;RecoParamZDC.tower_calib[23]=1;RecoParamZDC.tower_calib[18]=1;RecoParamZDC.tower_calib[16]=1;RecoParamZDC.tower_calib[17]=1;RecoParamZDC.tower_calib[15]=1;RecoParamZDC.tower_calib[8]=1;RecoParamZDC.tower_calib[9]=1;RecoParamZDC.tower_calib[7]=1;RecoParamZDC.tower_calib[10]=1' [[ $RUNTYPE != "COSMICS" ]] && [[ $RUNTYPE != "TECHNICAL" ]] && has_detectors_reco ITS && has_detector_matching PRIMVTX && [[ ! -z "$VERTEXING_SOURCES" ]] && EVE_CONFIG+=" --primary-vertex-mode" [[ $SYNCRAWMODE == 1 ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_trd_global_tracking:-} ]] && CONFIG_EXTRA_PROCESS_o2_trd_global_tracking='GPU_rec_trd.maxChi2=25;GPU_rec_trd.penaltyChi2=20;GPU_rec_trd.extraRoadY=4;GPU_rec_trd.extraRoadZ=10;GPU_rec_trd.applyDeflectionCut=0;GPU_rec_trd.trkltResRPhiIdeal=1' [[ $SYNCRAWMODE == 1 ]] && [[ -z ${ARGS_EXTRA_PROCESS_o2_phos_reco_workflow:-} ]] && ARGS_EXTRA_PROCESS_o2_phos_reco_workflow='--presamples 2 --fitmethod semigaus' From 64eb540737cbbc872cd84999e0cf599ed690a070 Mon Sep 17 00:00:00 2001 From: Chiara Zampolli Date: Mon, 21 Oct 2024 11:24:27 +0200 Subject: [PATCH 0373/2205] Adding plots vs TPC occupancy (#13552) * Adding plots vs TPC occupancy * Different histos in case of pp or PbPb (waiting for a feature in QC) and sampling * Changes to run outside the QC framework * bins in mult are now configurable * adding cut on DCA and cosPA * Preventing tracks without ITS to be used --- Detectors/GLOQC/CMakeLists.txt | 4 +- .../include/GLOQC/ITSTPCMatchingQCParams.h | 9 + Detectors/GLOQC/include/GLOQC/MatchITSTPCQC.h | 55 ++++- Detectors/GLOQC/src/MatchITSTPCQC.cxx | 210 ++++++++++++++++-- .../qc/src/ITSTPCMatchingQCSpec.cxx | 14 +- GPU/GPUTracking/CMakeLists.txt | 1 + 6 files changed, 262 insertions(+), 31 deletions(-) diff --git a/Detectors/GLOQC/CMakeLists.txt b/Detectors/GLOQC/CMakeLists.txt index cdb307a6515c8..9d2db85460b69 100644 --- a/Detectors/GLOQC/CMakeLists.txt +++ b/Detectors/GLOQC/CMakeLists.txt @@ -15,7 +15,9 @@ o2_add_library(GLOQC SOURCES src/MatchITSTPCQC.cxx src/ITSTPCMatchingQCParams.cxx - PUBLIC_LINK_LIBRARIES O2::DetectorsVertexing) + PUBLIC_LINK_LIBRARIES O2::DetectorsVertexing + PRIVATE_LINK_LIBRARIES O2::GPUO2Interface + O2::GPUTracking) o2_target_root_dictionary(GLOQC HEADERS include/GLOQC/MatchITSTPCQC.h diff --git a/Detectors/GLOQC/include/GLOQC/ITSTPCMatchingQCParams.h b/Detectors/GLOQC/include/GLOQC/ITSTPCMatchingQCParams.h index 799f9c526bec6..6bd88a9be64c0 100644 --- a/Detectors/GLOQC/include/GLOQC/ITSTPCMatchingQCParams.h +++ b/Detectors/GLOQC/include/GLOQC/ITSTPCMatchingQCParams.h @@ -39,6 +39,15 @@ struct ITSTPCMatchingQCParams : public o2::conf::ConfigurableParamHelper #include #include +#include #include #include #include "DataFormatsGlobalTracking/RecoContainer.h" @@ -28,6 +29,11 @@ #include "Steer/MCKinematicsReader.h" #include "ReconstructionDataFormats/PID.h" #include "DCAFitter/DCAFitterN.h" +#include "GPUO2InterfaceConfiguration.h" +// #include "GPUSettingsO2.h" +#include "GPUParam.h" +#include "GPUParam.inc" + #include #include #include @@ -63,7 +69,7 @@ class MatchITSTPCQC void setDataRequest(const std::shared_ptr& dr) { mDataRequest = dr; } void finalize(); void reset(); - bool processV0(int iv, o2::globaltracking::RecoContainer& recoData); + bool processV0(int iv, o2::globaltracking::RecoContainer& recoData, std::vector& mTBinClOcc, float pvTime); bool refitV0(const o2::dataformats::V0Index& id, o2::dataformats::V0& v0, o2::globaltracking::RecoContainer& recoData); TH1D* getHistoPtNum(matchType m) const { return mPtNum[m]; } @@ -130,7 +136,8 @@ class MatchITSTPCQC TH1D* getHisto1OverPtPhysPrimDen(matchType m) const { return m1OverPtPhysPrimDen[m]; } TEfficiency* getFractionITSTPCmatchPhysPrim1OverPt(matchType m) const { return mFractionITSTPCmatchPhysPrim1OverPt[m]; } - TH2F* getHistoK0MassVsPt() const { return mK0MassVsPt; } + TH3F* getHistoK0MassVsPtVsOccpp() const { return mK0MassVsPtVsOccpp; } + TH3F* getHistoK0MassVsPtVsOccPbPb() const { return mK0MassVsPtVsOccPbPb; } void getHistos(TObjArray& objar); @@ -228,7 +235,8 @@ class MatchITSTPCQC publisher->startPublishing(mDCArVsPtDen); publisher->startPublishing(mFractionITSTPCmatchDCArVsPt); if (mDoK0QC) { - publisher->startPublishing(mK0MassVsPt); + publisher->startPublishing(mK0MassVsPtVsOccpp); + publisher->startPublishing(mK0MassVsPtVsOccPbPb); } } @@ -269,6 +277,18 @@ class MatchITSTPCQC void setMaxK0Eta(float v) { mMaxEtaK0 = v; } void setRefitK0(bool v) { mRefit = v; } void setCutK0Mass(float v) { mCutK0Mass = v; } + void setMinTPCOccpp(float v) { mMinTPCOccpp = v; } + void setMaxTPCOccpp(float v) { mMaxTPCOccpp = v; } + void setNBinsTPCOccpp(int v) { mNBinsTPCOccpp = v; } + void setMinTPCOccPbPb(float v) { mMinTPCOccPbPb = v; } + void setMaxTPCOccPbPb(float v) { mMaxTPCOccPbPb = v; } + void setNBinsTPCOccPbPb(int v) { mNBinsTPCOccPbPb = v; } + void setK0Scaling(float v) { mK0Scaling = v; } + float getK0Scaling() const { return mK0Scaling; } + void setK0MaxDCA(float v) { mK0MaxDCA = v; } + float getK0MaxDCA() { return mK0MaxDCA; } + void setK0MinCosPA(float v) { mK0MinCosPA = v; } + float getK0MinCosPA() const { return mK0MinCosPA; } void printParams() { @@ -286,6 +306,12 @@ class MatchITSTPCQC LOG(info) << "etaCut = " << mEtaCut; LOG(info) << "cutK0Mass = " << mCutK0Mass; LOG(info) << "maxEtaK0 = " << mMaxEtaK0; + LOG(info) << "minTPCOccpp = " << mMinTPCOccpp; + LOG(info) << "maxTPCOccpp = " << mMaxTPCOccpp; + LOG(info) << "nBinsTPCOccpp = " << mNBinsTPCOccpp; + LOG(info) << "minTPCOccPbPb = " << mMinTPCOccPbPb; + LOG(info) << "maxTPCOccPbPb = " << mMaxTPCOccPbPb; + LOG(info) << "nBinsTPCOccPbPb = " << mNBinsTPCOccPbPb; } private: @@ -408,12 +434,33 @@ class MatchITSTPCQC // for V0s o2::vertexing::DCAFitterN<2> mFitterV0; - TH2F* mK0MassVsPt = nullptr; + TH3F* mK0MassVsPtVsOccpp = nullptr; + TH3F* mK0MassVsPtVsOccPbPb = nullptr; bool mDoK0QC = false; // whether to fill the K0 QC plot(s) float mCutK0Mass = 0.05; // cut on the difference between the K0 mass and the PDG mass bool mRefit = false; // whether to refit or not float mMaxEtaK0 = 0.8; // cut on the K0 eta long int mTimestamp = -1; // timestamp used to load the SVertexParam object: if differnt from -1, we don't load (it means we already did it) + std::unique_ptr mConfig; + std::unique_ptr mConfParam; + // std::unique_ptr mParam; + std::shared_ptr mParam = nullptr; + int mNHBPerTF = 0; + int mNTPCOccBinLength = 0; ///< TPC occ. histo bin length in TBs + float mNTPCOccBinLengthInv; + std::vector mTBinClOcc; ///< TPC occupancy histo: i-th entry is the integrated occupancy for ~1 orbit starting from the TB = i*mNTPCOccBinLength + gsl::span mTPCRefitterOccMap; ///< externally set TPC clusters occupancy map + bool mIsHI = false; + float mK0Scaling = 1.f; // permill that we want to keep of K0S + uint64_t mNK0 = 0; // number of found V0s + float mMinTPCOccpp = 0.f; // min TPC occupancy for K0s plot for pp collisions + float mMaxTPCOccpp = 1.e6; // max TPC occupancy for K0s plot for pp collisions + int mNBinsTPCOccpp = 6; // number of bins in TPC occupancy for K0s plot for pp collisions + float mMinTPCOccPbPb = 0.f; // min TPC occupancy for K0s plot for PbPb collisions + float mMaxTPCOccPbPb = 8.e6; // max TPC occupancy for K0s plot for PbPb collisions + int mNBinsTPCOccPbPb = 8; // number of bins in TPC occupancy for K0s plot for PbPb collisions + float mK0MaxDCA = 0.01; // max DCA to select the K0 + float mK0MinCosPA = 0.995; // min cosPA to select the K0 ClassDefNV(MatchITSTPCQC, 3); }; diff --git a/Detectors/GLOQC/src/MatchITSTPCQC.cxx b/Detectors/GLOQC/src/MatchITSTPCQC.cxx index a0ae896105d2d..56462344850d6 100644 --- a/Detectors/GLOQC/src/MatchITSTPCQC.cxx +++ b/Detectors/GLOQC/src/MatchITSTPCQC.cxx @@ -26,10 +26,17 @@ #include "DetectorsVertexing/SVertexerParams.h" #include "Framework/InputRecord.h" #include "Framework/TimingInfo.h" +#include "GPUO2InterfaceUtils.h" +#include "CommonConstants/LHCConstants.h" +#include "DataFormatsTPC/Constants.h" +#include "DetectorsCommonDataFormats/DetID.h" + +#include "GPUO2InterfaceRefit.h" using namespace o2::gloqc; using namespace o2::mcutils; using MCTrack = o2::MCTrackT; +using DetID = o2::detectors::DetID; MatchITSTPCQC::~MatchITSTPCQC() { @@ -42,6 +49,7 @@ MatchITSTPCQC::~MatchITSTPCQC() void MatchITSTPCQC::deleteHistograms() { + LOG(debug) << "Deleting histos..."; for (int i = 0; i < matchType::SIZE; ++i) { // Pt delete mPtNum[i]; @@ -124,7 +132,8 @@ void MatchITSTPCQC::deleteHistograms() delete mFractionITSTPCmatchDCArVsPt; // K0 - delete mK0MassVsPt; + delete mK0MassVsPtVsOccpp; + delete mK0MassVsPtVsOccPbPb; } //__________________________________________________________ @@ -205,7 +214,8 @@ void MatchITSTPCQC::reset() // K0 if (mDoK0QC) { - mK0MassVsPt->Reset(); + mK0MassVsPtVsOccpp->Reset(); + mK0MassVsPtVsOccPbPb->Reset(); } } @@ -375,14 +385,61 @@ bool MatchITSTPCQC::init() } } + // log binning for pT for K0s + const Int_t nbinsPtK0 = 10; + const Double_t xminPtK0 = 0.01; + const Double_t xmaxPtK0 = 20; + Double_t* xbinsPtK0 = new Double_t[nbinsPtK0 + 1]; + Double_t xlogminPtK0 = TMath::Log10(xminPtK0); + Double_t xlogmaxPtK0 = TMath::Log10(xmaxPtK0); + Double_t dlogxPtK0 = (xlogmaxPtK0 - xlogminPtK0) / nbinsPtK0; + for (int i = 0; i <= nbinsPtK0; i++) { + Double_t xlogPtK0 = xlogminPtK0 + i * dlogxPtK0; + xbinsPtK0[i] = TMath::Exp(TMath::Log(10) * xlogPtK0); + } + // the other bins + const Int_t nbinsMassK0 = 100; + Double_t* ybinsMassK0 = new Double_t[nbinsMassK0 + 1]; + Double_t yminMassK0 = 0.4; + Double_t ymaxMassK0 = 0.6; + Double_t dyMassK0 = (ymaxMassK0 - yminMassK0) / nbinsMassK0; + for (int i = 0; i <= nbinsMassK0; i++) { + ybinsMassK0[i] = yminMassK0 + i * dyMassK0; + } + const Int_t nbinsMultK0pp = mNBinsTPCOccpp; + Double_t* zbinsMultK0pp = new Double_t[nbinsMultK0pp + 1]; + Double_t zminMultK0pp = mMinTPCOccpp; + Double_t zmaxMultK0pp = mMaxTPCOccpp; + Double_t dzMultK0pp = (zmaxMultK0pp - zminMultK0pp) / nbinsMultK0pp; + for (int i = 0; i <= nbinsMultK0pp; i++) { + zbinsMultK0pp[i] = zminMultK0pp + i * dzMultK0pp; + } + + const Int_t nbinsMultK0PbPb = mNBinsTPCOccPbPb; + Double_t* zbinsMultK0PbPb = new Double_t[nbinsMultK0PbPb + 1]; + Double_t zminMultK0PbPb = mMinTPCOccPbPb; + Double_t zmaxMultK0PbPb = mMaxTPCOccPbPb; + Double_t dzMultK0PbPb = (zmaxMultK0PbPb - zminMultK0PbPb) / nbinsMultK0PbPb; + for (int i = 0; i <= nbinsMultK0PbPb; i++) { + zbinsMultK0PbPb[i] = zminMultK0PbPb + i * dzMultK0PbPb; + } + if (mDoK0QC) { // V0s - mK0MassVsPt = new TH2F("mK0MassVsPt", "K0 invariant mass vs Pt; Pt [GeV/c]; K0s mass [GeV/c^2]", 100, 0.f, 20.f, 100, 0.3, 0.7); + mK0MassVsPtVsOccpp = new TH3F("mK0MassVsPtVsOccpp", "K0 invariant mass vs Pt vs TPC occupancy; Pt [GeV/c]; K0s mass [GeV/c^2]; TPC occ.", nbinsPtK0, xbinsPtK0, nbinsMassK0, ybinsMassK0, nbinsMultK0pp, zbinsMultK0pp); + + mK0MassVsPtVsOccPbPb = new TH3F("mK0MassVsPtVsOccPbPb", "K0 invariant mass vs Pt vs TPC occupancy; Pt [GeV/c]; K0s mass [GeV/c^2]; TPC occ", nbinsPtK0, xbinsPtK0, nbinsMassK0, ybinsMassK0, nbinsMultK0PbPb, zbinsMultK0PbPb); } LOG(info) << "Printing configuration cuts"; printParams(); + delete[] xbinsPt; + delete[] xbinsPtK0; + delete[] ybinsMassK0; + delete[] zbinsMultK0pp; + delete[] zbinsMultK0PbPb; + return true; } @@ -404,6 +461,7 @@ void MatchITSTPCQC::initDataRequest() if (mDoK0QC) { mDataRequest->requestPrimaryVertices(mUseMC); mDataRequest->requestSecondaryVertices(mUseMC); + mDataRequest->requestTPCClusters(false); } } @@ -420,6 +478,13 @@ void MatchITSTPCQC::run(o2::framework::ProcessingContext& ctx) // we have not yet initialized the SVertexer params; let's do it ctx.inputs().get("SVParam"); mTimestamp = ctx.services().get().creation; + auto grplhcif = o2::base::GRPGeomHelper::instance().getGRPLHCIF(); + if (grplhcif->getBeamZ(0) != 1 || grplhcif->getBeamZ(1) != 1) { + LOG(info) << "We are in Heavy Ion: Z for beam 0 = " << grplhcif->getBeamZ(0) << " ; Z for beam 1 = " << grplhcif->getBeamZ(1); + mIsHI = true; + } else { + LOG(info) << "We are not in Heavy Ion: Z for beam 0 = " << grplhcif->getBeamZ(0) << " ; Z for beam 1 = " << grplhcif->getBeamZ(1); + } } static int evCount = 0; @@ -428,9 +493,9 @@ void MatchITSTPCQC::run(o2::framework::ProcessingContext& ctx) mITSTracks = mRecoCont.getITSTracks(); mITSTPCTracks = mRecoCont.getTPCITSTracks(); - LOG(debug) << "****** Number of found ITSTPC tracks = " << mITSTPCTracks.size(); - LOG(debug) << "****** Number of found TPC tracks = " << mTPCTracks.size(); - LOG(debug) << "****** Number of found ITS tracks = " << mITSTracks.size(); + LOG(info) << "****** Number of found ITSTPC tracks = " << mITSTPCTracks.size(); + LOG(info) << "****** Number of found TPC tracks = " << mTPCTracks.size(); + LOG(info) << "****** Number of found ITS tracks = " << mITSTracks.size(); // cache selection for TPC and ITS tracks std::vector isTPCTrackSelectedEntry(mTPCTracks.size(), false); @@ -532,7 +597,7 @@ void MatchITSTPCQC::run(o2::framework::ProcessingContext& ctx) } } } - LOG(info) << "number of entries in map for nominator (without duplicates) = " << mMapLabels.size(); + LOG(debug) << "number of entries in map for nominator (without duplicates) = " << mMapLabels.size(); // now we use only the tracks in the map to fill the histograms (--> tracks have passed the // track selection and there are no duplicated tracks wrt the same MC label) for (int i = 0; i < matchType::SIZE; ++i) { @@ -786,8 +851,8 @@ void MatchITSTPCQC::run(o2::framework::ProcessingContext& ctx) } } } - LOG(info) << "number of entries in map for denominator of TPC tracks (without duplicates) = " << mMapRefLabels[matchType::TPC].size() + mMapLabels[matchType::TPC].size(); - LOG(info) << "number of entries in map for denominator of ITS tracks (without duplicates) = " << mMapRefLabels[matchType::ITS].size() + mMapLabels[matchType::ITS].size(); + LOG(debug) << "number of entries in map for denominator of TPC tracks (without duplicates) = " << mMapRefLabels[matchType::TPC].size() + mMapLabels[matchType::TPC].size(); + LOG(debug) << "number of entries in map for denominator of ITS tracks (without duplicates) = " << mMapRefLabels[matchType::ITS].size() + mMapLabels[matchType::ITS].size(); // now we use only the tracks in the map to fill the histograms (--> tracks have passed the // track selection and there are no duplicated tracks wrt the same MC label) for (auto const& el : mMapRefLabels[matchType::TPC]) { @@ -895,45 +960,117 @@ void MatchITSTPCQC::run(o2::framework::ProcessingContext& ctx) } } - if (mDoK0QC) { + if (mDoK0QC && mRecoCont.getPrimaryVertices().size() > 0) { // now doing K0S const auto pvertices = mRecoCont.getPrimaryVertices(); - LOG(info) << "Found " << pvertices.size() << " primary vertices"; + LOG(info) << "****** Number of PVs = " << pvertices.size(); + + // getting occupancy estimator + mNHBPerTF = o2::base::GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); + if (!mParam) { + // for occupancy estimator + mParam = o2::gpu::GPUO2InterfaceUtils::getFullParamShared(0.f, mNHBPerTF); + } + size_t occupancyMapSizeBytes = o2::gpu::GPUO2InterfaceRefit::fillOccupancyMapGetSize(mNHBPerTF, mParam.get()); + LOG(debug) << "occupancyMapSizeBytes = " << occupancyMapSizeBytes; + mTPCRefitterOccMap = mRecoCont.occupancyMapTPC; + o2::gpu::GPUO2InterfaceUtils::paramUseExternalOccupancyMap(mParam.get(), mNHBPerTF, mTPCRefitterOccMap.data(), occupancyMapSizeBytes); + + std::vector mTBinClOcc; ///< TPC occupancy histo: i-th entry is the integrated occupancy for ~1 orbit starting from the TB = i * mNTPCOccBinLength + mTBinClOcc.clear(); + int mNTPCOccBinLength = mParam->rec.tpc.occupancyMapTimeBins; + LOG(debug) << "mNTPCOccBinLength = " << mNTPCOccBinLength; + mNTPCOccBinLengthInv = 1. / mNTPCOccBinLength; + if (mNTPCOccBinLength > 1 && mTPCRefitterOccMap.size()) { + int nTPCBinsInTF = mNHBPerTF * o2::constants::lhc::LHCMaxBunches / 8; // number of TPC time bins in 1 TF, considering that 1 TPC time bin is 8 bunches + int ninteg = 0; + int nTPCOccBinsInTF = nTPCBinsInTF * mNTPCOccBinLengthInv; // how many occupancy bins in 1 TF; mNTPCOccBinLengthInv is the inverse of the length of an occupancy bin + int sumBins = std::max(1, int(o2::constants::lhc::LHCMaxBunches / 8 * mNTPCOccBinLengthInv)); // we will integrate occupancy at max for this number of bins: the max between 1 and the number of occupancy bins in 1 orbit + LOG(debug) << "number of TPC TB in 1 TF = nTPCBinsInTF = " << nTPCBinsInTF << " ; number of occupancy bins in 1 TF = nTPCOccBinsInTF = " << nTPCOccBinsInTF; + LOG(debug) << "bins to integrate = sumBins = " << sumBins; + mTBinClOcc.resize(nTPCOccBinsInTF); + std::vector mltHistTB(nTPCOccBinsInTF); + float sm = 0., tb = 0.5 * mNTPCOccBinLength; + bool foundNotZero = false; + for (int i = 0; i < nTPCOccBinsInTF; i++) { // for every occupancy bin in the TF + mltHistTB[i] = mParam->GetUnscaledMult(tb); + if (mParam->GetUnscaledMult(tb) != 0) { + LOG(debug) << "i = " << i << " tb = " << tb << " mltHistTB[" << i << "] = " << mltHistTB[i]; + foundNotZero = true; + } + tb += mNTPCOccBinLength; + } + if (!foundNotZero) { + LOG(debug) << "No mult bin was found different from 0!"; + } + foundNotZero = false; + // now we fill the occupancy map; we integrate the sumBins after the current one, but when we are at the last 27 bins of the TF, where we integrate what we have left till the end of the TF; for practical reasons, we start from the end, adding all the time, and then also removing the last bin, when we have enough, so that we always add together sumBins bins (except, as said, for the last part of the TF) + for (int i = nTPCOccBinsInTF; i--;) { + if (mltHistTB[i] != 0) { + foundNotZero = true; + } + LOG(debug) << "i = " << i << " sm before = " << sm; + sm += mltHistTB[i]; + LOG(debug) << "i = " << i << " sm after = " << sm; + if (i + sumBins < nTPCOccBinsInTF) { + LOG(debug) << "i = " << i << " sumBins = " << sumBins << " nTPCOccBinsInTF = " << nTPCOccBinsInTF << " we have to decrease sm by = " << mltHistTB[i + sumBins]; + sm -= mltHistTB[i + sumBins]; + LOG(debug) << "i = " << i << " sm after 2 = " << sm; + } + mTBinClOcc[i] = sm; + LOG(debug) << "i = " << i << " mTBinClOcc[" << i << "] = " << mTBinClOcc[i]; + } + if (!foundNotZero) { + LOG(debug) << "No mult bin was found different from 0! sm = " << sm; + } + } else { + mTBinClOcc.resize(1); + } auto v0IDs = mRecoCont.getV0sIdx(); auto nv0 = v0IDs.size(); if (nv0 > mRecoCont.getV0s().size()) { mRefit = true; } - LOG(info) << "Found " << mRecoCont.getV0s().size() << " V0s in reco container"; - LOG(info) << "Found " << nv0 << " V0s ids"; + LOG(debug) << "Found " << mRecoCont.getV0s().size() << " V0s in reco container"; + LOG(debug) << "Found " << nv0 << " V0s ids"; // associating sec vtxs to prim vtx std::map> pv2sv; static int tfID = 0; for (int iv = 0; iv < nv0; iv++) { const auto v0id = v0IDs[iv]; - pv2sv[v0id.getVertexID()].push_back(iv); + o2::dataformats::GlobalTrackID id0 = v0id.getProngID(0), id1 = v0id.getProngID(1); + if (id0.getSourceDetectorsMask()[DetID::ITS] && id1.getSourceDetectorsMask()[DetID::ITS] && + mRecoCont.isTrackSourceLoaded(id0.getSource()) && mRecoCont.isTrackSourceLoaded(id1.getSource())) { // taking only tracks for which there is the ITS in the track sources + pv2sv[v0id.getVertexID()].push_back(iv); + } else { + LOG(debug) << "Skipping this V0: the track sources do not contain ITS"; + } } int nV0sOk = 0; // processing every sec vtx for each prim vtx + int myCount = 0; for (auto it : pv2sv) { int pvID = it.first; auto& vv = it.second; if (pvID < 0 || vv.size() == 0) { continue; } + const auto& pv = mRecoCont.getPrimaryVertex(pvID); + float pvTime = pv.getTimeStamp().getTimeStamp(); // in \mus for (int iv0 : vv) { - nV0sOk += processV0(iv0, mRecoCont) ? 1 : 0; + nV0sOk += processV0(iv0, mRecoCont, mTBinClOcc, pvTime) ? 1 : 0; } + ++myCount; } - LOG(info) << "Processed " << nV0sOk << " V0s"; + LOG(debug) << "Processed " << nV0sOk << " V0s"; } evCount++; } //__________________________________________________________ -bool MatchITSTPCQC::processV0(int iv, o2::globaltracking::RecoContainer& recoData) +bool MatchITSTPCQC::processV0(int iv, o2::globaltracking::RecoContainer& recoData, std::vector& mTBinClOcc, float pvTime) { o2::dataformats::V0 v0; auto v0s = recoData.getV0s(); @@ -941,6 +1078,13 @@ bool MatchITSTPCQC::processV0(int iv, o2::globaltracking::RecoContainer& recoDat static int tfID = 0; const auto& v0id = v0IDs[iv]; + ++mNK0; + if (mNK0 % int(1 / mK0Scaling) == 0) { + LOG(debug) << "Checking " << mNK0 << "th V0: refitting it, since we keep " << mK0Scaling * 100 << "% of all V0s"; + } else { + LOG(debug) << "Checking " << mNK0 << "th K0: NOT refitting it, but skipping it, since we keep " << mK0Scaling * 100 << "% of all V0s"; + return false; + } if (mRefit && !refitV0(v0id, v0, recoData)) { return false; } @@ -948,17 +1092,34 @@ bool MatchITSTPCQC::processV0(int iv, o2::globaltracking::RecoContainer& recoDat if (mMaxEtaK0 < std::abs(v0sel.getEta())) { return false; } - LOG(info) << "Find K0 with mass " << std::sqrt(v0sel.calcMass2AsK0()); - if (mCutK0Mass > 0 && std::abs(std::sqrt(v0sel.calcMass2AsK0()) - 0.497) > mCutK0Mass) { + + if (mCutK0Mass > 0 && std::abs(std::sqrt(v0sel.calcMass2AsK0()) - 0.497) > mCutK0Mass || v0sel.getDCA() > mK0MaxDCA || v0sel.getCosPA() < mK0MinCosPA) { + if (v0sel.getDCA() > mK0MaxDCA && v0sel.getCosPA() < mK0MinCosPA) { + LOG(debug) << "v0sel.getDCA() = " << v0sel.getDCA() << " max is " << mK0MaxDCA << " returning ... "; + } + if (v0sel.getCosPA() > mK0MinCosPA) { + LOG(debug) << "v0sel.getCosPA() = " << v0sel.getCosPA() << " min is " << mK0MinCosPA << " returning ... "; + } return false; } - mK0MassVsPt->Fill(v0sel.getPt(), std::sqrt(v0sel.calcMass2AsK0())); + // get the corresponding PV + int tb = pvTime / (8 * o2::constants::lhc::LHCBunchSpacingMUS) * mNTPCOccBinLengthInv; // V0 time in TPC time bins + LOG(debug) << "pvTime = " << pvTime << " tb = " << tb; + float mltTPC = tb < 0 ? mTBinClOcc[0] : (tb >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[tb]); + ++mNK0; + LOG(debug) << "Filling K0 histogram with pt = " << v0sel.getPt() << " mass = " << std::sqrt(v0sel.calcMass2AsK0()) << " mult TPC = " << mltTPC; + if (!mIsHI) { + mK0MassVsPtVsOccpp->Fill(v0sel.getPt(), std::sqrt(v0sel.calcMass2AsK0()), mltTPC); + } else { + mK0MassVsPtVsOccPbPb->Fill(v0sel.getPt(), std::sqrt(v0sel.calcMass2AsK0()), mltTPC); + } return true; } //__________________________________________________________ bool MatchITSTPCQC::refitV0(const o2::dataformats::V0Index& id, o2::dataformats::V0& v0, o2::globaltracking::RecoContainer& recoData) { + LOG(debug) << "Refitting V0"; if (!recoData.isTrackSourceLoaded(id.getProngID(0).getSource()) || !recoData.isTrackSourceLoaded(id.getProngID(1).getSource())) { return false; } @@ -1095,9 +1256,9 @@ void MatchITSTPCQC::setEfficiency(TEfficiency* eff, TH1* hnum, TH1* hden, bool i // we need to force to replace the total histogram, otherwise it will compare it to the previous passed one, and it might get an error of inconsistency in the bin contents if constexpr (false) { // checking bool bad{false}; - LOG(info) << "Setting efficiency " << eff->GetName() << " from " << hnum->GetName() << " and " << hden->GetName(); - LOG(info) << "Num " << hnum->GetName() << " " << hnum->GetNbinsX() << " " << hnum->GetNbinsY() << " with " << hnum->GetEntries() << " entries"; - LOG(info) << "Den " << hden->GetName() << " " << hden->GetNbinsX() << " " << hden->GetNbinsY() << " with " << hden->GetEntries() << " entries"; + LOG(debug) << "Setting efficiency " << eff->GetName() << " from " << hnum->GetName() << " and " << hden->GetName(); + LOG(debug) << "Num " << hnum->GetName() << " " << hnum->GetNbinsX() << " " << hnum->GetNbinsY() << " with " << hnum->GetEntries() << " entries"; + LOG(debug) << "Den " << hden->GetName() << " " << hden->GetNbinsX() << " " << hden->GetNbinsY() << " with " << hden->GetEntries() << " entries"; if (hnum->GetDimension() != hden->GetDimension()) { LOGP(warning, "Histograms have different dimensions (num={} to den={})", hnum->GetDimension(), hden->GetDimension()); bad = true; @@ -1228,5 +1389,6 @@ void MatchITSTPCQC::getHistos(TObjArray& objar) objar.Add(mFractionITSTPCmatchDCArVsPt); // V0 - objar.Add(mK0MassVsPt); + objar.Add(mK0MassVsPtVsOccpp); + objar.Add(mK0MassVsPtVsOccPbPb); } diff --git a/Detectors/GlobalTrackingWorkflow/qc/src/ITSTPCMatchingQCSpec.cxx b/Detectors/GlobalTrackingWorkflow/qc/src/ITSTPCMatchingQCSpec.cxx index fad4f9d36fb31..2f9ca99d29a79 100644 --- a/Detectors/GlobalTrackingWorkflow/qc/src/ITSTPCMatchingQCSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/qc/src/ITSTPCMatchingQCSpec.cxx @@ -51,6 +51,15 @@ void ITSTPCMatchingQCDevice::init(InitContext& /*ic*/) mMatchITSTPCQC->setEtaCut(params.etaCut); mMatchITSTPCQC->setCutK0Mass(params.cutK0Mass); mMatchITSTPCQC->setMaxK0Eta(params.maxEtaK0); + mMatchITSTPCQC->setK0Scaling(params.K0Scaling); + mMatchITSTPCQC->setMinTPCOccpp(params.minTPCOccpp); + mMatchITSTPCQC->setMaxTPCOccpp(params.maxTPCOccpp); + mMatchITSTPCQC->setNBinsTPCOccpp(params.nBinsTPCOccpp); + mMatchITSTPCQC->setMinTPCOccPbPb(params.minTPCOccPbPb); + mMatchITSTPCQC->setMaxTPCOccPbPb(params.maxTPCOccPbPb); + mMatchITSTPCQC->setNBinsTPCOccPbPb(params.nBinsTPCOccPbPb); + mMatchITSTPCQC->setK0MaxDCA(params.maxK0DCA); + mMatchITSTPCQC->setK0MinCosPA(params.minK0CosPA); o2::base::GRPGeomHelper::instance().setRequest(mCCDBRequest); if (mUseMC) { mMatchITSTPCQC->setUseMC(mUseMC); @@ -127,10 +136,11 @@ DataProcessorSpec getITSTPCMatchingQCDevice(bool useMC, bool doK0QC, std::string if (doK0QC) { dataRequest->requestPrimaryVertices(useMC); dataRequest->requestSecondaryVertices(useMC); + dataRequest->requestTPCClusters(false); } auto ccdbRequest = std::make_shared(false, // orbitResetTime - false, // GRPECS=true - false, // GRPLHCIF + true, // GRPECS=true + true, // GRPLHCIF true, // GRPMagField false, // askMatLUT o2::base::GRPGeomRequest::None, // geometry diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index c4c891ff229f3..f97e966287d41 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -167,6 +167,7 @@ set(HDRS_INSTALL TRDTracking/GPUTRDTrackletLabels.h TRDTracking/GPUTRDTrackPoint.h TRDTracking/GPUTRDTrackPoint.h + DataTypes/GPUTPCGMPolynomialField.h ) # Sources for O2 and for Standalone if requested in config file From 6dd7f9ded69e944f411a6d5e0c3e926a58edb6e3 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 21 Oct 2024 11:34:58 +0200 Subject: [PATCH 0374/2205] Try to fix CI by adding MIDRaw lib to digitization --- Steer/DigitizerWorkflow/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Steer/DigitizerWorkflow/CMakeLists.txt b/Steer/DigitizerWorkflow/CMakeLists.txt index 78f91144bf854..b4b8bc61ea139 100644 --- a/Steer/DigitizerWorkflow/CMakeLists.txt +++ b/Steer/DigitizerWorkflow/CMakeLists.txt @@ -110,6 +110,7 @@ o2_add_executable(digitizer-workflow O2::MCHDigitFiltering O2::MFTSimulation O2::MIDSimulation + O2::MIDRaw O2::PHOSSimulation O2::CPVSimulation O2::TOFSimulation From 1577c7e0588353ce3aaf12eb96b6b331f53e3b8a Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:52:55 +0200 Subject: [PATCH 0375/2205] DPL Analysis: enable cache without prefetching This give the same results in terms of reduced IOPs, without the problems with the multiple basket branches. It also adds explicitly to the cache all the _size branches. Not yet clear if we need to have ROOT v6.32.06-alice2 as well for this to work correctly. --- Framework/Core/src/TableTreeHelpers.cxx | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index ebddcf300461a..23aa934c2ca8b 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -499,14 +499,22 @@ void TreeToTable::addAllColumns(TTree* tree, std::vector&& names) if (mBranchReaders.empty()) { throw runtime_error("No columns will be read"); } - //tree->SetCacheSize(50000000); - // FIXME: see https://github.com/root-project/root/issues/8962 and enable - // again once fixed. - //tree->SetClusterPrefetch(true); - //for (auto& reader : mBranchReaders) { - // tree->AddBranchToCache(reader->branch()); - //} - //tree->StopCacheLearningPhase(); + // Was affected by https://github.com/root-project/root/issues/8962 + // Re-enabling this seems to cut the number of IOPS in half + tree->SetCacheSize(25000000); + // tree->SetClusterPrefetch(true); + for (auto& reader : mBranchReaders) { + tree->AddBranchToCache(reader->branch()); + if (strncmp(reader->branch()->GetName(), "fIndexArray", strlen("fIndexArray")) == 0) { + std::string sizeBranchName = reader->branch()->GetName(); + sizeBranchName += "_size"; + TBranch* sizeBranch = (TBranch*)tree->GetBranch(sizeBranchName.c_str()); + if (sizeBranch) { + tree->AddBranchToCache(sizeBranch); + } + } + } + tree->StopCacheLearningPhase(); } void TreeToTable::setLabel(const char* label) From 785f144c9181f06dcf86d21c6f088f033fb393c5 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 21 Oct 2024 23:07:59 +0200 Subject: [PATCH 0376/2205] suppress if (ENABLE_UPGRADES) in the CMakefile --- Steer/DigitizerWorkflow/CMakeLists.txt | 58 -------------------------- 1 file changed, 58 deletions(-) diff --git a/Steer/DigitizerWorkflow/CMakeLists.txt b/Steer/DigitizerWorkflow/CMakeLists.txt index b4b8bc61ea139..1b839ba462b63 100644 --- a/Steer/DigitizerWorkflow/CMakeLists.txt +++ b/Steer/DigitizerWorkflow/CMakeLists.txt @@ -9,7 +9,6 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -if (ENABLE_UPGRADES) o2_add_executable(digitizer-workflow COMPONENT_NAME sim SOURCES src/CTPDigitizerSpec.cxx @@ -69,63 +68,6 @@ o2_add_executable(digitizer-workflow $<$:O2::ITS3Simulation> $<$:O2::ITS3Workflow> $<$:O2::ITS3Align>) -else() -o2_add_executable(digitizer-workflow - COMPONENT_NAME sim - SOURCES src/CTPDigitizerSpec.cxx - src/FT0DigitizerSpec.cxx - src/FV0DigitizerSpec.cxx - src/FDDDigitizerSpec.cxx - src/GRPUpdaterSpec.cxx - src/HMPIDDigitizerSpec.cxx - src/ITSMFTDigitizerSpec.cxx - src/MCHDigitizerSpec.cxx - src/MIDDigitizerSpec.cxx - src/PHOSDigitizerSpec.cxx - src/CPVDigitizerSpec.cxx - src/SimReaderSpec.cxx - src/SimpleDigitizerWorkflow.cxx - src/TPCDigitRootWriterSpec.cxx - src/TPCDigitizerSpec.cxx - src/ZDCDigitizerSpec.cxx - src/TOFDigitizerSpec.cxx - PUBLIC_LINK_LIBRARIES O2::Framework - O2::Steer - O2::CommonConstants - O2::EMCALSimulation - O2::EMCALWorkflow - O2::FT0Simulation - O2::FV0Simulation - O2::FDDSimulation - O2::CTPSimulation - O2::CTPWorkflowIO - O2::FDDWorkflow - O2::HMPIDSimulation - O2::ITSMFTSimulation - O2::ITSSimulation - O2::ITSMFTWorkflow - O2::MCHSimulation - O2::MCHMappingImpl4 - O2::MCHIO - O2::MCHDigitFiltering - O2::MFTSimulation - O2::MIDSimulation - O2::MIDRaw - O2::PHOSSimulation - O2::CPVSimulation - O2::TOFSimulation - O2::TOFCalibration - O2::TOFReconstruction - O2::TOFWorkflowIO - O2::TPCSimulation - O2::TRDSimulation - O2::TRDWorkflow - O2::DataFormatsTRD - O2::ZDCSimulation - O2::ZDCWorkflow - O2::DetectorsRaw - ) -endif() o2_add_executable(mctruth-testworkflow From 6a5465269a968243ea7e456d80b16b5434cce2d5 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 21 Oct 2024 20:00:22 +0200 Subject: [PATCH 0377/2205] Optionally extract TPC clusters MC truth resolution --- .../GlobalTrackingStudy/TrackMCStudy.h | 3 +- .../GlobalTrackingStudy/TrackMCStudyConfig.h | 5 + .../GlobalTrackingStudy/TrackMCStudyTypes.h | 69 +++++- .../study/src/GlobalTrackingStudyLinkDef.h | 1 + .../study/src/TrackMCStudy.cxx | 198 ++++++++++++++++-- .../study/src/trackMCStudy-workflow.cxx | 9 +- 6 files changed, 262 insertions(+), 23 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h index f7d402577a18c..5d9c2cfd6d349 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h @@ -15,12 +15,13 @@ #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" #include "ReconstructionDataFormats/GlobalTrackID.h" +#include "TPCCalibration/CorrectionMapsLoader.h" namespace o2::trackstudy { /// create a processor spec -o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus); +o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts); } // namespace o2::trackstudy diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h index 895cb5222deac..c6af627c0f5dd 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h @@ -26,6 +26,11 @@ struct TrackMCStudyConfig : o2::conf::ConfigurableParamHelper clPos{}; + std::array below{}; + std::array above{}; + + int getNExt() const { return below[0] > 1. + above[0] > 1.; } + + float getDY() const { return clPos[1] - getYRef(); } + float getDZ() const { return clPos[2] - getZRef(); } + + float getYRef() const + { + float y = 0; + int n = 0; + if (below[0] > 1.) { + y += below[1]; + n++; + } + if (above[0] > 1.) { + y += above[1]; + n++; + } + return n == 1 ? y : 0.5 * y; + } + + float getZRef() const + { + float z = 0; + int n = 0; + if (below[0] > 1.) { + z += below[2]; + n++; + } + if (above[0] > 1.) { + z += above[2]; + n++; + } + return n == 1 ? z : 0.5 * z; + } + + float getDXMin() const + { + float adxA = 1e9, adxB = 1e9; + if (above[0] > 1.) { + adxA = clPos[0] - above[0]; + } + if (below[0] > 1.) { + adxB = clPos[0] - below[0]; + } + return std::abs(adxA) < std::abs(adxB) ? adxA : adxB; + } + + ClassDefNV(ClResTPC, 1); +}; + struct RecPV { o2::dataformats::PrimaryVertex pv{}; o2::MCEventLabel mcEvLbl{}; diff --git a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h index f4d56b50ec6ec..d6183e48af4da 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h +++ b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h @@ -33,5 +33,6 @@ #pragma link C++ class std::vector < o2::trackstudy::RecPV> + ; #pragma link C++ class o2::trackstudy::MCVertex + ; #pragma link C++ class std::vector < o2::trackstudy::MCVertex> + ; +#pragma link C++ class o2::trackstudy::ClResTPC + ; #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index d39e9bdb13710..cfeabd35f325e 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -51,6 +51,7 @@ #include "GPUParam.h" #include "GPUParam.inc" #include "MathUtils/fit.h" +#include #include #include #include @@ -79,8 +80,12 @@ using timeEst = o2::dataformats::TimeStampWithError; class TrackMCStudy : public Task { public: - TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src) - : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src) {} + TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) + : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src) + { + mTPCCorrMapsLoader.setLumiScaleType(sclOpts.lumiType); + mTPCCorrMapsLoader.setLumiScaleMode(sclOpts.lumiMode); + } ~TrackMCStudy() final = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; @@ -89,6 +94,7 @@ class TrackMCStudy : public Task void process(const o2::globaltracking::RecoContainer& recoData); private: + void processTPCTrackRefs(); void loadTPCOccMap(const o2::globaltracking::RecoContainer& recoData); void fillMCClusterInfo(const o2::globaltracking::RecoContainer& recoData); void prepareITSData(const o2::globaltracking::RecoContainer& recoData); @@ -102,6 +108,7 @@ class TrackMCStudy : public Task gsl::span mCurrMCTracks; TVector3 mCurrMCVertex; o2::tpc::VDriftHelper mTPCVDriftHelper{}; + o2::tpc::CorrectionMapsLoader mTPCCorrMapsLoader{}; std::shared_ptr mDataRequest; std::shared_ptr mGGCCDBRequest; std::unique_ptr mDBGOut; @@ -134,6 +141,8 @@ class TrackMCStudy : public Task }; std::vector> mDecaysMaps; // for every parent particle to watch store its label and entries of 1st/last decay product labels in mDecProdLblPool std::unordered_map mSelMCTracks; + std::unordered_map> mSelTRefIdx; + std::vector mSelTRefs; static constexpr float MaxSnp = 0.9; // max snp of ITS or TPC track at xRef to be matched }; @@ -154,6 +163,7 @@ void TrackMCStudy::init(InitContext& ic) mNCheckDecays++; } mDecaysMaps.resize(mNCheckDecays); + mTPCCorrMapsLoader.init(ic); } void TrackMCStudy::run(ProcessingContext& pc) @@ -175,12 +185,22 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc) { o2::base::GRPGeomHelper::instance().checkUpdates(pc); mTPCVDriftHelper.extractCCDBInputs(pc); + mTPCCorrMapsLoader.extractCCDBInputs(pc); + bool updateMaps = false; + if (mTPCCorrMapsLoader.isUpdated()) { + mTPCCorrMapsLoader.acknowledgeUpdate(); + updateMaps = true; + } if (mTPCVDriftHelper.isUpdated()) { LOGP(info, "Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}", mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift, mTPCVDriftHelper.getVDriftObject().timeOffsetCorr, mTPCVDriftHelper.getVDriftObject().refTimeOffset, mTPCVDriftHelper.getSourceName()); mTPCVDriftHelper.acknowledgeUpdate(); + updateMaps = true; + } + if (updateMaps) { + mTPCCorrMapsLoader.updateVDrift(mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift, mTPCVDriftHelper.getVDriftObject().getTimeOffset()); } static bool initOnceDone = false; if (!initOnceDone) { // this params need to be queried only once @@ -402,6 +422,9 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } // collect ITS/TPC cluster info for selected MC particles + if (params.minTPCRefsToExtractClRes > 0) { + processTPCTrackRefs(); + } fillMCClusterInfo(recoData); LOGP(info, "collected {} MC tracks", mSelMCTracks.size()); @@ -541,16 +564,74 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } } +void TrackMCStudy::processTPCTrackRefs() +{ + constexpr float alpsec[18] = {0.174533, 0.523599, 0.872665, 1.221730, 1.570796, 1.919862, 2.268928, 2.617994, 2.967060, 3.316126, 3.665191, 4.014257, 4.363323, 4.712389, 5.061455, 5.410521, 5.759587, 6.108652}; + constexpr float sinAlp[18] = {0.173648, 0.500000, 0.766044, 0.939693, 1.000000, 0.939693, 0.766044, 0.500000, 0.173648, -0.173648, -0.500000, -0.766044, -0.939693, -1.000000, -0.939693, -0.766044, -0.500000, -0.173648}; + constexpr float cosAlp[18] = {0.984808, 0.866025, 0.642788, 0.342020, 0.000000, -0.342020, -0.642788, -0.866025, -0.984808, -0.984808, -0.866025, -0.642788, -0.342020, -0.000000, 0.342020, 0.642788, 0.866025, 0.984808}; + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + for (auto& entry : mSelMCTracks) { + auto lb = entry.first; + auto trspan = mcReader.getTrackRefs(lb.getSourceID(), lb.getEventID(), lb.getTrackID()); + int q = entry.second.mcTrackInfo.track.getCharge(); + if (q * q != 1) { + continue; + } + int ref0entry = mSelTRefs.size(), nrefsSel = 0; + for (const auto& trf : trspan) { + if (trf.getDetectorId() != 1) { // process TPC only + continue; + } + float pT = std::sqrt(trf.Px() * trf.Px() + trf.Py() * trf.Py()); + if (pT < 0.05) { + continue; + } + float secX, secY, phi = std::atan2(trf.Y(), trf.X()); + int sector = o2::math_utils::angle2Sector(phi); + o2::math_utils::rotateZInv(trf.X(), trf.Y(), secX, secY, sinAlp[sector], cosAlp[sector]); // sector coordinates + float phiPt = std::atan2(trf.Py(), trf.Px()); + o2::math_utils::bringTo02Pi(phiPt); + auto dphiPt = phiPt - alpsec[sector]; + if (dphiPt > o2::constants::math::PI) { // account for wraps + dphiPt -= o2::constants::math::TwoPI; + } else if (dphiPt < -o2::constants::math::PI) { + dphiPt += o2::constants::math::TwoPI; + } else if (std::abs(dphiPt) > o2::constants::math::PIHalf * 0.8) { + continue; // ignore backward going or parallel to padrows tracks + } + float tgL = trf.Pz() / pT; + std::array pars = {secY, trf.Z(), std::sin(dphiPt), tgL, q / pT}; + auto& refTrack = mSelTRefs.emplace_back(secX, alpsec[sector], pars); + refTrack.setUserField(uint16_t(sector)); + nrefsSel++; + } + if (nrefsSel < params.minTPCRefsToExtractClRes) { + mSelTRefs.resize(ref0entry); // discard unused tracks + continue; + } else { + mSelTRefIdx[lb] = std::make_pair(ref0entry, ref0entry + nrefsSel); + } + } +} + void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& recoData) { // TPC clusters info const auto& TPCClusterIdxStruct = recoData.inputsTPCclusters->clusterIndex; const auto* TPCClMClab = recoData.inputsTPCclusters->clusterIndex.clustersMCTruth; - for (int sector = 0; sector < 36; sector++) { - for (int row = 0; row < 152; row++) { + const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + for (uint8_t sector = 0; sector < 36; sector++) { + for (uint8_t row = 0; row < 152; row++) { unsigned int offs = TPCClusterIdxStruct.clusterOffset[sector][row]; for (unsigned int icl0 = 0; icl0 < TPCClusterIdxStruct.nClusters[sector][row]; icl0++) { const auto labels = TPCClMClab->getLabels(icl0 + offs); + int ncontLb = 0; // number of real contrubutors to this label (w/o noise) + for (const auto& lbl : labels) { + if (!lbl.isValid()) { + continue; + } + ncontLb++; + } for (const auto& lbl : labels) { auto entry = mSelMCTracks.find(lbl); if (entry == mSelMCTracks.end()) { // not selected @@ -558,15 +639,90 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re } auto& mctr = entry->second.mcTrackInfo; mctr.nTPCCl++; - if (mctr.maxTPCRow < row) { + if (row > mctr.maxTPCRow) { mctr.maxTPCRow = row; + mctr.maxTPCRowSect = sector; } - if (mctr.minTPCRow > row) { + if (row < mctr.minTPCRow) { mctr.minTPCRow = row; + mctr.minTPCRowSect = sector; } - if (labels.size() > 1) { + if (mctr.minTPCRowSect == sector && row > mctr.maxTPCRowInner) { + mctr.maxTPCRowInner = row; + } + if (ncontLb > 1) { mctr.nTPCClShared++; } + // try to extract ideal track position + if (params.minTPCRefsToExtractClRes > 0) { + auto entTRefIDsIt = mSelTRefIdx.find(lbl); + if (entTRefIDsIt == mSelTRefIdx.end()) { + continue; + } + const auto& entTRefIDs = entTRefIDsIt->second; + // find bracketing TRef params + int entIDBelow = -1, entIDAbove = -1; + float xBelow = -1e6, xAbove = 1e6; + const auto& clus = TPCClusterIdxStruct.clusters[sector][row][icl0]; + float xc, yc, zc; + mTPCCorrMapsLoader.Transform(sector, row, clus.getPad(), clus.getTime(), xc, yc, zc, mctr.bcInTF / 8.); // nominal time of the track + + for (int entID = entTRefIDs.first; entID < entTRefIDs.second; entID++) { + const auto& refTr = mSelTRefs[entID]; + if (refTr.getUserField() != sector % 18) { + continue; + } + if (refTr.getX() < xc && refTr.getX() > xBelow && refTr.getX() > xc - params.maxTPCRefExtrap) { + xBelow = refTr.getX(); + entIDBelow = entID; + } + if (refTr.getX() > xc && refTr.getX() < xAbove && refTr.getX() < xc + params.maxTPCRefExtrap) { + xAbove = refTr.getX(); + entIDAbove = entID; + } + } + if ((entIDBelow < 0 && entIDAbove < 0) || (params.requireTopBottomRefs && (entIDBelow < 0 || entIDAbove < 0))) { + continue; + } + auto prop = o2::base::Propagator::Instance(); + o2::track::TrackPar tparAbove, tparBelow; + bool okBelow = entIDBelow >= 0 && prop->PropagateToXBxByBz((tparBelow = mSelTRefs[entIDBelow]), xc, 0.99, 2.); + bool okAbove = entIDAbove >= 0 && prop->PropagateToXBxByBz((tparAbove = mSelTRefs[entIDAbove]), xc, 0.99, 2.); + if ((!okBelow && !okAbove) || (params.requireTopBottomRefs && (!okBelow || !okAbove)) || (params.rejectClustersResStat > 0. && gRandom->Rndm() < params.rejectClustersResStat)) { + continue; + } + ClResTPC clRes{}; + + int nmeas = 0; + if (okBelow) { + clRes.below = {mSelTRefs[entIDBelow].getX(), tparBelow.getY(), tparBelow.getZ()}; + clRes.snp += tparBelow.getSnp(); + clRes.tgl += tparBelow.getTgl(); + nmeas++; + } + if (okAbove) { + clRes.above = {mSelTRefs[entIDAbove].getX(), tparAbove.getY(), tparAbove.getZ()}; + clRes.snp += tparAbove.getSnp(); + clRes.tgl += tparBelow.getTgl(); + nmeas++; + } + if (nmeas) { + if (nmeas > 1) { + clRes.snp *= 0.5; + clRes.tgl *= 0.5; + } + clRes.clPos = {xc, yc, zc}; + clRes.sect = sector; + clRes.row = row; + clRes.qtot = clus.getQtot(); + clRes.qmax = clus.getQmax(); + clRes.flags = clus.getFlags(); + clRes.ncont = ncontLb; + int occBin = mctr.bcInTF / 8 * mNTPCOccBinLengthInv; + clRes.occ = occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin]); + (*mDBGOut) << "clres" << "clr=" << clRes << "\n"; + } + } } } } @@ -635,6 +791,9 @@ void TrackMCStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) { return; } + if (mTPCCorrMapsLoader.accountCCDBInputs(matcher, obj)) { + return; + } if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) { LOG(info) << "ITS Alpide param updated"; const auto& par = o2::itsmft::DPLAlpideParam::Instance(); @@ -808,10 +967,9 @@ bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& l void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoData) { auto NHBPerTF = o2::base::GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); - o2::tpc::CorrectionMapsLoader TPCCorrMapsLoader{}; const auto& TPCOccMap = recoData.occupancyMapTPC; auto prop = o2::base::Propagator::Instance(); - auto TPCRefitter = std::make_unique(&recoData.inputsTPCclusters->clusterIndex, &TPCCorrMapsLoader, prop->getNominalBz(), + auto TPCRefitter = std::make_unique(&recoData.inputsTPCclusters->clusterIndex, &mTPCCorrMapsLoader, prop->getNominalBz(), recoData.getTPCTracksClusterRefs().data(), 0, recoData.clusterShMapTPC.data(), TPCOccMap.data(), TPCOccMap.size(), nullptr, prop); mNTPCOccBinLength = TPCRefitter->getParam()->rec.tpc.occupancyMapTimeBins; mTBinClOcc.clear(); @@ -838,16 +996,23 @@ void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoDa } } -DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters) +DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) { std::vector outputs; + Options opts{ + {"device-verbosity", VariantType::Int, 0, {"Verbosity level"}}, + {"dcay-vs-pt", VariantType::String, "0.0105 + 0.0350 / pow(x, 1.1)", {"Formula for global tracks DCAy vs pT cut"}}, + {"min-tpc-clusters", VariantType::Int, 60, {"Cut on TPC clusters"}}, + {"max-tpc-dcay", VariantType::Float, 2.f, {"Cut on TPC dcaY"}}, + {"max-tpc-dcaz", VariantType::Float, 2.f, {"Cut on TPC dcaZ"}}, + {"min-x-prop", VariantType::Float, 6.f, {"track should be propagated to this X at least"}}}; auto dataRequest = std::make_shared(); bool useMC = true; dataRequest->requestTracks(srcTracks, useMC); dataRequest->requestClusters(srcClusters, useMC); dataRequest->requestPrimaryVertices(useMC); o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs); - + o2::tpc::CorrectionMapsLoader::requestCCDBInputs(dataRequest->inputs, opts, sclOpts); auto ggRequest = std::make_shared(false, // orbitResetTime true, // GRPECS=true true, // GRPLHCIF @@ -861,15 +1026,8 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask "track-mc-study", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks)}, - Options{ - {"device-verbosity", VariantType::Int, 0, {"Verbosity level"}}, - {"dcay-vs-pt", VariantType::String, "0.0105 + 0.0350 / pow(x, 1.1)", {"Formula for global tracks DCAy vs pT cut"}}, - {"min-tpc-clusters", VariantType::Int, 60, {"Cut on TPC clusters"}}, - {"max-tpc-dcay", VariantType::Float, 2.f, {"Cut on TPC dcaY"}}, - {"max-tpc-dcaz", VariantType::Float, 2.f, {"Cut on TPC dcaZ"}}, - {"min-x-prop", VariantType::Float, 6.f, {"track should be propagated to this X at least"}}, - }}; + AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks, sclOpts)}, + opts}; } } // namespace o2::trackstudy diff --git a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx index 3674fd5f3e3a8..03271000c6203 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx @@ -19,6 +19,8 @@ #include "Framework/CallbacksPolicy.h" #include "DetectorsBase/DPLWorkflowUtils.h" #include "GlobalTrackingWorkflowHelpers/InputHelper.h" +#include "TPCCalibration/CorrectionMapsLoader.h" +#include "TPCWorkflow/TPCScalerSpec.h" #include "DetectorsRaw/HBFUtilsInitializer.h" using namespace o2::framework; @@ -41,6 +43,7 @@ void customize(std::vector& workflowOptions) {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation, never use it"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; + o2::tpc::CorrectionMapsLoader::addGlobalOptions(options); o2::raw::HBFUtilsInitializer::addConfigOption(options); std::swap(workflowOptions, options); } @@ -56,6 +59,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (!useMC) { throw std::runtime_error("MC cannot be disabled for this workflow"); } + auto sclOpt = o2::tpc::CorrectionMapsLoader::parseGlobalOptions(configcontext.options()); GID::mask_t allowedSourcesTrc = GID::getSourcesMask("ITS,TPC,ITS-TPC,TPC-TOF,TPC-TRD,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF"); GID::mask_t allowedSourcesClus = GID::getSourcesMask("ITS,TPC"); @@ -68,8 +72,11 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, true); // P-vertex is always needed - specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls)); + if (sclOpt.needTPCScalersWorkflow() && !configcontext.options().get("disable-root-input")) { + specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt.lumiType == 2, sclOpt.enableMShapeCorrection)); + } + specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, sclOpt)); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); From 60060b0bc490b662f4356caf95c131f2e6732040 Mon Sep 17 00:00:00 2001 From: Maximilian Korwieser Date: Fri, 4 Oct 2024 12:09:56 +0200 Subject: [PATCH 0378/2205] [TPC-QC] Add DCAr selection to Tracks.cxx --- Detectors/TPC/qc/include/TPCQC/Tracks.h | 34 +++++++----------- Detectors/TPC/qc/src/Tracks.cxx | 47 ++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/Detectors/TPC/qc/include/TPCQC/Tracks.h b/Detectors/TPC/qc/include/TPCQC/Tracks.h index 882e7c9222c29..f6cff7c2b8090 100644 --- a/Detectors/TPC/qc/include/TPCQC/Tracks.h +++ b/Detectors/TPC/qc/include/TPCQC/Tracks.h @@ -69,7 +69,7 @@ class Tracks // To set the elementary track cuts void setTrackCuts(float AbsEta = 1., - int nClusterCut = 60, float dEdxTot = 20, float cutPtForDCAr = 1.5, float samplingFractionDCAr = 0.1, bool turnOffHistosForAsync = false) + int nClusterCut = 60, float dEdxTot = 20, float cutPtForDCAr = 1.5, float samplingFractionDCAr = 0.1, bool turnOffHistosForAsync = false, float cutMaxAbsDCAr = 0.1, bool useCutMaxAbsDCArOnHistos = false) { mCutAbsEta = AbsEta; mCutMinnCls = nClusterCut; @@ -77,34 +77,24 @@ class Tracks mCutMinPtDCAr = cutPtForDCAr; mSamplingFractionDCAr = samplingFractionDCAr; mTurnOffHistosForAsync = turnOffHistosForAsync; + mCutMaxAbsDCAr = cutMaxAbsDCAr; + mUseCutMaxAbsDCArOnHistos = useCutMaxAbsDCArOnHistos; } - // Just for backward compatibility with crrent QC, temporary, will be removed in the next PR - /// get 1D histograms - std::vector& getHistograms1D() { return mHist1D; } - const std::vector& getHistograms1D() const { return mHist1D; } - - // Just for backward compatibility with crrent QC, temporary, will be removed in the next PR - /// get 2D histograms - std::vector& getHistograms2D() { return mHist2D; } - const std::vector& getHistograms2D() const { return mHist2D; } - - // Just for backward compatibility with crrent QC, temporary, will be removed in the next PR - /// get ratios of 1D histograms - std::vector& getHistogramRatios1D() { return mHistRatio1D; } - const std::vector& getHistogramRatios1D() const { return mHistRatio1D; } - /// get ratios of 1D histograms std::unordered_map>& getMapHist() { return mMapHist; } const std::unordered_map>& getMapHist() const { return mMapHist; } private: - float mCutAbsEta = 1.f; // Eta cut - int mCutMinnCls = 60; // minimum N clusters - float mCutMindEdxTot = 20.f; // dEdxTot min value - float mCutMinPtDCAr = 1.5f; // minimum pT for DCAr plots DCAr vs. phi, eta, nCluster - float mSamplingFractionDCAr = 0.1f; // sampling rate for calculation of DCAr - bool mTurnOffHistosForAsync = false; // Decide whether to turn off some histograms for async to reduce memory + float mCutAbsEta = 1.f; // Eta cut + int mCutMinnCls = 60; // minimum N clusters + float mCutMindEdxTot = 20.f; // dEdxTot min value + float mCutMinPtDCAr = 1.5f; // minimum pT for DCAr plots DCAr vs. phi, eta, nCluster + float mSamplingFractionDCAr = 0.1f; // sampling rate for calculation of DCAr + bool mTurnOffHistosForAsync = false; // Decide whether to turn off some histograms for async to reduce memory + float mCutMaxAbsDCAr = 1.f; // maximum DCAr + bool mUseCutMaxAbsDCArOnHistos = false; // Decide whether to use the cut on maximum DCAr for the histograms + std::unordered_map> mMapHist; std::vector mHist1D{}; ///< Initialize vector of 1D histograms std::vector mHist2D{}; ///< Initialize vector of 2D histograms diff --git a/Detectors/TPC/qc/src/Tracks.cxx b/Detectors/TPC/qc/src/Tracks.cxx index c42f35bd24644..9f1d9aabf9523 100644 --- a/Detectors/TPC/qc/src/Tracks.cxx +++ b/Detectors/TPC/qc/src/Tracks.cxx @@ -172,6 +172,9 @@ bool Tracks::processTrack(const o2::tpc::TrackTPC& track) sampleProb = randomGenerator.Uniform(1); } + bool isDcaCalculated = false; + float dcaValue = -999; + if (sampleProb > (Double_t)(1. - mSamplingFractionDCAr)) { if (propagator->getMatLUT() && propagator->hasMagFieldSet()) { @@ -190,6 +193,8 @@ bool Tracks::processTrack(const o2::tpc::TrackTPC& track) dcaHistEta_pTmin->Fill(eta, dca[0]); dcaHistNCluster_pTmin->Fill(nCls, dca[0]); } + dcaValue = dca[0]; + isDcaCalculated = true; } } else { static bool reported = false; @@ -207,6 +212,46 @@ bool Tracks::processTrack(const o2::tpc::TrackTPC& track) } } + if (mUseCutMaxAbsDCArOnHistos && !isDcaCalculated) { + // In this case the DCAr selection should be applied but is not available for the track, hence we simply return and report back + // For ease we just report back for every histogram that the propagator was not initialized + static bool reported = false; + if (!reported) { + LOGP(error, "o2::base::Propagator not properly initialized, MatLUT ({}) and / or Field ({}) missing, will not fill apply DCAr selection on histograms", (void*)propagator->getMatLUT(), propagator->hasMagFieldSet()); + mMapHist["hPhiAside"]->SetTitle("hPhiAside o2::base::Propagator not properly initialized"); + mMapHist["hPhiCside"]->SetTitle("hPhiCside o2::base::Propagator not properly initialized"); + mMapHist["hPhiBothSides"]->SetTitle("hPhiBothSides o2::base::Propagator not properly initialized"); + mMapHist["hPt"]->SetTitle("hPt o2::base::Propagator not properly initialized"); + mMapHist["hSign"]->SetTitle("hSign o2::base::Propagator not properly initialized"); + mMapHist["hQOverPt"]->SetTitle("hQOverPt o2::base::Propagator not properly initialized"); + mMapHist["hEtaNeg"]->SetTitle("hEtaNeg o2::base::Propagator not properly initialized"); + mMapHist["hPhiAsideNeg"]->SetTitle("hPhiAsideNeg o2::base::Propagator not properly initialized"); + mMapHist["hPhiCsideNeg"]->SetTitle("hPhiCsideNeg o2::base::Propagator not properly initialized"); + mMapHist["hEtaPos"]->SetTitle("hEtaPos o2::base::Propagator not properly initialized"); + mMapHist["hPtPos"]->SetTitle("hPtPos o2::base::Propagator not properly initialized"); + mMapHist["hPhiAsidePos"]->SetTitle("hPhiAsidePos o2::base::Propagator not properly initialized"); + mMapHist["hPhiCsidePos"]->SetTitle("hPhiCsidePos o2::base::Propagator not properly initialized"); + mMapHist["h2DNClustersEta"]->SetTitle("h2DNClustersEta o2::base::Propagator not properly initialized"); + mMapHist["h2DNClustersPhiAside"]->SetTitle("h2DNClustersPhiAside o2::base::Propagator not properly initialized"); + mMapHist["h2DQOverPtPhiAside"]->SetTitle("h2DQOverPtPhiAside o2::base::Propagator not properly initialized"); + mMapHist["h2DNClustersPhiCside"]->SetTitle("h2DNClustersPhiCside o2::base::Propagator not properly initialized"); + mMapHist["h2DQOverPtPhiCside"]->SetTitle("h2DQOverPtPhiCside o2::base::Propagator not properly initialized"); + mMapHist["h2DNClustersPt"]->SetTitle("h2DNClustersPt o2::base::Propagator not properly initialized"); + mMapHist["h2DEtaPhi"]->SetTitle("h2DEtaPhi o2::base::Propagator not properly initialized"); + mMapHist["h2DEtaPhiNeg"]->SetTitle("h2DEtaPhiNeg o2::base::Propagator not properly initialized"); + mMapHist["hEtaVsPtNeg"]->SetTitle("hEtaVsPtNeg o2::base::Propagator not properly initialized"); + mMapHist["hPhiVsPtNeg"]->SetTitle("hPhiVsPtNeg o2::base::Propagator not properly initialized"); + mMapHist["h2DEtaPhiPos"]->SetTitle("h2DEtaPhiPos o2::base::Propagator not properly initialized"); + mMapHist["hEtaVsPtPos"]->SetTitle("hEtaVsPtPos o2::base::Propagator not properly initialized"); + mMapHist["hPhiVsPtPos"]->SetTitle("hPhiVsPtPos o2::base::Propagator not properly initialized"); + } + return true; + } + + if (mUseCutMaxAbsDCArOnHistos && (std::abs(dcaValue) > mCutMaxAbsDCAr)) { + return true; + } + if (hasASideOnly == 1) { mMapHist["hPhiAside"]->Fill(phi); } else if (hasCSideOnly == 1) { @@ -304,4 +349,4 @@ void Tracks::dumpToFile(std::string_view filename) arr.Write(arr.GetName(), TObject::kSingleKey); } f->Close(); -} +} \ No newline at end of file From 293cffb18423ad1c7a461ddf15f4595aff6e21e7 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 23 Oct 2024 13:32:22 +0200 Subject: [PATCH 0379/2205] Fix IRFrames selection in ITS/MFT digits reader --- .../ITSMFT/common/workflow/src/DigitReaderSpec.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx index fa634c9d6fc5f..5b0a6204ae3e6 100644 --- a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx @@ -136,9 +136,9 @@ void DigitReader::run(ProcessingContext& pc) ent++; } o2::utils::IRFrameSelector irfSel; - irfSel.setSelectedIRFrames(irFrames, 0, 0, mROFBiasInBC, true); - const auto irMin = irFrames.front().getMin(); - const auto irMax = irFrames.back().getMax(); + irfSel.setSelectedIRFrames(irFrames, 0, 0, -mROFBiasInBC, true); + const auto irMin = irfSel.getIRFrames().front().getMin(); // use processed IRframes for rough comparisons (possible shift!) + const auto irMax = irfSel.getIRFrames().back().getMax(); LOGP(info, "Selecting IRFrame {}-{}", irMin.asString(), irMax.asString()); while (ent < mTree->GetEntries()) { // do we need to read a new entry? @@ -159,7 +159,7 @@ void DigitReader::run(ProcessingContext& pc) std::vector rofOld2New; rofOld2New.resize(mDigROFRec.size(), -1); - if (mDigROFRec.front().getBCData() <= irMax && mDigROFRec.back().getBCData() >= irMin) { // there is an overlap + if (mDigROFRec.front().getBCData() <= irMax && (mDigROFRec.back().getBCData() + mROFLengthInBC - 1) >= irMin) { // there is an overlap for (int irof = 0; irof < (int)mDigROFRec.size(); irof++) { const auto& rof = mDigROFRec[irof]; if (irfSel.check({rof.getBCData(), rof.getBCData() + mROFLengthInBC - 1}) != -1) { @@ -198,7 +198,7 @@ void DigitReader::run(ProcessingContext& pc) mc2rof.maxROF = mx; } } - if (mDigROFRec.back().getBCData() < irMax) { // need to check the next entry + if (mDigROFRec.back().getBCData() + mROFLengthInBC - 1 < irMax) { // need to check the next entry ent++; continue; } From 55d83570b580f2c4e0916abbb7af25de1bb4382a Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Mon, 28 Oct 2024 09:20:22 +0100 Subject: [PATCH 0380/2205] DPL Analysis: Staged declaration macro (#13624) --- Framework/Core/include/Framework/ASoA.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 1b8406b9109e3..46b031ec8b775 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2763,6 +2763,13 @@ DECLARE_SOA_ITERATOR_METADATA(); #define DECLARE_SOA_TABLE_VERSIONED(_Name_, _Origin_, _Description_, _Version_, ...) \ DECLARE_SOA_TABLE_FULL_VERSIONED(_Name_, #_Name_, _Origin_, _Description_, _Version_, __VA_ARGS__); +#define DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Description_, _Version_, ...) \ + DECLARE_SOA_TABLE_FULL_VERSIONED(_BaseName_, #_BaseName_, "AOD", _Description_, _Version_, __VA_ARGS__); \ + DECLARE_SOA_TABLE_FULL_VERSIONED(Stored##_BaseName_, "Stored" #_BaseName_, "AOD1", _Description_, _Version_, __VA_ARGS__, soa::Marker<1>); + +#define DECLARE_SOA_TABLE_STAGED(_BaseName_, _Description_, ...) \ + DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Description_, 0, __VA_ARGS__); + #define DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, _Table_, _Origin_, _Description_, ...) \ template \ struct _Name_##ExtensionFrom : o2::soa::Table { \ From 2367b286eeac41c14bb8c52f174c8e3a7a6f9353 Mon Sep 17 00:00:00 2001 From: pillot Date: Mon, 28 Oct 2024 11:03:48 +0100 Subject: [PATCH 0381/2205] extract digits from selected BC ranges if any (#13625) --- Detectors/MUON/MCH/IO/CMakeLists.txt | 1 + .../MCH/IO/include/MCHIO/DigitReaderSpec.h | 3 +- Detectors/MUON/MCH/IO/src/DigitReaderSpec.cxx | 202 ++++++++++++++---- .../MCH/IO/src/digits-reader-workflow.cxx | 5 +- 4 files changed, 162 insertions(+), 49 deletions(-) diff --git a/Detectors/MUON/MCH/IO/CMakeLists.txt b/Detectors/MUON/MCH/IO/CMakeLists.txt index 18a8630a7fed0..ed329b44922d8 100644 --- a/Detectors/MUON/MCH/IO/CMakeLists.txt +++ b/Detectors/MUON/MCH/IO/CMakeLists.txt @@ -25,6 +25,7 @@ o2_add_library(MCHIO O2::DataFormatsMCH O2::Framework O2::MCHBase + O2::MCHDigitFiltering O2::SimulationDataFormat ) diff --git a/Detectors/MUON/MCH/IO/include/MCHIO/DigitReaderSpec.h b/Detectors/MUON/MCH/IO/include/MCHIO/DigitReaderSpec.h index a7fd59b61a739..c061a260cf6f8 100644 --- a/Detectors/MUON/MCH/IO/include/MCHIO/DigitReaderSpec.h +++ b/Detectors/MUON/MCH/IO/include/MCHIO/DigitReaderSpec.h @@ -27,7 +27,8 @@ framework::DataProcessorSpec getDigitReaderSpec( bool useMC, std::string_view specName = "mch-digit-reader", std::string_view outputDigitDataDescription = "DIGITS", - std::string_view outputDigitRofDataDescription = "DIGITROFS"); + std::string_view outputDigitRofDataDescription = "DIGITROFS", + std::string_view outputDigitLabelDataDescription = "DIGITLABELS"); } } // namespace o2 diff --git a/Detectors/MUON/MCH/IO/src/DigitReaderSpec.cxx b/Detectors/MUON/MCH/IO/src/DigitReaderSpec.cxx index 541e6c5fa26c0..78a0022e07166 100644 --- a/Detectors/MUON/MCH/IO/src/DigitReaderSpec.cxx +++ b/Detectors/MUON/MCH/IO/src/DigitReaderSpec.cxx @@ -17,21 +17,32 @@ #include "MCHIO/DigitReaderSpec.h" #include -#include +#include #include -#include "DPLUtils/RootTreeReader.h" +#include + +#include + +#include + +#include +#include +#include +#include + +#include "CommonDataFormat/IRFrame.h" +#include "CommonUtils/IRFrameSelector.h" +#include "CommonUtils/StringUtils.h" +#include "DataFormatsMCH/Digit.h" +#include "DataFormatsMCH/ROFRecord.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/ControlService.h" #include "Framework/DataSpecUtils.h" -#include "Framework/Logger.h" -#include "Framework/Output.h" #include "Framework/Task.h" #include "Framework/WorkflowSpec.h" -#include "SimulationDataFormat/MCTruthContainer.h" +#include "MCHDigitFiltering/DigitFilterParam.h" #include "SimulationDataFormat/MCCompLabel.h" -#include "DataFormatsMCH/Digit.h" -#include "DataFormatsMCH/ROFRecord.h" -#include "CommonUtils/StringUtils.h" +#include "SimulationDataFormat/MCTruthContainer.h" using namespace o2::framework; @@ -43,72 +54,171 @@ namespace mch class DigitsReaderDeviceDPL { public: - DigitsReaderDeviceDPL(bool useMC, const std::vector& descriptions) - : mUseMC(useMC), mDescriptions(descriptions) {} + DigitsReaderDeviceDPL(bool useMC) : mUseMC(useMC) + { + if (mUseMC) { + mLabels = std::make_unique>>(mTreeReader, "MCHMCLabels"); + } + } void init(InitContext& ic) { - auto filename = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), ic.options().get("mch-digit-infile")); + auto fileName = utils::Str::concat_string(utils::Str::rectifyDirectory(ic.options().get("input-dir")), + ic.options().get("mch-digit-infile")); + connectTree(fileName); - if (mUseMC) { - mReader = std::make_unique("o2sim", filename.c_str(), -1, - RootTreeReader::PublishingMode::Single, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMCH, mDescriptions[0], 0}, "MCHDigit"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMCH, mDescriptions[1], 0}, "MCHROFRecords"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMCH, mDescriptions[2], 0}, "MCHMCLabels"}); - } else { - mReader = std::make_unique("o2sim", filename.c_str(), -1, - RootTreeReader::PublishingMode::Single, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMCH, mDescriptions[0], 0}, "MCHDigit"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMCH, mDescriptions[1], 0}, "MCHROFRecords"}); + if (ic.options().hasOption("ignore-irframes") && !ic.options().get("ignore-irframes")) { + mUseIRFrames = true; } + + mTimeOffset = ic.options().get("no-time-offset") ? 0 : DigitFilterParam::Instance().timeOffset; } void run(ProcessingContext& pc) { - if ((++(*mReader))(pc) == false) { - pc.services().get().endOfStream(); + if (mUseIRFrames) { + sendNextIRFrames(pc); + } else { + sendNextTF(pc); } } private: - std::unique_ptr mReader{}; - std::vector mDescriptions{}; + TTreeReader mTreeReader{}; + TTreeReaderValue> mRofs = {mTreeReader, "MCHROFRecords"}; + TTreeReaderValue> mDigits = {mTreeReader, "MCHDigit"}; + std::unique_ptr>> mLabels{}; bool mUseMC = true; + bool mUseIRFrames = false; + int mTimeOffset = 0; + + void connectTree(std::string fileName) + { + auto file = TFile::Open(fileName.c_str()); + if (!file || file->IsZombie()) { + throw std::invalid_argument(fmt::format("Opening file {} failed", fileName)); + } + + auto tree = file->Get("o2sim"); + if (!tree) { + throw std::invalid_argument(fmt::format("Tree o2sim not found in {}", fileName)); + } + mTreeReader.SetTree(tree); + mTreeReader.Restart(); + } + + void sendNextTF(ProcessingContext& pc) + { + // load the next TF and check its validity (missing branch, ...) + if (!mTreeReader.Next()) { + throw std::invalid_argument(mTreeReader.fgEntryStatusText[mTreeReader.GetEntryStatus()]); + } + + // send the whole TF + pc.outputs().snapshot(OutputRef{"rofs"}, *mRofs); + pc.outputs().snapshot(OutputRef{"digits"}, *mDigits); + if (mUseMC) { + pc.outputs().snapshot(OutputRef{"labels"}, **mLabels); + } + + // stop here if it was the last one + if (mTreeReader.GetCurrentEntry() + 1 >= mTreeReader.GetEntries()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } + } + + void sendNextIRFrames(ProcessingContext& pc) + { + std::vector rofs{}; + std::vector digits{}; + dataformats::MCTruthContainer labels{}; + + // get the IR frames to select + auto irFrames = pc.inputs().get>("driverInfo"); + + if (!irFrames.empty()) { + utils::IRFrameSelector irfSel{}; + irfSel.setSelectedIRFrames(irFrames, 0, 0, -mTimeOffset, true); + const auto irMin = irfSel.getIRFrames().front().getMin(); + const auto irMax = irfSel.getIRFrames().back().getMax(); + + // load the first TF if not already done + bool loadNextTF = mTreeReader.GetCurrentEntry() < 0; + + while (true) { + // load the next TF if requested + if (loadNextTF && !mTreeReader.Next()) { + throw std::invalid_argument(mTreeReader.fgEntryStatusText[mTreeReader.GetEntryStatus()]); + } + + // look for selected ROFs in this TF and copy them + if (!mRofs->empty() && mRofs->front().getBCData() <= irMax && + mRofs->back().getBCData() + mRofs->back().getBCWidth() - 1 >= irMin) { + for (const auto& rof : *mRofs) { + if (irfSel.check({rof.getBCData(), rof.getBCData() + rof.getBCWidth() - 1}) != -1) { + rofs.emplace_back(rof); + rofs.back().setDataRef(digits.size(), rof.getNEntries()); + digits.insert(digits.end(), mDigits->begin() + rof.getFirstIdx(), mDigits->begin() + rof.getFirstIdx() + rof.getNEntries()); + if (mUseMC) { + for (auto i = 0; i < rof.getNEntries(); ++i) { + labels.addElements(labels.getIndexedSize(), (*mLabels)->getLabels(rof.getFirstIdx() + i)); + } + } + } + } + } + + // move to the next TF if needed and if any + if ((mRofs->empty() || mRofs->back().getBCData() + mRofs->back().getBCWidth() - 1 < irMax) && + mTreeReader.GetCurrentEntry() + 1 < mTreeReader.GetEntries()) { + loadNextTF = true; + continue; + } + + break; + } + } + + // send the selected data + pc.outputs().snapshot(OutputRef{"rofs"}, rofs); + pc.outputs().snapshot(OutputRef{"digits"}, digits); + if (mUseMC) { + pc.outputs().snapshot(OutputRef{"labels"}, labels); + } + + // stop here if they were the last IR frames to select + if (irFrames.empty() || irFrames.back().isLast()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } + } }; -framework::DataProcessorSpec getDigitReaderSpec( - bool useMC, - std::string_view specName, - std::string_view outputDigitDataDescription, - std::string_view outputDigitRofDataDescription) +DataProcessorSpec getDigitReaderSpec(bool useMC, std::string_view specName, + std::string_view outputDigitDataDescription, + std::string_view outputDigitRofDataDescription, + std::string_view outputDigitLabelDataDescription) { - std::vector outputs; - std::vector descriptions; - std::stringstream ss; - ss << "A:" << header::gDataOriginMCH.as() << "/" << outputDigitDataDescription << "/0"; - ss << ";B:" << header::gDataOriginMCH.as() << "/" << outputDigitRofDataDescription << "/0"; + std::string output = fmt::format("digits:MCH/{}/0;rofs:MCH/{}/0", outputDigitDataDescription, outputDigitRofDataDescription); if (useMC) { - ss << ";C:" << header::gDataOriginMCH.as() << "/DIGITLABELS/0"; + output += fmt::format(";labels:MCH/{}/0", outputDigitLabelDataDescription); } - auto matchers = select(ss.str().c_str()); + + std::vector outputs; + auto matchers = select(output.c_str()); for (auto& matcher : matchers) { outputs.emplace_back(DataSpecUtils::asOutputSpec(matcher)); - descriptions.emplace_back(DataSpecUtils::asConcreteDataDescription(matcher)); } return DataProcessorSpec{ std::string(specName), Inputs{}, outputs, - AlgorithmSpec{adaptFromTask(useMC, descriptions)}, + AlgorithmSpec{adaptFromTask(useMC)}, Options{{"mch-digit-infile", VariantType::String, "mchdigits.root", {"Name of the input file"}}, - {"input-dir", VariantType::String, "none", {"Input directory"}}}}; + {"input-dir", VariantType::String, "none", {"Input directory"}}, + {"no-time-offset", VariantType::Bool, false, {"no time offset between IRFrames and digits"}}}}; } } // namespace mch } // namespace o2 diff --git a/Detectors/MUON/MCH/IO/src/digits-reader-workflow.cxx b/Detectors/MUON/MCH/IO/src/digits-reader-workflow.cxx index 0ec46f2fc4d3b..d6c91023de53a 100644 --- a/Detectors/MUON/MCH/IO/src/digits-reader-workflow.cxx +++ b/Detectors/MUON/MCH/IO/src/digits-reader-workflow.cxx @@ -35,7 +35,7 @@ void customize(std::vector& workflowOptions) {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}, {"mch-output-digits-data-description", VariantType::String, "DIGITS", {"description string for the output digits message"}}, {"mch-output-digitrofs-data-description", VariantType::String, "DIGITROFS", {"description string for the output digit rofs message"}}, - }; + {"mch-output-digitlabels-data-description", VariantType::String, "DIGITLABELS", {"description string for the output digit labels message"}}}; workflowOptions.insert(workflowOptions.end(), options.begin(), options.end()); o2::raw::HBFUtilsInitializer::addConfigOption(workflowOptions); } @@ -55,7 +55,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cc) useMC, name, cc.options().get("mch-output-digits-data-description"), - cc.options().get("mch-output-digitrofs-data-description"))); + cc.options().get("mch-output-digitrofs-data-description"), + cc.options().get("mch-output-digitlabels-data-description"))); o2::raw::HBFUtilsInitializer hbfIni(cc, specs); From 52a1d7571f91be218df39f24a30ee355dac28eec Mon Sep 17 00:00:00 2001 From: pillot Date: Mon, 28 Oct 2024 11:04:17 +0100 Subject: [PATCH 0382/2205] add option to change digit labels data description (#13626) --- .../MUON/MCH/IO/include/MCHIO/DigitWriterSpec.h | 3 ++- Detectors/MUON/MCH/IO/src/DigitWriterSpec.cxx | 15 +++++++-------- .../MUON/MCH/IO/src/digits-writer-workflow.cxx | 4 +++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Detectors/MUON/MCH/IO/include/MCHIO/DigitWriterSpec.h b/Detectors/MUON/MCH/IO/include/MCHIO/DigitWriterSpec.h index 66909ec5972b8..c615774c1add9 100644 --- a/Detectors/MUON/MCH/IO/include/MCHIO/DigitWriterSpec.h +++ b/Detectors/MUON/MCH/IO/include/MCHIO/DigitWriterSpec.h @@ -25,7 +25,8 @@ o2::framework::DataProcessorSpec getDigitWriterSpec( std::string_view specName = "mch-digit-writer", std::string_view outfile = "mchdigits.root", std::string_view inputDigitDataDescription = "DIGITS", - std::string_view inputDigitRofDataDescription = "DIGITROFS"); + std::string_view inputDigitRofDataDescription = "DIGITROFS", + std::string_view inputDigitLabelDataDescription = "DIGITLABELS"); } // end namespace mch } // end namespace o2 diff --git a/Detectors/MUON/MCH/IO/src/DigitWriterSpec.cxx b/Detectors/MUON/MCH/IO/src/DigitWriterSpec.cxx index 9d5755bd7911c..84a20d855dab7 100644 --- a/Detectors/MUON/MCH/IO/src/DigitWriterSpec.cxx +++ b/Detectors/MUON/MCH/IO/src/DigitWriterSpec.cxx @@ -38,9 +38,7 @@ o2::framework::DataProcessorSpec getMCHDigitWriterSpec(bool mctruth) 1, // default number of events BranchDefinition>{InputSpec{"mchdigits", "MCH", "DIGITS"}, "MCHDigit"}, BranchDefinition>{InputSpec{"mchrofrecords", "MCH", "DIGITROFS"}, "MCHROFRecords"}, - BranchDefinition>{InputSpec{"mchdigitlabels", "MCH", "DIGITSLABELS"}, "MCHMCLabels", mctruth ? 1 : 0} - // add more branch definitions (for example Monte Carlo labels here) - )(); + BranchDefinition>{InputSpec{"mchdigitlabels", "MCH", "DIGITSLABELS"}, "MCHMCLabels", mctruth ? 1 : 0})(); } o2::framework::DataProcessorSpec getDigitWriterSpec( @@ -48,23 +46,24 @@ o2::framework::DataProcessorSpec getDigitWriterSpec( std::string_view specName, std::string_view outfile, std::string_view inputDigitDataDescription, - std::string_view inputDigitRofDataDescription) + std::string_view inputDigitRofDataDescription, + std::string_view inputDigitLabelDataDescription) { std::string input = - fmt::format("digits:MCH/{};rofs:MCH/{}", - inputDigitDataDescription, inputDigitRofDataDescription); + fmt::format("digits:MCH/{};rofs:MCH/{};labels:MCH/{}", + inputDigitDataDescription, inputDigitRofDataDescription, inputDigitLabelDataDescription); framework::Inputs inputs{framework::select(input.c_str())}; auto rofs = std::find_if(inputs.begin(), inputs.end(), [](const framework::InputSpec& is) { return is.binding == "rofs"; }); auto digits = std::find_if(inputs.begin(), inputs.end(), [](const framework::InputSpec& is) { return is.binding == "digits"; }); + auto labels = std::find_if(inputs.begin(), inputs.end(), [](const framework::InputSpec& is) { return is.binding == "labels"; }); return framework::MakeRootTreeWriterSpec( std::string(specName).c_str(), std::string(outfile).c_str(), framework::MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree MCH Digits"}, BranchDefinition>{framework::InputSpec{*rofs}, "MCHROFRecords"}, BranchDefinition>{framework::InputSpec{*digits}, "MCHDigit"}, - BranchDefinition>{ - framework::InputSpec{"mchdigitlabels", "MCH", "DIGITSLABELS"}, "MCHMCLabels", useMC ? 1 : 0})(); + BranchDefinition>{framework::InputSpec{*labels}, "MCHMCLabels", useMC ? 1 : 0})(); } } // end namespace mch diff --git a/Detectors/MUON/MCH/IO/src/digits-writer-workflow.cxx b/Detectors/MUON/MCH/IO/src/digits-writer-workflow.cxx index b806039ac9062..4915a9de483f2 100644 --- a/Detectors/MUON/MCH/IO/src/digits-writer-workflow.cxx +++ b/Detectors/MUON/MCH/IO/src/digits-writer-workflow.cxx @@ -47,6 +47,7 @@ void customize(std::vector& workflowOptions) { workflowOptions.emplace_back(ConfigParamSpec{"input-digits-data-description", VariantType::String, "DIGITS", {"description string for the input digits data"}}); workflowOptions.emplace_back(ConfigParamSpec{"input-digitrofs-data-description", VariantType::String, "DIGITROFS", {"description string for the input digit rofs data"}}); + workflowOptions.emplace_back(ConfigParamSpec{"input-digitlabels-data-description", VariantType::String, "DIGITLABELS", {"description string for the input digit labels data"}}); workflowOptions.emplace_back(ConfigParamSpec{"enable-mc", VariantType::Bool, false, {" output MC labels if available "}}); workflowOptions.emplace_back(ConfigParamSpec{"mch-digit-outfile", VariantType::String, "mchdigits.root", {"name of digit root file"}}); } @@ -65,5 +66,6 @@ WorkflowSpec defineDataProcessing(const ConfigContext& cc) name, cc.options().get("mch-digit-outfile"), cc.options().get("input-digits-data-description"), - cc.options().get("input-digitrofs-data-description"))}; + cc.options().get("input-digitrofs-data-description"), + cc.options().get("input-digitlabels-data-description"))}; } From f485cc05cbf8d8163241a1c5c6ea38f6ed2b13f7 Mon Sep 17 00:00:00 2001 From: jokonig Date: Mon, 21 Oct 2024 11:26:02 +0200 Subject: [PATCH 0383/2205] [O2-5395, EMCAL-501] Implement correct handling of events preceding timeframe - Reject digits if it comes from a collision happening at a bc before the RO starts and the time of the digit also comes before the RO - Time of current collision calculated w.r.t start of RO --- .../include/EMCALSimulation/Digitizer.h | 3 +++ Detectors/EMCAL/simulation/src/Digitizer.cxx | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Detectors/EMCAL/simulation/include/EMCALSimulation/Digitizer.h b/Detectors/EMCAL/simulation/include/EMCALSimulation/Digitizer.h index b9be86965152a..ad296a4d65a58 100644 --- a/Detectors/EMCAL/simulation/include/EMCALSimulation/Digitizer.h +++ b/Detectors/EMCAL/simulation/include/EMCALSimulation/Digitizer.h @@ -110,6 +110,9 @@ class Digitizer : public TObject bool mSmearEnergy = true; ///< do time and energy smearing bool mSimulateTimeResponse = true; ///< simulate time response const SimParam* mSimParam = nullptr; ///< SimParam object + bool mIsBeforeFirstRO = false; ///< check if the signal comes before the ROF + o2::InteractionRecord mIRFirstSampledTF; ///< IR of the 1st sampled IR, noise-only ROFs will be inserted till this IR only + double mTimeBCns; ///< time difference between bc and start of ROF in ns std::vector mTempDigitVector; ///< temporary digit storage o2::emcal::DigitsWriteoutBuffer mDigits; ///< used to sort digits and labels by tower diff --git a/Detectors/EMCAL/simulation/src/Digitizer.cxx b/Detectors/EMCAL/simulation/src/Digitizer.cxx index a1ebcf477d560..8360cb4fd67e8 100644 --- a/Detectors/EMCAL/simulation/src/Digitizer.cxx +++ b/Detectors/EMCAL/simulation/src/Digitizer.cxx @@ -26,6 +26,8 @@ #include "CommonDataFormat/InteractionRecord.h" #include "CommonUtils/TreeStreamRedirector.h" #include "SimConfig/DigiParams.h" +#include "DetectorsRaw/HBFUtilsInitializer.h" +#include "DetectorsRaw/HBFUtils.h" ClassImp(o2::emcal::Digitizer); @@ -80,6 +82,8 @@ void Digitizer::init() } else { } + mIRFirstSampledTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); + if (mEnableDebugStreaming) { mDebugStream = std::make_unique("emcaldigitsDebug.root", "RECREATE"); } @@ -164,6 +168,13 @@ void Digitizer::sampleSDigit(const Digit& sDigit) return; } + // check if this hit because it comes from an event before readout starts and it does not effect this RO + LOG(debug) << "mIsBeforeFirstRO " << mIsBeforeFirstRO << " sDigit.getTimeStamp() " << sDigit.getTimeStamp() << " mSimParam->getSignalDelay() " << mSimParam->getSignalDelay() << " mPhase " << mPhase << " total: " << sDigit.getTimeStamp() + mSimParam->getSignalDelay() + mPhase * 25 << " EMC_TOF_MAX " << EMC_TOF_MAX << " mTimeBCns " << mTimeBCns; + if (mIsBeforeFirstRO && sDigit.getTimeStamp() + mTimeBCns < 0) { + LOG(debug) << "disregard this hit because it comes from an event before readout starts and it does not effect this RO"; + return; + } + Double_t energies[15]; if (mSimulateTimeResponse) { if (sDigit.getTimeStamp() + mSimParam->getSignalDelay() + mPhase * 25 > EMC_TOF_MAX) { @@ -246,4 +257,16 @@ void Digitizer::setEventTime(o2::InteractionTimeRecord record, bool trigger) mPhase = 0; mEventTimeOffset++; } + + // get time difference between current bc and start of RO in ns + auto nbc = record.differenceInBC(mIRFirstSampledTF); + mTimeBCns = record.getTimeOffsetWrtBC(); + mTimeBCns += nbc * o2::constants::lhc::LHCBunchSpacingNS; + + if (nbc < 0) { + // this event is before the first RO + mIsBeforeFirstRO = true; + } else { + mIsBeforeFirstRO = false; + } } \ No newline at end of file From 2c3147314f88117478802d7e3c081ee2302ffa1e Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 23 Oct 2024 19:08:21 +0200 Subject: [PATCH 0384/2205] Fix in TPC MC cl.resoluion extraction --- .../GlobalTrackingStudy/TrackMCStudyConfig.h | 7 +- .../GlobalTrackingStudy/TrackMCStudyTypes.h | 78 ++++++++++--- .../study/src/GlobalTrackingStudyLinkDef.h | 2 + .../study/src/TrackMCStudy.cxx | 103 ++++++++++++------ 4 files changed, 138 insertions(+), 52 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h index c6af627c0f5dd..7d89928a20b37 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyConfig.h @@ -27,10 +27,9 @@ struct TrackMCStudyConfig : o2::conf::ConfigurableParamHelper +#include namespace o2::trackstudy { @@ -112,24 +113,20 @@ struct TrackFamily { // set of tracks related to the same MC label ClassDefNV(TrackFamily, 1); }; -struct ClResTPC { - uint8_t sect = 0; - uint8_t row = 0; - uint8_t ncont = 0; - uint8_t flags = 0; - float snp = 0; - float tgl = 0; - float qmax = 0; - float qtot = 0; - float occ = 0; - std::array clPos{}; +struct ClResTPCCont { + // contributor to TPC Cluster + std::array xyz{}; std::array below{}; std::array above{}; + float snp = 0.; + float tgl = 0.; + float q2pt = 0.; + bool corrAttach = false; - int getNExt() const { return below[0] > 1. + above[0] > 1.; } + int getNExt() const { return (below[0] > 1.) + (above[0] > 1.); } - float getDY() const { return clPos[1] - getYRef(); } - float getDZ() const { return clPos[2] - getZRef(); } + float getDY() const { return xyz[1] - getYRef(); } + float getDZ() const { return xyz[2] - getZRef(); } float getYRef() const { @@ -165,15 +162,62 @@ struct ClResTPC { { float adxA = 1e9, adxB = 1e9; if (above[0] > 1.) { - adxA = clPos[0] - above[0]; + adxA = xyz[0] - above[0]; } if (below[0] > 1.) { - adxB = clPos[0] - below[0]; + adxB = xyz[1] - below[0]; } return std::abs(adxA) < std::abs(adxB) ? adxA : adxB; } - ClassDefNV(ClResTPC, 1); + float getDXMax() const + { + float adxA = 0, adxB = 0; + if (above[0] > 1.) { + adxA = xyz[0] - above[0]; + } + if (below[0] > 1.) { + adxB = xyz[0] - below[0]; + } + return std::abs(adxA) > std::abs(adxB) ? adxA : adxB; + } + + float getEY() const { return getNExt() > 1 ? below[1] - above[1] : -999; } + float getEZ() const { return getNExt() > 1 ? below[2] - above[2] : -999; } + + ClassDefNV(ClResTPCCont, 1); +}; + +struct ClResTPC { + uint8_t sect = 0; + uint8_t row = 0; + uint8_t ncont = 0; + uint8_t flags = 0; + float qmax = 0; + float qtot = 0; + float occ = 0; + + std::vector contTracks; + int getNCont() const { return contTracks.size(); } + + float getDY(int i) const { return i < getNCont() ? contTracks[i].getDY() : -999.; } + float getDZ(int i) const { return i < getNCont() ? contTracks[i].getDZ() : -999.; } + float getYRef(int i) const { return i < getNCont() ? contTracks[i].getYRef() : -999.; } + float getZRef(int i) const { return i < getNCont() ? contTracks[i].getZRef() : -999.; } + float getDXMin(int i) const { return i < getNCont() ? contTracks[i].getDXMin() : -999.; } + float getDXMax(int i) const { return i < getNCont() ? contTracks[i].getDXMax() : -999.; } + float getEY(int i) const { return i < getNCont() ? contTracks[i].getEY() : -999.; } + float getEZ(int i) const { return i < getNCont() ? contTracks[i].getEZ() : -999.; } + + void sortCont() + { + std::sort(contTracks.begin(), contTracks.end(), [](const ClResTPCCont& a, const ClResTPCCont& b) { + float dya = a.getDY(), dyb = b.getDY(), dza = a.getDZ(), dzb = b.getDZ(); + return dya * dya + dza * dza < dyb * dyb + dzb * dzb; + }); + } + + ClassDefNV(ClResTPC, 2); }; struct RecPV { diff --git a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h index d6183e48af4da..1e8fd688ca2fa 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h +++ b/Detectors/GlobalTrackingWorkflow/study/src/GlobalTrackingStudyLinkDef.h @@ -34,5 +34,7 @@ #pragma link C++ class o2::trackstudy::MCVertex + ; #pragma link C++ class std::vector < o2::trackstudy::MCVertex> + ; #pragma link C++ class o2::trackstudy::ClResTPC + ; +#pragma link C++ class o2::trackstudy::ClResTPCCont + ; +#pragma link C++ class std::vector < o2::trackstudy::ClResTPCCont> + ; #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index cfeabd35f325e..b82eb45db9bba 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -263,6 +263,26 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) return -1; }; + auto flagTPCClusters = [&recoData](const o2::tpc::TrackTPC& trc, o2::MCCompLabel lbTrc) { + if (recoData.inputsTPCclusters) { + const auto clRefs = recoData.getTPCTracksClusterRefs(); + const auto* TPCClMClab = recoData.inputsTPCclusters->clusterIndex.clustersMCTruth; + const auto& TPCClusterIdxStruct = recoData.inputsTPCclusters->clusterIndex; + for (int ic = 0; ic < trc.getNClusterReferences(); ic++) { + uint8_t clSect = 0, clRow = 0; + uint32_t clIdx = 0; + trc.getClusterReference(clRefs, ic, clSect, clRow, clIdx); + auto labels = TPCClMClab->getLabels(clIdx + TPCClusterIdxStruct.clusterOffset[clSect][clRow]); + for (auto& lbl : labels) { + if (lbl == lbTrc) { + const_cast(lbl).setFakeFlag(true); // actually, in this way we are flagging that this cluster was correctly attached + break; + } + } + } + } + }; + { const auto* digconst = mcReader.getDigitizationContext(); const auto& mcEvRecords = digconst->getEventRecords(false); @@ -421,13 +441,11 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } } - // collect ITS/TPC cluster info for selected MC particles - if (params.minTPCRefsToExtractClRes > 0) { + LOGP(info, "collected {} MC tracks", mSelMCTracks.size()); + if (params.minTPCRefsToExtractClRes > 0) { // prepare MC trackrefs for TPC processTPCTrackRefs(); } - fillMCClusterInfo(recoData); - LOGP(info, "collected {} MC tracks", mSelMCTracks.size()); int mcnt = 0; for (auto& entry : mSelMCTracks) { auto& trackFam = entry.second; @@ -489,6 +507,7 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) const auto& trtpc = recoData.getTPCTrack(gidSet[GTrackID::TPC]); tref.nClTPC = trtpc.getNClusters(); tref.lowestPadRow = getLowestPadrow(trtpc); + flagTPCClusters(trtpc, entry.first); if (trackFam.entTPC < 0) { trackFam.entTPC = tcnt; trackFam.tpcT0 = trtpc.getTime0(); @@ -533,6 +552,10 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) auto& trackFam = entry.second; (*mDBGOut) << "tracks" << "tr=" << trackFam << "\n"; } + + // collect ITS/TPC cluster info for selected MC particles + fillMCClusterInfo(recoData); + // decays std::vector decFam; for (int id = 0; id < mNCheckDecays; id++) { @@ -620,6 +643,8 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re const auto& TPCClusterIdxStruct = recoData.inputsTPCclusters->clusterIndex; const auto* TPCClMClab = recoData.inputsTPCclusters->clusterIndex.clustersMCTruth; const auto& params = o2::trackstudy::TrackMCStudyConfig::Instance(); + + ClResTPC clRes{}; for (uint8_t sector = 0; sector < 36; sector++) { for (uint8_t row = 0; row < 152; row++) { unsigned int offs = TPCClusterIdxStruct.clusterOffset[sector][row]; @@ -632,7 +657,12 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re } ncontLb++; } - for (const auto& lbl : labels) { + const auto& clus = TPCClusterIdxStruct.clusters[sector][row][icl0]; + clRes.contTracks.clear(); + bool doClusRes = (params.minTPCRefsToExtractClRes > 0) && (params.rejectClustersResStat <= 0. || gRandom->Rndm() < params.rejectClustersResStat); + for (auto lbl : labels) { + bool corrAttach = lbl.isFake(); // was this flagged in the flagTPCClusters called from process ? + lbl.setFakeFlag(false); auto entry = mSelMCTracks.find(lbl); if (entry == mSelMCTracks.end()) { // not selected continue; @@ -654,29 +684,29 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re mctr.nTPCClShared++; } // try to extract ideal track position - if (params.minTPCRefsToExtractClRes > 0) { + if (doClusRes) { auto entTRefIDsIt = mSelTRefIdx.find(lbl); if (entTRefIDsIt == mSelTRefIdx.end()) { continue; } + float xc, yc, zc; + mTPCCorrMapsLoader.Transform(sector, row, clus.getPad(), clus.getTime(), xc, yc, zc, mctr.bcInTF / 8.); // nominal time of the track + const auto& entTRefIDs = entTRefIDsIt->second; // find bracketing TRef params int entIDBelow = -1, entIDAbove = -1; float xBelow = -1e6, xAbove = 1e6; - const auto& clus = TPCClusterIdxStruct.clusters[sector][row][icl0]; - float xc, yc, zc; - mTPCCorrMapsLoader.Transform(sector, row, clus.getPad(), clus.getTime(), xc, yc, zc, mctr.bcInTF / 8.); // nominal time of the track for (int entID = entTRefIDs.first; entID < entTRefIDs.second; entID++) { const auto& refTr = mSelTRefs[entID]; if (refTr.getUserField() != sector % 18) { continue; } - if (refTr.getX() < xc && refTr.getX() > xBelow && refTr.getX() > xc - params.maxTPCRefExtrap) { + if ((refTr.getX() < xc) && (refTr.getX() > xBelow) && (refTr.getX() > xc - params.maxTPCRefExtrap)) { xBelow = refTr.getX(); entIDBelow = entID; } - if (refTr.getX() > xc && refTr.getX() < xAbove && refTr.getX() < xc + params.maxTPCRefExtrap) { + if ((refTr.getX() > xc) && (refTr.getX() < xAbove) && (refTr.getX() < xc + params.maxTPCRefExtrap)) { xAbove = refTr.getX(); entIDAbove = entID; } @@ -688,42 +718,53 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re o2::track::TrackPar tparAbove, tparBelow; bool okBelow = entIDBelow >= 0 && prop->PropagateToXBxByBz((tparBelow = mSelTRefs[entIDBelow]), xc, 0.99, 2.); bool okAbove = entIDAbove >= 0 && prop->PropagateToXBxByBz((tparAbove = mSelTRefs[entIDAbove]), xc, 0.99, 2.); - if ((!okBelow && !okAbove) || (params.requireTopBottomRefs && (!okBelow || !okAbove)) || (params.rejectClustersResStat > 0. && gRandom->Rndm() < params.rejectClustersResStat)) { + if ((!okBelow && !okAbove) || (params.requireTopBottomRefs && (!okBelow || !okAbove))) { continue; } - ClResTPC clRes{}; int nmeas = 0; + auto& clCont = clRes.contTracks.emplace_back(); + clCont.corrAttach = corrAttach; if (okBelow) { - clRes.below = {mSelTRefs[entIDBelow].getX(), tparBelow.getY(), tparBelow.getZ()}; - clRes.snp += tparBelow.getSnp(); - clRes.tgl += tparBelow.getTgl(); + clCont.below = {mSelTRefs[entIDBelow].getX(), tparBelow.getY(), tparBelow.getZ()}; + clCont.snp += tparBelow.getSnp(); + clCont.tgl += tparBelow.getTgl(); + clCont.q2pt += tparBelow.getQ2Pt(); nmeas++; } if (okAbove) { - clRes.above = {mSelTRefs[entIDAbove].getX(), tparAbove.getY(), tparAbove.getZ()}; - clRes.snp += tparAbove.getSnp(); - clRes.tgl += tparBelow.getTgl(); + clCont.above = {mSelTRefs[entIDAbove].getX(), tparAbove.getY(), tparAbove.getZ()}; + clCont.snp += tparAbove.getSnp(); + clCont.tgl += tparAbove.getTgl(); + clCont.q2pt += tparAbove.getQ2Pt(); nmeas++; } if (nmeas) { + if (clRes.contTracks.size() == 1) { + int occBin = mctr.bcInTF / 8 * mNTPCOccBinLengthInv; + clRes.occ = occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin]); + } + clCont.xyz = {xc, yc, zc}; if (nmeas > 1) { - clRes.snp *= 0.5; - clRes.tgl *= 0.5; + clCont.snp *= 0.5; + clCont.tgl *= 0.5; + clCont.q2pt *= 0.5; } - clRes.clPos = {xc, yc, zc}; - clRes.sect = sector; - clRes.row = row; - clRes.qtot = clus.getQtot(); - clRes.qmax = clus.getQmax(); - clRes.flags = clus.getFlags(); - clRes.ncont = ncontLb; - int occBin = mctr.bcInTF / 8 * mNTPCOccBinLengthInv; - clRes.occ = occBin < 0 ? mTBinClOcc[0] : (occBin >= mTBinClOcc.size() ? mTBinClOcc.back() : mTBinClOcc[occBin]); - (*mDBGOut) << "clres" << "clr=" << clRes << "\n"; + } else { + clRes.contTracks.pop_back(); } } } + if (clRes.getNCont()) { + clRes.sect = sector; + clRes.row = row; + clRes.qtot = clus.getQtot(); + clRes.qmax = clus.getQmax(); + clRes.flags = clus.getFlags(); + clRes.ncont = ncontLb; + clRes.sortCont(); + (*mDBGOut) << "clres" << "clr=" << clRes << "\n"; + } } } } From e40ebede2f8fdc33a32feb79ccb634f8c7e3bedc Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 26 Oct 2024 19:20:35 +0200 Subject: [PATCH 0385/2205] Add check for V0s prongs binding on top of reco status --- .../GlobalTrackingStudy/TrackMCStudy.h | 2 +- .../GlobalTrackingStudy/TrackMCStudyTypes.h | 4 +- .../study/src/TrackMCStudy.cxx | 153 ++++++++++++++++-- .../study/src/trackMCStudy-workflow.cxx | 7 +- 4 files changed, 152 insertions(+), 14 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h index 5d9c2cfd6d349..d1326a47ac909 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h @@ -21,7 +21,7 @@ namespace o2::trackstudy { /// create a processor spec -o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts); +o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV); } // namespace o2::trackstudy diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h index 5639c7ba1bbe6..43dac1ca1b4e7 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h @@ -40,8 +40,10 @@ struct MCTrackInfo { int bcInTF = -1; int pdg = 0; int pdgParent = 0; + int parentEntry = -1; int16_t nTPCCl = 0; int16_t nTPCClShared = 0; + int8_t parentDecID = -1; uint8_t minTPCRow = -1; uint8_t maxTPCRow = 0; uint8_t maxTPCRowInner = 0; // highest row in the sector containing the lowest one @@ -49,7 +51,7 @@ struct MCTrackInfo { uint8_t maxTPCRowSect = -1; int8_t nITSCl = 0; int8_t pattITSCl = 0; - ClassDefNV(MCTrackInfo, 2); + ClassDefNV(MCTrackInfo, 3); }; struct RecTrack { diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index b82eb45db9bba..bfcc84180d82c 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -13,6 +13,7 @@ #include #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "ReconstructionDataFormats/V0.h" #include "ReconstructionDataFormats/TrackTPCITS.h" #include "ReconstructionDataFormats/GlobalTrackID.h" #include "TPCCalibration/VDriftHelper.h" @@ -45,6 +46,8 @@ #include "ReconstructionDataFormats/VtxTrackRef.h" #include "ReconstructionDataFormats/DCA.h" #include "Steer/MCKinematicsReader.h" +#include "DCAFitter/DCAFitterN.h" +#include "DetectorsVertexing/SVertexerParams.h" #include "CommonUtils/ConfigurableParam.h" #include "CommonUtils/ConfigurableParamHelper.h" #include "GPUO2InterfaceRefit.h" @@ -80,8 +83,8 @@ using timeEst = o2::dataformats::TimeStampWithError; class TrackMCStudy : public Task { public: - TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) - : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src) + TrackMCStudy(std::shared_ptr dr, std::shared_ptr gr, GTrackID::mask_t src, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV) + : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src), mCheckSV(checkSV) { mTPCCorrMapsLoader.setLumiScaleType(sclOpts.lumiType); mTPCCorrMapsLoader.setLumiScaleMode(sclOpts.lumiMode); @@ -102,6 +105,7 @@ class TrackMCStudy : public Task bool addMCParticle(const MCTrack& mctr, const o2::MCCompLabel& lb, TParticlePDG* pPDG = nullptr); bool acceptMCCharged(const MCTrack& tr, const o2::MCCompLabel& lb, int followDec = -1); bool propagateToRefX(o2::track::TrackParCov& trcTPC, o2::track::TrackParCov& trcITS); + bool refitV0(int i, o2::dataformats::V0& v0, const o2::globaltracking::RecoContainer& recoData); void updateTimeDependentParams(ProcessingContext& pc); float getDCAYCut(float pt) const; @@ -116,6 +120,7 @@ class TrackMCStudy : public Task std::vector mIntBC; ///< interaction global BC wrt TF start std::vector mTPCOcc; ///< TPC occupancy for this interaction time std::vector mITSOcc; //< N ITS clusters in the ROF containing collision + bool mCheckSV = false; //< check SV binding (apart from prongs availability) int mNTPCOccBinLength = 0; ///< TPC occ. histo bin length in TBs float mNTPCOccBinLengthInv; int mVerbose = 0; @@ -138,12 +143,13 @@ class TrackMCStudy : public Task int pdg = 0; int daughterFirst = -1; int daughterLast = -1; + int foundSVID = -1; }; - std::vector> mDecaysMaps; // for every parent particle to watch store its label and entries of 1st/last decay product labels in mDecProdLblPool + std::vector> mDecaysMaps; // for every parent particle to watch, store its label and entries of 1st/last decay product labels in mDecProdLblPool std::unordered_map mSelMCTracks; std::unordered_map> mSelTRefIdx; std::vector mSelTRefs; - + o2::vertexing::DCAFitterN<2> mFitterV0; static constexpr float MaxSnp = 0.9; // max snp of ITS or TPC track at xRef to be matched }; @@ -211,6 +217,25 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc) auto& elParam = o2::tpc::ParameterElectronics::Instance(); mTPCTBinMUS = elParam.ZbinWidth; + + if (mCheckSV) { + const auto& svparam = o2::vertexing::SVertexerParams::Instance(); + mFitterV0.setBz(o2::base::Propagator::Instance()->getNominalBz()); + mFitterV0.setUseAbsDCA(svparam.useAbsDCA); + mFitterV0.setPropagateToPCA(false); + mFitterV0.setMaxR(svparam.maxRIni); + mFitterV0.setMinParamChange(svparam.minParamChange); + mFitterV0.setMinRelChi2Change(svparam.minRelChi2Change); + mFitterV0.setMaxDZIni(svparam.maxDZIni); + mFitterV0.setMaxDXYIni(svparam.maxDXYIni); + mFitterV0.setMaxChi2(svparam.maxChi2); + mFitterV0.setMatCorrType(o2::base::Propagator::MatCorrType(svparam.matCorr)); + mFitterV0.setUsePropagator(svparam.usePropagator); + mFitterV0.setRefitWithMatCorr(svparam.refitWithMatCorr); + mFitterV0.setMaxStep(svparam.maxStep); + mFitterV0.setMaxSnp(svparam.maxSnp); + mFitterV0.setMinXSeed(svparam.minXSeed); + } } } @@ -547,6 +572,54 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } } + // SVertices (V0s) + if (mCheckSV) { + auto v0s = recoData.getV0sIdx(); + auto prpr = [](o2::trackstudy::TrackFamily& f) { + std::string s; + s += fmt::format(" par {} Ntpccl={} Nitscl={} ", f.mcTrackInfo.pdgParent, f.mcTrackInfo.nTPCCl, f.mcTrackInfo.nITSCl); + for (auto& t : f.recTracks) { + s += t.gid.asString(); + s += " "; + } + return s; + }; + for (int svID; svID < (int)v0s.size(); svID++) { + const auto& v0idx = v0s[svID]; + int nOKProngs = 0, realMCSVID = -1; + int8_t decTypeID = -1; + for (int ipr = 0; ipr < v0idx.getNProngs(); ipr++) { + auto mcl = recoData.getTrackMCLabel(v0idx.getProngID(ipr)); // was this MC particle selected? + auto itl = mSelMCTracks.find(mcl); + if (itl == mSelMCTracks.end()) { + nOKProngs = -1; // was not selected as interesting one, ignore + break; + } + auto& trackFamily = itl->second; + int decayParentIndex = trackFamily.mcTrackInfo.parentEntry; + if (decayParentIndex < 0) { // does not come from decay + break; + } + if (ipr == 0) { + realMCSVID = decayParentIndex; + decTypeID = trackFamily.mcTrackInfo.parentDecID; + nOKProngs = 1; + LOGP(debug, "Prong{} {} comes from {}/{}", ipr, prpr(trackFamily), decTypeID, realMCSVID); + continue; + } + if (realMCSVID != decayParentIndex || decTypeID != trackFamily.mcTrackInfo.parentDecID) { + break; + } + LOGP(debug, "Prong{} {} comes from {}/{}", ipr, prpr(trackFamily), decTypeID, realMCSVID); + nOKProngs++; + } + if (nOKProngs == v0idx.getNProngs()) { // all prongs are from the decay of MC parent which deemed to be interesting, flag it + LOGP(debug, "Decay {}/{} was found", decTypeID, realMCSVID); + mDecaysMaps[decTypeID][realMCSVID].foundSVID = svID; + } + } + } + // single tracks for (auto& entry : mSelMCTracks) { auto& trackFam = entry.second; @@ -574,7 +647,11 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) decFam.push_back(dtFamily); } if (!skip) { - (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "\n"; + o2::dataformats::V0 v0; + if (dec.foundSVID >= 0 && !refitV0(dec.foundSVID, v0, recoData)) { + v0.invalidate(); + } + (*mDBGOut) << decTreeName.c_str() << "pdgPar=" << dec.pdg << "trPar=" << dec.parent << "prod=" << decFam << "found=" << dec.foundSVID << "sv=" << v0 << "\n"; } } } @@ -891,6 +968,7 @@ bool TrackMCStudy::processMCParticle(int src, int ev, int trid) } } if (decay >= 0) { // check if decay and kinematics is acceptable + auto& decayPool = mDecaysMaps[decay]; int idd0 = mcPart.getFirstDaughterTrackId(), idd1 = mcPart.getLastDaughterTrackId(); // we want only charged and trackable daughters int dtStart = mDecProdLblPool.size(), dtEnd = -1; if (idd0 < 0) { @@ -908,12 +986,17 @@ bool TrackMCStudy::processMCParticle(int src, int ev, int trid) } if (decay >= 0) { // account decay - dtEnd = mDecProdLblPool.size() - 1; + dtEnd = mDecProdLblPool.size(); + for (int dtid = dtStart; dtid < dtEnd; dtid++) { // flag selected decay parent entry in the prongs MCs + mSelMCTracks[mDecProdLblPool[dtid]].mcTrackInfo.parentEntry = decayPool.size(); + mSelMCTracks[mDecProdLblPool[dtid]].mcTrackInfo.parentDecID = int8_t(decay); + } + dtEnd--; std::array xyz{(float)mcPart.GetStartVertexCoordinatesX(), (float)mcPart.GetStartVertexCoordinatesY(), (float)mcPart.GetStartVertexCoordinatesZ()}; std::array pxyz{(float)mcPart.GetStartVertexMomentumX(), (float)mcPart.GetStartVertexMomentumY(), (float)mcPart.GetStartVertexMomentumZ()}; - mDecaysMaps[decay].emplace_back(DecayRef{lbl, - o2::track::TrackPar(xyz, pxyz, TMath::Nint(O2DatabasePDG::Instance()->GetParticle(mcPart.GetPdgCode())->Charge() / 3), false), - mcPart.GetPdgCode(), dtStart, dtEnd}); + decayPool.emplace_back(DecayRef{lbl, + o2::track::TrackPar(xyz, pxyz, TMath::Nint(O2DatabasePDG::Instance()->GetParticle(mcPart.GetPdgCode())->Charge() / 3), false), + mcPart.GetPdgCode(), dtStart, dtEnd}); if (mVerbose > 1) { LOGP(info, "Adding MC parent pdg={} {}, with prongs in {}:{} range", pdg, lbl.asString(), dtStart, dtEnd); } @@ -1005,6 +1088,51 @@ bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& l return true; } +bool TrackMCStudy::refitV0(int i, o2::dataformats::V0& v0, const o2::globaltracking::RecoContainer& recoData) +{ + const auto& id = recoData.getV0sIdx()[i]; + auto seedP = recoData.getTrackParam(id.getProngID(0)); + auto seedN = recoData.getTrackParam(id.getProngID(1)); + bool isTPConly = (id.getProngID(0).getSource() == GTrackID::TPC) || (id.getProngID(1).getSource() == GTrackID::TPC); + const auto& svparam = o2::vertexing::SVertexerParams::Instance(); + if (svparam.mTPCTrackPhotonTune && isTPConly) { + mFitterV0.setMaxDZIni(svparam.mTPCTrackMaxDZIni); + mFitterV0.setMaxDXYIni(svparam.mTPCTrackMaxDXYIni); + mFitterV0.setMaxChi2(svparam.mTPCTrackMaxChi2); + mFitterV0.setCollinear(true); + } + int nCand = mFitterV0.process(seedP, seedN); + if (svparam.mTPCTrackPhotonTune && isTPConly) { // restore + // Reset immediately to the defaults + mFitterV0.setMaxDZIni(svparam.maxDZIni); + mFitterV0.setMaxDXYIni(svparam.maxDXYIni); + mFitterV0.setMaxChi2(svparam.maxChi2); + mFitterV0.setCollinear(false); + } + if (nCand == 0) { // discard this pair + return false; + } + const int cand = 0; + if (!mFitterV0.isPropagateTracksToVertexDone(cand) && !mFitterV0.propagateTracksToVertex(cand)) { + return false; + } + const auto& trPProp = mFitterV0.getTrack(0, cand); + const auto& trNProp = mFitterV0.getTrack(1, cand); + std::array pP{}, pN{}; + trPProp.getPxPyPzGlo(pP); + trNProp.getPxPyPzGlo(pN); + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + auto p2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1] + pV0[2] * pV0[2]; + const auto& pv = recoData.getPrimaryVertex(id.getVertexID()); + const auto v0XYZ = mFitterV0.getPCACandidatePos(cand); + float dx = v0XYZ[0] - pv.getX(), dy = v0XYZ[1] - pv.getY(), dz = v0XYZ[2] - pv.getZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; + float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); + new (&v0) o2::dataformats::V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), trPProp, trNProp); + v0.setDCA(mFitterV0.getChi2AtPCACandidate(cand)); + v0.setCosPA(cosPA); + return true; +} + void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoData) { auto NHBPerTF = o2::base::GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); @@ -1037,7 +1165,7 @@ void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoDa } } -DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts) +DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV) { std::vector outputs; Options opts{ @@ -1052,6 +1180,9 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask dataRequest->requestTracks(srcTracks, useMC); dataRequest->requestClusters(srcClusters, useMC); dataRequest->requestPrimaryVertices(useMC); + if (checkSV) { + dataRequest->requestSecondaryVertices(useMC); + } o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs); o2::tpc::CorrectionMapsLoader::requestCCDBInputs(dataRequest->inputs, opts, sclOpts); auto ggRequest = std::make_shared(false, // orbitResetTime @@ -1067,7 +1198,7 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask "track-mc-study", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks, sclOpts)}, + AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, srcTracks, sclOpts, checkSV)}, opts}; } diff --git a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx index 03271000c6203..7ad11068f8a64 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx @@ -41,6 +41,7 @@ void customize(std::vector& workflowOptions) {"track-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of track sources to use"}}, {"cluster-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of cluster sources to use"}}, {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, + {"ignore-sv-check", VariantType::Bool, false, {"disable check for SV combinatorics"}}, {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation, never use it"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; o2::tpc::CorrectionMapsLoader::addGlobalOptions(options); @@ -56,6 +57,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) { WorkflowSpec specs; auto useMC = !configcontext.options().get("disable-mc"); + auto checkSV = !configcontext.options().get("ignore-sv-check"); if (!useMC) { throw std::runtime_error("MC cannot be disabled for this workflow"); } @@ -72,11 +74,14 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, true); // P-vertex is always needed + if (checkSV) { + o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); + } if (sclOpt.needTPCScalersWorkflow() && !configcontext.options().get("disable-root-input")) { specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt.lumiType == 2, sclOpt.enableMShapeCorrection)); } - specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, sclOpt)); + specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, sclOpt, checkSV)); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); From 365398d79b8f11fe81ede5549b906e7a7d0d5a92 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 18 Oct 2024 12:57:07 +0200 Subject: [PATCH 0386/2205] O2-5395: Trivial collision cut for some digitizers Adding a protection which cuts away collisions happening before the start of a timeframe. This is just a crude security measure to not get wrong digits coming from such collisions. To fully achieve the goal of https://its.cern.ch/jira/browse/O2-5395, a more careful handling of these collisions need to be implemented on a case-by-case (detector level) basis. --- Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx | 1 + Steer/DigitizerWorkflow/src/CPVDigitizerSpec.cxx | 13 +++++++++++++ Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx | 12 ++++++++++++ Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx | 12 ++++++++++++ Steer/DigitizerWorkflow/src/FV0DigitizerSpec.cxx | 13 +++++++++++++ Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx | 13 +++++++++++++ Steer/DigitizerWorkflow/src/PHOSDigitizerSpec.cxx | 14 ++++++++++++++ Steer/DigitizerWorkflow/src/ZDCDigitizerSpec.cxx | 12 ++++++++++++ 8 files changed, 90 insertions(+) diff --git a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx index 5d010b050e8b1..339f0e27ae050 100644 --- a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx @@ -93,6 +93,7 @@ class TRDDPLDigitizerTask : public o2::base::BaseDPLDigitizer size_t currTrig = 0; // from which collision is the current TRD trigger (only needed for debug information) bool firstEvent = true; // Flag for the first event processed + // the interaction record marking the timeframe start auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); TStopwatch timer; diff --git a/Steer/DigitizerWorkflow/src/CPVDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/CPVDigitizerSpec.cxx index fc64106e39d79..91b39a8f5031e 100644 --- a/Steer/DigitizerWorkflow/src/CPVDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/CPVDigitizerSpec.cxx @@ -29,6 +29,7 @@ #include "DetectorsBase/BaseDPLDigitizer.h" #include "SimConfig/DigiParams.h" #include "Framework/CCDBParamSpec.h" +#include "DetectorsRaw/HBFUtils.h" using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -121,9 +122,21 @@ void DigitizerSpec::run(framework::ProcessingContext& pc) bool isLastStream = true; double eventTime = timesview[0].getTimeNS() - o2::cpv::CPVSimParams::Instance().mDeadTime; // checked above that list not empty int eventId = 0; + + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + // loop over all composite collisions given from context // (aka loop over all the interaction records) for (int collID = 0; collID < n; ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (timesview[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } double dt = timesview[collID].getTimeNS() - eventTime; // start new PHOS readout, continue current or dead time? if (dt > mReadoutTime && dt < mDeadTime) { // dead time, skip event diff --git a/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx index 901c7e709d265..cb193aed81f73 100644 --- a/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx @@ -30,6 +30,7 @@ #include "DataFormatsFDD/ChannelData.h" #include "DataFormatsFDD/MCLabel.h" #include "DataFormatsFIT/DeadChannelMap.h" +#include "DetectorsRaw/HBFUtils.h" using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -96,7 +97,18 @@ class FDDDPLDigitizerTask : public o2::base::BaseDPLDigitizer std::vector hits; o2::dataformats::MCTruthContainer labels; + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + for (int collID = 0; collID < irecords.size(); ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (irecords[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } const auto& irec = irecords[collID]; mDigitizer.setInteractionRecord(irec); diff --git a/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx index 9098240d17627..5c6ba32c80819 100644 --- a/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx @@ -113,11 +113,23 @@ class FT0DPLDigitizerTask : public o2::base::BaseDPLDigitizer // o2::dataformats::MCTruthContainer labelAccum; o2::dataformats::MCTruthContainer labels; + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + // mDigitizer.setMCLabels(&labels); auto& eventParts = context->getEventParts(withQED); // loop over all composite collisions given from context // (aka loop over all the interaction records) for (int collID = 0; collID < timesview.size(); ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (timesview[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } + mDigitizer.setInteractionRecord(timesview[collID]); LOG(debug) << " setInteractionRecord " << timesview[collID] << " bc " << mDigitizer.getBC() << " orbit " << mDigitizer.getOrbit(); // for each collision, loop over the constituents event and source IDs diff --git a/Steer/DigitizerWorkflow/src/FV0DigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FV0DigitizerSpec.cxx index bb5174dfcbb2c..28f259c11162b 100644 --- a/Steer/DigitizerWorkflow/src/FV0DigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FV0DigitizerSpec.cxx @@ -29,6 +29,7 @@ #include "DataFormatsFV0/MCLabel.h" #include "SimulationDataFormat/MCCompLabel.h" #include "DetectorsBase/BaseDPLDigitizer.h" +#include "DetectorsRaw/HBFUtils.h" #include using namespace o2::framework; @@ -71,10 +72,22 @@ class FV0DPLDigitizerTask : public o2::base::BaseDPLDigitizer auto& irecords = context->getEventRecords(withQED); //TODO: QED implementation to be tested auto& eventParts = context->getEventParts(withQED); //TODO: QED implementation to be tested + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + // loop over all composite collisions given from context // (aka loop over all the interaction records) std::vector hits; for (int collID = 0; collID < irecords.size(); ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (irecords[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } + mDigitizer.clear(); const auto& irec = irecords[collID]; mDigitizer.setInteractionRecord(irec); diff --git a/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx index 2e888166d16fc..c0049cae8c443 100644 --- a/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx @@ -30,6 +30,7 @@ #include "DetectorsBase/BaseDPLDigitizer.h" #include "DetectorsCommonDataFormats/DetID.h" #include +#include "DetectorsRaw/HBFUtils.h" using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -95,9 +96,21 @@ class HMPIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer mIntRecord.push_back(o2::hmpid::Trigger(o2::InteractionRecord(mDigitizer.getBc(), mDigitizer.getOrbit()), first, digitsAccum.size() - first)); }; + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + // loop over all composite collisions given from context // (aka loop over all the interaction records) for (int collID = 0; collID < irecords.size(); ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (irecords[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } + // try to start new readout cycle by setting the trigger time auto triggeraccepted = mDigitizer.setTriggerTime(irecords[collID].getTimeNS()); if (triggeraccepted) { diff --git a/Steer/DigitizerWorkflow/src/PHOSDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/PHOSDigitizerSpec.cxx index 0b7b968d22ff6..da5e299b9eac2 100644 --- a/Steer/DigitizerWorkflow/src/PHOSDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/PHOSDigitizerSpec.cxx @@ -25,6 +25,7 @@ #include "PHOSBase/PHOSSimParams.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsPHOS/MCLabel.h" +#include "DetectorsRaw/HBFUtils.h" #include using namespace o2::framework; @@ -112,9 +113,22 @@ void DigitizerSpec::run(framework::ProcessingContext& pc) bool isLastStream = true; double eventTime = timesview[0].getTimeNS() - o2::phos::PHOSSimParams::Instance().mDeadTime; // checked above that list not empty int eventId = 0; + + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + // loop over all composite collisions given from context // (aka loop over all the interaction records) for (int collID = 0; collID < n; ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (timesview[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } + double dt = timesview[collID].getTimeNS() - eventTime; // start new PHOS readout, continue current or dead time? if (dt > mReadoutTime && dt < mDeadTime) { // dead time, skip event continue; diff --git a/Steer/DigitizerWorkflow/src/ZDCDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/ZDCDigitizerSpec.cxx index cd07f6389c43f..4b98ea8242916 100644 --- a/Steer/DigitizerWorkflow/src/ZDCDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/ZDCDigitizerSpec.cxx @@ -35,6 +35,7 @@ #include "SimConfig/DigiParams.h" #include "ZDCBase/ModuleConfig.h" #include "ZDCSimulation/SimCondition.h" +#include "DetectorsRaw/HBFUtils.h" using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -108,7 +109,18 @@ class ZDCDPLDigitizerTask : public o2::base::BaseDPLDigitizer // (aka loop over all the interaction records) std::vector hits; + // the interaction record marking the timeframe start + auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0); + for (int collID = 0; collID < irecords.size(); ++collID) { + // Note: Very crude filter to neglect collisions coming before + // the first interaction record of the timeframe. Remove this, once these collisions can be handled + // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe. + // See https://its.cern.ch/jira/browse/O2-5395. + if (irecords[collID] < firstTF) { + LOG(info) << "Too early: Not digitizing collision " << collID; + continue; + } const auto& irec = irecords[collID]; mDigitizer.setInteractionRecord(irec); From ffc81fd27a9780c56ccfc8d1578aa36efacf575c Mon Sep 17 00:00:00 2001 From: mcoquet642 Date: Mon, 28 Oct 2024 13:31:30 +0100 Subject: [PATCH 0387/2205] Updating alpide parameters also when no clusterization --- Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index d798bbc62204d..d104d05bb22b5 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -300,18 +300,18 @@ void STFDecoder::updateTimeDependentParams(ProcessingContext& pc) o2::base::GRPGeomHelper::instance().checkUpdates(pc); if (pc.services().get().globalRunNumberChanged) { // this params need to be queried only in the beginning of the run pc.inputs().get("noise"); + pc.inputs().get*>("alppar"); + const auto& alpParams = DPLAlpideParam::Instance(); + alpParams.printKeyValues(); if (mDoClusters) { mClusterer->setContinuousReadOut(o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(Mapping::getDetID())); pc.inputs().get("cldict"); - pc.inputs().get*>("alppar"); pc.inputs().get*>("cluspar"); // settings for the fired pixel overflow masking - const auto& alpParams = DPLAlpideParam::Instance(); const auto& clParams = ClustererParam::Instance(); if (clParams.maxBCDiffToMaskBias > 0 && clParams.maxBCDiffToSquashBias > 0) { LOGP(fatal, "maxBCDiffToMaskBias = {} and maxBCDiffToMaskBias = {} cannot be set at the same time. Either set masking or squashing with a BCDiff > 0", clParams.maxBCDiffToMaskBias, clParams.maxBCDiffToSquashBias); } - alpParams.printKeyValues(); clParams.printKeyValues(); auto nbc = clParams.maxBCDiffToMaskBias; nbc += mClusterer->isContinuousReadOut() ? alpParams.roFrameLengthInBC : (alpParams.roFrameLengthTrig / o2::constants::lhc::LHCBunchSpacingNS); From 804f7a218ab0d88a1177b9d5768ae493acb2cd16 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:42:12 +0100 Subject: [PATCH 0388/2205] DPL: finally use concepts to separate the make method (#13611) --- .../Core/include/Framework/DataAllocator.h | 189 ++++++++++-------- 1 file changed, 104 insertions(+), 85 deletions(-) diff --git a/Framework/Core/include/Framework/DataAllocator.h b/Framework/Core/include/Framework/DataAllocator.h index 0f1030c44ca86..9c563b06910b5 100644 --- a/Framework/Core/include/Framework/DataAllocator.h +++ b/Framework/Core/include/Framework/DataAllocator.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -57,14 +58,6 @@ namespace o2::framework { struct ServiceRegistry; -#define ERROR_STRING \ - "data type T not supported by API, " \ - "\n specializations available for" \ - "\n - trivially copyable, non-polymorphic structures" \ - "\n - arrays of those" \ - "\n - TObject with additional constructor arguments" \ - "\n - std containers of those" - /// Helper to allow framework managed objecs to have a callback /// when they go out of scope. For example, this could /// be used to serialize a message into a buffer before the @@ -130,6 +123,10 @@ struct LifetimeHolder { } }; +template +concept VectorOfMessageableTypes = is_specialization_v && + is_messageable::value; + /// This allocator is responsible to make sure that the messages created match /// the provided spec and that depending on how many pipelined reader we /// have, messages get created on the channel for the reader of the current @@ -143,6 +140,7 @@ class DataAllocator using DataOrigin = o2::header::DataOrigin; using DataDescription = o2::header::DataDescription; using SubSpecificationType = o2::header::DataHeader::SubSpecificationType; + template requires std::is_fundamental_v struct UninitializedVector { @@ -163,93 +161,114 @@ class DataAllocator // and with subspecification 0xdeadbeef. void cookDeadBeef(const Output& spec); - /// Generic helper to create an object which is owned by the framework and - /// returned as a reference to the own object. - /// Note: decltype(auto) will deduce the return type from the expression and it - /// will be lvalue reference for the framework-owned objects. Instances of local - /// variables like shared_ptr will be returned by value/move/return value optimization. - /// Objects created this way will be sent to the channel specified by @spec template + requires is_specialization_v decltype(auto) make(const Output& spec, Args... args) { auto& timingInfo = mRegistry.get(); auto& context = mRegistry.get(); - if constexpr (is_specialization_v) { - auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); - // plain buffer as polymorphic spectator std::vector, which does not run constructors / destructors - using ValueType = typename T::value_type; - - // Note: initial payload size is 0 and will be set by the context before sending - fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, 0); - return context.add>>>>( - std::move(headerMessage), routeIndex, 0, std::forward(args)...) - .get(); - } else if constexpr (is_specialization_v && has_messageable_value_type::value) { - auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); - // this catches all std::vector objects with messageable value type before checking if is also - // has a root dictionary, so non-serialized transmission is preferred - using ValueType = typename T::value_type; - - // Note: initial payload size is 0 and will be set by the context before sending - fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, 0); - return context.add>(std::move(headerMessage), routeIndex, 0, std::forward(args)...).get(); - } else if constexpr (has_root_dictionary::value == true && is_messageable::value == false) { - auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); - // Extended support for types implementing the Root ClassDef interface, both TObject - // derived types and others - if constexpr (enable_root_serialization::value) { - fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodROOT, 0); - - return context.add::object_type>(std::move(headerMessage), routeIndex, std::forward(args)...).get(); - } else { - static_assert(enable_root_serialization::value, "Please make sure you include RootMessageContext.h"); - } - // Note: initial payload size is 0 and will be set by the context before sending - } else if constexpr (std::is_base_of_v) { - auto* s = new std::string(args...); - adopt(spec, s); - return *s; - } else if constexpr (requires { static_cast(std::declval>()); }) { - auto tb = std::move(LifetimeHolder(new std::decay_t(args...))); - adopt(spec, tb); - return tb; - } else if constexpr (requires { static_cast(std::declval>()); }) { - auto t2t = std::move(LifetimeHolder(new std::decay_t(args...))); - adopt(spec, t2t); - return t2t; - } else if constexpr (sizeof...(Args) == 0) { - if constexpr (is_messageable::value == true) { - return *reinterpret_cast(newChunk(spec, sizeof(T)).data()); - } else { - static_assert(always_static_assert_v, ERROR_STRING); - } - } else if constexpr (sizeof...(Args) == 1) { - using FirstArg = typename std::tuple_element<0, std::tuple>::type; - if constexpr (std::is_integral_v) { - if constexpr (is_messageable::value == true) { - auto [nElements] = std::make_tuple(args...); - auto size = nElements * sizeof(T); - auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); - - fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, size); - return context.add>(std::move(headerMessage), routeIndex, 0, nElements).get(); - } - } else if constexpr (std::is_same_v>) { - if constexpr (std::is_base_of_v) { - auto [schema] = std::make_tuple(args...); - std::shared_ptr writer; - create(spec, &writer, schema); - return writer; - } - } else { - static_assert(always_static_assert_v, ERROR_STRING); - } + auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); + // plain buffer as polymorphic spectator std::vector, which does not run constructors / destructors + using ValueType = typename T::value_type; + + // Note: initial payload size is 0 and will be set by the context before sending + fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, 0); + return context.add>>>>( + std::move(headerMessage), routeIndex, 0, std::forward(args)...) + .get(); + } + + template + requires VectorOfMessageableTypes + decltype(auto) make(const Output& spec, Args... args) + { + auto& timingInfo = mRegistry.get(); + auto& context = mRegistry.get(); + + auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); + // this catches all std::vector objects with messageable value type before checking if is also + // has a root dictionary, so non-serialized transmission is preferred + using ValueType = typename T::value_type; + + // Note: initial payload size is 0 and will be set by the context before sending + fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, 0); + return context.add>(std::move(headerMessage), routeIndex, 0, std::forward(args)...).get(); + } + + template + requires(!VectorOfMessageableTypes && has_root_dictionary::value == true && is_messageable::value == false) + decltype(auto) make(const Output& spec, Args... args) + { + auto& timingInfo = mRegistry.get(); + auto& context = mRegistry.get(); + + auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); + // Extended support for types implementing the Root ClassDef interface, both TObject + // derived types and others + if constexpr (enable_root_serialization::value) { + fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodROOT, 0); + + return context.add::object_type>(std::move(headerMessage), routeIndex, std::forward(args)...).get(); } else { - static_assert(always_static_assert_v, ERROR_STRING); + static_assert(enable_root_serialization::value, "Please make sure you include RootMessageContext.h"); } } + template + requires std::is_base_of_v + decltype(auto) make(const Output& spec, Args... args) + { + auto* s = new std::string(args...); + adopt(spec, s); + return *s; + } + + template + requires(requires { static_cast(std::declval>()); }) + decltype(auto) make(const Output& spec, Args... args) + { + auto tb = std::move(LifetimeHolder(new std::decay_t(args...))); + adopt(spec, tb); + return tb; + } + + template + requires(requires { static_cast(std::declval>()); }) + decltype(auto) make(const Output& spec, Args... args) + { + auto t2t = std::move(LifetimeHolder(new std::decay_t(args...))); + adopt(spec, t2t); + return t2t; + } + + template + requires is_messageable::value && (!is_specialization_v) + decltype(auto) make(const Output& spec) + { + return *reinterpret_cast(newChunk(spec, sizeof(T)).data()); + } + + template + requires is_messageable::value && (!is_specialization_v) + decltype(auto) make(const Output& spec, std::integral auto nElements) + { + auto& timingInfo = mRegistry.get(); + auto& context = mRegistry.get(); + auto routeIndex = matchDataHeader(spec, timingInfo.timeslice); + + fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodNone, nElements * sizeof(T)); + return context.add>(std::move(headerMessage), routeIndex, 0, nElements).get(); + } + + template + decltype(auto) make(const Output& spec, std::same_as> auto schema) + { + std::shared_ptr writer; + create(spec, &writer, schema); + return writer; + } + /// Adopt a string in the framework and serialize / send /// it to the consumers of @a spec once done. void From 4618fcc463792756c207e53bf676141ad61c16a6 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:42:35 +0100 Subject: [PATCH 0389/2205] DPL Analysis: cleanup unused code (#13608) --- .../AnalysisSupport/src/DataInputDirector.cxx | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/Framework/AnalysisSupport/src/DataInputDirector.cxx b/Framework/AnalysisSupport/src/DataInputDirector.cxx index 6e072d47e523f..172ecd66c0e64 100644 --- a/Framework/AnalysisSupport/src/DataInputDirector.cxx +++ b/Framework/AnalysisSupport/src/DataInputDirector.cxx @@ -35,15 +35,6 @@ #include #endif -std::vector getColumnNames(o2::header::DataHeader dh) -{ - auto description = std::string(dh.dataDescription.str); - auto origin = std::string(dh.dataOrigin.str); - - // default: column names = {} - return {}; -} - namespace o2::framework { using namespace rapidjson; @@ -395,20 +386,10 @@ bool DataInputDescriptor::readTree(DataAllocator& outputs, header::DataHeader dh // add branches to read // fill the table - auto colnames = getColumnNames(dh); t2t->setLabel(tree->GetName()); - if (colnames.size() == 0) { - totalSizeCompressed += tree->GetZipBytes(); - totalSizeUncompressed += tree->GetTotBytes(); - t2t->addAllColumns(tree); - } else { - for (auto& colname : colnames) { - TBranch* branch = tree->GetBranch(colname.c_str()); - totalSizeCompressed += branch->GetZipBytes("*"); - totalSizeUncompressed += branch->GetTotBytes("*"); - } - t2t->addAllColumns(tree, std::move(colnames)); - } + totalSizeCompressed += tree->GetZipBytes(); + totalSizeUncompressed += tree->GetTotBytes(); + t2t->addAllColumns(tree); t2t->fill(tree); delete tree; From e4c085bf9887fd85536eff6bd9251568f2d12e60 Mon Sep 17 00:00:00 2001 From: Andrea Sofia Triolo Date: Tue, 29 Oct 2024 08:58:26 +0100 Subject: [PATCH 0390/2205] Adding ITS Efficiency study (#13600) * Adding ITS efficiency study * ITS Efficiency study: Separating studies per layer and adding 2D efficiency plots * ITS Efficiency study: adding method to calculate the efficiency in data. Changed way to calculate phi. Updating phi cuts. * ITS efficiency study: Added saveDataInfo() to save pt eta and phi for data. Trying with B=0 Added chi2 cut in MC and data * Please consider the following formatting changes * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot --- .../ITS/postprocessing/studies/CMakeLists.txt | 37 +- .../studies/include/ITSStudies/Efficiency.h | 61 + .../ITSStudies/ITSStudiesConfigParam.h | 7 + .../postprocessing/studies/src/Efficiency.cxx | 2862 +++++++++++++++++ .../studies/src/ITSStudiesConfigParam.cxx | 2 + .../studies/src/ITSStudiesLinkDef.h | 2 + .../standalone-postprocessing-workflow.cxx | 13 +- 7 files changed, 2965 insertions(+), 19 deletions(-) create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt index d1205aebbccfc..361ab4db4fb8e 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt @@ -10,23 +10,24 @@ # or submit itself to any jurisdiction. o2_add_library(ITSPostprocessing - SOURCES src/ImpactParameter.cxx - src/AvgClusSize.cxx - src/PIDStudy.cxx - src/ITSStudiesConfigParam.cxx - src/AnomalyStudy.cxx - src/TrackCheck.cxx - src/TrackExtension.cxx - src/Helpers.cxx - PUBLIC_LINK_LIBRARIES O2::GlobalTracking - O2::GlobalTrackingWorkflowReaders - O2::GlobalTrackingWorkflowHelpers - O2::DataFormatsGlobalTracking - O2::DetectorsVertexing - O2::DetectorsBase) +SOURCES src/ImpactParameter.cxx + src/AvgClusSize.cxx + src/PIDStudy.cxx + src/ITSStudiesConfigParam.cxx + src/AnomalyStudy.cxx + src/TrackCheck.cxx + src/TrackExtension.cxx + src/Efficiency.cxx + src/Helpers.cxx +PUBLIC_LINK_LIBRARIES O2::GlobalTracking + O2::GlobalTrackingWorkflowReaders + O2::GlobalTrackingWorkflowHelpers + O2::DataFormatsGlobalTracking + O2::DetectorsVertexing + O2::DetectorsBase) o2_target_root_dictionary(ITSPostprocessing - HEADERS include/ITSStudies/ITSStudiesConfigParam.h - include/ITSStudies/TrackCuts.h - include/ITSStudies/TrackMethods.h - LINKDEF src/ITSStudiesLinkDef.h) +HEADERS include/ITSStudies/ITSStudiesConfigParam.h + include/ITSStudies/TrackCuts.h + include/ITSStudies/TrackMethods.h +LINKDEF src/ITSStudiesLinkDef.h) \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h new file mode 100644 index 0000000000000..19df2279a2813 --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h @@ -0,0 +1,61 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_EFFICIENCY_STUDY_H +#define O2_EFFICIENCY_STUDY_H + +#include "Framework/DataProcessorSpec.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" + +namespace o2 +{ +namespace steer +{ +class MCKinematicsReader; +} +namespace its +{ +namespace study +{ +using mask_t = o2::dataformats::GlobalTrackID::mask_t; +o2::framework::DataProcessorSpec getEfficiencyStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader); + +////// phi cuts for B=0 +float mPhiCutsL0[10][2] = {{-122.5, -122}, {-91.8, -91.7}, {-61, -60}, {-30.1, -29.8}, {30, 30.2}, {59, 59.5}, {88, 89}, {117, 118.5}, {147, 147.8}, {176.5, 176.6}}; +float mPhiCutsL1[12][2] = {{-137, -136.5}, {-114, -113.5}, {-91.5, -91}, {-68.5, -68}, {-45.6, -45.4}, {-23.1, -22.9}, {45.4, 45.6}, {67.4, 67.6}, {89.4, 89.6}, {110.4, 110.6}, {132.4, 132.6}, {154.4, 154.6}}; +float mPhiCutsL2[17][2] = {{-162.85, -162.65}, {-145, -144.5}, {-127, -126.5}, {-109, -108.5}, {-91, -90.5}, {-73, -72.5}, {-55.1, -54.9}, {-37.35, -37.15}, {-19.5, -19}, {36.8, 37}, {54.4, 54.6}, {71.9, 72.1}, {89, 89.5}, {106.4, 106.6}, {123.65, 123.85}, {141.4, 141.6}, {158.9, 159.1}}; + +float mEtaCuts[2] = {-1.0, 1.0}; +// float mPtCuts[2] = {1, 4.5}; //// for B=5 +float mPtCuts[2] = {0, 10}; /// no cut for B=0 +int mChi2cut = 100; + +// values obtained from the dca study for B=5 +// float dcaXY[3] = {-0.000326, -0.000217, -0.000187}; +// float dcaZ[3] = {0.000020, -0.000004, 0.000032}; +// float sigmaDcaXY[3] = {0.001375, 0.001279, 0.002681}; +// float sigmaDcaZ[3] = {0.002196, 0.002083, 0.004125}; + +// values obtained from the dca study for B=0 +float dcaXY[3] = {-0.000328, -0.000213, -0.000203}; +float dcaZ[3] = {-0.000000543, -0.000013, 0.000001}; +float sigmaDcaXY[3] = {0.00109, 0.000895, 0.001520}; +float sigmaDcaZ[3] = {0.001366, 0.001149, 0.001868}; + +int dcaCut = 8; + +float mDCACutsXY[3][2] = {{dcaXY[0] - dcaCut * sigmaDcaXY[0], dcaXY[0] + dcaCut* sigmaDcaXY[0]}, {dcaXY[1] - dcaCut * sigmaDcaXY[1], dcaXY[1] + dcaCut* sigmaDcaXY[1]}, {dcaXY[2] - dcaCut * sigmaDcaXY[2], dcaXY[2] + dcaCut* sigmaDcaXY[2]}}; // cuts at 8 sigma for each layer for xy. The values represent m-8sigma and m+8sigma +float mDCACutsZ[3][2] = {{dcaZ[0] - dcaCut * sigmaDcaZ[0], dcaZ[0] + dcaCut* sigmaDcaZ[0]}, {dcaZ[1] - dcaCut * sigmaDcaZ[1], dcaZ[1] + dcaCut* sigmaDcaZ[1]}, {dcaZ[2] - dcaCut * sigmaDcaZ[2], dcaZ[2] + dcaCut* sigmaDcaZ[2]}}; + +} // namespace study +} // namespace its +} // namespace o2 +#endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h index 5884a0cadd815..85e114e0fb739 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h @@ -94,6 +94,13 @@ struct AnomalyStudyParamConfig : public o2::conf::ConfigurableParamHelper { + std::string outFileName = "ITS_efficiencyStudy.root"; + double b = 0; // Solenoid field in kG (+/-) + + O2ParamDef(ITSEfficiencyParamConfig, "ITSEfficiencyParam"); +}; + struct ITSImpactParameterParamConfig : public o2::conf::ConfigurableParamHelper { std::string outFileName = "its_ImpParameter.root"; int minNumberOfContributors = 0; diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx new file mode 100644 index 0000000000000..28e09e5d9a3be --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx @@ -0,0 +1,2862 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "TGeoGlobalMagField.h" +#include "ITSStudies/Efficiency.h" +#include "ITSStudies/ITSStudiesConfigParam.h" +#include "CommonUtils/TreeStreamRedirector.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/TopologyDictionary.h" +#include "DataFormatsGlobalTracking/RecoContainer.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/Task.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITStracking/IOUtils.h" +#include "ReconstructionDataFormats/DCA.h" +#include "SimulationDataFormat/MCTrack.h" +#include "Steer/MCKinematicsReader.h" +#include "ReconstructionDataFormats/TrackParametrization.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NLAYERS 3 + +namespace o2::its::study +{ +using namespace o2::framework; +using namespace o2::globaltracking; + +using GTrackID = o2::dataformats::GlobalTrackID; + +class EfficiencyStudy : public Task +{ + public: + EfficiencyStudy(std::shared_ptr dr, + mask_t src, + bool useMC, + std::shared_ptr kineReader, + std::shared_ptr gr) : mDataRequest(dr), mTracksSrc(src), mUseMC(useMC), mKineReader(kineReader), mGGCCDBRequest(gr){}; + + ~EfficiencyStudy() final = default; + void init(InitContext&) final; + void run(ProcessingContext&) final; + void endOfStream(EndOfStreamContext&) final; + void finaliseCCDB(ConcreteDataMatcher&, void*) final; + void initialiseRun(o2::globaltracking::RecoContainer&); + void stileEfficiencyGraph(std::unique_ptr& eff, const char* name, const char* title, bool bidimensional, const int markerStyle, const double markersize, const int markercolor, const int linercolor); + int getDCAClusterTrackMC(int countDuplicated); + void studyDCAcutsMC(); + void studyClusterSelectionMC(); + void countDuplicatedAfterCuts(); + void getEfficiency(bool isMC); + void getEfficiencyAndTrackInfo(bool isMC); + void saveDataInfo(); + void process(o2::globaltracking::RecoContainer&); + void setClusterDictionary(const o2::itsmft::TopologyDictionary* d) { mDict = d; } + + private: + void updateTimeDependentParams(ProcessingContext& pc); + bool mVerboseOutput = false; + bool mUseMC; + std::string mOutFileName; + double b; + std::shared_ptr mKineReader; + GeometryTGeo* mGeometry; + const o2::itsmft::TopologyDictionary* mDict = nullptr; + float mrangesPt[NLAYERS][2] = {{0., 0.5}, {0.5, 2.}, {2., 7.5}}; + + // Spans + gsl::span mTracksROFRecords; + gsl::span mClustersROFRecords; + gsl::span mTracks; + gsl::span mTracksMCLabels; + gsl::span mClusters; + gsl::span mClusPatterns; + gsl::span mInputITSidxs; + const o2::dataformats::MCLabelContainer* mClustersMCLCont; + std::vector> mITSClustersArray; + + // Data + GTrackID::mask_t mTracksSrc{}; + std::shared_ptr mDataRequest; + unsigned short mMask = 0x7f; + + // Utils + std::shared_ptr mGGCCDBRequest; + std::unique_ptr mOutFile; + int mDuplicated_layer[NLAYERS] = {0}; + const o2::parameters::GRPMagField* mGRPMagField = nullptr; + + //// Histos + // Distance betweeen original and duplicated clusters + std::unique_ptr mDistanceClustersX[NLAYERS]; + std::unique_ptr mDistanceClustersY[NLAYERS]; + std::unique_ptr mDistanceClustersZ[NLAYERS]; + std::unique_ptr mDistanceClusters[NLAYERS]; + // DCA betweeen track and original cluster + std::unique_ptr mDCAxyOriginal[NLAYERS]; + std::unique_ptr mDCAzOriginal[NLAYERS]; + // DCA betweeen track and duplicated cluster + std::unique_ptr mDCAxyDuplicated; + std::unique_ptr mDCAzDuplicated; + + // DCA betweeen track and duplicated cluster per layer + std::unique_ptr mDCAxyDuplicated_layer[NLAYERS]; + std::unique_ptr mDCAzDuplicated_layer[NLAYERS]; + + // phi, eta, pt of the cluster + std::unique_ptr mPhiOriginal[NLAYERS]; + std::unique_ptr mPhiTrackOriginal[NLAYERS]; + std::unique_ptr mEtaOriginal[NLAYERS]; + std::unique_ptr mPtOriginal[NLAYERS]; + TH1D* mPtDuplicated[NLAYERS]; + TH1D* mEtaDuplicated[NLAYERS]; + TH1D* mPhiDuplicated[NLAYERS]; + TH1D* mPhiTrackDuplicated[NLAYERS]; + TH2D* mPhiTrackDuplicatedvsphiDuplicated[NLAYERS]; + TH2D* mPhiTrackoriginalvsphioriginal[NLAYERS]; + TH1D* mPhiOriginalIfDuplicated[NLAYERS]; + + std::unique_ptr mZvsPhiDUplicated[NLAYERS]; + + // position of the clusters + std::unique_ptr m3DClusterPositions; + std::unique_ptr m3DDuplicatedClusterPositions; + std::unique_ptr m2DClusterOriginalPositions; + std::unique_ptr m2DClusterDuplicatedPositions; + + std::unique_ptr mXoriginal; + std::unique_ptr mYoriginal; + std::unique_ptr mZoriginal; + std::unique_ptr mXduplicated; + std::unique_ptr mYduplicated; + std::unique_ptr mZduplicated; + + // Efficiency histos + std::unique_ptr mEfficiencyGoodMatch; + std::unique_ptr mEfficiencyFakeMatch; + std::unique_ptr mEfficiencyTotal; + std::unique_ptr mEfficiencyGoodMatch_layer[NLAYERS]; + std::unique_ptr mEfficiencyFakeMatch_layer[NLAYERS]; + std::unique_ptr mEfficiencyTotal_layer[NLAYERS]; + TH2D* mEfficiencyGoodMatchPt_layer[NLAYERS]; + TH2D* mEfficiencyFakeMatchPt_layer[NLAYERS]; + TH2D* mEfficiencyGoodMatchEta_layer[NLAYERS]; + TH2D* mEfficiencyFakeMatchEta_layer[NLAYERS]; + TH2D* mEfficiencyGoodMatchPhi_layer[NLAYERS]; + TH2D* mEfficiencyGoodMatchPhiTrack_layer[NLAYERS]; + TH2D* mEfficiencyGoodMatchPhiOriginal_layer[NLAYERS]; + TH2D* mEfficiencyFakeMatchPhi_layer[NLAYERS]; + TH2D* mEfficiencyFakeMatchPhiTrack_layer[NLAYERS]; + + // phi, eta, pt of the duplicated cluster per layer + TH2D* mPt_EtaDupl[NLAYERS]; + + // duplicated per layer and per cut + std::unique_ptr mDuplicatedEtaAllPt[NLAYERS]; + std::unique_ptr mDuplicatedEta[NLAYERS][3]; + std::unique_ptr mDuplicatedPhiAllPt[NLAYERS]; + std::unique_ptr mDuplicatedPhi[NLAYERS][3]; + TH1D* mDuplicatedPt[NLAYERS]; + TH1D* mDuplicatedRow[NLAYERS]; + TH2D* mDuplicatedPtEta[NLAYERS]; + TH2D* mDuplicatedPtPhi[NLAYERS]; + TH2D* mDuplicatedEtaPhi[NLAYERS]; + + // matches per layer and per cut + std::unique_ptr mNGoodMatchesEtaAllPt[NLAYERS]; + std::unique_ptr mNGoodMatchesEta[NLAYERS][3]; + std::unique_ptr mNGoodMatchesPhiAllPt[NLAYERS]; + std::unique_ptr mNGoodMatchesPhi[NLAYERS][3]; + + std::unique_ptr mNFakeMatchesEtaAllPt[NLAYERS]; + std::unique_ptr mNFakeMatchesEta[NLAYERS][3]; + std::unique_ptr mNFakeMatchesPhiAllPt[NLAYERS]; + std::unique_ptr mNFakeMatchesPhi[NLAYERS][3]; + + TH1D* mNGoodMatchesPt[NLAYERS]; + TH1D* mNFakeMatchesPt[NLAYERS]; + + TH1D* mNGoodMatchesRow[NLAYERS]; + TH1D* mNFakeMatchesRow[NLAYERS]; + + TH2D* mNGoodMatchesPtEta[NLAYERS]; + TH2D* mNFakeMatchesPtEta[NLAYERS]; + + TH2D* mNGoodMatchesPtPhi[NLAYERS]; + TH2D* mNFakeMatchesPtPhi[NLAYERS]; + + TH2D* mNGoodMatchesEtaPhi[NLAYERS]; + TH2D* mNFakeMatchesEtaPhi[NLAYERS]; + + // calculating the efficiency with TEfficiency class + std::unique_ptr mEffPtGood[NLAYERS]; + std::unique_ptr mEffPtFake[NLAYERS]; + std::unique_ptr mEffRowGood[NLAYERS]; + std::unique_ptr mEffRowFake[NLAYERS]; + std::unique_ptr mEffPtEtaGood[NLAYERS]; + std::unique_ptr mEffPtEtaFake[NLAYERS]; + std::unique_ptr mEffPtPhiGood[NLAYERS]; + std::unique_ptr mEffPtPhiFake[NLAYERS]; + std::unique_ptr mEffEtaPhiGood[NLAYERS]; + std::unique_ptr mEffEtaPhiFake[NLAYERS]; + + std::unique_ptr mEffEtaGoodAllPt[NLAYERS]; + std::unique_ptr mEffEtaGood[NLAYERS][3]; + std::unique_ptr mEffEtaFakeAllPt[NLAYERS]; + std::unique_ptr mEffEtaFake[NLAYERS][3]; + + std::unique_ptr mEffPhiGoodAllPt[NLAYERS]; + std::unique_ptr mEffPhiGood[NLAYERS][3]; + std::unique_ptr mEffPhiFakeAllPt[NLAYERS]; + std::unique_ptr mEffPhiFake[NLAYERS][3]; + + TH2D* mnGoodMatchesPt_layer[NLAYERS]; + TH2D* mnFakeMatchesPt_layer[NLAYERS]; + + TH2D* mnGoodMatchesEta_layer[NLAYERS]; + TH2D* mnFakeMatchesEta_layer[NLAYERS]; + + TH2D* mnGoodMatchesPhi_layer[NLAYERS]; + TH2D* mnGoodMatchesPhiTrack_layer[NLAYERS]; + TH2D* mnGoodMatchesPhiOriginal_layer[NLAYERS]; + TH2D* mnFakeMatchesPhi_layer[NLAYERS]; + TH2D* mnFakeMatchesPhiTrack_layer[NLAYERS]; + + std::unique_ptr DCAxyData[NLAYERS]; + std::unique_ptr DCAzData[NLAYERS]; + + std::unique_ptr DCAxyRejected[NLAYERS]; + std::unique_ptr DCAzRejected[NLAYERS]; + + std::unique_ptr DistanceClustersX[NLAYERS]; + std::unique_ptr DistanceClustersY[NLAYERS]; + std::unique_ptr DistanceClustersZ[NLAYERS]; + std::unique_ptr DistanceClustersXAftercuts[NLAYERS]; + std::unique_ptr DistanceClustersYAftercuts[NLAYERS]; + std::unique_ptr DistanceClustersZAftercuts[NLAYERS]; + + TH1D* denPt[NLAYERS]; + TH1D* numPt[NLAYERS]; + TH1D* numPtGood[NLAYERS]; + TH1D* numPtFake[NLAYERS]; + + TH1D* denPhi[NLAYERS]; + TH1D* numPhi[NLAYERS]; + TH1D* numPhiGood[NLAYERS]; + TH1D* numPhiFake[NLAYERS]; + + TH1D* denEta[NLAYERS]; + TH1D* numEta[NLAYERS]; + TH1D* numEtaGood[NLAYERS]; + TH1D* numEtaFake[NLAYERS]; + + int nDuplicatedClusters[NLAYERS] = {0}; + int nTracksSelected[NLAYERS] = {0}; // denominator fot the efficiency calculation + + TH2D* diffPhivsPt[NLAYERS]; + TH1D* diffTheta[NLAYERS]; + + TH1D* thetaOriginal[NLAYERS]; + TH1D* thetaOriginalCalc[NLAYERS]; + TH1D* thetaDuplicated[NLAYERS]; + TH1D* thetaOriginalCalcWhenDuplicated[NLAYERS]; + TH1D* thetaOriginalWhenDuplicated[NLAYERS]; + + std::unique_ptr IPOriginalxy[NLAYERS]; + std::unique_ptr IPOriginalz[NLAYERS]; + std::unique_ptr IPOriginalifDuplicatedxy[NLAYERS]; + std::unique_ptr IPOriginalifDuplicatedz[NLAYERS]; + + std::unique_ptr chipRowDuplicated[NLAYERS]; + std::unique_ptr chipRowOriginalIfDuplicated[NLAYERS]; + + std::unique_ptr chi2track; + std::unique_ptr chi2trackAccepted; +}; + +void EfficiencyStudy::init(InitContext& ic) +{ + LOGP(info, "--------------- init"); + + o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); + + auto& pars = o2::its::study::ITSEfficiencyParamConfig::Instance(); + mOutFileName = pars.outFileName; + b = pars.b; + + int nbPt = 75; + double xbins[nbPt + 1], ptcutl = 0.05, ptcuth = 7.5; + double a = std::log(ptcuth / ptcutl) / nbPt; + for (int i = 0; i <= nbPt; i++) { + xbins[i] = ptcutl * std::exp(i * a); + } + + mOutFile = std::make_unique(mOutFileName.c_str(), "recreate"); + + mXoriginal = std::make_unique("xoriginal", "x original ;x (cm); ", 200, 0, 0); + mYoriginal = std::make_unique("yoriginal", "y original ;y (cm); ", 200, 0, 0); + mZoriginal = std::make_unique("zoriginal", "z original ;z (cm); ", 300, 0, 0); + mXduplicated = std::make_unique("xduplicated", "x duplicated ;x (cm); ", 200, -10, 10); + mYduplicated = std::make_unique("yduplicated", "y duplicated ;y (cm); ", 200, -10, 10); + mZduplicated = std::make_unique("zduplicated", "z duplicated ;z (cm); ", 300, -30, 30); + + mDCAxyDuplicated = std::make_unique("dcaXYDuplicated", "Distance between track and duplicated cluster ;DCA xy (cm); ", 400, -0.2, 0.2); + mDCAzDuplicated = std::make_unique("dcaZDuplicated", "Distance between track and duplicated cluster ;DCA z (cm); ", 400, -0.2, 0.2); + + m3DClusterPositions = std::make_unique("3DClusterPositions", ";x (cm);y (cm);z (cm)", 200, -10, 10, 200, -10, 10, 400, -20, 20); + m3DDuplicatedClusterPositions = std::make_unique("3DDuplicatedClusterPositions", ";x (cm);y (cm);z (cm)", 200, -10, 10, 200, -10, 10, 500, -30, 30); + m2DClusterOriginalPositions = std::make_unique("m2DClusterOriginalPositions", ";x (cm);y (cm)", 400, -10, 10, 400, -6, 6); + m2DClusterDuplicatedPositions = std::make_unique("m2DClusterDuplicatedPositions", ";x (cm);y (cm)", 400, -10, 10, 400, -6, 6); + + mEfficiencyGoodMatch = std::make_unique("mEfficiencyGoodMatch", ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + mEfficiencyFakeMatch = std::make_unique("mEfficiencyFakeMatch", ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + mEfficiencyTotal = std::make_unique("mEfficiencyTotal", ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + + chi2track = std::make_unique("chi2track", "; $chi^{2}", 500, 0, 100); + chi2trackAccepted = std::make_unique("chi2trackAccepted", "; $chi^{2}", 500, 0, 100); + + for (int i = 0; i < NLAYERS; i++) { + + chipRowDuplicated[i] = std::make_unique(Form("chipPosDuplicated_L%d", i), Form("L%d; row", i), 512, -0.5, 511.5); + chipRowOriginalIfDuplicated[i] = std::make_unique(Form("chipPosOriginalIfDuplicated%d", i), Form("L%d; row", i), 512, -0.5, 511.5); + + DCAxyData[i] = std::make_unique(Form("dcaXYData_L%d", i), "Distance between track and original cluster ;DCA xy (cm); ", 4000, -2, 2); + DCAzData[i] = std::make_unique(Form("dcaZData_L%d", i), "Distance between track and original cluster ;DCA z (cm); ", 4000, -2, 2); + DCAxyRejected[i] = std::make_unique(Form("DCAxyRejected%d", i), "Distance between track and original cluster (rejected) ;DCA xy (cm); ", 30000, -30, 30); + DCAzRejected[i] = std::make_unique(Form("DCAzRejected%d", i), "Distance between track and original cluster (rejected) ;DCA z (cm); ", 30000, -30, 30); + + DistanceClustersX[i] = std::make_unique(Form("distanceClustersX_L%d", i), ";Distance x (cm); ", 100, 0, 1); + DistanceClustersY[i] = std::make_unique(Form("distanceClustersY_L%d", i), ";Distance y (cm); ", 100, 0, 1); + DistanceClustersZ[i] = std::make_unique(Form("distanceClustersZ_L%d", i), ";Distance z (cm); ", 100, 0, 1); + DistanceClustersXAftercuts[i] = std::make_unique(Form("distanceClustersXAftercuts_L%d", i), ";Distance x (cm); ", 100, 0, 1); + DistanceClustersYAftercuts[i] = std::make_unique(Form("distanceClustersYAftercuts_L%d", i), ";Distance y (cm); ", 100, 0, 1); + DistanceClustersZAftercuts[i] = std::make_unique(Form("distanceClustersZAftercuts_L%d", i), ";Distance z (cm); ", 100, 0, 1); + + mDistanceClustersX[i] = std::make_unique(Form("distanceClustersX_L%d", i), ";Distance x (cm); ", 100, 0, 1); + mDistanceClustersY[i] = std::make_unique(Form("distanceClustersY_L%d", i), ";Distance y (cm); ", 100, 0, 1); + mDistanceClustersZ[i] = std::make_unique(Form("distanceClustersZ_L%d", i), ";Distance z (cm); ", 100, 0, 1); + mDistanceClusters[i] = std::make_unique(Form("distanceClusters_L%d", i), ";Distance (cm); ", 100, 0, 1); + + mDCAxyOriginal[i] = std::make_unique(Form("dcaXYOriginal_L%d", i), "Distance between track and original cluster ;DCA xy (cm); ", 400, -0.2, 0.2); + mDCAzOriginal[i] = std::make_unique(Form("dcaZOriginal_L%d", i), "Distance between track and original cluster ;DCA z (cm); ", 400, -0.2, 0.2); + + mPhiOriginal[i] = std::make_unique(Form("phiOriginal_L%d", i), ";phi (deg); ", 1440, -180, 180); + mPhiTrackOriginal[i] = std::make_unique(Form("phiTrackOriginal_L%d", i), ";phi Track (deg); ", 1440, 0, 360); + mEtaOriginal[i] = std::make_unique(Form("etaOriginal_L%d", i), ";eta (deg); ", 100, -2, 2); + mPtOriginal[i] = std::make_unique(Form("ptOriginal_L%d", i), ";pt (GeV/c); ", 100, 0, 10); + + mZvsPhiDUplicated[i] = std::make_unique(Form("zvsphiDuplicated_L%d", i), ";z (cm);phi (deg)", 400, -20, 20, 1440, -180, 180); + + mPtDuplicated[i] = new TH1D(Form("ptDuplicated_L%d", i), ";pt (GeV/c); ", nbPt, 0, 7.5); // xbins); + mEtaDuplicated[i] = new TH1D(Form("etaDuplicated_L%d", i), ";eta; ", 40, -2, 2); + mPhiDuplicated[i] = new TH1D(Form("phiDuplicated_L%d", i), ";phi (deg); ", 1440, -180, 180); + mPhiTrackDuplicated[i] = new TH1D(Form("phiTrackDuplicated_L%d", i), ";phi Track (deg); ", 1440, 0, 360); + mPhiOriginalIfDuplicated[i] = new TH1D(Form("phiOriginalIfDuplicated_L%d", i), ";phi (deg); ", 1440, -180, 180); + mPhiTrackDuplicatedvsphiDuplicated[i] = new TH2D(Form("phiTrackDuplicatedvsphiDuplicated_L%d", i), ";phi track (deg);phi oridinal if duplicated (deg); ", 1440, 0, 360, 1440, -180, 180); + mPhiTrackoriginalvsphioriginal[i] = new TH2D(Form("phiTrackoriginalvsphioriginal_L%d", i), ";phi track (deg);phi original (deg); ", 1440, 0, 360, 1440, -180, 180); + mDCAxyDuplicated_layer[i] = std::make_unique(Form("dcaXYDuplicated_layer_L%d", i), "Distance between track and duplicated cluster ;DCA xy (cm); ", 400, -0.2, 0.2); + mDCAzDuplicated_layer[i] = std::make_unique(Form("dcaZDuplicated_layer_L%d", i), "Distance between track and duplicated cluster ;DCA z (cm); ", 400, -0.2, 0.2); + + mEfficiencyGoodMatch_layer[i] = std::make_unique(Form("mEfficiencyGoodMatch_layer_L%d", i), ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + mEfficiencyFakeMatch_layer[i] = std::make_unique(Form("mEfficiencyFakeMatch_layer_L%d", i), ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + mEfficiencyTotal_layer[i] = std::make_unique(Form("mEfficiencyTotal_layer_L%d", i), ";#sigma(DCA) cut;Efficiency;", 20, 0.5, 20.5); + + mEfficiencyGoodMatchPt_layer[i] = new TH2D(Form("mEfficiencyGoodMatchPt_layer_L%d", i), ";#it{p}_{T} (GeV/c);#sigma(DCA) cut;Efficiency;", nbPt, 0, 7.5, /* xbins*/ 20, 0.5, 20.5); + mEfficiencyFakeMatchPt_layer[i] = new TH2D(Form("mEfficiencyFakeMatchPt_layer_L%d", i), ";#it{p}_{T} (GeV/c);#sigma(DCA) cut;Efficiency;", nbPt, 0, 7.5, /* xbins*/ 20, 0.5, 20.5); + + mEfficiencyGoodMatchEta_layer[i] = new TH2D(Form("mEfficiencyGoodMatchEta_layer_L%d", i), ";#eta;#sigma(DCA) cut;Efficiency;", 40, -2, 2, 20, 0.5, 20.5); + mEfficiencyFakeMatchEta_layer[i] = new TH2D(Form("mEfficiencyFakeMatchEta_layer_L%d", i), ";#eta;#sigma(DCA) cut;Efficiency;", 40, -2, 2, 20, 0.5, 20.5); + + mEfficiencyGoodMatchPhi_layer[i] = new TH2D(Form("mEfficiencyGoodMatchPhi_layer_L%d", i), ";#phi;#sigma(DCA) cut;Efficiency;", 1440, -180, 180, 20, 0.5, 20.5); + mEfficiencyGoodMatchPhiTrack_layer[i] = new TH2D(Form("mEfficiencyGoodMatchPhiTrack_layer_L%d", i), ";#phi track;#sigma(DCA) cut;Efficiency;", 1440, 0, 360, 20, 0.5, 20.5); + mEfficiencyGoodMatchPhiOriginal_layer[i] = new TH2D(Form("mEfficiencyGoodMatchPhiOriginal_layer_L%d", i), ";#phi Original;#sigma(DCA) cut;Efficiency;", 1440, -180, 180, 20, 0.5, 20.5); + mEfficiencyFakeMatchPhi_layer[i] = new TH2D(Form("mEfficiencyFakeMatchPhi_layer_L%d", i), ";#phi;#sigma(DCA) cut;Efficiency;", 1440, -180, 180, 20, 0.5, 20.5); + mEfficiencyFakeMatchPhiTrack_layer[i] = new TH2D(Form("mEfficiencyFakeMatchPhiTrack_layer_L%d", i), ";#phi Track;#sigma(DCA) cut;Efficiency;", 1440, 0, 360, 20, 0.5, 20.5); + + mPt_EtaDupl[i] = new TH2D(Form("mPt_EtaDupl_L%d", i), ";#it{p}_{T} (GeV/c);#eta; ", 100, 0, 10, 100, -2, 2); + + mDuplicatedPt[i] = new TH1D(Form("mDuplicatedPt_log_L%d", i), Form("; #it{p}_{T} (GeV/c); Number of duplciated clusters L%d", i), nbPt, 0, 7.5 /* xbins*/); + mDuplicatedPt[i]->Sumw2(); + mNGoodMatchesPt[i] = new TH1D(Form("mNGoodMatchesPt_L%d", i), Form("; #it{p}_{T} (GeV/c); Number of good matches L%d", i), nbPt, 0, 7.5 /* xbins*/); + mNGoodMatchesPt[i]->Sumw2(); + mNFakeMatchesPt[i] = new TH1D(Form("mNFakeMatchesPt_L%d", i), Form("; #it{p}_{T} (GeV/c); Number of fake matches L%d", i), nbPt, 0, 7.5 /* xbins*/); + mNFakeMatchesPt[i]->Sumw2(); + + mDuplicatedRow[i] = new TH1D(Form("mDuplicatedRow_L%d", i), Form("; Row; Number of duplciated clusters L%d", i), 512, -0.5, 511.5); + mDuplicatedRow[i]->Sumw2(); + mNGoodMatchesRow[i] = new TH1D(Form("mNGoodMatchesRow_L%d", i), Form("; Row; Number of good matches L%d", i), 512, -0.5, 511.5); + mNGoodMatchesRow[i]->Sumw2(); + mNFakeMatchesRow[i] = new TH1D(Form("mNFakeMatchesRow_L%d", i), Form(";Row; Number of fake matches L%d", i), 512, -0.5, 511.5); + mNFakeMatchesRow[i]->Sumw2(); + + mDuplicatedPtEta[i] = new TH2D(Form("mDuplicatedPtEta_log_L%d", i), Form("; #it{p}_{T} (GeV/c);#eta; Number of duplciated clusters L%d", i), nbPt, 0, 7.5 /* xbins*/, 40, -2, 2); + mDuplicatedPtEta[i]->Sumw2(); + mNGoodMatchesPtEta[i] = new TH2D(Form("mNGoodMatchesPtEta_L%d", i), Form("; #it{p}_{T} (GeV/c);#eta; Number of good matches L%d", i), nbPt, 0, 7.5 /* xbins*/, 40, -2, 2); + mNGoodMatchesPtEta[i]->Sumw2(); + mNFakeMatchesPtEta[i] = new TH2D(Form("mNFakeMatchesPtEta_L%d", i), Form("; #it{p}_{T} (GeV/c);#eta; Number of good matches L%d", i), nbPt, 0, 7.5 /* xbins*/, 40, -2, 2); + mNFakeMatchesPtEta[i]->Sumw2(); + + mDuplicatedPtPhi[i] = new TH2D(Form("mDuplicatedPtPhi_log_L%d", i), Form("; #it{p}_{T} (GeV/c);#phi (deg); Number of duplciated clusters L%d", i), nbPt, 0, 7.5 /* xbins*/, 1440, -180, 180); + mDuplicatedPtPhi[i]->Sumw2(); + mNGoodMatchesPtPhi[i] = new TH2D(Form("mNGoodMatchesPtPhi_L%d", i), Form("; #it{p}_{T} (GeV/c);#phi (deg); Number of good matches L%d", i), nbPt, 0, 7.5 /* xbins*/, 1440, -180, 180); + mNGoodMatchesPtPhi[i]->Sumw2(); + mNFakeMatchesPtPhi[i] = new TH2D(Form("mNFakeMatchesPtPhi_L%d", i), Form("; #it{p}_{T} (GeV/c);#phi (deg); Number of good matches L%d", i), nbPt, 0, 7.5 /* xbins*/, 1440, -180, 180); + mNFakeMatchesPtPhi[i]->Sumw2(); + + mDuplicatedEtaPhi[i] = new TH2D(Form("mDuplicatedEtaPhi_L%d", i), Form("; #eta;#phi (deg); Number of duplciated clusters L%d", i), 40, -2, 2, 1440, -180, 180); + mDuplicatedEtaPhi[i]->Sumw2(); + mNGoodMatchesEtaPhi[i] = new TH2D(Form("mNGoodMatchesEtaPhi_L%d", i), Form("; #eta;#phi (deg); Number of good matches L%d", i), 40, -2, 2, 1440, -180, 180); + mNGoodMatchesEtaPhi[i]->Sumw2(); + mNFakeMatchesEtaPhi[i] = new TH2D(Form("mNFakeMatchesEtaPhi_L%d", i), Form("; #eta;#phi (deg); Number of good matches L%d", i), 40, -2, 2, 1440, -180, 180); + mNFakeMatchesEtaPhi[i]->Sumw2(); + + mDuplicatedEtaAllPt[i] = std::make_unique(Form("mDuplicatedEtaAllPt_L%d", i), Form("; #eta; Number of duplicated clusters L%d", i), 40, -2, 2); + mNGoodMatchesEtaAllPt[i] = std::make_unique(Form("mNGoodMatchesEtaAllPt_L%d", i), Form("; #eta; Number of good matches L%d", i), 40, -2, 2); + mNFakeMatchesEtaAllPt[i] = std::make_unique(Form("mNFakeMatchesEtaAllPt_L%d", i), Form("; #eta; Number of fake matches L%d", i), 40, -2, 2); + + mDuplicatedPhiAllPt[i] = std::make_unique(Form("mDuplicatedPhiAllPt_L%d", i), Form("; #phi (deg); Number of duplicated clusters L%d", i), 1440, -180, 180); + mNGoodMatchesPhiAllPt[i] = std::make_unique(Form("mNGoodMatchesPhiAllPt_L%d", i), Form("; #phi (deg); Number of good matches L%d", i), 1440, -180, 180); + mNFakeMatchesPhiAllPt[i] = std::make_unique(Form("mNFakeMatchesPhiAllPt_L%d", i), Form("; #phi (deg); Number of fake matches L%d", i), 1440, -180, 180); + + mnGoodMatchesPt_layer[i] = new TH2D(Form("mnGoodMatchesPt_layer_L%d", i), ";pt; nGoodMatches", nbPt, 0, 7.5 /* xbins*/, 20, 0.5, 20.5); + mnFakeMatchesPt_layer[i] = new TH2D(Form("mnFakeMatchesPt_layer_L%d", i), ";pt; nFakeMatches", nbPt, 0, 7.5 /* xbins*/, 20, 0.5, 20.5); + mnGoodMatchesEta_layer[i] = new TH2D(Form("mnGoodMatchesEta_layer_L%d", i), ";#eta; nGoodMatches", 40, -2, 2, 20, 0.5, 20.5); + mnFakeMatchesEta_layer[i] = new TH2D(Form("mnFakeMatchesEta_layer_L%d", i), ";#eta; nFakeMatches", 40, -2, 2, 20, 0.5, 20.5); + mnGoodMatchesPhi_layer[i] = new TH2D(Form("mnGoodMatchesPhi_layer_L%d", i), ";#Phi; nGoodMatches", 1440, -180, 180, 20, 0.5, 20.5); + mnGoodMatchesPhiTrack_layer[i] = new TH2D(Form("mnGoodMatchesPhiTrack_layer_L%d", i), ";#Phi track; nGoodMatches", 1440, 0, 360, 20, 0.5, 20.5); + mnGoodMatchesPhiOriginal_layer[i] = new TH2D(Form("mnGoodMatchesPhiOriginal_layer_L%d", i), ";#Phi of the original Cluster; nGoodMatches", 1440, -180, 180, 20, 0.5, 20.5); + mnFakeMatchesPhi_layer[i] = new TH2D(Form("mnFakeMatchesPhi_layer_L%d", i), ";#Phi; nFakeMatches", 1440, -180, 180, 20, 0.5, 20.5); + mnFakeMatchesPhiTrack_layer[i] = new TH2D(Form("mnFakeMatchesPhiTrack_layer_L%d", i), ";#Phi track; nFakeMatches", 1440, 0, 360, 20, 0.5, 20.5); + + denPt[i] = new TH1D(Form("denPt_L%d", i), Form("denPt_L%d", i), nbPt, 0, 7.5 /* xbins*/); + numPt[i] = new TH1D(Form("numPt_L%d", i), Form("numPt_L%d", i), nbPt, 0, 7.5 /* xbins*/); + numPtGood[i] = new TH1D(Form("numPtGood_L%d", i), Form("numPtGood_L%d", i), nbPt, 0, 7.5 /* xbins*/); + numPtFake[i] = new TH1D(Form("numPtFake_L%d", i), Form("numPtFake_L%d", i), nbPt, 0, 7.5 /* xbins*/); + + denPhi[i] = new TH1D(Form("denPhi_L%d", i), Form("denPhi_L%d", i), 1440, -180, 180); + numPhi[i] = new TH1D(Form("numPhi_L%d", i), Form("numPhi_L%d", i), 1440, -180, 180); + numPhiGood[i] = new TH1D(Form("numPhiGood_L%d", i), Form("numPhiGood_L%d", i), 1440, -180, 180); + numPhiFake[i] = new TH1D(Form("numPhiFake_L%d", i), Form("numPhiFake_L%d", i), 1440, -180, 180); + + denEta[i] = new TH1D(Form("denEta_L%d", i), Form("denEta_L%d", i), 200, -2, 2); + numEta[i] = new TH1D(Form("numEta_L%d", i), Form("numEta_L%d", i), 200, -2, 2); + numEtaGood[i] = new TH1D(Form("numEtaGood_L%d", i), Form("numEtaGood_L%d", i), 200, -2, 2); + numEtaFake[i] = new TH1D(Form("numEtaFake_L%d", i), Form("numEtaFake_L%d", i), 200, -2, 2); + + diffPhivsPt[i] = new TH2D(Form("diffPhivsPt_L%d", i), Form("diffPhivsPt_L%d", i), nbPt, 0, 7.5 /* xbins*/, 50, 0, 5); + + IPOriginalxy[i] = std::make_unique(Form("IPOriginalxy_L%d", i), Form("IPOriginalxy_L%d", i), 500, -0.002, 0.002); + IPOriginalz[i] = std::make_unique(Form("IPOriginalz_L%d", i), Form("IPOriginalz_L%d", i), 200, -10, 10); + IPOriginalifDuplicatedxy[i] = std::make_unique(Form("IPOriginalifDuplicatedxy_L%d", i), Form("IPOriginalifDuplicatedxy_L%d", i), 1000, -0.005, 0.005); + IPOriginalifDuplicatedz[i] = std::make_unique(Form("IPOriginalifDuplicatedz_L%d", i), Form("IPOriginalifDuplicatedz_L%d", i), 200, -10, 10); + + for (int j = 0; j < 3; j++) { + mDuplicatedEta[i][j] = std::make_unique(Form("mDuplicatedEta_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #eta; Number of duplicated clusters L%d", mrangesPt[j][0], mrangesPt[j][1], i), 40, -2, 2); + mNGoodMatchesEta[i][j] = std::make_unique(Form("mNGoodMatchesEta_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #eta; Number of good matches L%d", mrangesPt[j][0], mrangesPt[j][1], i), 40, -2, 2); + mNFakeMatchesEta[i][j] = std::make_unique(Form("mNFakeMatchesEta_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #eta; Number of fake matches L%d", mrangesPt[j][0], mrangesPt[j][1], i), 40, -2, 2); + + mDuplicatedPhi[i][j] = std::make_unique(Form("mDuplicatedPhi_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #phi; Number of duplicated clusters L%d", mrangesPt[j][0], mrangesPt[j][1], i), 1440, -180, 180); + mNGoodMatchesPhi[i][j] = std::make_unique(Form("mNGoodMatchesPhi_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #phi; Number of good matches L%d", mrangesPt[j][0], mrangesPt[j][1], i), 1440, -180, 180); + mNFakeMatchesPhi[i][j] = std::make_unique(Form("mNFakeMatchesPhi_L%d_pt%d", i, j), Form("%f < #it{p}_{T} < %f GeV/c; #phi; Number of fake matches L%d", mrangesPt[j][0], mrangesPt[j][1], i), 1440, -180, 180); + } + } + gStyle->SetPalette(55); +} + +void EfficiencyStudy::run(ProcessingContext& pc) +{ + LOGP(info, "--------------- run"); + o2::globaltracking::RecoContainer recoData; + recoData.collectData(pc, *mDataRequest.get()); + + updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions + initialiseRun(recoData); + process(recoData); +} + +void EfficiencyStudy::initialiseRun(o2::globaltracking::RecoContainer& recoData) +{ + LOGP(info, "--------------- initialiseRun"); + if (mUseMC) { + mTracksMCLabels = recoData.getITSTracksMCLabels(); + mClustersMCLCont = recoData.getITSClustersMCLabels(); + } + + mITSClustersArray.clear(); + mTracksROFRecords = recoData.getITSTracksROFRecords(); + mTracks = recoData.getITSTracks(); + mClusters = recoData.getITSClusters(); + mClustersROFRecords = recoData.getITSClustersROFRecords(); + mClusPatterns = recoData.getITSClustersPatterns(); + mInputITSidxs = recoData.getITSTracksClusterRefs(); + mITSClustersArray.reserve(mClusters.size()); + auto pattIt = mClusPatterns.begin(); + o2::its::ioutils::convertCompactClusters(mClusters, pattIt, mITSClustersArray, mDict); // clusters converted to 3D spacepoints +} + +void EfficiencyStudy::stileEfficiencyGraph(std::unique_ptr& eff, const char* name, const char* title, bool bidimensional = false, const int markerStyle = kFullCircle, const double markersize = 1, const int markercolor = kBlack, const int linecolor = kBlack) +{ + eff->SetName(name); + eff->SetTitle(title); + if (!bidimensional) { + eff->SetMarkerStyle(markerStyle); + eff->SetMarkerSize(markersize); + eff->SetMarkerColor(markercolor); + eff->SetLineColor(linecolor); + } +} + +int EfficiencyStudy::getDCAClusterTrackMC(int countDuplicated = 0) +{ + // get the DCA between the clusters and the track from MC and fill histograms: distance between original and duplicated cluster, DCA, phi, clusters + // used to study the DCA cut to be applied + LOGP(info, "--------------- getDCAClusterTrackMC"); + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + auto bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + int duplicated = 0; + + std::unordered_map> label_vecClus[mClustersROFRecords.size()][NLAYERS]; // array of maps nRofs x Nlayers -> {label, vec(iClus)} where vec(iClus) are the clusters that share the same label + + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + + float ip[2]; + track.getImpactParams(0, 0, 0, 0, ip); + + // if (abs(ip[0])>0.001 ) continue; ///pv not in (0,0,0) + + auto& tracklab = mTracksMCLabels[iTrack]; + if (tracklab.isFake()) { + continue; + } + + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + + float phiTrack = trackParCov.getPhi() * 180 / M_PI; + + if (pt < mPtCuts[0] || pt > mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + + float phioriginal = 0; + float phiduplicated = 0; + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; // cluster spacepoint in the tracking system + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + UShort_t rowOriginal = clusOriginal.getRow(); + UShort_t colOriginal = clusOriginal.getCol(); + + auto layer = mGeometry->getLayer(clusOriginal.getSensorID()); + if (layer >= NLAYERS) { + continue; // checking only selected layers + } + auto labsTrack = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + + phioriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + mPhiTrackoriginalvsphioriginal[layer]->Fill(phiTrack, phioriginal); + + mPhiOriginal[layer]->Fill(phioriginal); + mPtOriginal[layer]->Fill(pt); + mEtaOriginal[layer]->Fill(eta); + m3DClusterPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y(), clusOriginalPointGlob.z()); + m2DClusterOriginalPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y()); + + for (auto& labT : labsTrack) { // for each valid label iterate over ALL the clusters in the ROF to see if there are duplicates + if (labT != tracklab) { + continue; + } + nLabels++; + if (labT.isValid()) { + for (unsigned int iClus = rofIndexClus; iClus < rofIndexClus + rofNEntriesClus; iClus++) { // iteration over ALL the clusters in the ROF + + auto clusDuplicated = mClusters[iClus]; + auto clusDuplicatedPoint = mITSClustersArray[iClus]; + + auto layerClus = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerClus != layer) { + continue; + } + + o2::math_utils::Point3D clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + // phiduplicated = std::atan2(clusDuplicatedPointGlob.y(), clusDuplicatedPointGlob.x()) * 180 / M_PI + 180; + phiduplicated = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + auto labsClus = mClustersMCLCont->getLabels(iClus); // ideally I can have more than one label per cluster + for (auto labC : labsClus) { + if (labC == labT) { + label_vecClus[iROF][layerClus][labT].push_back(iClus); // same cluster: label from the track = label from the cluster + // if a duplicate cluster is found, propagate the track to the duplicate cluster and compute the distance from the original cluster + // if (clusOriginalPointGlob != clusDuplicatedPointGlob) { /// check that the duplicated cluster is not the original one just counted twice + // if (clusDuplicated.getSensorID() != clusOriginal.getSensorID()) { /// check that the duplicated cluster is not the original one just counted twice + + // applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerClus) { + continue; + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + duplicated++; + + if (countDuplicated == 0) { + UShort_t rowDuplicated = clusDuplicated.getRow(); + UShort_t colDuplicated = clusDuplicated.getCol(); + + chipRowDuplicated[layerDuplicated]->Fill(rowDuplicated); + chipRowOriginalIfDuplicated[layerDuplicated]->Fill(rowOriginal); + + mDuplicated_layer[layerDuplicated]++; // This has to be incremented at the first call + mPtDuplicated[layerClus]->Fill(pt); + mEtaDuplicated[layerClus]->Fill(eta); + mPhiDuplicated[layerClus]->Fill(phiduplicated); + mZvsPhiDUplicated[layerClus]->Fill(clusDuplicatedPointGlob.Z(), phiduplicated); + mPhiTrackDuplicated[layerClus]->Fill(phiTrack); + mPhiTrackDuplicatedvsphiDuplicated[layerClus]->Fill(phiTrack, phioriginal); + mPhiOriginalIfDuplicated[layerClus]->Fill(phioriginal); + } + + if (countDuplicated == 1) { + for (int ipt = 0; ipt < 3; ipt++) { + if (pt >= mrangesPt[ipt][0] && pt < mrangesPt[ipt][1]) { + mDuplicatedEta[layerDuplicated][ipt]->Fill(eta); + mDuplicatedPhi[layerDuplicated][ipt]->Fill(phiduplicated); + } + } + UShort_t rowDuplicated = clusDuplicated.getRow(); + mDuplicatedRow[layerDuplicated]->Fill(rowOriginal); + mDuplicatedPt[layerDuplicated]->Fill(pt); + mDuplicatedPtEta[layerDuplicated]->Fill(pt, eta); + mDuplicatedPtPhi[layerDuplicated]->Fill(pt, phiduplicated); + mDuplicatedEtaPhi[layerDuplicated]->Fill(eta, phiduplicated); + + mDuplicatedEtaAllPt[layerDuplicated]->Fill(eta); + mDuplicatedPhiAllPt[layerDuplicated]->Fill(phiduplicated); + mPt_EtaDupl[layerClus]->Fill(pt, eta); + } + + m3DClusterPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y(), clusDuplicatedPointGlob.z()); + m2DClusterDuplicatedPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y()); + + /// compute the distance between original and dubplicated cluster + mDistanceClustersX[layerClus]->Fill(abs(clusOriginalPointGlob.x() - clusDuplicatedPointGlob.x())); + mDistanceClustersY[layerClus]->Fill(abs(clusOriginalPointGlob.y() - clusDuplicatedPointGlob.y())); + mDistanceClustersZ[layerClus]->Fill(abs(clusOriginalPointGlob.z() - clusDuplicatedPointGlob.z())); + mDistanceClusters[layerClus]->Fill(std::hypot(clusOriginalPointGlob.x() - clusDuplicatedPointGlob.x(), clusOriginalPointGlob.y() - clusDuplicatedPointGlob.y(), clusOriginalPointGlob.z() - clusDuplicatedPointGlob.z())); + + /// Compute the DCA between the cluster location and the track + + /// first propagate to the original cluster + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusOriginal.getSensorID())); + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusOriginal.getSensorID())); + if (propagator->propagateToDCA(clusOriginalPointGlob, trackParCov, b, 2.f, matCorr, &clusOriginalDCA)) { + mDCAxyOriginal[layerClus]->Fill(clusOriginalDCA[0]); + mDCAzOriginal[layerClus]->Fill(clusOriginalDCA[1]); + } + /// then propagate to the duplicated cluster + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusDuplicated.getSensorID())); + if (propagator->propagateToDCA(clusDuplicatedPointGlob, trackParCov, b, 2.f, matCorr, &clusDuplicatedDCA)) { + mDCAxyDuplicated->Fill(clusDuplicatedDCA[0]); + mDCAzDuplicated->Fill(clusDuplicatedDCA[1]); + mDCAxyDuplicated_layer[layerDuplicated]->Fill(clusDuplicatedDCA[0]); + mDCAzDuplicated_layer[layerDuplicated]->Fill(clusDuplicatedDCA[1]); + } + /////////////////////////////////////////////////////// + } + } + } + } + } + } // end loop on clusters + totClus += NLAYERS; // summing only the number of clusters in the considered layers. Since the imposition of 7-clusters tracks, if the track is valid should release as clusters as the number of considered layers + } // end loop on tracks per ROF + } // end loop on ROFRecords array + LOGP(info, "Total number of clusters: {} ", totClus); + LOGP(info, "total nLabels: {}", nLabels); + LOGP(info, "Number of duplicated clusters: {}", duplicated); + + if (mVerboseOutput && mUseMC) { + // printing the duplicates + for (unsigned int iROF = 0; iROF < mClustersROFRecords.size(); iROF++) { + LOGP(info, "°°°°°°°°°°°°°°°°°°°°°°°° ROF {} °°°°°°°°°°°°°°°°°°°°°°°°", iROF); + for (unsigned int lay = 0; lay < NLAYERS; lay++) { + LOGP(info, "°°°°°°°°°°°°°°°°°°°°°°°° LAYER {} °°°°°°°°°°°°°°°°°°°°°°°°", lay); + for (auto& it : label_vecClus[iROF][lay]) { + if (it.second.size() <= 1) { + continue; // printing only duplicates + } + std::cout << " \n++++++++++++ Label: "; + auto label = it.first; + it.first.print(); + for (auto iClus : it.second) { + auto name = mGeometry->getSymbolicName(mClusters[iClus].getSensorID()); + auto chipid = mClusters[iClus].getChipID(); + auto clus = mClusters[iClus]; + auto clusPoint = mITSClustersArray[iClus]; + + o2::math_utils::Point3D clusPointTrack = {clusPoint.getX(), clusPoint.getY(), clusPoint.getZ()}; + o2::math_utils::Point3D clusPointGlob = mGeometry->getMatrixT2G(clus.getSensorID()) * clusPointTrack; + std::cout << "ROF: " << iROF << ", iClus: " << iClus << " -> chip: " << chipid << " = " << name << std::endl; + LOGP(info, "LOCtrack: {} {} {}", clusPointTrack.x(), clusPointTrack.y(), clusPointTrack.z()); + LOGP(info, "LOCglob {} {} {}", clusPointGlob.x(), clusPointGlob.y(), clusPointGlob.z()); + } + } + } + } + } + return duplicated; +} + +void EfficiencyStudy::countDuplicatedAfterCuts() +{ + // count the effective number of duplicated cluster good matches after applying the pt eta and phi cuts on the track + // to check the applied cuts + LOGP(info, "--------------- countDuplicatedAfterCuts"); + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + int duplicated[3] = {0}; + int possibleduplicated[3] = {0}; + + std::cout << "Track candidates: " << std::endl; + + std::unordered_map> label_vecClus[mClustersROFRecords.size()][NLAYERS]; // array of maps nRofs x Nlayers -> {label, vec(iClus)} where vec(iClus) are the clusters that share the same label + + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + std::cout << "ROF number: " << iROF << std::endl; + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + // std::cout<<"Track number: "< mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + + float phi = -999.; + float phiOriginal = -999.; + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; // cluster spacepoint in the tracking system + auto layerOriginal = mGeometry->getLayer(clusOriginal.getSensorID()); + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + auto layer = mGeometry->getLayer(clusOriginal.getSensorID()); + if (layer >= NLAYERS) { + continue; // checking only selected layers + } + auto labsTrack = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + phiOriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + /// applying the cuts on the phi of the original cluster + bool keepTrack = false; /// wether or not a cluster is found in an eligible track in the corresponding layer + + if (layerOriginal == 0) { + for (int i = 0; i < 10; i++) { + if ((phiOriginal >= mPhiCutsL0[i][0] && phiOriginal <= mPhiCutsL0[i][1])) { + possibleduplicated[0]++; + keepTrack = true; + } + } + } + if (layerOriginal == 1) { + for (int i = 0; i < 12; i++) { + if ((phiOriginal >= mPhiCutsL1[i][0] && phiOriginal <= mPhiCutsL1[i][1])) { + possibleduplicated[1]++; + keepTrack = true; + } + } + } + if (layerOriginal == 2) { + for (int i = 0; i < 17; i++) { + if ((phiOriginal >= mPhiCutsL2[i][0] && phiOriginal <= mPhiCutsL2[i][1])) { + possibleduplicated[2]++; + keepTrack = true; + } + } + } + + if (!keepTrack) { + continue; /// if the track (cluster) is not eligible for any layer, go to the next one + } + + for (auto& labT : labsTrack) { // for each valid label iterate over ALL the clusters in the ROF to see if there are duplicates + if (labT != tracklab) { + continue; + } + + if (labT.isValid()) { + for (unsigned int iClus = rofIndexClus; iClus < rofIndexClus + rofNEntriesClus; iClus++) { // iteration over ALL the clusters in the ROF + + auto clusDuplicated = mClusters[iClus]; + auto clusDuplicatedPoint = mITSClustersArray[iClus]; + + auto layerClus = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerClus != layer) { + continue; + } + + o2::math_utils::Point3D clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + phi = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + auto labsClus = mClustersMCLCont->getLabels(iClus); // ideally I can have more than one label per cluster + for (auto labC : labsClus) { + if (labC == labT) { + label_vecClus[iROF][layerClus][labT].push_back(iClus); // same cluster: label from the track = label from the cluster + // if a duplicate cluster is found, propagate the track to the duplicate cluster and compute the distance from the original cluster + // if (clusOriginalPointGlob != clusDuplicatedPointGlob) { /// check that the duplicated cluster is not the original one just counted twice + // if (clusDuplicated.getSensorID() != clusOriginal.getSensorID()) { /// check that the duplicated cluster is not the original one just counted twice + + // applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerClus) { + continue; + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + duplicated[layer]++; + std::cout << "Taken L" << layer << " # " << duplicated[layer] << " : pt, eta, phi = " << pt << " , " << eta << " , " << phiOriginal << " Label: " << std::endl; + labC.print(); + } + } + } + } + } + } // end loop on clusters + totClus += ncl; + } // end loop on tracks per ROF + } // end loop on ROFRecords array + + LOGP(info, "Total number of possible cluster duplicated in L0: {} ", possibleduplicated[0]); + LOGP(info, "Total number of possible cluster duplicated in L1: {} ", possibleduplicated[1]); + LOGP(info, "Total number of possible cluster duplicated in L2: {} ", possibleduplicated[2]); + + LOGP(info, "Total number of cluster duplicated in L0: {} ", duplicated[0]); + LOGP(info, "Total number of cluster duplicated in L1: {} ", duplicated[1]); + LOGP(info, "Total number of cluster duplicated in L2: {} ", duplicated[2]); +} + +void EfficiencyStudy::studyDCAcutsMC() +{ + //// Study the DCA cuts to be applied + + LOGP(info, "--------------- studyDCAcutsMC"); + + int duplicated = getDCAClusterTrackMC(0); + + double meanDCAxyDuplicated[NLAYERS] = {0}; + double meanDCAzDuplicated[NLAYERS] = {0}; + double sigmaDCAxyDuplicated[NLAYERS] = {0}; + double sigmaDCAzDuplicated[NLAYERS] = {0}; + + std::ofstream ofs("dcaValues.csv", std::ofstream::out); + ofs << "layer,dcaXY,dcaZ,sigmaDcaXY,sigmaDcaZ" << std::endl; + + for (int l = 0; l < NLAYERS; l++) { + meanDCAxyDuplicated[l] = mDCAxyDuplicated_layer[l]->GetMean(); + meanDCAzDuplicated[l] = mDCAzDuplicated_layer[l]->GetMean(); + sigmaDCAxyDuplicated[l] = mDCAxyDuplicated_layer[l]->GetRMS(); + sigmaDCAzDuplicated[l] = mDCAzDuplicated_layer[l]->GetRMS(); + ofs << l << "," << meanDCAxyDuplicated[l] << "," << meanDCAzDuplicated[l] << "," << sigmaDCAxyDuplicated[l] << "," << sigmaDCAzDuplicated[l] << std::endl; + } + + for (int l = 0; l < NLAYERS; l++) { + LOGP(info, "meanDCAxyDuplicated L{}: {}, meanDCAzDuplicated: {}, sigmaDCAxyDuplicated: {}, sigmaDCAzDuplicated: {}", l, meanDCAxyDuplicated[l], meanDCAzDuplicated[l], sigmaDCAxyDuplicated[l], sigmaDCAzDuplicated[l]); + } + // now we have the DCA distribution: + // ->iterate again over tracks and over duplicated clusters and find the matching ones basing on DCA cuts (1 sigma, 2 sigma,...) + // then control if the matching ones according to the DCA matches have the same label + // if yes, then we have a good match -> increase the good match counter + // if not, keep it as a fake match -> increase the fake match counter + // the efficiency of each one will be match counter / total of the duplicated clusters + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + unsigned int nDCAMatches[20] = {0}; + unsigned int nGoodMatches[20] = {0}; + unsigned int nFakeMatches[20] = {0}; + + unsigned int nGoodMatches_layer[NLAYERS][20] = {0}; + unsigned int nFakeMatches_layer[NLAYERS][20] = {0}; + + int nbPt = 75; + double xbins[nbPt + 1], ptcutl = 0.05, ptcuth = 7.5; + double a = std::log(ptcuth / ptcutl) / nbPt; + for (int i = 0; i <= nbPt; i++) { + xbins[i] = ptcutl * std::exp(i * a); + } + + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + + float ip[2]; + track.getImpactParams(0, 0, 0, 0, ip); + + if (pt < mPtCuts[0] || pt > mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + + float phiTrack = trackParCov.getPhi() * 180 / M_PI; + + float phi = -999.; + float phiOriginal = -999.; + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + + auto& tracklab = mTracksMCLabels[iTrack]; + if (tracklab.isFake()) { + continue; + } + + if (mVerboseOutput) { + LOGP(info, "--------- track Label: "); + tracklab.print(); + } + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track to extract layer, stave and chip to restrict the possible matches to be searched with the DCA cut + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; // cluster spacepoint in the tracking system + auto layerOriginal = mGeometry->getLayer(clusOriginal.getSensorID()); + if (layerOriginal >= NLAYERS) { + continue; + } + auto labsOriginal = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track (original) + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + + phiOriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + for (auto& labT : labsOriginal) { // for each valid label iterate over ALL the clusters in the ROF to see if there are duplicates + if (labT != tracklab) { + continue; + } + if (!labT.isValid()) { + continue; + } + + /// for each oroginal cluster iterate over all the possible "adjacent" clusters (stave +-1, chip =,+-1) and calculate the DCA with the track. Then compare the cluster label with the track label to see if it is a true or fake match + for (unsigned int iClus = rofIndexClus; iClus < rofIndexClus + rofNEntriesClus; iClus++) { // iteration over ALL the clusters in the ROF + auto clusDuplicated = mClusters[iClus]; + //// applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerOriginal) { + continue; + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + auto labsDuplicated = mClustersMCLCont->getLabels(iClus); + + /// if the cheks are passed, then calculate the DCA + auto clusDuplicatedPoint = mITSClustersArray[iClus]; + + o2::math_utils::Point3D clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + phi = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + /// Compute the DCA between the duplicated cluster location and the track + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusDuplicated.getSensorID())); + if (propagator->propagateToDCA(clusDuplicatedPointGlob, trackParCov, b, 2.f, matCorr, &clusDuplicatedDCA)) { // check if the propagation fails + if (mVerboseOutput) { + LOGP(info, "Propagation ok"); + } + /// checking the DCA for 20 different sigma ranges + for (int i = 0; i < 20; i++) { + if (abs(dcaXY[layerDuplicated] - clusDuplicatedDCA[0]) < (i + 1) * sigmaDcaXY[layerDuplicated] && abs(dcaZ[layerDuplicated] - clusDuplicatedDCA[1]) < (i + 1) * sigmaDcaZ[layerDuplicated]) { // check if the DCA is within the cut i*sigma + + if (mVerboseOutput) { + LOGP(info, "Check DCA ok: {} < {}; {} < {}", abs(meanDCAxyDuplicated[layerDuplicated] - clusDuplicatedDCA[0]), (i + 1) * sigmaDCAxyDuplicated[layerDuplicated], abs(meanDCAzDuplicated[layerDuplicated] - clusDuplicatedDCA[1]), (i + 1) * sigmaDCAzDuplicated[layerDuplicated]); + } + nDCAMatches[i]++; + bool isGoodMatch = false; + + for (auto labD : labsDuplicated) { // at this point the track has been matched with a duplicated cluster based on the DCA cut. Now we check if the matching is good ore not based on the label + if (mVerboseOutput) { + LOGP(info, "tracklab, labD:"); + tracklab.print(); + labD.print(); + } + if (labD == tracklab) { //// check if the label of the origial cluster is equal to the label of the duplicated cluster among all the labels for a cluster + isGoodMatch = true; + continue; + } + } + + if (isGoodMatch) { + nGoodMatches[i]++; + nGoodMatches_layer[layerDuplicated][i]++; + mnGoodMatchesPt_layer[layerDuplicated]->Fill(pt, i); + mnGoodMatchesEta_layer[layerDuplicated]->Fill(eta, i); + mnGoodMatchesPhi_layer[layerDuplicated]->Fill(phi, i); + mnGoodMatchesPhiTrack_layer[layerDuplicated]->Fill(phiTrack, i); + mnGoodMatchesPhiOriginal_layer[layerDuplicated]->Fill(phiOriginal, i); + } else { + + nFakeMatches[i]++; + nFakeMatches_layer[layerDuplicated][i]++; + mnFakeMatchesPt_layer[layerDuplicated]->Fill(pt, i); + mnFakeMatchesEta_layer[layerDuplicated]->Fill(eta, i); + mnFakeMatchesPhi_layer[layerDuplicated]->Fill(phi, i); + mnFakeMatchesPhiTrack_layer[layerDuplicated]->Fill(phiTrack, i); + } + } else if (mVerboseOutput) { + LOGP(info, "Check DCA failed"); + } + } + } else if (mVerboseOutput) { + LOGP(info, "Propagation failed"); + } + } // end loop on all the clusters in the rof + } + } // end loop on clusters associated to the track + } // end loop on tracks per ROF + } // end loop on ROFRecords array + + for (int i = 0; i < 20; i++) { + LOGP(info, "Cut: {} sigma -> number of duplicated clusters: {} nDCAMatches: {} nGoodMatches: {} nFakeMatches: {}", i + 1, duplicated, nDCAMatches[i], nGoodMatches[i], nFakeMatches[i]); + mEfficiencyGoodMatch->SetBinContent(i + 1, nGoodMatches[i]); + mEfficiencyFakeMatch->SetBinContent(i + 1, nFakeMatches[i]); + mEfficiencyTotal->SetBinContent(i + 1, double(nGoodMatches[i] + nFakeMatches[i])); + + for (int l = 0; l < NLAYERS; l++) { + mEfficiencyGoodMatch_layer[l]->SetBinContent(i + 1, nGoodMatches_layer[l][i]); + mEfficiencyFakeMatch_layer[l]->SetBinContent(i + 1, nFakeMatches_layer[l][i]); + mEfficiencyTotal_layer[l]->SetBinContent(i + 1, double(nGoodMatches_layer[l][i] + nFakeMatches_layer[l][i])); + + for (int ipt = 0; ipt < mPtDuplicated[l]->GetNbinsX(); ipt++) { + if (mPtDuplicated[l]->GetBinContent(ipt + 1) != 0) { + mEfficiencyGoodMatchPt_layer[l]->SetBinContent(ipt + 1, i + 1, mnGoodMatchesPt_layer[l]->GetBinContent(ipt + 1, i + 1) / mPtDuplicated[l]->GetBinContent(ipt + 1)); + } + mEfficiencyFakeMatchPt_layer[l]->SetBinContent(ipt + 1, i + 1, mnFakeMatchesPt_layer[l]->GetBinContent(ipt + 1, i + 1) / mPtDuplicated[l]->GetBinContent(ipt + 1)); + } + + for (int ieta = 0; ieta < mEtaDuplicated[l]->GetNbinsX(); ieta++) { + if (mEtaDuplicated[l]->GetBinContent(ieta + 1) != 0) { + mEfficiencyGoodMatchEta_layer[l]->SetBinContent(ieta + 1, i + 1, mnGoodMatchesEta_layer[l]->GetBinContent(ieta + 1, i + 1) / mEtaDuplicated[l]->GetBinContent(ieta + 1)); + } + mEfficiencyFakeMatchEta_layer[l]->SetBinContent(ieta + 1, i + 1, mnFakeMatchesEta_layer[l]->GetBinContent(ieta + 1, i + 1) / mEtaDuplicated[l]->GetBinContent(ieta + 1)); + } + + for (int iphi = 0; iphi < mPhiDuplicated[l]->GetNbinsX(); iphi++) { + if (mPhiDuplicated[l]->GetBinContent(iphi + 1) != 0) { + mEfficiencyGoodMatchPhi_layer[l]->SetBinContent(iphi + 1, i + 1, mnGoodMatchesPhi_layer[l]->GetBinContent(iphi + 1, i + 1) / mPhiDuplicated[l]->GetBinContent(iphi + 1)); + } + mEfficiencyFakeMatchPhi_layer[l]->SetBinContent(iphi + 1, i + 1, mnFakeMatchesPhi_layer[l]->GetBinContent(iphi + 1, i + 1) / mPhiDuplicated[l]->GetBinContent(iphi + 1)); + } + + for (int iphi = 0; iphi < mPhiOriginalIfDuplicated[l]->GetNbinsX(); iphi++) { + if (mPhiOriginalIfDuplicated[l]->GetBinContent(iphi + 1) != 0) { + mEfficiencyGoodMatchPhiOriginal_layer[l]->SetBinContent(iphi + 1, i + 1, mnGoodMatchesPhiOriginal_layer[l]->GetBinContent(iphi + 1, i + 1) / mPhiOriginalIfDuplicated[l]->GetBinContent(iphi + 1)); + } + } + + for (int iphi = 0; iphi < mPhiTrackDuplicated[l]->GetNbinsX(); iphi++) { + if (mPhiTrackDuplicated[l]->GetBinContent(iphi + 1) != 0) { + mEfficiencyGoodMatchPhiTrack_layer[l]->SetBinContent(iphi + 1, i + 1, mnGoodMatchesPhiTrack_layer[l]->GetBinContent(iphi + 1, i + 1) / mPhiTrackDuplicated[l]->GetBinContent(iphi + 1)); + } + mEfficiencyFakeMatchPhiTrack_layer[l]->SetBinContent(iphi + 1, i + 1, mnFakeMatchesPhiTrack_layer[l]->GetBinContent(iphi + 1, i + 1) / mPhiTrackDuplicated[l]->GetBinContent(iphi + 1)); + } + } + } + for (int i = 0; i < NLAYERS; i++) { + std::cout << "+++++++++ Duplicated in layer L" << i << ": " << mDuplicated_layer[i] << std::endl; + } + + for (int l = 0; l < NLAYERS; l++) { + mEfficiencyGoodMatch_layer[l]->Scale(1. / double(mDuplicated_layer[l]), "b"); + mEfficiencyFakeMatch_layer[l]->Scale(1. / double(mDuplicated_layer[l]), "b"); + mEfficiencyTotal_layer[l]->Scale(1. / double(mDuplicated_layer[l]), "b"); + } + + mEfficiencyGoodMatch->Scale(1. / double(duplicated), "b"); + mEfficiencyFakeMatch->Scale(1. / double(duplicated), "b"); + mEfficiencyTotal->Scale(1. / double(duplicated), "b"); + + mOutFile->mkdir("EffVsDCA2D/"); + mOutFile->cd("EffVsDCA2D/"); + for (int l = 0; l < NLAYERS; l++) { + mEfficiencyGoodMatchPt_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyGoodMatchPt_layer[l]->Write(); + mEfficiencyGoodMatchEta_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyGoodMatchEta_layer[l]->Write(); + mEfficiencyGoodMatchPhi_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyGoodMatchPhi_layer[l]->Write(); + mEfficiencyGoodMatchPhiTrack_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyGoodMatchPhiTrack_layer[l]->Write(); + mEfficiencyGoodMatchPhiOriginal_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyGoodMatchPhiOriginal_layer[l]->Write(); + mEfficiencyFakeMatchPt_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyFakeMatchPt_layer[l]->Write(); + mEfficiencyFakeMatchEta_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyFakeMatchEta_layer[l]->Write(); + mEfficiencyFakeMatchPhi_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyFakeMatchPhi_layer[l]->Write(); + mEfficiencyFakeMatchPhiTrack_layer[l]->GetZaxis()->SetRangeUser(0, 1); + mEfficiencyFakeMatchPhiTrack_layer[l]->Write(); + } + + mOutFile->mkdir("Efficiency/"); + mOutFile->cd("Efficiency/"); + mEfficiencyGoodMatch->Write(); + mEfficiencyFakeMatch->Write(); + mEfficiencyTotal->Write(); + for (int l = 0; l < NLAYERS; l++) { + + mEfficiencyGoodMatch_layer[l]->Write(); + mEfficiencyFakeMatch_layer[l]->Write(); + mEfficiencyTotal_layer[l]->Write(); + + mEfficiencyGoodMatch_layer[l]->GetYaxis()->SetRangeUser(-0.1, 1.1); + mEfficiencyFakeMatch_layer[l]->GetYaxis()->SetRangeUser(-0.1, 1.1); + mEfficiencyTotal_layer[l]->GetYaxis()->SetRangeUser(-0.1, 1.1); + } + + mEfficiencyGoodMatch->GetYaxis()->SetRangeUser(-0.1, 1.1); + mEfficiencyFakeMatch->GetYaxis()->SetRangeUser(-0.1, 1.1); + mEfficiencyTotal->GetYaxis()->SetRangeUser(-0.1, 1.1); + + TCanvas c; + c.SetName("EffVsDCA_allLayers"); + auto leg = std::make_unique(0.75, 0.45, 0.89, 0.65); + leg->AddEntry(mEfficiencyGoodMatch.get(), "#frac{# good matches}{# tot duplicated clusters}", "p"); + leg->AddEntry(mEfficiencyFakeMatch.get(), "#frac{# fake matches}{# tot duplicated clusters}", "p"); + leg->AddEntry(mEfficiencyTotal.get(), "#frac{# tot matches}{# tot duplicated clusters}", "p"); + + mEfficiencyGoodMatch->Draw("P l E1_NOSTAT PLC PMC "); + mEfficiencyFakeMatch->Draw("same P l E1_NOSTAT PLC PMC"); + mEfficiencyTotal->Draw("same P l E1_NOSTAT PLC PMC"); + leg->Draw("same"); + c.Write(); + c.SaveAs("prova.png"); + + TCanvas cc[NLAYERS]; + for (int l = 0; l < NLAYERS; l++) { + cc[l].cd(); + cc[l].SetName(Form("EffVsDCA_layer_L%d", l)); + + auto leg = std::make_unique(0.75, 0.45, 0.89, 0.65); + leg->AddEntry(mEfficiencyGoodMatch_layer[l].get(), "#frac{# good matches}{# tot duplicated clusters}", "p"); + leg->AddEntry(mEfficiencyFakeMatch_layer[l].get(), "#frac{# fake matches}{# tot duplicated clusters}", "p"); + leg->AddEntry(mEfficiencyTotal_layer[l].get(), "#frac{# tot matches}{# tot duplicated clusters}", "p"); + + mEfficiencyGoodMatch_layer[l]->SetLineColor(kBlue + 3); + mEfficiencyGoodMatch_layer[l]->SetMarkerColor(kBlue + 3); + mEfficiencyGoodMatch_layer[l]->Draw("P l E1_NOSTAT"); + mEfficiencyFakeMatch_layer[l]->SetLineColor(kAzure + 7); + mEfficiencyFakeMatch_layer[l]->SetMarkerColor(kAzure + 7); + mEfficiencyFakeMatch_layer[l]->Draw("same P l E1_NOSTAT"); + mEfficiencyTotal_layer[l]->SetLineColor(kGreen + 1); + mEfficiencyTotal_layer[l]->SetMarkerColor(kGreen + 1); + mEfficiencyTotal_layer[l]->Draw("same P l E1_NOSTAT"); + leg->Draw("same"); + cc[l].Write(); + cc[l].SaveAs(Form("provaLayer%d.png", l)); + } +} + +void EfficiencyStudy::studyClusterSelectionMC() +{ + // study to find a good selection method for the duplicated cluster, to be used for non-MC data + // iterate over tracks an associated clusters, and find the closer cluster that is not the original one applying cuts on staveID and chipID + // fix the DCA < 10 sigma, then compute the efficiency for each bin of pt, eta and phi and also in the rows + + LOGP(info, "--------------- studyClusterSelection"); + + int duplicated = getDCAClusterTrackMC(1); + + std::cout << "duplicated: " << duplicated << std::endl; + + double meanDCAxyDuplicated[NLAYERS] = {0}; + double meanDCAzDuplicated[NLAYERS] = {0}; + double sigmaDCAxyDuplicated[NLAYERS] = {0}; + double sigmaDCAzDuplicated[NLAYERS] = {0}; + + for (int l = 0; l < NLAYERS; l++) { + meanDCAxyDuplicated[l] = mDCAxyDuplicated_layer[l]->GetMean(); + meanDCAzDuplicated[l] = mDCAzDuplicated_layer[l]->GetMean(); + sigmaDCAxyDuplicated[l] = mDCAxyDuplicated_layer[l]->GetRMS(); + sigmaDCAzDuplicated[l] = mDCAzDuplicated_layer[l]->GetRMS(); + } + + for (int l = 0; l < NLAYERS; l++) { + LOGP(info, "meanDCAxyDuplicated L{}: {}, meanDCAzDuplicated: {}, sigmaDCAxyDuplicated: {}, sigmaDCAzDuplicated: {}", l, meanDCAxyDuplicated[l], meanDCAzDuplicated[l], sigmaDCAxyDuplicated[l], sigmaDCAzDuplicated[l]); + } + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + unsigned int nDCAMatches[15] = {0}; + unsigned int nGoodMatches[15] = {0}; + unsigned int nFakeMatches[15] = {0}; + + std::map, bool> clusterMatchesPtEta[100][100] = {}; + + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + //////calculcating efficiency vs pt, eta, phi + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + + /// cut on primary vertex position (?) + float ip[2]; + track.getImpactParams(0, 0, 0, 0, ip); + + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + + auto& tracklab = mTracksMCLabels[iTrack]; + if (tracklab.isFake()) { + continue; + } + + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + + if (pt < mPtCuts[0] || pt > mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + + // auto phi = trackParCov.getPhi()*180/M_PI; + float phi = -999.; + float phiOriginal = -999.; + float phiDuplicated = -999.; + UShort_t row = -999; + + if (mVerboseOutput) { + LOGP(info, "--------- track Label: "); + tracklab.print(); + } + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track to extract layer, stave and chip to restrict the possible matches to be searched with the DCA cut + // LOGP(info, "New cluster"); + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto layerOriginal = mGeometry->getLayer(clusOriginal.getSensorID()); + if (layerOriginal >= NLAYERS) { + continue; + } + + IPOriginalxy[layerOriginal]->Fill(ip[0]); + IPOriginalz[layerOriginal]->Fill(ip[1]); + + UShort_t rowOriginal = clusOriginal.getRow(); + + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + + auto phiOriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + auto labsOriginal = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track (original) + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + std::tuple> clusID_rDCA_label = {0, 999., gsl::span()}; // inizializing tuple with dummy values + + bool adjacentFound = 0; + /// for each oroginal cluster iterate over all the possible "adjacten" clusters (stave +-1, chip =,+-1) and calculate the DCA with the track. Then choose the closest one. + for (unsigned int iClus = rofIndexClus; iClus < rofIndexClus + rofNEntriesClus; iClus++) { // iteration over ALL the clusters in the ROF + auto clusDuplicated = mClusters[iClus]; + + //// applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerOriginal) { + continue; + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + auto labsDuplicated = mClustersMCLCont->getLabels(iClus); + + /// if the cheks are passed, then calculate the DCA + auto clusDuplicatedPoint = mITSClustersArray[iClus]; + + o2::math_utils::Point3D clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + + auto phiDuplicated = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + /// Compute the DCA between the duplicated cluster location and the track + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusDuplicated.getSensorID())); + if (!propagator->propagateToDCA(clusDuplicatedPointGlob, trackParCov, b, 2.f, matCorr, &clusDuplicatedDCA)) { // check if the propagation fails + continue; + } + + // Imposing that the distance between the original cluster and the duplicated one is less than x sigma + if (!(abs(meanDCAxyDuplicated[layerDuplicated] - clusDuplicatedDCA[0]) < 8 * sigmaDCAxyDuplicated[layerDuplicated] && abs(meanDCAzDuplicated[layerDuplicated] - clusDuplicatedDCA[1]) < 8 * sigmaDCAzDuplicated[layerDuplicated])) { + continue; + } + + if (mVerboseOutput) { + LOGP(info, "Propagation ok"); + } + double rDCA = std::hypot(clusDuplicatedDCA[0], clusDuplicatedDCA[1]); + + // taking the closest cluster within x sigma + if (rDCA < std::get<1>(clusID_rDCA_label)) { // updating the closest cluster + clusID_rDCA_label = {iClus, rDCA, labsDuplicated}; + phi = phiDuplicated; + row = rowOriginal; + } + adjacentFound = 1; + + } // end loop on all the clusters in the rof + + // here clusID_rDCA_label is updated with the closest cluster to the track other than the original one + // checking if it is a good or fake match looking at the labels + + if (!adjacentFound) { + continue; + } + + bool isGood = false; + for (auto lab : std::get<2>(clusID_rDCA_label)) { + if (lab == tracklab) { + isGood = true; + diffPhivsPt[layerOriginal]->Fill(pt, abs(phi - phiOriginal)); + IPOriginalifDuplicatedxy[layerOriginal]->Fill(ip[0]); + IPOriginalifDuplicatedz[layerOriginal]->Fill(ip[1]); + + mNGoodMatchesPt[layerOriginal]->Fill(pt); + mNGoodMatchesRow[layerOriginal]->Fill(row); + mNGoodMatchesPtEta[layerOriginal]->Fill(pt, eta); + mNGoodMatchesPtPhi[layerOriginal]->Fill(pt, phi); + mNGoodMatchesEtaPhi[layerOriginal]->Fill(eta, phi); + + mNGoodMatchesEtaAllPt[layerOriginal]->Fill(eta); + mNGoodMatchesPhiAllPt[layerOriginal]->Fill(phi); + for (int ipt = 0; ipt < 3; ipt++) { + if (pt >= mrangesPt[ipt][0] && pt < mrangesPt[ipt][1]) { + mNGoodMatchesEta[layerOriginal][ipt]->Fill(eta); + mNGoodMatchesPhi[layerOriginal][ipt]->Fill(phi); + } + } + + break; + } + } + if (!isGood) { + + mNFakeMatchesPt[layerOriginal]->Fill(pt); + mNFakeMatchesRow[layerOriginal]->Fill(row); + mNFakeMatchesPtEta[layerOriginal]->Fill(pt, eta); + mNFakeMatchesPtPhi[layerOriginal]->Fill(pt, phi); + mNFakeMatchesEtaPhi[layerOriginal]->Fill(eta, phi); + mNFakeMatchesEtaAllPt[layerOriginal]->Fill(eta); + mNFakeMatchesPhiAllPt[layerOriginal]->Fill(phi); + + for (int ipt = 0; ipt < 3; ipt++) { + if (pt >= mrangesPt[ipt][0] && pt < mrangesPt[ipt][1]) { + mNFakeMatchesEta[layerOriginal][ipt]->Fill(eta); + mNFakeMatchesPhi[layerOriginal][ipt]->Fill(phi); + } + } + } + } // end loop on clusters associated to the track + } // end loop on tracks per ROF + } // end loop on ROFRecords array + + mOutFile->mkdir("EfficiencyCuts/"); + mOutFile->cd("EfficiencyCuts/"); + + std::cout << "------Calculatin efficiency..." << std::endl; + TH1D* axpt = new TH1D("axpt", "", 1, 0.05, 7.5); + TH1D* axRow = new TH1D("axRow", "", 1, -0.5, 511.5); + TH2D* axptetaGood = new TH2D("axptetaGood", "", 1, 0.05, 7.5, 1, -2, 2); + TH2D* axptetaFake = new TH2D("axptetaFake", "", 1, 0.05, 7.5, 1, -2, 2); + TH2D* axptphiGood = new TH2D("axptphiGood", "", 1, 0.05, 7.5, 1, -180, 180); + TH2D* axptphiFake = new TH2D("axptphiFake", "", 1, 0.05, 7.5, 1, -180, 180); + TH2D* axetaphiGood = new TH2D("axetaphiGood", "", 1, -2, 2, 1, -180, 180); + TH2D* axetaphiFake = new TH2D("axetaphiFake", "", 1, -2, 2, 1, -180, 180); + TH1D* axetaAllPt = new TH1D("axetaAllPt", "", 1, -2, 2); + TH1D* axeta[NLAYERS]; + TH1D* axphi[NLAYERS]; + for (int ipt = 0; ipt < 3; ipt++) { + axeta[ipt] = new TH1D(Form("axeta%d", ipt), Form("axeta%d", ipt), 1, -2, 2); + axphi[ipt] = new TH1D(Form("axphi%d", ipt), Form("axphi%d", ipt), 1, -180, 180); + } + TH1D* axphiAllPt = new TH1D("axphi", "", 1, -180, 180); + + TCanvas* effPt[NLAYERS]; + TCanvas* effRow[NLAYERS]; + TCanvas* effPtEta[NLAYERS][2]; + TCanvas* effPtPhi[NLAYERS][2]; + TCanvas* effEtaPhi[NLAYERS][2]; + TCanvas* effEtaAllPt[NLAYERS]; + TCanvas* effEta[NLAYERS][3]; + TCanvas* effPhiAllPt[NLAYERS]; + TCanvas* effPhi[NLAYERS][3]; + + ///////////////// plotting results + for (int l = 0; l < 3; l++) { + if (mVerboseOutput) { + std::cout << "Pt L" << l << "\n\n"; + } + + diffPhivsPt[l]->Write(); + IPOriginalifDuplicatedxy[l]->Write(); + IPOriginalifDuplicatedz[l]->Write(); + + // Pt + effPt[l] = new TCanvas(Form("effPt_L%d", l)); + + mEffPtGood[l] = std::make_unique(*mNGoodMatchesPt[l], *mDuplicatedPt[l]); + stileEfficiencyGraph(mEffPtGood[l], Form("mEffPtGood_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});Efficiency", l), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesPt[l]->GetNbinsX(); ibin++) { + if (mNFakeMatchesPt[l]->GetBinContent(ibin) > mDuplicatedPt[l]->GetBinContent(ibin)) { + std::cout << "--- Pt: Npass = " << mNFakeMatchesPt[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedPt[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + mNFakeMatchesPt[l]->SetBinContent(ibin, mDuplicatedPt[l]->GetBinContent(ibin)); + } + } + mEffPtFake[l] = std::make_unique(*mNFakeMatchesPt[l], *mDuplicatedPt[l]); + stileEfficiencyGraph(mEffPtFake[l], Form("mEffPtFake_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});Efficiency", l), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axpt->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});Efficiency", l)); + axpt->GetYaxis()->SetRangeUser(-0.1, 1.1); + axpt->GetXaxis()->SetRangeUser(0.05, 7.5); + axpt->Draw(); + mEffPtGood[l]->Draw("same p"); + mEffPtFake[l]->Draw("same p"); + + auto legpt = std::make_unique(0.70, 0.15, 0.89, 0.35); + legpt->AddEntry(mEffPtGood[l].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legpt->AddEntry(mEffPtFake[l].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legpt->Draw("same"); + effPt[l]->Write(); + + // PtEtaGood + effPtEta[l][0] = new TCanvas(Form("effPtEtaGood_L%d", l)); + + mEffPtEtaGood[l] = std::make_unique(*mNGoodMatchesPtEta[l], *mDuplicatedPtEta[l]); + stileEfficiencyGraph(mEffPtEtaGood[l], Form("mEffPtEtaGood_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l), true); + + axptetaGood->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l)); + axptetaGood->GetZaxis()->SetRangeUser(-0.1, 1.1); + axptetaGood->GetYaxis()->SetRangeUser(-2., 2.); + axptetaGood->GetXaxis()->SetRangeUser(0.05, 7.5); + axptetaGood->Draw(); + mEffPtEtaGood[l]->Draw("same colz"); + effPtEta[l][0]->Update(); + effPtEta[l][0]->Write(); + + if (mVerboseOutput) { + std::cout << "Underflow (bin 0,0): " << mNFakeMatchesPtEta[l]->GetBinContent(0, 0) << " " << mDuplicatedPtEta[l]->GetBinContent(0, 0) << std::endl; + std::cout << "Overflow (bin nbinsx,nbinsy): " << mNFakeMatchesPtEta[l]->GetNbinsX() << " " << mNFakeMatchesPtEta[l]->GetNbinsY() << " -> " << mNFakeMatchesPtEta[l]->GetBinContent(mNFakeMatchesPtEta[l]->GetNbinsX(), mNFakeMatchesPtEta[l]->GetNbinsY()) << " " << mDuplicatedPtEta[l]->GetBinContent(mNFakeMatchesPtEta[l]->GetNbinsX(), mNFakeMatchesPtEta[l]->GetNbinsY()) << std::endl; + } + + for (int ibin = 1; ibin <= mNFakeMatchesPtEta[l]->GetNbinsX(); ibin++) { + for (int jbin = 1; jbin <= mNFakeMatchesPtEta[l]->GetNbinsY(); jbin++) { + if (mNFakeMatchesPtEta[l]->GetBinContent(ibin, jbin) > mDuplicatedPtEta[l]->GetBinContent(ibin, jbin)) { + if (mVerboseOutput) { + std::cout << "--- PtEta fakematches : Npass = " << mNFakeMatchesPtEta[l]->GetBinContent(ibin, jbin) << ", Nall = " << mDuplicatedPtEta[l]->GetBinContent(ibin, jbin) << " for ibin = " << ibin << ", jbin = " << jbin << std::endl; + } + mNFakeMatchesPtEta[l]->SetBinContent(ibin, jbin, mDuplicatedPtEta[l]->GetBinContent(ibin, jbin)); + } + } + } + + // Row + effRow[l] = new TCanvas(Form("effRow_L%d", l)); + + for (int ibin = 1; ibin <= mNGoodMatchesRow[l]->GetNbinsX(); ibin++) { + std::cout << "--- Good Row: Npass = " << mNGoodMatchesRow[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedRow[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + + mEffRowGood[l] = std::make_unique(*mNGoodMatchesRow[l], *mDuplicatedRow[l]); + stileEfficiencyGraph(mEffRowGood[l], Form("mEffRowGood_L%d", l), Form("L%d;Row;Efficiency", l), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesRow[l]->GetNbinsX(); ibin++) { + if (mNFakeMatchesRow[l]->GetBinContent(ibin) > mDuplicatedRow[l]->GetBinContent(ibin)) { + std::cout << "--- Row: Npass = " << mNFakeMatchesRow[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedRow[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + mNFakeMatchesRow[l]->SetBinContent(ibin, mDuplicatedRow[l]->GetBinContent(ibin)); + } + } + mEffRowFake[l] = std::make_unique(*mNFakeMatchesRow[l], *mDuplicatedRow[l]); + stileEfficiencyGraph(mEffRowFake[l], Form("mEffRowFake_L%d", l), Form("L%d;Row;Efficiency", l), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axRow->SetTitle(Form("L%d;Row;Efficiency", l)); + axRow->GetYaxis()->SetRangeUser(-0.1, 1.1); + axRow->GetXaxis()->SetRangeUser(0.05, 7.5); + axRow->Draw(); + mEffRowGood[l]->Draw("same p"); + mEffRowFake[l]->Draw("same p"); + + auto legRow = std::make_unique(0.70, 0.15, 0.89, 0.35); + legRow->AddEntry(mEffRowGood[l].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legRow->AddEntry(mEffRowFake[l].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legRow->Draw("same"); + effRow[l]->Write(); + + // PtEtaGood + effPtEta[l][0] = new TCanvas(Form("effPtEtaGood_L%d", l)); + + mEffPtEtaGood[l] = std::make_unique(*mNGoodMatchesPtEta[l], *mDuplicatedPtEta[l]); + stileEfficiencyGraph(mEffPtEtaGood[l], Form("mEffPtEtaGood_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l), true); + + axptetaGood->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l)); + axptetaGood->GetZaxis()->SetRangeUser(-0.1, 1.1); + axptetaGood->GetYaxis()->SetRangeUser(-2., 2.); + axptetaGood->GetXaxis()->SetRangeUser(0.05, 7.5); + axptetaGood->Draw(); + mEffPtEtaGood[l]->Draw("same colz"); + effPtEta[l][0]->Update(); + effPtEta[l][0]->Write(); + + if (mVerboseOutput) { + std::cout << "Underflow (bin 0,0): " << mNFakeMatchesPtEta[l]->GetBinContent(0, 0) << " " << mDuplicatedPtEta[l]->GetBinContent(0, 0) << std::endl; + std::cout << "Overflow (bin nbinsx,nbinsy): " << mNFakeMatchesPtEta[l]->GetNbinsX() << " " << mNFakeMatchesPtEta[l]->GetNbinsY() << " -> " << mNFakeMatchesPtEta[l]->GetBinContent(mNFakeMatchesPtEta[l]->GetNbinsX(), mNFakeMatchesPtEta[l]->GetNbinsY()) << " " << mDuplicatedPtEta[l]->GetBinContent(mNFakeMatchesPtEta[l]->GetNbinsX(), mNFakeMatchesPtEta[l]->GetNbinsY()) << std::endl; + } + + for (int ibin = 1; ibin <= mNFakeMatchesPtEta[l]->GetNbinsX(); ibin++) { + for (int jbin = 1; jbin <= mNFakeMatchesPtEta[l]->GetNbinsY(); jbin++) { + if (mNFakeMatchesPtEta[l]->GetBinContent(ibin, jbin) > mDuplicatedPtEta[l]->GetBinContent(ibin, jbin)) { + if (mVerboseOutput) { + std::cout << "--- PtEta fakematches : Npass = " << mNFakeMatchesPtEta[l]->GetBinContent(ibin, jbin) << ", Nall = " << mDuplicatedPtEta[l]->GetBinContent(ibin, jbin) << " for ibin = " << ibin << ", jbin = " << jbin << std::endl; + } + mNFakeMatchesPtEta[l]->SetBinContent(ibin, jbin, mDuplicatedPtEta[l]->GetBinContent(ibin, jbin)); + } + } + } + + // PtEtaFake + effPtEta[l][1] = new TCanvas(Form("effPtEtaFake_L%d", l)); + + mEffPtEtaFake[l] = std::make_unique(*mNFakeMatchesPtEta[l], *mDuplicatedPtEta[l]); + stileEfficiencyGraph(mEffPtEtaFake[l], Form("mEffPtEtaFake_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l), true); + axptetaFake->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});#eta;Efficiency", l)); + axptetaFake->GetZaxis()->SetRangeUser(-0.1, 1.1); + axptetaFake->GetYaxis()->SetRangeUser(-2., 2.); + axptetaFake->GetXaxis()->SetRangeUser(0.05, 7.5); + axptetaFake->Draw(); + mEffPtEtaFake[l]->Draw("same colz"); + effPtEta[l][1]->Update(); + effPtEta[l][1]->Write(); + + // PtPhiGood + effPtPhi[l][0] = new TCanvas(Form("effPtPhiGood_L%d", l)); + + mEffPtPhiGood[l] = std::make_unique(*mNGoodMatchesPtPhi[l], *mDuplicatedPtPhi[l]); + stileEfficiencyGraph(mEffPtPhiGood[l], Form("mEffPtPhiGood_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});#phi (deg);Efficiency", l), true); + + axptphiGood->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});#phi (deg);Efficiency", l)); + axptphiGood->GetZaxis()->SetRangeUser(-0.1, 1.1); + axptphiGood->GetYaxis()->SetRangeUser(-180, 180); + axptphiGood->GetXaxis()->SetRangeUser(0.05, 7.5); + axptphiGood->Draw(); + mEffPtPhiGood[l]->Draw("same colz"); + effPtPhi[l][0]->Update(); + effPtPhi[l][0]->Write(); + + for (int ibin = 1; ibin <= mNFakeMatchesPtPhi[l]->GetNbinsX(); ibin++) { + for (int jbin = 1; jbin <= mNFakeMatchesPtPhi[l]->GetNbinsY(); jbin++) { + if (mNFakeMatchesPtPhi[l]->GetBinContent(ibin, jbin) > mDuplicatedPtPhi[l]->GetBinContent(ibin, jbin)) { + if (mVerboseOutput) { + std::cout << "--- Pt: Npass = " << mNFakeMatchesPtPhi[l]->GetBinContent(ibin, jbin) << ", Nall = " << mDuplicatedPtPhi[l]->GetBinContent(ibin, jbin) << " for ibin = " << ibin << ", jbin = " << jbin << std::endl; + } + mNFakeMatchesPtPhi[l]->SetBinContent(ibin, jbin, mDuplicatedPtPhi[l]->GetBinContent(ibin, jbin)); + } + } + } + + // PtPhiFake + effPtPhi[l][1] = new TCanvas(Form("effPtPhiFake_L%d", l)); + + mEffPtPhiFake[l] = std::make_unique(*mNFakeMatchesPtPhi[l], *mDuplicatedPtPhi[l]); + stileEfficiencyGraph(mEffPtPhiFake[l], Form("mEffPtPhiFake_L%d", l), Form("L%d;#it{p}_{T} (GeV/#it{c});#phi (deg);Efficiency", l), true); + axptphiFake->SetTitle(Form("L%d;#it{p}_{T} (GeV/#it{c});#phi (deg);Efficiency", l)); + axptphiFake->GetZaxis()->SetRangeUser(-0.1, 1.1); + axptphiFake->GetYaxis()->SetRangeUser(-180, 180); + axptphiFake->GetXaxis()->SetRangeUser(0.05, 7.5); + axptphiFake->Draw(); + mEffPtPhiFake[l]->Draw("same colz"); + effPtPhi[l][1]->Update(); + effPtPhi[l][1]->Write(); + + // EtaPhiGood + effEtaPhi[l][0] = new TCanvas(Form("effEtaPhiGood_L%d", l)); + + mEffEtaPhiGood[l] = std::make_unique(*mNGoodMatchesEtaPhi[l], *mDuplicatedEtaPhi[l]); + stileEfficiencyGraph(mEffEtaPhiGood[l], Form("mEffEtaPhiGood_L%d", l), Form("L%d;#eta;#phi (deg);Efficiency", l), true); + + axetaphiGood->SetTitle(Form("L%d;#eta;#phi (deg);Efficiency", l)); + axetaphiGood->GetZaxis()->SetRangeUser(-0.1, 1.1); + axetaphiGood->GetYaxis()->SetRangeUser(-180, 180); + axetaphiGood->GetXaxis()->SetRangeUser(-2, 2); + axetaphiGood->Draw(); + mEffEtaPhiGood[l]->Draw("same colz"); + effEtaPhi[l][0]->Update(); + effEtaPhi[l][0]->Write(); + + for (int ibin = 1; ibin <= mNFakeMatchesEtaPhi[l]->GetNbinsX(); ibin++) { + for (int jbin = 1; jbin <= mNFakeMatchesEtaPhi[l]->GetNbinsY(); jbin++) { + if (mNFakeMatchesEtaPhi[l]->GetBinContent(ibin, jbin) > mDuplicatedEtaPhi[l]->GetBinContent(ibin, jbin)) { + if (mVerboseOutput) { + std::cout << "--- Eta: Npass = " << mNFakeMatchesEtaPhi[l]->GetBinContent(ibin, jbin) << ", Nall = " << mDuplicatedEtaPhi[l]->GetBinContent(ibin, jbin) << " for ibin = " << ibin << ", jbin = " << jbin << std::endl; + } + mNFakeMatchesEtaPhi[l]->SetBinContent(ibin, jbin, mDuplicatedEtaPhi[l]->GetBinContent(ibin, jbin)); + } + } + } + + // EtaPhiFake + effEtaPhi[l][1] = new TCanvas(Form("effEtaPhiFake_L%d", l)); + + mEffEtaPhiFake[l] = std::make_unique(*mNFakeMatchesEtaPhi[l], *mDuplicatedEtaPhi[l]); + stileEfficiencyGraph(mEffEtaPhiFake[l], Form("mEffEtaPhiFake_L%d", l), Form("L%d;#eta;#phi (deg);Efficiency", l), true); + axetaphiFake->SetTitle(Form("L%d;#eta;#phi (deg);Efficiency", l)); + axetaphiFake->GetZaxis()->SetRangeUser(-0.1, 1.1); + axetaphiFake->GetYaxis()->SetRangeUser(-180, 180); + axetaphiFake->GetXaxis()->SetRangeUser(-2, 2); + axetaphiFake->Draw(); + mEffEtaPhiFake[l]->Draw("same colz"); + effEtaPhi[l][1]->Update(); + effEtaPhi[l][1]->Write(); + + // EtaAllPt + if (mVerboseOutput) { + std::cout << "Eta L" << l << "\n\n"; + } + + effEtaAllPt[l] = new TCanvas(Form("effEtaAllPt_L%d", l)); + + mEffEtaGoodAllPt[l] = std::make_unique(*mNGoodMatchesEtaAllPt[l], *mDuplicatedEtaAllPt[l]); + stileEfficiencyGraph(mEffEtaGoodAllPt[l], Form("mEffEtaGoodAllPt_L%d", l), Form("L%d;#eta;Efficiency", l), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesEtaAllPt[l]->GetNbinsX(); ibin++) { + if (mNFakeMatchesEtaAllPt[l]->GetBinContent(ibin) > mDuplicatedEtaAllPt[l]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- EtaAllPt: Npass = " << mNFakeMatchesEtaAllPt[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedEtaAllPt[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNFakeMatchesEtaAllPt[l]->SetBinContent(ibin, mDuplicatedEtaAllPt[l]->GetBinContent(ibin)); + } + } + mEffEtaFakeAllPt[l] = std::make_unique(*mNFakeMatchesEtaAllPt[l], *mDuplicatedEtaAllPt[l]); + stileEfficiencyGraph(mEffEtaFakeAllPt[l], Form("mEffEtaFakeAllPt_L%d", l), Form("L%d;#eta;Efficiency", l), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axetaAllPt->SetTitle(Form("L%d;#eta;Efficiency", l)); + axetaAllPt->GetYaxis()->SetRangeUser(-0.1, 1.1); + + axetaAllPt->Draw(); + mEffEtaGoodAllPt[l]->Draw("same p"); + mEffEtaFakeAllPt[l]->Draw("same p"); + + auto legEta = std::make_unique(0.70, 0.15, 0.89, 0.35); + legEta->AddEntry(mEffEtaGoodAllPt[l].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legEta->AddEntry(mEffEtaFakeAllPt[l].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legEta->Draw("same"); + effEtaAllPt[l]->Write(); + + /// eta and phi in different pt ranges + for (int ipt = 0; ipt < 3; ipt++) { + // eta + effEta[l][ipt] = new TCanvas(Form("effEta_L%d_pt%d", l, ipt)); + + mEffEtaGood[l][ipt] = std::make_unique(*mNGoodMatchesEta[l][ipt], *mDuplicatedEta[l][ipt]); + stileEfficiencyGraph(mEffEtaGood[l][ipt], Form("mEffEtaGood_L%d_pt%d", l, ipt), Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#eta;Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1]), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesEta[l][ipt]->GetNbinsX(); ibin++) { + if (mNFakeMatchesEta[l][ipt]->GetBinContent(ibin) > mDuplicatedEta[l][ipt]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- Eta : Npass = " << mNFakeMatchesEta[l][ipt]->GetBinContent(ibin) << ", Nall = " << mDuplicatedEta[l][ipt]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNFakeMatchesEta[l][ipt]->SetBinContent(ibin, mDuplicatedEta[l][ipt]->GetBinContent(ibin)); + } + } + + mEffEtaFake[l][ipt] = std::make_unique(*mNFakeMatchesEta[l][ipt], *mDuplicatedEta[l][ipt]); + stileEfficiencyGraph(mEffEtaFake[l][ipt], Form("mEffEtaFake_L%d_pt%d", l, ipt), Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#eta;Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1]), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axeta[ipt]->SetTitle(Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#eta;Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1])); + axeta[ipt]->GetYaxis()->SetRangeUser(-0.1, 1.1); + + axeta[ipt]->Draw(); + mEffEtaGood[l][ipt]->Draw("same p"); + mEffEtaFake[l][ipt]->Draw("same p"); + + auto legEta = std::make_unique(0.70, 0.15, 0.89, 0.35); + legEta->AddEntry(mEffEtaGood[l][ipt].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legEta->AddEntry(mEffEtaFake[l][ipt].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legEta->Draw("same"); + effEta[l][ipt]->Write(); + + // phi + effPhi[l][ipt] = new TCanvas(Form("effPhi_L%d_pt%d", l, ipt)); + + for (int ibin = 1; ibin <= mNGoodMatchesPhi[l][ipt]->GetNbinsX(); ibin++) { + if (mNGoodMatchesPhi[l][ipt]->GetBinContent(ibin) > mDuplicatedPhi[l][ipt]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- Phi L: Npass = " << mNGoodMatchesPhi[l][ipt]->GetBinContent(ibin) << ", Nall = " << mDuplicatedPhi[l][ipt]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNGoodMatchesPhi[l][ipt]->SetBinContent(ibin, 0); + } + } + + mEffPhiGood[l][ipt] = std::make_unique(*mNGoodMatchesPhi[l][ipt], *mDuplicatedPhi[l][ipt]); + stileEfficiencyGraph(mEffPhiGood[l][ipt], Form("mEffPhiGood_L%d_pt%d", l, ipt), Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#phi (deg);Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1]), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesPhi[l][ipt]->GetNbinsX(); ibin++) { + if (mNFakeMatchesPhi[l][ipt]->GetBinContent(ibin) > mDuplicatedPhi[l][ipt]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- Phi L: Npass = " << mNFakeMatchesPhi[l][ipt]->GetBinContent(ibin) << ", Nall = " << mDuplicatedPhi[l][ipt]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNFakeMatchesPhi[l][ipt]->SetBinContent(ibin, mDuplicatedPhi[l][ipt]->GetBinContent(ibin)); + } + } + + mEffPhiFake[l][ipt] = std::make_unique(*mNFakeMatchesPhi[l][ipt], *mDuplicatedPhi[l][ipt]); + stileEfficiencyGraph(mEffPhiFake[l][ipt], Form("mEffPhiFake_L%d_pt%d", l, ipt), Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#phi (deg);Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1]), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axphi[ipt]->SetTitle(Form("L%d %.1f #leq #it{p}_{T} < %.1f GeV/#it{c};#phi (deg);Efficiency", l, mrangesPt[ipt][0], mrangesPt[ipt][1])); + axphi[ipt]->GetYaxis()->SetRangeUser(-0.1, 1.1); + + axphi[ipt]->Draw(); + mEffPhiGood[l][ipt]->Draw("same p"); + mEffPhiFake[l][ipt]->Draw("same p"); + + auto legPhi = std::make_unique(0.70, 0.15, 0.89, 0.35); + legPhi->AddEntry(mEffPhiGood[l][ipt].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legPhi->AddEntry(mEffPhiFake[l][ipt].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legPhi->Draw("same"); + effPhi[l][ipt]->Write(); + } + + // PhiAllPt + if (mVerboseOutput) { + std::cout << "Phi L" << l << "\n\n"; + } + + effPhiAllPt[l] = new TCanvas(Form("effPhiAllPt_L%d", l)); + + for (int ibin = 1; ibin <= mNGoodMatchesPhiAllPt[l]->GetNbinsX(); ibin++) { + if (mNGoodMatchesPhiAllPt[l]->GetBinContent(ibin) > mDuplicatedPhiAllPt[l]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- phi all good Npass = " << mNGoodMatchesPhiAllPt[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedPhiAllPt[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNGoodMatchesPhiAllPt[l]->SetBinContent(ibin, 0); + } + } + + mEffPhiGoodAllPt[l] = std::make_unique(*mNGoodMatchesPhiAllPt[l], *mDuplicatedPhiAllPt[l]); + stileEfficiencyGraph(mEffPhiGoodAllPt[l], Form("mEffPhiGoodAllPt_L%d", l), Form("L%d;#phi;Efficiency", l), false, kFullDiamond, 1, kGreen + 3, kGreen + 3); + + for (int ibin = 1; ibin <= mNFakeMatchesPhiAllPt[l]->GetNbinsX(); ibin++) { + if (mNFakeMatchesPhiAllPt[l]->GetBinContent(ibin) > mDuplicatedPhiAllPt[l]->GetBinContent(ibin)) { + if (mVerboseOutput) { + std::cout << "--- phi all fake Npass = " << mNFakeMatchesPhiAllPt[l]->GetBinContent(ibin) << ", Nall = " << mDuplicatedPhiAllPt[l]->GetBinContent(ibin) << " for ibin = " << ibin << std::endl; + } + mNFakeMatchesPhiAllPt[l]->SetBinContent(ibin, mDuplicatedPhiAllPt[l]->GetBinContent(ibin)); + } + } + mEffPhiFakeAllPt[l] = std::make_unique(*mNFakeMatchesPhiAllPt[l], *mDuplicatedPhiAllPt[l]); + stileEfficiencyGraph(mEffPhiFakeAllPt[l], Form("mEffPhiFakeAllPt_L%d", l), Form("L%d;#phi;Efficiency", l), false, kFullDiamond, 1, kRed + 1, kRed + 1); + + axphiAllPt->SetTitle(Form("L%d;#phi;Efficiency", l)); + axphiAllPt->GetYaxis()->SetRangeUser(-0.1, 1.1); + axphiAllPt->Draw(); + mEffPhiGoodAllPt[l]->Draw("same p"); + mEffPhiFakeAllPt[l]->Draw("same p"); + + auto legPhi = std::make_unique(0.70, 0.15, 0.89, 0.35); + legPhi->AddEntry(mEffPhiGoodAllPt[l].get(), "#frac{# good matches}{# tot duplicated clusters}", "pl"); + legPhi->AddEntry(mEffPhiFakeAllPt[l].get(), "#frac{# fake matches}{# tot duplicated clusters}", "pl"); + legPhi->Draw("same"); + effPhiAllPt[l]->Write(); + } +} + +void EfficiencyStudy::saveDataInfo() +{ + // save histograms for data (phi, eta, pt,...) + LOGP(info, "--------------- saveDataInfo"); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + unsigned int totClus = 0; + + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + float ip[2]; + track.getImpactParams(0, 0, 0, 0, ip); + + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + + float phiTrack = trackParCov.getPhi() * 180 / M_PI; + + // if (pt < mPtCuts[0] || pt > mPtCuts[1]) continue; + // if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) continue; + + float phioriginal = 0; + float phiduplicated = 0; + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; // cluster spacepoint in the tracking system + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + auto layer = mGeometry->getLayer(clusOriginal.getSensorID()); + if (layer >= NLAYERS) { + continue; // checking only selected layers + } + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + + phioriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + mPhiOriginal[layer]->Fill(phioriginal); + mPhiTrackOriginal[layer]->Fill(phiTrack); + mPtOriginal[layer]->Fill(pt); + mEtaOriginal[layer]->Fill(eta); + m3DClusterPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y(), clusOriginalPointGlob.z()); + m2DClusterOriginalPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y()); + } // end loop on clusters + totClus += ncl; + } // end loop on tracks per ROF + } // end loop on ROFRecords array + LOGP(info, "Total number of clusters: {} ", totClus); +} + +void EfficiencyStudy::getEfficiency(bool isMC) +{ + // Extract the efficiency for the IB, exploiting the staves overlaps and the duplicated clusters for the tracks passing through the overlaps + // The denominator for the efficiency calculation will be the number of tracks per layer fulfilling some cuts (DCA, phi, eta, pt) + // The numerator will be the number of duplicated clusters for the tracks passing through the overlaps + + LOGP(info, "--------------- getEfficiency"); + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + int nbPt = 75; + double xbins[nbPt + 1], ptcutl = 0.05, ptcuth = 7.5; + double a = std::log(ptcuth / ptcutl) / nbPt; + for (int i = 0; i <= nbPt; i++) { + xbins[i] = ptcutl * std::exp(i * a); + } + + int totNClusters; + int nDuplClusters; + + // denominator fot the efficiency calculation + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + ////// imposing cuts on the tracks = collecting tracks for the denominator + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + float phi = -999.; + float phiOriginal = -999.; + + float chi2 = track.getChi2(); + + float ip[2]; + track.getImpactParams(0, 0, 0, 0, ip); + + float phiTrack = trackParCov.getPhi() * 180 / M_PI; + + // applying the cuts on the track - only pt and eta, and chi2 cuts since for phi(cluster) the layer is needed + if (pt < mPtCuts[0] || pt > mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + if (chi2 > mChi2cut) { + continue; + } + + /// the cut on phi, since it is layer-dependent, can be applied only after finding the cluster and then the layer + + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + + o2::MCCompLabel tracklab; + if (isMC) { + tracklab = mTracksMCLabels[iTrack]; + if (tracklab.isFake()) { + continue; + } + } + + if (mVerboseOutput && isMC) { + LOGP(info, "--------- track Label: "); + tracklab.print(); + } + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track to extract layer, stave and chip to restrict the possible matches to be searched with the DCA cut + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; + auto layerOriginal = mGeometry->getLayer(clusOriginal.getSensorID()); + + UShort_t rowOriginal = clusOriginal.getRow(); + + if (layerOriginal >= NLAYERS) { + continue; + } + + IPOriginalxy[layerOriginal]->Fill(ip[0]); + IPOriginalz[layerOriginal]->Fill(ip[1]); + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + // phiOriginal = std::(clusOriginalPointGlob.y(), clusOriginalPointGlob.x()) * 180 / M_PI + 180; + phiOriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + mXoriginal->Fill(clusOriginalPointGlob.x()); + mYoriginal->Fill(clusOriginalPointGlob.y()); + mZoriginal->Fill(clusOriginalPointGlob.z()); + + // std::cout<<" Layer: "<Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y()); + m3DClusterPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y(), clusOriginalPointGlob.z()); + + /// applying the cuts on the phi of the original cluster + bool keepTrack = false; /// wether or not a cluster is found in an eligible track in the corresponding layer + if (layerOriginal == 0) { + + for (int i = 0; i < 10; i++) { + if ((phiOriginal >= mPhiCutsL0[i][0] && phiOriginal <= mPhiCutsL0[i][1])) { + keepTrack = true; + } + } + } + if (layerOriginal == 1) { + for (int i = 0; i < 12; i++) { + if ((phiOriginal >= mPhiCutsL1[i][0] && phiOriginal <= mPhiCutsL1[i][1])) { + keepTrack = true; + } + } + } + if (layerOriginal == 2) { + for (int i = 0; i < 17; i++) { + if ((phiOriginal >= mPhiCutsL2[i][0] && phiOriginal <= mPhiCutsL2[i][1])) { + keepTrack = true; + } + } + } + + ///////////////////////////////////// + if (!(keepTrack)) { + continue; /// if the track (cluster) is not eligible for any layer, go to the next one + } else { /// fill the den and go ahead + chi2trackAccepted->Fill(chi2); + denPt[layerOriginal]->Fill(pt); + denPhi[layerOriginal]->Fill(phiOriginal); + denEta[layerOriginal]->Fill(eta); + nTracksSelected[layerOriginal]++; + } + + /// if the cuts up to here are passed, then search for the duplicated cluster, otherwise go to the next cluster + gsl::span labsOriginal = {}; + if (isMC) { + labsOriginal = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track (original) + } + + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + std::tuple> clusID_rDCA_label = {0, 999., gsl::span()}; // inizializing tuple with dummy values (if data, ignore the third value) + + bool adjacentFound = 0; + float phiDuplicated = -999.; + float ptDuplicated = -999.; + float etaDuplicated = -999.; + float clusZ = -999.; + /// for each original cluster iterate over all the possible duplicated clusters to see first wether increment or not the denominator (if a track has a possible duplicated cluster in the selected phi region) + /// then if the phi is within the cuts, select the "adjacent" clusters (stave +-1, chip =,+-1) and calculate the DCA with the track. Then choose the closest one. + // std::cout<<"Loop on clusters 2"< clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + phi = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + //// applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerOriginal) { + continue; + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + gsl::span labsDuplicated = {}; + if (isMC) { + labsDuplicated = mClustersMCLCont->getLabels(iClus); + } + + /// if the cheks are passed, then calculate the DCA + /// Compute the DCA between the duplicated cluster location and the track + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusDuplicated.getSensorID())); + if (!propagator->propagateToDCA(clusDuplicatedPointGlob, trackParCov, b, 2.f, matCorr, &clusDuplicatedDCA)) { // check if the propagation fails + continue; + } + + DCAxyData[layerDuplicated]->Fill(clusDuplicatedDCA[0]); + DCAzData[layerDuplicated]->Fill(clusDuplicatedDCA[1]); + // std::cout<<"DCA: "<Fill(abs(clusDuplicatedPointGlob.x() - clusOriginalPointGlob.x())); + DistanceClustersY[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.y() - clusOriginalPointGlob.y())); + DistanceClustersZ[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.z() - clusOriginalPointGlob.z())); + + // Imposing that the distance between the duplicated cluster and the track is less than x sigma + if (!(clusDuplicatedDCA[0] > mDCACutsXY[layerDuplicated][0] && clusDuplicatedDCA[0] < mDCACutsXY[layerDuplicated][1] && clusDuplicatedDCA[1] > mDCACutsZ[layerDuplicated][0] && clusDuplicatedDCA[1] < mDCACutsZ[layerDuplicated][1])) { + DCAxyRejected[layerDuplicated]->Fill(clusDuplicatedDCA[0]); + DCAzRejected[layerDuplicated]->Fill(clusDuplicatedDCA[1]); + continue; + } + + m2DClusterDuplicatedPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y()); + m3DDuplicatedClusterPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y(), clusDuplicatedPointGlob.z()); + + mXduplicated->Fill(clusDuplicatedPointGlob.x()); + mYduplicated->Fill(clusDuplicatedPointGlob.y()); + mZduplicated->Fill(clusDuplicatedPointGlob.z()); + + IPOriginalifDuplicatedxy[layerOriginal]->Fill(ip[0]); + IPOriginalifDuplicatedz[layerOriginal]->Fill(ip[1]); + + DistanceClustersXAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.x() - clusOriginalPointGlob.x())); + DistanceClustersYAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.y() - clusOriginalPointGlob.y())); + DistanceClustersZAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.z() - clusOriginalPointGlob.z())); + + if (mVerboseOutput) { + LOGP(info, "Propagation ok"); + } + double rDCA = std::hypot(clusDuplicatedDCA[0], clusDuplicatedDCA[1]); + + // taking the closest cluster within x sigma + if (rDCA < std::get<1>(clusID_rDCA_label)) { // updating the closest cluster + if (isMC) { + clusID_rDCA_label = {iClus, rDCA, labsDuplicated}; + } else { + clusID_rDCA_label = {iClus, rDCA, gsl::span()}; + } + phiDuplicated = phiOriginal; + ptDuplicated = pt; + etaDuplicated = eta; + clusZ = clusOriginalPointGlob.z(); + } + adjacentFound = 1; + } // end loop on all the clusters in the rof -> at this point we have the information on the closest cluster (if there is one) + + // here clusID_rDCA_label is updated with the closest cluster to the track other than the original one + + if (!adjacentFound) { + continue; + } + nDuplClusters++; + nDuplicatedClusters[layerOriginal]++; + numPt[layerOriginal]->Fill(ptDuplicated); + numPhi[layerOriginal]->Fill(phiDuplicated); + numEta[layerOriginal]->Fill(etaDuplicated); + mZvsPhiDUplicated[layerOriginal]->Fill(clusZ, phiDuplicated); + + // checking if it is a good or fake match looking at the labels (only if isMC) + if (isMC) { + bool isGood = false; + for (auto lab : std::get<2>(clusID_rDCA_label)) { + if (lab == tracklab) { + isGood = true; + numPtGood[layerOriginal]->Fill(ptDuplicated); + numPhiGood[layerOriginal]->Fill(phiDuplicated); + numEtaGood[layerOriginal]->Fill(etaDuplicated); + continue; + } + } + if (!isGood) { + numPtFake[layerOriginal]->Fill(ptDuplicated); + numPhiFake[layerOriginal]->Fill(phiDuplicated); + numEtaFake[layerOriginal]->Fill(etaDuplicated); + } + } + } // end loop on clusters associated to the track + totNClusters += NLAYERS; + } // end loop on tracks per ROF + } // end loop on ROFRecords array + + std::cout << " Num of duplicated clusters L0: " << nDuplicatedClusters[0] << " N tracks selected: " << nTracksSelected[0] << std::endl; + std::cout << " Num of duplicated clusters L1: " << nDuplicatedClusters[1] << " N tracks selected: " << nTracksSelected[1] << std::endl; + std::cout << " Num of duplicated clusters L2: " << nDuplicatedClusters[2] << " N tracks selected: " << nTracksSelected[2] << std::endl; + + std::cout << " --------- N total clusters: " << totNClusters << std::endl; + std::cout << " --------- N duplicated clusters: " << nDuplClusters << std::endl; +} + +void EfficiencyStudy::getEfficiencyAndTrackInfo(bool isMC) +{ + // Extract the efficiency for the IB, exploiting the staves overlaps and the duplicated clusters for the tracks passing through the overlaps + // The denominator for the efficiency calculation will be the number of tracks per layer fulfilling some cuts (DCA, phi, eta, pt) + // The numerator will be the number of duplicated clusters for the tracks passing through the overlaps + // additionally, print/save info (to be used in MC) + + LOGP(info, "--------------- getEfficiency"); + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::gpu::gpustd::array clusOriginalDCA, clusDuplicatedDCA; + auto propagator = o2::base::Propagator::Instance(); + + unsigned int rofIndexTrack = 0; + unsigned int rofNEntriesTrack = 0; + unsigned int rofIndexClus = 0; + unsigned int rofNEntriesClus = 0; + int nLabels = 0; + unsigned int totClus = 0; + + int nbPt = 75; + double xbins[nbPt + 1], ptcutl = 0.05, ptcuth = 7.5; + double a = std::log(ptcuth / ptcutl) / nbPt; + for (int i = 0; i <= nbPt; i++) { + xbins[i] = ptcutl * std::exp(i * a); + } + + int totNClusters; + int nDuplClusters; + + // denominator fot the efficiency calculation + for (unsigned int iROF = 0; iROF < mTracksROFRecords.size(); iROF++) { // loop on ROFRecords array + + rofIndexTrack = mTracksROFRecords[iROF].getFirstEntry(); + rofNEntriesTrack = mTracksROFRecords[iROF].getNEntries(); + + rofIndexClus = mClustersROFRecords[iROF].getFirstEntry(); + rofNEntriesClus = mClustersROFRecords[iROF].getNEntries(); + + ////// imposing cuts on the tracks = collecting tracks for the denominator + for (unsigned int iTrack = rofIndexTrack; iTrack < rofIndexTrack + rofNEntriesTrack; iTrack++) { // loop on tracks per ROF + auto track = mTracks[iTrack]; + o2::track::TrackParCov trackParCov = mTracks[iTrack]; + + auto pt = trackParCov.getPt(); + auto eta = trackParCov.getEta(); + float phi = -999.; + float phiOriginal = -999.; + + float chi2 = track.getChi2(); + + chi2track->Fill(chi2); + + float phiTrack = trackParCov.getPhi() * 180 / M_PI; + + // applying the cuts on the track - only pt and eta cuts since for phi(cluster) the layer is needed + if (pt < mPtCuts[0] || pt > mPtCuts[1]) { + continue; + } + if (eta < mEtaCuts[0] || eta > mEtaCuts[1]) { + continue; + } + if (chi2 > mChi2cut) { + continue; + } + /// the cut on phi, since it is layer-dependent, can be applied only after finding the cluster and then the layer + + int firstClus = track.getFirstClusterEntry(); // get the first cluster of the track + int ncl = track.getNumberOfClusters(); // get the number of clusters of the track + + if (ncl < 7) { + continue; + } + + o2::MCCompLabel tracklab; + if (isMC) { + tracklab = mTracksMCLabels[iTrack]; + if (tracklab.isFake()) { + continue; + } + } + + if (mVerboseOutput && isMC) { + LOGP(info, "--------- track Label: "); + tracklab.print(); + } + + for (int iclTrack = firstClus; iclTrack < firstClus + ncl; iclTrack++) { // loop on clusters associated to the track to extract layer, stave and chip to restrict the possible matches to be searched with the DCA cut + auto& clusOriginal = mClusters[mInputITSidxs[iclTrack]]; + auto clusOriginalPoint = mITSClustersArray[mInputITSidxs[iclTrack]]; + auto layerOriginal = mGeometry->getLayer(clusOriginal.getSensorID()); + + UShort_t rowOriginal = clusOriginal.getRow(); + + if (layerOriginal >= NLAYERS) { + continue; + } + + o2::math_utils::Point3D clusOriginalPointTrack = {clusOriginalPoint.getX(), clusOriginalPoint.getY(), clusOriginalPoint.getZ()}; + o2::math_utils::Point3D clusOriginalPointGlob = mGeometry->getMatrixT2G(clusOriginal.getSensorID()) * clusOriginalPointTrack; + phiOriginal = clusOriginalPointGlob.phi() * 180 / M_PI; + + mXoriginal->Fill(clusOriginalPointGlob.x()); + mYoriginal->Fill(clusOriginalPointGlob.y()); + mZoriginal->Fill(clusOriginalPointGlob.z()); + + m2DClusterOriginalPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y()); + m3DClusterPositions->Fill(clusOriginalPointGlob.x(), clusOriginalPointGlob.y(), clusOriginalPointGlob.z()); + + /// applying the cuts on the phi of the original cluster + bool keepTrack = false; /// wether or not a cluster is found in an eligible track in the corresponding layer + + if (layerOriginal == 0) { + for (int i = 0; i < 10; i++) { + if ((phiOriginal >= mPhiCutsL0[i][0] && phiOriginal <= mPhiCutsL0[i][1])) { + keepTrack = true; + } + } + } + if (layerOriginal == 1) { + for (int i = 0; i < 12; i++) { + if ((phiOriginal >= mPhiCutsL1[i][0] && phiOriginal <= mPhiCutsL1[i][1])) { + keepTrack = true; + } + } + } + if (layerOriginal == 2) { + for (int i = 0; i < 17; i++) { + if ((phiOriginal >= mPhiCutsL2[i][0] && phiOriginal <= mPhiCutsL2[i][1])) { + keepTrack = true; + } + } + } + if (!(keepTrack)) { + continue; /// if the track (cluster) is not eligible for any layer, go to the next one + } else { /// fill the den and go ahead + chi2trackAccepted->Fill(chi2); + denPt[layerOriginal]->Fill(pt); + denPhi[layerOriginal]->Fill(phiOriginal); + denEta[layerOriginal]->Fill(eta); + nTracksSelected[layerOriginal]++; + } + gsl::span labsOriginal = {}; + if (isMC) { + labsOriginal = mClustersMCLCont->getLabels(mInputITSidxs[iclTrack]); // get labels of the cluster associated to the track (original) + } + + auto staveOriginal = mGeometry->getStave(clusOriginal.getSensorID()); + auto chipOriginal = mGeometry->getChipIdInStave(clusOriginal.getSensorID()); + + std::tuple> clusID_rDCA_label = {0, 999., gsl::span()}; // inizializing tuple with dummy values (if data, ignore the third value) + + bool adjacentFound = 0; + float phiDuplicated = -999.; + float ptDuplicated = -999.; + float etaDuplicated = -999.; + float clusZ = -999.; + + o2::MCCompLabel labelCandidateDuplicated; + bool duplExists = false; + + /// for each original cluster iterate over all the possible duplicated clusters to see first wether increment or not the denominator (if a track has a possible duplicated cluster in the selected phi region) + /// then if the phi is within the cuts, select the "adjacent" clusters (stave +-1, chip =,+-1) and calculate the DCA with the track. Then choose the closest one. + for (unsigned int iClus = rofIndexClus; iClus < rofIndexClus + rofNEntriesClus; iClus++) { // iteration over ALL the clusters in the ROF + auto clusDuplicated = mClusters[iClus]; + + auto clusDuplicatedPoint = mITSClustersArray[iClus]; + + o2::math_utils::Point3D clusDuplicatedPointTrack = {clusDuplicatedPoint.getX(), clusDuplicatedPoint.getY(), clusDuplicatedPoint.getZ()}; + o2::math_utils::Point3D clusDuplicatedPointGlob = mGeometry->getMatrixT2G(clusDuplicated.getSensorID()) * clusDuplicatedPointTrack; + phi = clusDuplicatedPointGlob.phi() * 180 / M_PI; + + //// applying constraints: the cluster should be on the same layer, should be on an adjacent stave and on the same or adjacent chip position + if (clusDuplicated.getSensorID() == clusOriginal.getSensorID()) { + continue; + } + auto layerDuplicated = mGeometry->getLayer(clusDuplicated.getSensorID()); + if (layerDuplicated != layerOriginal) { + continue; + } + labelCandidateDuplicated = mClustersMCLCont->getLabels(iClus)[0]; + if (labelCandidateDuplicated == tracklab) { + duplExists = true; + std::cout << "Duplicated should exist with label: " << labelCandidateDuplicated.asString() << " , phi = " << phi << " and be: "; + clusDuplicated.print(); + } + auto staveDuplicated = mGeometry->getStave(clusDuplicated.getSensorID()); + if (abs(staveDuplicated - staveOriginal) != 1) { + continue; + } + auto chipDuplicated = mGeometry->getChipIdInStave(clusDuplicated.getSensorID()); + if (abs(chipDuplicated - chipOriginal) > 1) { + continue; + } + + std::cout << "checks passed" << std::endl; + + gsl::span labsDuplicated = {}; + if (isMC) { + labsDuplicated = mClustersMCLCont->getLabels(iClus); + } + + /// if the cheks are passed, then calculate the DCA + /// Compute the DCA between the duplicated cluster location and the track + trackParCov.rotate(mGeometry->getSensorRefAlpha(clusDuplicated.getSensorID())); + if (!propagator->propagateToDCA(clusDuplicatedPointGlob, trackParCov, b, 2.f, matCorr, &clusDuplicatedDCA)) { // check if the propagation fails + continue; + } + + std::cout << "dca calculated: " << clusDuplicatedDCA[0] << " " << clusDuplicatedDCA[1] << std::endl; + + DCAxyData[layerDuplicated]->Fill(clusDuplicatedDCA[0]); + DCAzData[layerDuplicated]->Fill(clusDuplicatedDCA[1]); + DistanceClustersX[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.x() - clusOriginalPointGlob.x())); + DistanceClustersY[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.y() - clusOriginalPointGlob.y())); + DistanceClustersZ[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.z() - clusOriginalPointGlob.z())); + + // Imposing that the distance between the duplicated cluster and the track is less than x sigma + if (!(clusDuplicatedDCA[0] > mDCACutsXY[layerDuplicated][0] && clusDuplicatedDCA[0] < mDCACutsXY[layerDuplicated][1] && clusDuplicatedDCA[1] > mDCACutsZ[layerDuplicated][0] && clusDuplicatedDCA[1] < mDCACutsZ[layerDuplicated][1])) { + DCAxyRejected[layerDuplicated]->Fill(clusDuplicatedDCA[0]); + DCAzRejected[layerDuplicated]->Fill(clusDuplicatedDCA[1]); + continue; + } + m2DClusterDuplicatedPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y()); + m3DDuplicatedClusterPositions->Fill(clusDuplicatedPointGlob.x(), clusDuplicatedPointGlob.y(), clusDuplicatedPointGlob.z()); + mXduplicated->Fill(clusDuplicatedPointGlob.x()); + mYduplicated->Fill(clusDuplicatedPointGlob.y()); + mZduplicated->Fill(clusDuplicatedPointGlob.z()); + + DistanceClustersXAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.x() - clusOriginalPointGlob.x())); + DistanceClustersYAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.y() - clusOriginalPointGlob.y())); + DistanceClustersZAftercuts[layerDuplicated]->Fill(abs(clusDuplicatedPointGlob.z() - clusOriginalPointGlob.z())); + + if (mVerboseOutput) { + LOGP(info, "Propagation ok"); + } + double rDCA = std::hypot(clusDuplicatedDCA[0], clusDuplicatedDCA[1]); + + // taking the closest cluster within x sigma + if (rDCA < std::get<1>(clusID_rDCA_label)) { // updating the closest cluster + if (isMC) { + clusID_rDCA_label = {iClus, rDCA, labsDuplicated}; + } else { + clusID_rDCA_label = {iClus, rDCA, gsl::span()}; + } + phiDuplicated = phiOriginal; + ptDuplicated = pt; + etaDuplicated = eta; + clusZ = clusOriginalPointGlob.z(); + } + adjacentFound = 1; + std::cout << "Duplicated found with label: " << labsDuplicated[0] << " and phi: " << phiDuplicated << std::endl; + clusDuplicated.print(); + std::cout << "-----" << std::endl; + } // end loop on all the clusters in the rof -> at this point we have the information on the closest cluster (if there is one) + + // here clusID_rDCA_label is updated with the closest cluster to the track other than the original one + // checking if it is a good or fake match looking at the labels (only if isMC) + if (!adjacentFound) { + if (duplExists) { + std::cout << "No duplicated found but should exist" << std::endl; + std::cout << "DCA cuts were: xy-> " << mDCACutsXY[layerOriginal][0] << " to " << mDCACutsXY[layerOriginal][1] << " and z-> " << mDCACutsZ[layerOriginal][0] << " to " << mDCACutsZ[layerOriginal][1] << "\n-----" << std::endl; + } else { + std::cout << "No duplicated found and does not exist" << std::endl; + } + continue; + } + std::cout << "-----" << std::endl; + nDuplClusters++; + nDuplicatedClusters[layerOriginal]++; + numPt[layerOriginal]->Fill(ptDuplicated); + numPhi[layerOriginal]->Fill(phiDuplicated); + numEta[layerOriginal]->Fill(etaDuplicated); + mZvsPhiDUplicated[layerOriginal]->Fill(clusZ, phiDuplicated); + + if (isMC) { + bool isGood = false; + for (auto lab : std::get<2>(clusID_rDCA_label)) { + if (lab == tracklab) { + isGood = true; + numPtGood[layerOriginal]->Fill(ptDuplicated); + numPhiGood[layerOriginal]->Fill(phiDuplicated); + numEtaGood[layerOriginal]->Fill(etaDuplicated); + continue; + } + } + if (!isGood) { + numPtFake[layerOriginal]->Fill(ptDuplicated); + numPhiFake[layerOriginal]->Fill(phiDuplicated); + numEtaFake[layerOriginal]->Fill(etaDuplicated); + } + } + } // end loop on clusters associated to the track + totNClusters += NLAYERS; + } // end loop on tracks per ROF + } // end loop on ROFRecords array + + std::cout << " Num of duplicated clusters L0: " << nDuplicatedClusters[0] << " N tracks selected: " << nTracksSelected[0] << std::endl; + std::cout << " Num of duplicated clusters L1: " << nDuplicatedClusters[1] << " N tracks selected: " << nTracksSelected[1] << std::endl; + std::cout << " Num of duplicated clusters L2: " << nDuplicatedClusters[2] << " N tracks selected: " << nTracksSelected[2] << std::endl; + + std::cout << " --------- N total clusters: " << totNClusters << std::endl; + std::cout << " --------- N duplicated clusters: " << nDuplClusters << std::endl; +} + +void EfficiencyStudy::process(o2::globaltracking::RecoContainer& recoData) +{ + LOGP(info, "--------------- process"); + + o2::base::GRPGeomHelper::instance().getGRPMagField()->print(); + + if (mUseMC) { + // getDCAClusterTrackMC(); + // studyDCAcutsMC(); + // studyClusterSelectionMC(); + // getEfficiencyAndTrackInfo(mUseMC); + // countDuplicatedAfterCuts(); + } else if (!mUseMC) { + // saveDataInfo(); + } + + getEfficiency(mUseMC); + + LOGP(info, "** Found in {} rofs:\n\t- {} clusters\n\t", + mClustersROFRecords.size(), mClusters.size()); + + if (mUseMC) { + LOGP(info, "mClusters size: {}, mClustersROFRecords size: {}, mClustersMCLCont size: {}, mClustersconverted size: {} ", mClusters.size(), mClustersROFRecords.size(), mClustersMCLCont->getNElements(), mITSClustersArray.size()); + LOGP(info, "mTracks size: {}, mTracksROFRecords size: {}, mTracksMCLabels size: {}", mTracks.size(), mTracksROFRecords.size(), mTracksMCLabels.size()); + } else { + LOGP(info, "mClusters size: {}, mClustersROFRecords size: {}, mClustersconverted size: {} ", mClusters.size(), mClustersROFRecords.size(), mITSClustersArray.size()); + LOGP(info, "mTracks size: {}, mTracksROFRecords size: {}", mTracks.size(), mTracksROFRecords.size()); + } +} + +void EfficiencyStudy::updateTimeDependentParams(ProcessingContext& pc) +{ + static bool initOnceDone = false; + o2::base::GRPGeomHelper::instance().checkUpdates(pc); + if (!initOnceDone) { // this params need to be queried only once + initOnceDone = true; + mGeometry = GeometryTGeo::Instance(); + mGeometry->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G, o2::math_utils::TransformType::L2G)); + } +} + +void EfficiencyStudy::endOfStream(EndOfStreamContext& ec) +{ + LOGP(info, "--------------- endOfStream"); + + mOutFile->mkdir("EfficiencyFinal/"); + mOutFile->mkdir("DCAFinal/"); + + mOutFile->mkdir("DistanceClusters/"); + mOutFile->mkdir("DCA/"); + mOutFile->mkdir("Pt_Eta_Phi/"); + + if (mUseMC) { + + mOutFile->cd("DistanceClusters"); + for (int i = 0; i < NLAYERS; i++) { + mDistanceClustersX[i]->Write(); + mDistanceClustersY[i]->Write(); + mDistanceClustersZ[i]->Write(); + mDistanceClusters[i]->Write(); + } + + mOutFile->cd("DCA"); + mDCAxyDuplicated->Write(); + mDCAzDuplicated->Write(); + for (int i = 0; i < NLAYERS; i++) { + mDCAxyDuplicated_layer[i]->Write(); + mDCAzDuplicated_layer[i]->Write(); + + mDCAxyOriginal[i]->Write(); + mDCAzOriginal[i]->Write(); + } + + mOutFile->cd("Pt_Eta_Phi/"); + for (int i = 0; i < NLAYERS; i++) { + mPhiOriginal[i]->Write(); + mPhiTrackOriginal[i]->Write(); + mDuplicatedPhiAllPt[i]->Write(); + mPtOriginal[i]->Write(); + mPtDuplicated[i]->Write(); + mEtaDuplicated[i]->Write(); + mPhiDuplicated[i]->Write(); + mPhiTrackDuplicated[i]->Write(); + mPhiTrackDuplicatedvsphiDuplicated[i]->Write(); + mPhiTrackoriginalvsphioriginal[i]->Write(); + mPhiOriginalIfDuplicated[i]->Write(); + mDuplicatedPt[i]->Write(); + mDuplicatedPtEta[i]->Write(); + mDuplicatedPtPhi[i]->Write(); + mDuplicatedEtaPhi[i]->Write(); + mEtaOriginal[i]->Write(); + mDuplicatedEtaAllPt[i]->Write(); + mDuplicatedRow[i]->Write(); + + for (int p = 0; p < 3; p++) { + mDuplicatedEta[i][p]->Write(); + mDuplicatedPhi[i][p]->Write(); + } + mPt_EtaDupl[i]->Write(); + } + } + + mOutFile->cd("Pt_Eta_Phi/"); + for (int i = 0; i < NLAYERS; i++) { + IPOriginalxy[i]->Write(); + IPOriginalz[i]->Write(); + mPhiOriginal[i]->Write(); + mPhiTrackOriginal[i]->Write(); + mPtOriginal[i]->Write(); + mEtaOriginal[i]->Write(); + mZvsPhiDUplicated[i]->Write(); + chipRowDuplicated[i]->Write(); + chipRowOriginalIfDuplicated[i]->Write(); + } + + mOutFile->mkdir("chi2"); + mOutFile->cd("chi2/"); + + chi2track->Write(); + chi2trackAccepted->Write(); + + mOutFile->cd("EfficiencyFinal/"); + + for (int l = 0; l < NLAYERS; l++) { + + TEfficiency* effPt = new TEfficiency(*numPt[l], *denPt[l]); + effPt->SetName(Form("effPt_layer%d", l)); + effPt->SetTitle(Form("L%d;p_{T} (GeV/c);Efficiency", l)); + TEfficiency* effPtGood = new TEfficiency(*numPtGood[l], *denPt[l]); + effPtGood->SetName(Form("effPtGood_layer%d", l)); + effPtGood->SetTitle(Form("L%d;p_{T} (GeV/c);Efficiency Good Matches", l)); + TEfficiency* effPtFake = new TEfficiency(*numPtFake[l], *denPt[l]); + effPtFake->SetName(Form("effPtFake_layer%d", l)); + effPtFake->SetTitle(Form("L%d;p_{T} (GeV/c);Efficiency Fake Matches", l)); + effPt->Write(); + effPtGood->Write(); + effPtFake->Write(); + + TEfficiency* effPhi = new TEfficiency(*numPhi[l], *denPhi[l]); + effPhi->SetName(Form("effPhi_layer%d", l)); + effPhi->SetTitle(Form("L%d;#phi;Efficiency", l)); + TEfficiency* effPhiGood = new TEfficiency(*numPhiGood[l], *denPhi[l]); + effPhiGood->SetName(Form("effPhiGood_layer%d", l)); + effPhiGood->SetTitle(Form("L%d;#phi;Efficiency Good Matches", l)); + TEfficiency* effPhiFake = new TEfficiency(*numPhiFake[l], *denPhi[l]); + effPhiFake->SetName(Form("effPhiFake_layer%d", l)); + effPhiFake->SetTitle(Form("L%d;#phi;Efficiency Fake Matches", l)); + effPhi->Write(); + effPhiGood->Write(); + effPhiFake->Write(); + + TEfficiency* effEta = new TEfficiency(*numEta[l], *denEta[l]); + effEta->SetName(Form("effEta_layer%d", l)); + effEta->SetTitle(Form("L%d;#eta;Efficiency", l)); + TEfficiency* effEtaGood = new TEfficiency(*numEtaGood[l], *denEta[l]); + effEtaGood->SetName(Form("effEtaGood_layer%d", l)); + effEtaGood->SetTitle(Form("L%d;#eta;Efficiency Good Matches", l)); + TEfficiency* effEtaFake = new TEfficiency(*numEtaFake[l], *denEta[l]); + effEtaFake->SetName(Form("effEtaFake_layer%d", l)); + effEtaFake->SetTitle(Form("L%d;#eta;Efficiency Fake Matches", l)); + effEta->Write(); + effEtaGood->Write(); + effEtaFake->Write(); + + numPhi[l]->Write(); + denPhi[l]->Write(); + numPt[l]->Write(); + denPt[l]->Write(); + numEta[l]->Write(); + denEta[l]->Write(); + } + + mOutFile->cd("DCAFinal/"); + + for (int l = 0; l < NLAYERS; l++) { + DCAxyData[l]->Write(); + DCAzData[l]->Write(); + DistanceClustersX[l]->Write(); + DistanceClustersY[l]->Write(); + DistanceClustersZ[l]->Write(); + DistanceClustersXAftercuts[l]->Write(); + DistanceClustersYAftercuts[l]->Write(); + DistanceClustersZAftercuts[l]->Write(); + DCAxyRejected[l]->Write(); + DCAzRejected[l]->Write(); + } + + mOutFile->Close(); +} + +void EfficiencyStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) +{ + std::cout << "-------- finaliseCCDB" << std::endl; + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } + if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) { + setClusterDictionary((const o2::itsmft::TopologyDictionary*)obj); + return; + } +} + +DataProcessorSpec getEfficiencyStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader) +{ + std::vector outputs; + auto dataRequest = std::make_shared(); + dataRequest->requestTracks(srcTracksMask, useMC); + dataRequest->requestClusters(srcClustersMask, useMC); + + auto ggRequest = std::make_shared(false, // orbitResetTime + true, // GRPECS=true + false, // GRPLHCIF + true, // GRPMagField + true, // askMatLUT + o2::base::GRPGeomRequest::Aligned, // geometry + dataRequest->inputs, + true); + return DataProcessorSpec{ + "its-efficiency-study", + dataRequest->inputs, + outputs, + AlgorithmSpec{adaptFromTask(dataRequest, srcTracksMask, useMC, kineReader, ggRequest)}, + Options{}}; +} + +} // namespace o2::its::study \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx index 3f9ea07bf1f51..c0b2d2863f3cc 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx @@ -22,12 +22,14 @@ static auto& sPIDStudyParamITS = o2::its::study::PIDStudyParamConfig::Instance() static auto& sCheckTracksParamsITS = o2::its::study::ITSCheckTracksParamConfig::Instance(); static auto& sImpactParameterParamsITS = o2::its::study::ITSImpactParameterParamConfig::Instance(); static auto& sAnomalyStudy = o2::its::study::AnomalyStudyParamConfig::Instance(); +static auto& sEfficiencyParamsITS = o2::its::study::ITSEfficiencyParamConfig::Instance(); O2ParamImpl(o2::its::study::ITSAvgClusSizeParamConfig); O2ParamImpl(o2::its::study::PIDStudyParamConfig); O2ParamImpl(o2::its::study::ITSCheckTracksParamConfig); O2ParamImpl(o2::its::study::ITSImpactParameterParamConfig); O2ParamImpl(o2::its::study::AnomalyStudyParamConfig); +O2ParamImpl(o2::its::study::ITSEfficiencyParamConfig); } // namespace study } // namespace its diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h index 2ceae2ea981f6..d56d718390b47 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h @@ -19,11 +19,13 @@ #pragma link C++ class o2::its::study::PIDStudyParamConfig + ; #pragma link C++ class o2::its::study::ITSImpactParameterParamConfig + ; #pragma link C++ class o2::its::study::AnomalyStudyParamConfig + ; +#pragma link C++ class o2::its::study::ITSEfficiencyParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSAvgClusSizeParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::PIDStudyParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSCheckTracksParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSImpactParameterParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::AnomalyStudyParamConfig> + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSEfficiencyParamConfig> + ; #pragma link C++ function o2::its::studies::makeLogBinning + ; #endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx index 66844255536a1..02a75def154fc 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx @@ -22,6 +22,7 @@ #include "ITSStudies/AvgClusSize.h" #include "ITSStudies/PIDStudy.h" #include "ITSStudies/AnomalyStudy.h" +#include "ITSStudies/Efficiency.h" #include "ITSStudies/TrackCheck.h" #include "ITSStudies/TrackExtension.h" #include "Steer/MCKinematicsReader.h" @@ -51,8 +52,9 @@ void customize(std::vector& workflowOptions) {"impact-parameter-study", VariantType::Bool, false, {"Perform the impact parameter study"}}, {"anomaly-study", VariantType::Bool, false, {"Perform the anomaly study"}}, {"track-extension-study", VariantType::Bool, false, {"Perform the track extension study"}}, + {"efficiency-study", VariantType::Bool, false, {"Perform the efficiency study"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; - o2::raw::HBFUtilsInitializer::addConfigOption(options, "o2_tfidinfo.root"); + // o2::raw::HBFUtilsInitializer::addConfigOption(options, "o2_tfidinfo.root"); std::swap(workflowOptions, options); } @@ -117,6 +119,15 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); specs.emplace_back(o2::its::study::getTrackExtensionStudy(srcTrc, srcCls, useMC, mcKinematicsReader)); } + if (configcontext.options().get("efficiency-study")) { + anyStudy = true; + srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); + srcCls = GID::getSourcesMask(configcontext.options().get("cluster-sources")); + if (!configcontext.options().get("input-from-upstream")) { + o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); + } + specs.emplace_back(o2::its::study::getEfficiencyStudy(GID::getSourcesMask("ITS"), GID::getSourcesMask("ITS"), useMC, mcKinematicsReader)); + } if (!anyStudy) { LOGP(info, "No study selected, dryrunning"); } From b4d225b814fd1e9a19ab1721c4716aa5788049a4 Mon Sep 17 00:00:00 2001 From: ehellbar Date: Tue, 29 Oct 2024 12:23:30 +0100 Subject: [PATCH 0391/2205] DebugGUI: adding minor features to inputs/outputs display (#13628) --- .../src/FrameworkGUIDataRelayerUsage.cxx | 42 ++++++++++++++- .../src/FrameworkGUIDataRelayerUsage.h | 2 +- .../src/FrameworkGUIDeviceInspector.cxx | 19 +++++-- .../src/FrameworkGUIDevicesGraph.cxx | 2 +- Framework/GUISupport/src/InspectorHelpers.h | 51 +++++++++++++++++++ 5 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 Framework/GUISupport/src/InspectorHelpers.h diff --git a/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.cxx b/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.cxx index 876801792b631..8e683d46131ea 100644 --- a/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.cxx @@ -12,8 +12,10 @@ #include #include "Framework/DeviceMetricsInfo.h" #include "Framework/DeviceInfo.h" +#include "Framework/DeviceSpec.h" #include "Framework/DataDescriptorMatcher.h" #include "Framework/DataProcessingStates.h" +#include "InspectorHelpers.h" #include "PaletteHelpers.h" #include "Framework/Logger.h" #include @@ -31,6 +33,7 @@ struct HeatMapHelper { template static void draw(const char* name, ImVec2 const& sizeHint, + std::function const& getNumInputs, std::function const& getNumRecords, std::function const& getRecord, std::function const& getNumItems, @@ -48,12 +51,13 @@ struct HeatMapHelper { ImVec2 winPos = ImGui::GetCursorScreenPos() + ImVec2{0, 7}; auto records = getNumRecords(); auto boxSizeX = std::min(size.x / records, MAX_BOX_X_SIZE); + auto numInputs = getNumInputs(); ImGui::InvisibleButton("sensible area", ImVec2(size.x, size.y)); if (ImGui::IsItemHovered()) { auto pos = ImGui::GetMousePos() - winPos; auto slot = std::lround(std::trunc(pos.x / size.x * records)); - auto row = std::lround(std::trunc(pos.y / size.y)); + auto row = std::lround(std::trunc(pos.y / size.y * numInputs)); describeCell(row, slot); } @@ -96,9 +100,20 @@ struct HeatMapHelper { void displayDataRelayer(DeviceMetricsInfo const& metrics, DeviceInfo const& info, + DeviceSpec const& spec, DataProcessingStates const& states, ImVec2 const& size) { + auto getNumInputs = [&states]() -> size_t { + auto& inputsView = states.statesViews[(int)ProcessingStateId::DATA_QUERIES]; + std::string_view inputs(states.statesBuffer.data() + inputsView.first, inputsView.size); + if (inputs.size() == 0) { + return 0; + } + // count the number of semi-colon separators to get number of inputs + int numInputs = std::count(inputs.begin(), inputs.end(), ';'); + return numInputs; + }; auto getNumRecords = [&states]() -> size_t { auto& view = states.statesViews[(int)ProcessingStateId::DATA_RELAYER_BASE]; if (view.size == 0) { @@ -154,8 +169,30 @@ void displayDataRelayer(DeviceMetricsInfo const& metrics, } return SLOT_ERROR; }; - auto describeCell = [&states](int input, int slot) -> void { + auto describeCell = [&states, &spec](int row, int slot) -> void { ImGui::BeginTooltip(); + + // display the input (origin/descr/subspec) + auto& inputsView = states.statesViews[(int)ProcessingStateId::DATA_QUERIES]; + std::string_view inputs(states.statesBuffer.data() + inputsView.first, inputsView.size); + auto beginInputs = inputs.begin(); + auto endInputs = beginInputs + inputsView.size; + char const* input = beginInputs; + size_t i = 0; + while (input != endInputs) { + auto end = std::find(input, endInputs, ';'); + if ((end - input) == 0) { + continue; + } + if (i == row) { + ImGui::Text("%d %.*s (%s)", row, int(end - input), input, InspectorHelpers::getLifeTimeStr(spec.inputs[i].matcher.lifetime).c_str()); + break; + } + ++i; + input = end + 1; + } + + // display context variables ImGui::Text("Input query matched values for slot: %d", slot); auto& view = states.statesViews[(short)ProcessingStateId::CONTEXT_VARIABLES_BASE + (short)slot]; auto begin = view.first; @@ -190,6 +227,7 @@ void displayDataRelayer(DeviceMetricsInfo const& metrics, if (getNumRecords()) { HeatMapHelper::draw("DataRelayer", size, + getNumInputs, getNumRecords, getRecord, getNumItems, diff --git a/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.h b/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.h index b36476d5486fb..8c4941474d8a7 100644 --- a/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.h +++ b/Framework/GUISupport/src/FrameworkGUIDataRelayerUsage.h @@ -21,7 +21,7 @@ namespace gui { /// View of the DataRelayer metrics for a given DeviceInfo -void displayDataRelayer(DeviceMetricsInfo const& metrics, DeviceInfo const& info, DataProcessingStates const&, ImVec2 const& size); +void displayDataRelayer(DeviceMetricsInfo const& metrics, DeviceInfo const& info, DeviceSpec const& spec, DataProcessingStates const&, ImVec2 const& size); } // namespace gui } // namespace o2::framework diff --git a/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx b/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx index 0e7d21f5eaf27..9b2a13c07987d 100644 --- a/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDeviceInspector.cxx @@ -21,6 +21,7 @@ #include "Framework/DeviceController.h" #include "Framework/DataProcessingStates.h" #include "Framework/Signpost.h" +#include "InspectorHelpers.h" #include #include "DebugGUI/imgui.h" @@ -78,7 +79,7 @@ void deviceStateTable(DataProcessingStates const& states) } } -void deviceInfoTable(char const* label, ProcessingStateId id, DataProcessingStates const& states, DeviceMetricsInfo const& metrics) +void deviceInfoTable(char const* label, ProcessingStateId id, DataProcessingStates const& states, std::variant, std::vector> routes, DeviceMetricsInfo const& metrics) { // Find the state spec associated to data_queries auto& view = states.statesViews[(int)id]; @@ -94,13 +95,21 @@ void deviceInfoTable(char const* label, ProcessingStateId id, DataProcessingStat if ((end - input) == 0) { continue; } - ImGui::Text("%zu: %.*s", i, int(end - input), input); + auto getLifetime = [&routes, &i]() -> Lifetime { + if (std::get_if>(&routes)) { + return std::get>(routes)[i].matcher.lifetime; + } else { + return std::get>(routes)[i].matcher.lifetime; + } + }; + ImGui::Text("%zu: %.*s (%s)", i, int(end - input), input, InspectorHelpers::getLifeTimeStr(getLifetime()).c_str()); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::Text("%zu: %.*s", i, int(end - input), input); + ImGui::Text("%zu: %.*s (%s)", i, int(end - input), input, InspectorHelpers::getLifeTimeStr(getLifetime()).c_str()); ImGui::EndTooltip(); } input = end + 1; + ++i; } } } @@ -337,8 +346,8 @@ void displayDeviceInspector(DeviceSpec const& spec, } deviceStateTable(states); - deviceInfoTable("Inputs:", ProcessingStateId::DATA_QUERIES, states, metrics); - deviceInfoTable("Outputs:", ProcessingStateId::OUTPUT_MATCHERS, states, metrics); + deviceInfoTable("Inputs:", ProcessingStateId::DATA_QUERIES, states, std::variant, std::vector>(spec.inputs), metrics); + deviceInfoTable("Outputs:", ProcessingStateId::OUTPUT_MATCHERS, states, std::variant, std::vector>(spec.outputs), metrics); configurationTable(info.currentConfig, info.currentProvenance); optionsTable("Workflow Options", metadata.workflowOptions, control); if (ImGui::CollapsingHeader("Labels", ImGuiTreeNodeFlags_DefaultOpen)) { diff --git a/Framework/GUISupport/src/FrameworkGUIDevicesGraph.cxx b/Framework/GUISupport/src/FrameworkGUIDevicesGraph.cxx index 0b6ca07a9c86d..a7e781ffba275 100644 --- a/Framework/GUISupport/src/FrameworkGUIDevicesGraph.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDevicesGraph.cxx @@ -705,7 +705,7 @@ void showTopologyNodeGraph(WorkspaceGUIState& state, default: break; } - gui::displayDataRelayer(metricsInfos[node->ID], infos[node->ID], allStates[node->ID], ImVec2(140., 90.)); + gui::displayDataRelayer(metricsInfos[node->ID], infos[node->ID], specs[node->ID], allStates[node->ID], ImVec2(140., 90.)); ImGui::EndGroup(); // Save the size of what we have emitted and whether any of the widgets are being used diff --git a/Framework/GUISupport/src/InspectorHelpers.h b/Framework/GUISupport/src/InspectorHelpers.h new file mode 100644 index 0000000000000..124c714f54df5 --- /dev/null +++ b/Framework/GUISupport/src/InspectorHelpers.h @@ -0,0 +1,51 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_INSPECTORHELPERS_H_ +#define O2_FRAMEWORK_INSPECTORHELPERS_H_ + +#include + +#include "Framework/Lifetime.h" + +namespace o2::framework +{ + +/// A helper class for inpsection of device information +struct InspectorHelpers { + static const std::string getLifeTimeStr(Lifetime lifetime) + { + switch (lifetime) { + case Lifetime::Timeframe: + return "Timeframe"; + case Lifetime::Condition: + return "Condition"; + case Lifetime::Sporadic: + return "Sporadic"; + case Lifetime::Transient: + return "Transient"; + case Lifetime::Timer: + return "Timer"; + case Lifetime::Enumeration: + return "Enumeration"; + case Lifetime::Signal: + return "Signal"; + case Lifetime::Optional: + return "Optional"; + case Lifetime::OutOfBand: + return "OutOfBand"; + } + return "none"; + }; +}; + +} // namespace o2::framework + +#endif // O2_FRAMEWORK_INSPECTORHELPERS_H_ From fb8e068eff4fba325c75b3fa9c77e59db10a50a6 Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:47:59 +0100 Subject: [PATCH 0392/2205] Fix in fetching of AlpideParam in STFDecoder (#13630) * Updating alpide parameters also when no clusterization * Fixing alpide param fetching --- Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index d104d05bb22b5..76bd1ec7454a0 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -406,9 +406,9 @@ DataProcessorSpec getSTFDecoderSpec(const STFDecoderInp& inp) } inputs.emplace_back("noise", inp.origin, "NOISEMAP", 0, Lifetime::Condition, o2::framework::ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", inp.origin.as()))); + inputs.emplace_back("alppar", inp.origin, "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Config/AlpideParam", inp.origin.as()))); if (inp.doClusters) { inputs.emplace_back("cldict", inp.origin, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", inp.origin.as()))); - inputs.emplace_back("alppar", inp.origin, "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Config/AlpideParam", inp.origin.as()))); inputs.emplace_back("cluspar", inp.origin, "CLUSPARAM", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Config/ClustererParam", inp.origin.as()))); } From f68a63e7ac6b8689afb0a8d3a0cfa97dfbd39df7 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 29 Oct 2024 15:58:06 +0100 Subject: [PATCH 0393/2205] GPU: Disable some stuff on ARM --- GPU/GPUTracking/Standalone/Benchmark/standalone.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index ad4c20a9d1700..3626c33dfbb2c 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -53,7 +53,9 @@ #include "GPUTPCGMMergedTrack.h" #include "GPUSettings.h" #include +#if not(defined(__ARM_NEON) or defined(__aarch64__)) // ARM doesn't have SSE #include +#endif #include "GPUO2DataTypes.h" #ifdef GPUCA_HAVE_O2HEADERS From 61a22692426c5bed87be946fb476879df1cf975a Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Tue, 29 Oct 2024 23:02:15 +0100 Subject: [PATCH 0394/2205] MID: extract digits from selected BC ranges (#13631) --- .../MUON/MID/Workflow/src/DigitReaderSpec.cxx | 183 +++++++++++++----- 1 file changed, 136 insertions(+), 47 deletions(-) diff --git a/Detectors/MUON/MID/Workflow/src/DigitReaderSpec.cxx b/Detectors/MUON/MID/Workflow/src/DigitReaderSpec.cxx index 7f380d1afe13a..f65415b8d701a 100644 --- a/Detectors/MUON/MID/Workflow/src/DigitReaderSpec.cxx +++ b/Detectors/MUON/MID/Workflow/src/DigitReaderSpec.cxx @@ -17,22 +17,28 @@ #include "MIDWorkflow/DigitReaderSpec.h" #include +#include #include #include -#include "DPLUtils/RootTreeReader.h" + +#include "TFile.h" +#include "TTree.h" +#include "TTreeReader.h" +#include "TTreeReaderValue.h" + #include "Framework/ConfigParamRegistry.h" #include "Framework/ControlService.h" #include "Framework/DataSpecUtils.h" -#include "Framework/Logger.h" -#include "Framework/Output.h" #include "Framework/Task.h" #include "Framework/WorkflowSpec.h" +#include "Framework/Variant.h" +#include "CommonDataFormat/IRFrame.h" +#include "CommonUtils/IRFrameSelector.h" +#include "CommonUtils/StringUtils.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "DataFormatsMID/ColumnData.h" #include "DataFormatsMID/ROFRecord.h" #include "DataFormatsMID/MCLabel.h" -#include "CommonUtils/NameConf.h" -#include "CommonUtils/StringUtils.h" using namespace o2::framework; @@ -44,82 +50,165 @@ namespace mid class DigitsReaderDeviceDPL { public: - DigitsReaderDeviceDPL(bool useMC, const std::vector& descriptions) - : mUseMC(useMC), mDescriptions(descriptions) {} + DigitsReaderDeviceDPL(bool useMC) : mUseMC(useMC) + { + if (mUseMC) { + mLabels = std::make_unique>>(mTreeReader, "MIDDigitMCLabels"); + } + } void init(InitContext& ic) { auto filename = utils::Str::concat_string(utils::Str::rectifyDirectory(ic.options().get("input-dir")), ic.options().get("mid-digit-infile")); - if (mUseMC) { - mReader = std::make_unique("o2sim", filename.c_str(), -1, - RootTreeReader::PublishingMode::Single, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMID, mDescriptions[0], 0}, "MIDDigit"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMID, mDescriptions[1], 0}, "MIDROFRecords"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMID, mDescriptions[2], 0}, "MIDDigitMCLabels"}, - &mPublishDigits); - } else { - mReader = std::make_unique("o2sim", filename.c_str(), -1, - RootTreeReader::PublishingMode::Single, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMID, mDescriptions[0], 0}, "MIDDigit"}, - RootTreeReader::BranchDefinition>{ - Output{header::gDataOriginMID, mDescriptions[1], 0}, "MIDROFRecords"}, - &mPublishDigits); + + connectTree(filename); + + if (ic.options().hasOption("ignore-irframes") && !ic.options().get("ignore-irframes")) { + mUseIRFrames = true; } } void run(ProcessingContext& pc) { - if ((++(*mReader))(pc) == false) { - pc.services().get().endOfStream(); + if (mUseIRFrames) { + sendNextIRFrames(pc); + } else { + sendNextTF(pc); } } private: - std::unique_ptr mReader{}; - std::vector mDescriptions{}; + TTreeReader mTreeReader{}; + TTreeReaderValue> mRofs = {mTreeReader, "MIDROFRecords"}; + TTreeReaderValue> mDigits = {mTreeReader, "MIDDigit"}; + std::unique_ptr>> mLabels{}; bool mUseMC = true; + bool mUseIRFrames = false; + + void connectTree(std::string filename) + { + auto file = TFile::Open(filename.c_str()); + if (!file || file->IsZombie()) { + throw std::invalid_argument(fmt::format("Opening file {} failed", filename)); + } + + auto tree = file->Get("o2sim"); + if (!tree) { + throw std::invalid_argument(fmt::format("Tree o2sim not found in {}", filename)); + } + mTreeReader.SetTree(tree); + mTreeReader.Restart(); + } + + void sendNextTF(ProcessingContext& pc) + { + // load the next TF and check its validity (missing branch, ...) + if (!mTreeReader.Next()) { + throw std::invalid_argument(mTreeReader.fgEntryStatusText[mTreeReader.GetEntryStatus()]); + } - /// structure holding the function to convert and publish the digits - RootTreeReader::SpecialPublishHook mPublishDigits{ - [](std::string_view name, ProcessingContext& pc, Output const& output, char* data) -> bool { - if (name == "MIDDigit") { - auto inputDigits = reinterpret_cast*>(data); - std::vector digits{}; - digits.insert(digits.end(), inputDigits->begin(), inputDigits->end()); - pc.outputs().snapshot(output, digits); - LOG(debug) << "MIDDigitsReader pushed " << digits.size() << " digits"; - return true; + // send the whole TF + pc.outputs().snapshot(OutputRef{"rofs"}, *mRofs); + pc.outputs().snapshot(OutputRef{"digits"}, *mDigits); + if (mUseMC) { + pc.outputs().snapshot(OutputRef{"labels"}, **mLabels); + } + + // stop here if it was the last one + if (mTreeReader.GetCurrentEntry() + 1 >= mTreeReader.GetEntries()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } + } + + void sendNextIRFrames(ProcessingContext& pc) + { + std::vector rofs{}; + std::vector digits{}; + dataformats::MCTruthContainer labels{}; + + // get the IR frames to select + auto irFrames = pc.inputs().get>("driverInfo"); + + if (!irFrames.empty()) { + utils::IRFrameSelector irfSel{}; + irfSel.setSelectedIRFrames(irFrames, 0, 0, 0, true); + const auto irMin = irfSel.getIRFrames().front().getMin(); + const auto irMax = irfSel.getIRFrames().back().getMax(); + + // load the first TF if not already done + bool loadNextTF = mTreeReader.GetCurrentEntry() < 0; + + while (true) { + // load the next TF if requested + if (loadNextTF && !mTreeReader.Next()) { + throw std::invalid_argument(mTreeReader.fgEntryStatusText[mTreeReader.GetEntryStatus()]); + } + + // look for selected ROFs in this TF and copy them + if (!mRofs->empty() && mRofs->front().interactionRecord <= irMax && + mRofs->back().interactionRecord >= irMin) { + for (const auto& rof : *mRofs) { + if (irfSel.check(rof.interactionRecord) != -1) { + rofs.emplace_back(rof); + rofs.back().firstEntry = digits.size(); + rofs.back().nEntries = rof.nEntries; + digits.insert(digits.end(), mDigits->begin() + rof.firstEntry, mDigits->begin() + rof.getEndIndex()); + if (mUseMC) { + for (auto idig = 0; idig < rof.nEntries; ++idig) { + labels.addElements(labels.getIndexedSize(), (*mLabels)->getLabels(rof.firstEntry + idig)); + } + } + } + } + } + + // move to the next TF if needed and if any + if ((mRofs->empty() || mRofs->back().interactionRecord < irMax) && + mTreeReader.GetCurrentEntry() + 1 < mTreeReader.GetEntries()) { + loadNextTF = true; + continue; + } + + break; } - return false; - }}; + } + + // send the selected data + pc.outputs().snapshot(OutputRef{"rofs"}, rofs); + pc.outputs().snapshot(OutputRef{"digits"}, digits); + if (mUseMC) { + pc.outputs().snapshot(OutputRef{"labels"}, labels); + } + + // stop here if they were the last IR frames to select + if (irFrames.empty() || irFrames.back().isLast()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } + } }; DataProcessorSpec getDigitReaderSpec(bool useMC, const char* baseDescription) { std::vector outputs; - std::vector descriptions; std::stringstream ss; - ss << "A:" << header::gDataOriginMID.as() << "/" << baseDescription << "/0"; - ss << ";B:" << header::gDataOriginMID.as() << "/" << baseDescription << "ROF/0"; + ss << "digits:" << header::gDataOriginMID.as() << "/" << baseDescription << "/0"; + ss << ";rofs:" << header::gDataOriginMID.as() << "/" << baseDescription << "ROF/0"; if (useMC) { - ss << ";C:" << header::gDataOriginMID.as() << "/" << baseDescription << "LABELS/0"; + ss << ";labels:" << header::gDataOriginMID.as() << "/" << baseDescription << "LABELS/0"; } auto matchers = select(ss.str().c_str()); for (auto& matcher : matchers) { outputs.emplace_back(DataSpecUtils::asOutputSpec(matcher)); - descriptions.emplace_back(DataSpecUtils::asConcreteDataDescription(matcher)); } return DataProcessorSpec{ "MIDDigitsReader", Inputs{}, outputs, - AlgorithmSpec{adaptFromTask(useMC, descriptions)}, + AlgorithmSpec{adaptFromTask(useMC)}, Options{{"mid-digit-infile", VariantType::String, "middigits.root", {"Name of the input file"}}, {"input-dir", VariantType::String, "none", {"Input directory"}}}}; } From 95092e28afd5b1ccff48d6b53a7906428b7525ee Mon Sep 17 00:00:00 2001 From: ehellbar Date: Tue, 29 Oct 2024 23:04:19 +0100 Subject: [PATCH 0395/2205] DebugGUI: assign proper log level to ROOT log messages printed in the GUI (#13635) --- .../GUISupport/src/FrameworkGUIDebugger.cxx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Framework/GUISupport/src/FrameworkGUIDebugger.cxx b/Framework/GUISupport/src/FrameworkGUIDebugger.cxx index a025822a2abcb..0e48910c31c8b 100644 --- a/Framework/GUISupport/src/FrameworkGUIDebugger.cxx +++ b/Framework/GUISupport/src/FrameworkGUIDebugger.cxx @@ -71,6 +71,8 @@ ImVec4 colorForLogLevel(LogParsingHelpers::LogLevel logLevel) return PaletteHelpers::GREEN; case LogParsingHelpers::LogLevel::Debug: return PaletteHelpers::WHITE; + case LogParsingHelpers::LogLevel::Alarm: + return PaletteHelpers::YELLOW; case LogParsingHelpers::LogLevel::Warning: return PaletteHelpers::DARK_YELLOW; case LogParsingHelpers::LogLevel::Error: @@ -140,6 +142,24 @@ void displayHistory(const DeviceInfo& info, DeviceControl& control) auto& line = info.history[ji]; auto logLevel = info.historyLevel[ji]; + // assign proper loglevel to ROOT log messages from stderr + auto getLogLevelUnknown = [&line]() -> LogParsingHelpers::LogLevel { + if (line.starts_with("Print in") || line.starts_with("Info in") || line.starts_with("[INFO]")) { + return LogParsingHelpers::LogLevel::Info; + } else if (line.starts_with("Warning in")) { + return LogParsingHelpers::LogLevel::Warning; + } else if (line.starts_with("Error in") || line.starts_with("SysError in")) { + return LogParsingHelpers::LogLevel::Error; + } else if (line.starts_with("Fatal in") || line.starts_with("*** Break ***")) { + return LogParsingHelpers::LogLevel::Fatal; + } else { + return LogParsingHelpers::LogLevel::Unknown; + } + }; + if (logLevel == LogParsingHelpers::LogLevel::Unknown) { + logLevel = getLogLevelUnknown(); + } + // Skip empty lines if (line.empty()) { ji = (ji + 1) % historySize; From b797c12377b4b71311a57d7d5e0a250cff1ab123 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 30 Oct 2024 06:52:39 +0100 Subject: [PATCH 0396/2205] DPL: use concepts rather than SFINAE (#13638) --- Framework/Core/include/Framework/Task.h | 67 +++---------------------- 1 file changed, 6 insertions(+), 61 deletions(-) diff --git a/Framework/Core/include/Framework/Task.h b/Framework/Core/include/Framework/Task.h index 3d80f1ae9f0f6..edb343e898a33 100644 --- a/Framework/Core/include/Framework/Task.h +++ b/Framework/Core/include/Framework/Task.h @@ -14,66 +14,11 @@ #include "Framework/AlgorithmSpec.h" #include "Framework/CallbackService.h" #include "Framework/EndOfStreamContext.h" -#include #include namespace o2::framework { -/// Check if the class task has EndOfStream -template -class has_endOfStream -{ - typedef char one; - struct two { - char x[2]; - }; - - template - static one test(decltype(&C::endOfStream)); - template - static two test(...); - - public: - enum { value = sizeof(test(nullptr)) == sizeof(char) }; -}; - -/// Check if the class task has EndOfStream -template -class has_finaliseCCDB -{ - typedef char one; - struct two { - char x[2]; - }; - - template - static one test(decltype(&C::finaliseCCDB)); - template - static two test(...); - - public: - enum { value = sizeof(test(nullptr)) == sizeof(char) }; -}; - -/// Check if the class task has Stop -template -class has_stop -{ - typedef char one; - struct two { - char x[2]; - }; - - template - static one test(decltype(&C::stop)); - template - static two test(...); - - public: - enum { value = sizeof(test(nullptr)) == sizeof(char) }; -}; - /// A more familiar task API for the DPL. /// This allows you to define your own tasks as subclasses /// of o2::framework::Task and to pass them in the specification @@ -115,19 +60,19 @@ AlgorithmSpec adaptFromTask(Args&&... args) { return AlgorithmSpec::InitCallback{[=](InitContext& ic) { auto task = std::make_shared(args...); - if constexpr (has_endOfStream::value) { + if constexpr (requires { &T::endOfStream; }) { auto& callbacks = ic.services().get(); callbacks.set([task](EndOfStreamContext& eosContext) { task->endOfStream(eosContext); }); } - if constexpr (has_finaliseCCDB::value) { + if constexpr (requires { &T::finaliseCCDB; }) { auto& callbacks = ic.services().get(); callbacks.set([task](ConcreteDataMatcher& matcher, void* obj) { task->finaliseCCDB(matcher, obj); }); } - if constexpr (has_stop::value) { + if constexpr (requires { &T::stop; }) { auto& callbacks = ic.services().get(); callbacks.set([task]() { task->stop(); @@ -144,19 +89,19 @@ template AlgorithmSpec adoptTask(std::shared_ptr task) { return AlgorithmSpec::InitCallback{[task](InitContext& ic) { - if constexpr (has_endOfStream::value) { + if constexpr (requires { &T::endOfStream; }) { auto& callbacks = ic.services().get(); callbacks.set([task](EndOfStreamContext& eosContext) { task->endOfStream(eosContext); }); } - if constexpr (has_finaliseCCDB::value) { + if constexpr (requires { &T::finaliseCCDB; }) { auto& callbacks = ic.services().get(); callbacks.set([task](ConcreteDataMatcher& matcher, void* obj) { task->finaliseCCDB(matcher, obj); }); } - if constexpr (has_stop::value) { + if constexpr (requires { &T::stop; }) { auto& callbacks = ic.services().get(); callbacks.set([task]() { task->stop(); From 6a2cc7e940863599154897007ac556cb51e72f59 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 30 Oct 2024 08:54:20 +0100 Subject: [PATCH 0397/2205] Add SMatrixGPU compatibility to trackParCov (#13602) * Add SMatrixGPU compatibility to trackParCov * Hide TrackParCov from GPU code * Remove SMatrix.h as not needed anymore --- .../MathUtils/include/MathUtils/SMatrixGPU.h | 37 +++++++++++++++++++ .../TrackParametrizationWithError.h | 13 ++++--- .../src/TrackParametrizationWithError.cxx | 31 ++++++++-------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index ef76c490ddfbd..60965a4fa2776 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -446,6 +446,8 @@ class SMatrixGPU GPUdi() SMatrixGPU(SMatrixNoInit) {} GPUd() SMatrixGPU(SMatrixIdentity); GPUd() SMatrixGPU(const SMatrixGPU& rhs); + template + GPUd() SMatrixGPU(const SMatrixGPU& rhs); template GPUd() SMatrixGPU(const Expr& rhs); template @@ -497,6 +499,11 @@ class SMatrixGPU GPUd() SMatrixRowGPU operator[](unsigned int i) { return SMatrixRowGPU(*this, i); } template GPUd() SMatrixGPU& operator+=(const SMatrixGPU& rhs); + GPUd() SMatrixGPU& operator*=(const T& rhs); + template + GPUd() SMatrixGPU& operator*=(const SMatrixGPU& rhs); + template + GPUd() SMatrixGPU& operator*=(const Expr& rhs); GPUd() bool Invert(); GPUd() bool IsInUse(const T* p) const; @@ -528,6 +535,13 @@ GPUdi() SMatrixGPU::SMatrixGPU(const SMatrixGPU& rhs mRep = rhs.mRep; } +template +template +GPUd() SMatrixGPU::SMatrixGPU(const SMatrixGPU& rhs) +{ + operator=(rhs); +} + template GPUdi() T* SMatrixGPU::begin() { @@ -1387,6 +1401,29 @@ GPUdi() SMatrixGPU& SMatrixGPU::operator+=(const SMa return *this; } +template +GPUdi() SMatrixGPU& SMatrixGPU::operator*=(const T & rhs) +{ + for (unsigned int i = 0; i < R::kSize; ++i) { + mRep.Array()[i] *= rhs; + } + return *this; +} + +template +template +GPUdi() SMatrixGPU& SMatrixGPU::operator*=(const SMatrixGPU& rhs) +{ + return operator=(*this* rhs); +} + +template +template +GPUdi() SMatrixGPU& SMatrixGPU::operator*=(const Expr& rhs) +{ + return operator=(*this* rhs); +} + template struct TranspPolicyGPU { enum { diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h index 536bacf1a6a70..015b5d37e258c 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h @@ -18,6 +18,7 @@ #define INCLUDE_RECONSTRUCTIONDATAFORMATS_TRACKPARAMETRIZATIONWITHERROR_H_ #include "ReconstructionDataFormats/TrackParametrization.h" +#include namespace o2 { @@ -38,8 +39,8 @@ class TrackParametrizationWithError : public TrackParametrization #endif using covMat_t = gpu::gpustd::array; - using MatrixDSym5 = ROOT::Math::SMatrix>; - using MatrixD5 = ROOT::Math::SMatrix>; + using MatrixDSym5 = o2::math_utils::SMatrix>; + using MatrixD5 = o2::math_utils::SMatrix>; GPUd() TrackParametrizationWithError(); GPUd() TrackParametrizationWithError(value_t x, value_t alpha, const params_t& par, const covMat_t& cov, int charge = 1, const PID pid = PID::Pion); @@ -100,12 +101,12 @@ class TrackParametrizationWithError : public TrackParametrization template GPUd() value_t getPredictedChi2(const BaseCluster& p) const; - void buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const; - value_t getPredictedChi2(const TrackParametrizationWithError& rhs, MatrixDSym5& covToSet) const; + GPUd() void buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const; + GPUd() value_t getPredictedChi2(const TrackParametrizationWithError& rhs, MatrixDSym5& covToSet) const; GPUd() value_t getPredictedChi2(const TrackParametrizationWithError& rhs) const; GPUd() value_t getPredictedChi2Quiet(const TrackParametrizationWithError& rhs) const; - bool update(const TrackParametrizationWithError& rhs, const MatrixDSym5& covInv); - bool update(const TrackParametrizationWithError& rhs); + GPUd() bool update(const TrackParametrizationWithError& rhs, const MatrixDSym5& covInv); + GPUd() bool update(const TrackParametrizationWithError& rhs); GPUd() bool update(const dim2_t& p, const dim3_t& cov); GPUd() bool update(const value_t* p, const value_t* cov); diff --git a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx index e56830deace14..0dd4a4441c0b3 100644 --- a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx @@ -14,11 +14,14 @@ #include "ReconstructionDataFormats/DCA.h" #include +#ifndef __OPENCL__ +#include +#else +#include +#endif + #ifndef GPUCA_GPUCODE_DEVICE #include -#ifndef GPUCA_STANDALONE -#include "Math/SMatrix.h" -#endif #endif #ifndef GPUCA_ALIGPUCODE @@ -754,11 +757,17 @@ GPUd() auto TrackParametrizationWithError::getPredictedChi2Quiet(const return (d * (szz * d - sdz * z) + z * (sdd * z - d * sdz)) / det; } -#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // Disable function relying on ROOT SMatrix on GPU +//______________________________________________ +template +GPUd() auto TrackParametrizationWithError::getPredictedChi2(const TrackParametrizationWithError& rhs) const -> value_t +{ + MatrixDSym5 cov; // perform matrix operations in double! + return getPredictedChi2(rhs, cov); +} //______________________________________________ template -void TrackParametrizationWithError::buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const +GPUd() void TrackParametrizationWithError::buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const { // fill combined cov.matrix (NOT inverted) cov(kY, kY) = static_cast(getSigmaY2()) + static_cast(rhs.getSigmaY2()); @@ -778,14 +787,6 @@ void TrackParametrizationWithError::buildCombinedCovMatrix(const TrackP cov(kQ2Pt, kQ2Pt) = static_cast(getSigma1Pt2()) + static_cast(rhs.getSigma1Pt2()); } -//______________________________________________ -template -GPUd() auto TrackParametrizationWithError::getPredictedChi2(const TrackParametrizationWithError& rhs) const -> value_t -{ - MatrixDSym5 cov; // perform matrix operations in double! - return getPredictedChi2(rhs, cov); -} - //______________________________________________ template GPUd() auto TrackParametrizationWithError::getPredictedChi2(const TrackParametrizationWithError& rhs, MatrixDSym5& covToSet) const -> value_t @@ -867,7 +868,7 @@ GPUd() bool TrackParametrizationWithError::update(const TrackParametriz } // updated covariance: Cov0 = Cov0 - K*Cov0 - matK *= ROOT::Math::SMatrix>(matC0); + matK *= o2::math_utils::SMatrix>(matC0); mC[kSigY2] -= matK(kY, kY); mC[kSigZY] -= matK(kZ, kY); mC[kSigZ2] -= matK(kZ, kZ); @@ -901,8 +902,6 @@ GPUd() bool TrackParametrizationWithError::update(const TrackParametriz return update(rhs, covI); } -#endif - //______________________________________________ template GPUd() bool TrackParametrizationWithError::update(const value_t* p, const value_t* cov) From 03fd79af2fa775471a2cc196d4c900487e6fc9fd Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Wed, 30 Oct 2024 15:38:34 +0100 Subject: [PATCH 0398/2205] ITSGPU: Port findNeighbours on GPU (#13636) --- .../GPU/ITStrackingGPU/TimeFrameChunk.h | 150 ++++++ .../GPU/ITStrackingGPU/TimeFrameGPU.h | 156 +----- .../GPU/ITStrackingGPU/TrackingKernels.h | 31 ++ .../ITS/tracking/GPU/ITStrackingGPU/Utils.h | 12 + .../ITS/tracking/GPU/cuda/CMakeLists.txt | 5 +- .../ITS/tracking/GPU/cuda/TimeFrameChunk.cu | 293 +++++++++++ .../ITS/tracking/GPU/cuda/TimeFrameGPU.cu | 471 +++++------------- .../tracking/GPU/cuda/TrackerTraitsGPU.cxx | 96 ++-- .../ITS/tracking/GPU/cuda/TrackingKernels.cu | 232 +++++++-- .../ITS/tracking/GPU/hip/CMakeLists.txt | 3 +- .../tracking/include/ITStracking/TimeFrame.h | 2 +- 11 files changed, 893 insertions(+), 558 deletions(-) create mode 100644 Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameChunk.h create mode 100644 Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameChunk.cu diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameChunk.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameChunk.h new file mode 100644 index 0000000000000..c477922e59533 --- /dev/null +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameChunk.h @@ -0,0 +1,150 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// + +#ifndef TRACKINGITSGPU_INCLUDE_TIMEFRAMECHUNKGPU_H +#define TRACKINGITSGPU_INCLUDE_TIMEFRAMECHUNKGPU_H + +#include "ITStracking/Configuration.h" +#include "ITStracking/TimeFrame.h" + +#include "ITStrackingGPU/ClusterLinesGPU.h" +#include "ITStrackingGPU/Array.h" +#include "ITStrackingGPU/Vector.h" +#include "ITStrackingGPU/Stream.h" + +#include + +namespace o2::its::gpu +{ +template +struct StaticTrackingParameters { + StaticTrackingParameters& operator=(const StaticTrackingParameters& t) = default; + void set(const TrackingParameters& pars) + { + ClusterSharing = pars.ClusterSharing; + MinTrackLength = pars.MinTrackLength; + NSigmaCut = pars.NSigmaCut; + PVres = pars.PVres; + DeltaROF = pars.DeltaROF; + ZBins = pars.ZBins; + PhiBins = pars.PhiBins; + CellDeltaTanLambdaSigma = pars.CellDeltaTanLambdaSigma; + } + + /// General parameters + int ClusterSharing = 0; + int MinTrackLength = nLayers; + float NSigmaCut = 5; + float PVres = 1.e-2f; + int DeltaROF = 0; + int ZBins{256}; + int PhiBins{128}; + + /// Cell finding cuts + float CellDeltaTanLambdaSigma = 0.007f; +}; + +template +class GpuTimeFrameChunk +{ + public: + static size_t computeScalingSizeBytes(const int, const TimeFrameGPUParameters&); + static size_t computeFixedSizeBytes(const TimeFrameGPUParameters&); + static size_t computeRofPerChunk(const TimeFrameGPUParameters&, const size_t); + + GpuTimeFrameChunk() = delete; + GpuTimeFrameChunk(o2::its::TimeFrame* tf, TimeFrameGPUParameters& conf) + { + mTimeFramePtr = tf; + mTFGPUParams = &conf; + } + ~GpuTimeFrameChunk(); + + /// Most relevant operations + void allocate(const size_t, Stream&); + void reset(const Task, Stream&); + size_t loadDataOnDevice(const size_t, const size_t, const int, Stream&); + + /// Interface + Cluster* getDeviceClusters(const int); + int* getDeviceClusterExternalIndices(const int); + int* getDeviceIndexTables(const int); + Tracklet* getDeviceTracklets(const int); + int* getDeviceTrackletsLookupTables(const int); + CellSeed* getDeviceCells(const int); + int* getDeviceCellsLookupTables(const int); + int* getDeviceRoadsLookupTables(const int); + TimeFrameGPUParameters* getTimeFrameGPUParameters() const { return mTFGPUParams; } + + int* getDeviceCUBTmpBuffer() { return mCUBTmpBufferDevice; } + int* getDeviceFoundTracklets() { return mFoundTrackletsDevice; } + int* getDeviceNFoundCells() { return mNFoundCellsDevice; } + int* getDeviceCellNeigboursLookupTables(const int); + int* getDeviceCellNeighbours(const int); + CellSeed** getDeviceArrayCells() const { return mCellsDeviceArray; } + int** getDeviceArrayNeighboursCell() const { return mNeighboursCellDeviceArray; } + int** getDeviceArrayNeighboursCellLUT() const { return mNeighboursCellLookupTablesDeviceArray; } + + /// Vertexer only + int* getDeviceNTrackletCluster(const int combid) { return mNTrackletsPerClusterDevice[combid]; } + Line* getDeviceLines() { return mLinesDevice; }; + int* getDeviceNFoundLines() { return mNFoundLinesDevice; } + int* getDeviceNExclusiveFoundLines() { return mNExclusiveFoundLinesDevice; } + unsigned char* getDeviceUsedTracklets() { return mUsedTrackletsDevice; } + int* getDeviceClusteredLines() { return mClusteredLinesDevice; } + size_t getNPopulatedRof() const { return mNPopulatedRof; } + + private: + /// Host + std::array, nLayers> mHostClusters; + std::array, nLayers> mHostIndexTables; + + /// Device + std::array mClustersDevice; + std::array mClusterExternalIndicesDevice; + std::array mIndexTablesDevice; + std::array mTrackletsDevice; + std::array mTrackletsLookupTablesDevice; + std::array mCellsDevice; + // Road* mRoadsDevice; + std::array mCellsLookupTablesDevice; + std::array mNeighboursCellDevice; + std::array mNeighboursCellLookupTablesDevice; + std::array mRoadsLookupTablesDevice; + + // These are to make them accessible using layer index + CellSeed** mCellsDeviceArray; + int** mNeighboursCellDeviceArray; + int** mNeighboursCellLookupTablesDeviceArray; + + // Small accessory buffers + int* mCUBTmpBufferDevice; + int* mFoundTrackletsDevice; + int* mNFoundCellsDevice; + + /// Vertexer only + Line* mLinesDevice; + int* mNFoundLinesDevice; + int* mNExclusiveFoundLinesDevice; + unsigned char* mUsedTrackletsDevice; + std::array mNTrackletsPerClusterDevice; + int* mClusteredLinesDevice; + + /// State and configuration + bool mAllocated = false; + size_t mNRof = 0; + size_t mNPopulatedRof = 0; + o2::its::TimeFrame* mTimeFramePtr = nullptr; + TimeFrameGPUParameters* mTFGPUParams = nullptr; +}; +} // namespace o2::its::gpu +#endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h index 73955be325ff7..db1bfd836e8e6 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h @@ -20,23 +20,14 @@ #include "ITStrackingGPU/Array.h" #include "ITStrackingGPU/Vector.h" #include "ITStrackingGPU/Stream.h" +#include "ITStrackingGPU/TimeFrameChunk.h" #include namespace o2 { -namespace gpu -{ -class GPUChainITS; -} namespace its { -template -struct gpuPair { - T1 first; - T2 second; -}; - namespace gpu { @@ -44,132 +35,6 @@ class DefaultGPUAllocator : public ExternalAllocator { void* allocate(size_t size) override; }; -template -struct StaticTrackingParameters { - StaticTrackingParameters& operator=(const StaticTrackingParameters& t) = default; - void set(const TrackingParameters& pars) - { - ClusterSharing = pars.ClusterSharing; - MinTrackLength = pars.MinTrackLength; - NSigmaCut = pars.NSigmaCut; - PVres = pars.PVres; - DeltaROF = pars.DeltaROF; - ZBins = pars.ZBins; - PhiBins = pars.PhiBins; - CellDeltaTanLambdaSigma = pars.CellDeltaTanLambdaSigma; - } - - /// General parameters - int ClusterSharing = 0; - int MinTrackLength = nLayers; - float NSigmaCut = 5; - float PVres = 1.e-2f; - int DeltaROF = 0; - int ZBins{256}; - int PhiBins{128}; - - /// Cell finding cuts - float CellDeltaTanLambdaSigma = 0.007f; -}; - -enum class Task { - Tracker = 0, - Vertexer = 1 -}; - -template -class GpuTimeFrameChunk -{ - public: - static size_t computeScalingSizeBytes(const int, const TimeFrameGPUParameters&); - static size_t computeFixedSizeBytes(const TimeFrameGPUParameters&); - static size_t computeRofPerChunk(const TimeFrameGPUParameters&, const size_t); - - GpuTimeFrameChunk() = delete; - GpuTimeFrameChunk(o2::its::TimeFrame* tf, TimeFrameGPUParameters& conf) - { - mTimeFramePtr = tf; - mTFGPUParams = &conf; - } - ~GpuTimeFrameChunk(); - - /// Most relevant operations - void allocate(const size_t, Stream&); - void reset(const Task, Stream&); - size_t loadDataOnDevice(const size_t, const size_t, const int, Stream&); - - /// Interface - Cluster* getDeviceClusters(const int); - int* getDeviceClusterExternalIndices(const int); - int* getDeviceIndexTables(const int); - Tracklet* getDeviceTracklets(const int); - int* getDeviceTrackletsLookupTables(const int); - CellSeed* getDeviceCells(const int); - int* getDeviceCellsLookupTables(const int); - int* getDeviceRoadsLookupTables(const int); - TimeFrameGPUParameters* getTimeFrameGPUParameters() const { return mTFGPUParams; } - - int* getDeviceCUBTmpBuffer() { return mCUBTmpBufferDevice; } - int* getDeviceFoundTracklets() { return mFoundTrackletsDevice; } - int* getDeviceNFoundCells() { return mNFoundCellsDevice; } - int* getDeviceCellNeigboursLookupTables(const int); - int* getDeviceCellNeighbours(const int); - CellSeed** getDeviceArrayCells() const { return mCellsDeviceArray; } - int** getDeviceArrayNeighboursCell() const { return mNeighboursCellDeviceArray; } - int** getDeviceArrayNeighboursCellLUT() const { return mNeighboursCellLookupTablesDeviceArray; } - - /// Vertexer only - int* getDeviceNTrackletCluster(const int combid) { return mNTrackletsPerClusterDevice[combid]; } - Line* getDeviceLines() { return mLinesDevice; }; - int* getDeviceNFoundLines() { return mNFoundLinesDevice; } - int* getDeviceNExclusiveFoundLines() { return mNExclusiveFoundLinesDevice; } - unsigned char* getDeviceUsedTracklets() { return mUsedTrackletsDevice; } - int* getDeviceClusteredLines() { return mClusteredLinesDevice; } - size_t getNPopulatedRof() const { return mNPopulatedRof; } - - private: - /// Host - std::array, nLayers> mHostClusters; - std::array, nLayers> mHostIndexTables; - - /// Device - std::array mClustersDevice; - std::array mClusterExternalIndicesDevice; - std::array mIndexTablesDevice; - std::array mTrackletsDevice; - std::array mTrackletsLookupTablesDevice; - std::array mCellsDevice; - // Road* mRoadsDevice; - std::array mCellsLookupTablesDevice; - std::array mNeighboursCellDevice; - std::array mNeighboursCellLookupTablesDevice; - std::array mRoadsLookupTablesDevice; - - // These are to make them accessible using layer index - CellSeed** mCellsDeviceArray; - int** mNeighboursCellDeviceArray; - int** mNeighboursCellLookupTablesDeviceArray; - - // Small accessory buffers - int* mCUBTmpBufferDevice; - int* mFoundTrackletsDevice; - int* mNFoundCellsDevice; - - /// Vertexer only - Line* mLinesDevice; - int* mNFoundLinesDevice; - int* mNExclusiveFoundLinesDevice; - unsigned char* mUsedTrackletsDevice; - std::array mNTrackletsPerClusterDevice; - int* mClusteredLinesDevice; - - /// State and configuration - bool mAllocated = false; - size_t mNRof = 0; - size_t mNPopulatedRof = 0; - o2::its::TimeFrame* mTimeFramePtr = nullptr; - TimeFrameGPUParameters* mTFGPUParams = nullptr; -}; template class TimeFrameGPU : public TimeFrame @@ -191,13 +56,19 @@ class TimeFrameGPU : public TimeFrame void loadClustersDevice(); void loadTrackletsDevice(); void loadCellsDevice(); + void loadCellsLUT(); void loadTrackSeedsDevice(); void loadTrackSeedsChi2Device(); void loadRoadsDevice(); void loadTrackSeedsDevice(std::vector&); - void createCellNeighboursDevice(const unsigned int& layer, std::vector>& neighbours); + void createNeighboursDevice(const unsigned int& layer, std::vector>& neighbours); + void createNeighboursLUTDevice(const int, const unsigned int); void createTrackITSExtDevice(std::vector&); void downloadTrackITSExtDevice(std::vector&); + void downloadCellsNeighbours(std::vector>>&, const int); + void downloadNeighboursLUT(std::vector&, const int); + void downloadCellsDevice(const int); + void unregisterRest(); void initDeviceChunks(const int, const int); template size_t loadChunkData(const size_t, const size_t, const size_t); @@ -224,6 +95,7 @@ class TimeFrameGPU : public TimeFrame // Hybrid Road* getDeviceRoads() { return mRoadsDevice; } TrackITSExt* getDeviceTrackITSExt() { return mTrackITSExtDevice; } + int* getDeviceNeighboursLUT(const int layer) { return mNeighboursLUTDevice[layer]; } gpuPair* getDeviceNeighbours(const int layer) { return mNeighboursDevice[layer]; } TrackingFrameInfo* getDeviceTrackingFrameInfo(const int); // TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() { return mTrackingFrameInfoDeviceArray; } @@ -231,10 +103,14 @@ class TimeFrameGPU : public TimeFrame Cluster** getDeviceArrayClusters() const { return mClustersDeviceArray; } Cluster** getDeviceArrayUnsortedClusters() const { return mUnsortedClustersDeviceArray; } Tracklet** getDeviceArrayTracklets() const { return mTrackletsDeviceArray; } + int** getDeviceArrayCellsLUT() const { return mCellsLUTDeviceArray; } + int** getDeviceArrayNeighboursCellLUT() const { return mNeighboursCellLUTDeviceArray; } CellSeed** getDeviceArrayCells() const { return mCellsDeviceArray; } CellSeed* getDeviceTrackSeeds() { return mTrackSeedsDevice; } o2::track::TrackParCovF** getDeviceArrayTrackSeeds() { return mCellSeedsDeviceArray; } float** getDeviceArrayTrackSeedsChi2() { return mCellSeedsChi2DeviceArray; } + int* getDeviceNeighboursIndexTables(const int layer) { return mNeighboursIndexTablesDevice[layer]; } + void setDevicePropagator(const o2::base::PropagatorImpl*) override; // Host-specific getters @@ -263,7 +139,13 @@ class TimeFrameGPU : public TimeFrame Cluster** mUnsortedClustersDeviceArray; std::array mTrackletsDevice; Tracklet** mTrackletsDeviceArray; + std::array mCellsLUTDevice; + std::array mNeighboursLUTDevice; + int** mCellsLUTDeviceArray; + int** mNeighboursCellDeviceArray; + int** mNeighboursCellLUTDeviceArray; std::array mCellsDevice; + std::array mNeighboursIndexTablesDevice; CellSeed* mTrackSeedsDevice; CellSeed** mCellsDeviceArray; std::array mCellSeedsDevice; diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h index cc74456bbb1aa..167baa905f790 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h @@ -49,6 +49,37 @@ GPUg() void fitTrackSeedsKernel( const o2::base::PropagatorF::MatCorrType matCorrType = o2::base::PropagatorF::MatCorrType::USEMatCorrLUT); #endif } // namespace gpu +void countCellNeighboursHandler(CellSeed** cellsLayersDevice, + int* neighboursLUTs, + int** cellsLUTs, + gpuPair* cellNeighbours, + int* neighboursIndexTable, + const float maxChi2ClusterAttachment, + const float bz, + const int layerIndex, + const unsigned int nCells, + const unsigned int nCellsNext, + const int maxCellNeighbours, + const int nBlocks, + const int nThreads); + +void computeCellNeighboursHandler(CellSeed** cellsLayersDevice, + int* neighboursLUTs, + int** cellsLUTs, + gpuPair* cellNeighbours, + int* neighboursIndexTable, + const float maxChi2ClusterAttachment, + const float bz, + const int layerIndex, + const unsigned int nCells, + const unsigned int nCellsNext, + const int maxCellNeighbours, + const int nBlocks, + const int nThreads); + +void filterCellNeighboursHandler(std::vector&, + gpuPair*, + unsigned int); void trackSeedHandler(CellSeed* trackSeeds, const TrackingFrameInfo** foundTrackingFrameInfo, diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h index 42b2777d9b4dd..66244bf854b5f 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h @@ -23,8 +23,20 @@ namespace o2 { namespace its { +template +struct gpuPair { + T1 first; + T2 second; +}; + namespace gpu { + +enum class Task { + Tracker = 0, + Vertexer = 1 +}; + template GPUhd() T* getPtrFromRuler(int index, T* src, const int* ruler, const int stride = 1) { diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt index 2f8422112dc58..c8e1d0a910e5b 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt @@ -13,13 +13,14 @@ if(CUDA_ENABLED) find_package(CUDAToolkit) message(STATUS "Building ITS CUDA tracker") - +# add_compile_options(-O0 -g -lineinfo -fPIC) o2_add_library(ITStrackingCUDA SOURCES ClusterLinesGPU.cu Context.cu Stream.cu TrackerTraitsGPU.cxx TimeFrameGPU.cu + TimeFrameChunk.cu TracerGPU.cu TrackingKernels.cu VertexingKernels.cu @@ -31,7 +32,7 @@ o2_add_library(ITStrackingCUDA O2::SimulationDataFormat O2::ReconstructionDataFormats O2::GPUCommon - CUDA::nvToolsExt # TODO: change to CUDA::nvtx3 when CMake bump >= 3.25 + CUDA::nvToolsExt PRIVATE_LINK_LIBRARIES O2::GPUTrackingCUDAExternalProvider TARGETVARNAME targetName) diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameChunk.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameChunk.cu new file mode 100644 index 0000000000000..8353b6ff0aa8b --- /dev/null +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameChunk.cu @@ -0,0 +1,293 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include + +#include "ITStracking/Constants.h" + +#include "ITStrackingGPU/Utils.h" +#include "ITStrackingGPU/TracerGPU.h" + +#include "ITStrackingGPU/TimeFrameChunk.h" + +#include +#include + +#include "GPUCommonDef.h" +#include "GPUCommonMath.h" +#include "GPUCommonLogger.h" + +#ifndef __HIPCC__ +#define THRUST_NAMESPACE thrust::cuda +#else +#define THRUST_NAMESPACE thrust::hip +#endif + +namespace o2::its +{ +using constants::GB; +using constants::MB; +namespace gpu +{ +using utils::checkGPUError; + +template +GpuTimeFrameChunk::~GpuTimeFrameChunk() +{ + if (mAllocated) { + for (int i = 0; i < nLayers; ++i) { + checkGPUError(cudaFree(mClustersDevice[i])); + // checkGPUError(cudaFree(mTrackingFrameInfoDevice[i])); + checkGPUError(cudaFree(mClusterExternalIndicesDevice[i])); + checkGPUError(cudaFree(mIndexTablesDevice[i])); + if (i < nLayers - 1) { + checkGPUError(cudaFree(mTrackletsDevice[i])); + checkGPUError(cudaFree(mTrackletsLookupTablesDevice[i])); + if (i < nLayers - 2) { + checkGPUError(cudaFree(mCellsDevice[i])); + checkGPUError(cudaFree(mCellsLookupTablesDevice[i])); + checkGPUError(cudaFree(mRoadsLookupTablesDevice[i])); + if (i < nLayers - 3) { + checkGPUError(cudaFree(mNeighboursCellLookupTablesDevice[i])); + checkGPUError(cudaFree(mNeighboursCellDevice[i])); + } + } + } + } + // checkGPUError(cudaFree(mRoadsDevice)); + checkGPUError(cudaFree(mCUBTmpBufferDevice)); + checkGPUError(cudaFree(mFoundTrackletsDevice)); + checkGPUError(cudaFree(mNFoundCellsDevice)); + checkGPUError(cudaFree(mCellsDeviceArray)); + checkGPUError(cudaFree(mNeighboursCellDeviceArray)); + checkGPUError(cudaFree(mNeighboursCellLookupTablesDeviceArray)); + } +} + +template +void GpuTimeFrameChunk::allocate(const size_t nrof, Stream& stream) +{ + RANGE("device_partition_allocation", 2); + mNRof = nrof; + // for (int i = 0; i < nLayers; ++i) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClustersDevice[i])), sizeof(Cluster) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackingFrameInfoDevice[i])), sizeof(TrackingFrameInfo) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClusterExternalIndicesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mIndexTablesDevice[i])), sizeof(int) * (256 * 128 + 1) * nrof, &stream, true); + // if (i < nLayers - 1) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsDevice[i])), sizeof(Tracklet) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // if (i < nLayers - 2) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->validatedTrackletsCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsDevice[i])), sizeof(CellSeed) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsLookupTablesDevice[i]), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // if (i < nLayers - 3) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); + // } + // if (i < 2) { + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNTrackletsPerClusterDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // } + // } + // } + // } + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCUBTmpBufferDevice), mTFGPUParams->tmpCUBBufferSize * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mLinesDevice), sizeof(Line) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNExclusiveFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof + 1, &stream, true); // + 1 for cub::DeviceScan::ExclusiveSum, to cover cases where we have maximum number of clusters per ROF + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mUsedTrackletsDevice), sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mClusteredLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * nrof, &stream, true); + // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsDevice), sizeof(Road) * mTFGPUParams->maxRoadPerRofSize * nrof, &stream, true); + + // /// Invariant allocations + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mFoundTrackletsDevice), (nLayers - 1) * sizeof(int) * nrof, &stream, true); // No need to reset, we always read it after writing + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundCellsDevice), (nLayers - 2) * sizeof(int) * nrof, &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); + // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellLookupTablesDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); + + // /// Copy pointers of allocated memory to regrouping arrays + // checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, stream.get())); + // checkGPUError(cudaMemcpyAsync(mNeighboursCellDeviceArray, mNeighboursCellDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); + // checkGPUError(cudaMemcpyAsync(mNeighboursCellLookupTablesDeviceArray, mNeighboursCellLookupTablesDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); + + mAllocated = true; +} + +template +void GpuTimeFrameChunk::reset(const Task task, Stream& stream) +{ + RANGE("buffer_reset", 0); + // if ((bool)task) { // Vertexer-only initialisation (cannot be constexpr: due to the presence of gpu raw calls can't be put in header) + // for (int i = 0; i < 2; i++) { + // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); + // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; + // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); + // checkGPUError(cudaMemsetAsync(mNTrackletsPerClusterDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // } + // checkGPUError(cudaMemsetAsync(mUsedTrackletsDevice, false, sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mClusteredLinesDevice, -1, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * mNRof, stream.get())); + // } else { + // for (int i = 0; i < nLayers; ++i) { + // if (i < nLayers - 1) { + // checkGPUError(cudaMemsetAsync(mTrackletsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); + // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); + // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; + // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); + // if (i < nLayers - 2) { + // checkGPUError(cudaMemsetAsync(mCellsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->cellsLUTsize * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mRoadsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // if (i < nLayers - 3) { + // checkGPUError(cudaMemsetAsync(mNeighboursCellLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // checkGPUError(cudaMemsetAsync(mNeighboursCellDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); + // } + // } + // } + // } + // checkGPUError(cudaMemsetAsync(mNFoundCellsDevice, 0, (nLayers - 2) * sizeof(int), stream.get())); + // } +} + +template +size_t GpuTimeFrameChunk::computeScalingSizeBytes(const int nrof, const TimeFrameGPUParameters& config) +{ + size_t rofsize = nLayers * sizeof(int); // number of clusters per ROF + // rofsize += nLayers * sizeof(Cluster) * config.clustersPerROfCapacity; // clusters + // rofsize += nLayers * sizeof(TrackingFrameInfo) * config.clustersPerROfCapacity; // tracking frame info + // rofsize += nLayers * sizeof(int) * config.clustersPerROfCapacity; // external cluster indices + // rofsize += nLayers * sizeof(int) * (256 * 128 + 1); // index tables + // rofsize += (nLayers - 1) * sizeof(int) * config.clustersPerROfCapacity; // tracklets lookup tables + // rofsize += (nLayers - 1) * sizeof(Tracklet) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // tracklets + // rofsize += 2 * sizeof(int) * config.clustersPerROfCapacity; // tracklets found per cluster (vertexer) + // rofsize += sizeof(unsigned char) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // used tracklets (vertexer) + // rofsize += (nLayers - 2) * sizeof(int) * config.validatedTrackletsCapacity; // cells lookup tables + // rofsize += (nLayers - 2) * sizeof(CellSeed) * config.maxNeighboursSize; // cells + // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours lookup tables + // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours + // rofsize += sizeof(Road) * config.maxRoadPerRofSize; // roads + // rofsize += (nLayers - 2) * sizeof(int) * config.maxNeighboursSize; // road LUT + // rofsize += sizeof(Line) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // lines + // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines + // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines exclusive sum + // rofsize += sizeof(int) * config.clustersPerROfCapacity * config.maxTrackletsPerCluster; // lines used in clusterlines + + // rofsize += (nLayers - 1) * sizeof(int); // total found tracklets + // rofsize += (nLayers - 2) * sizeof(int); // total found cells + + return rofsize * nrof; +} + +template +size_t GpuTimeFrameChunk::computeFixedSizeBytes(const TimeFrameGPUParameters& config) +{ + size_t total = config.tmpCUBBufferSize; // CUB tmp buffers + total += sizeof(gpu::StaticTrackingParameters); // static parameters loaded once + return total; +} + +template +size_t GpuTimeFrameChunk::computeRofPerChunk(const TimeFrameGPUParameters& config, const size_t m) +{ + return (m * GB / (float)(config.nTimeFrameChunks) - GpuTimeFrameChunk::computeFixedSizeBytes(config)) / (float)GpuTimeFrameChunk::computeScalingSizeBytes(1, config); +} + +/// Interface +template +Cluster* GpuTimeFrameChunk::getDeviceClusters(const int layer) +{ + return mClustersDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceClusterExternalIndices(const int layer) +{ + return mClusterExternalIndicesDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceIndexTables(const int layer) +{ + return mIndexTablesDevice[layer]; +} + +template +Tracklet* GpuTimeFrameChunk::getDeviceTracklets(const int layer) +{ + return mTrackletsDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceTrackletsLookupTables(const int layer) +{ + return mTrackletsLookupTablesDevice[layer]; +} + +template +CellSeed* GpuTimeFrameChunk::getDeviceCells(const int layer) +{ + return mCellsDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceCellsLookupTables(const int layer) +{ + return mCellsLookupTablesDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceCellNeigboursLookupTables(const int layer) +{ + return mNeighboursCellLookupTablesDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceCellNeighbours(const int layer) +{ + return mNeighboursCellDevice[layer]; +} + +template +int* GpuTimeFrameChunk::getDeviceRoadsLookupTables(const int layer) +{ + return mRoadsLookupTablesDevice[layer]; +} + +// Load data +template +size_t GpuTimeFrameChunk::loadDataOnDevice(const size_t startRof, const size_t maxRof, const int maxLayers, Stream& stream) +{ + RANGE("load_clusters_data", 5); + // auto nRofs = std::min(maxRof - startRof, mNRof); + // mNPopulatedRof = mTimeFramePtr->getNClustersROFrange(startRof, nRofs, 0).size(); + // for (int i = 0; i < maxLayers; ++i) { + // mHostClusters[i] = mTimeFramePtr->getClustersPerROFrange(startRof, nRofs, i); + // mHostIndexTables[i] = mTimeFramePtr->getIndexTablePerROFrange(startRof, nRofs, i); + // if (mHostClusters[i].size() > mTFGPUParams->clustersPerROfCapacity * nRofs) { + // LOGP(warning, "Clusters on layer {} exceed the expected value, resizing to config value: {}, will lose information!", i, mTFGPUParams->clustersPerROfCapacity * nRofs); + // } + // checkGPUError(cudaMemcpyAsync(mClustersDevice[i], + // mHostClusters[i].data(), + // (int)std::min(mHostClusters[i].size(), mTFGPUParams->clustersPerROfCapacity * nRofs) * sizeof(Cluster), + // cudaMemcpyHostToDevice, stream.get())); + // if (mHostIndexTables[i].data()) { + // checkGPUError(cudaMemcpyAsync(mIndexTablesDevice[i], + // mHostIndexTables[i].data(), + // mHostIndexTables[i].size() * sizeof(int), + // cudaMemcpyHostToDevice, stream.get())); + // } + // } + return mNPopulatedRof; // return the number of ROFs we loaded the data for. +} +template class GpuTimeFrameChunk<7>; +} // namespace gpu +} // namespace o2::its \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu index 05edc847f1e05..c9c6792b5417b 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu @@ -45,291 +45,224 @@ using utils::checkGPUError; void* DefaultGPUAllocator::allocate(size_t size) { - LOGP(info, "Called DefaultGPUAllocator::allocate with size {}", size); + LOGP(fatal, "Called DefaultGPUAllocator::allocate with size {}", size); return nullptr; // to be implemented } -///////////////////////////////////////////////////////////////////////////////////////// -// GpuChunk -///////////////////////////////////////////////////////////////////////////////////////// template -GpuTimeFrameChunk::~GpuTimeFrameChunk() +TimeFrameGPU::TimeFrameGPU() { - if (mAllocated) { - for (int i = 0; i < nLayers; ++i) { - checkGPUError(cudaFree(mClustersDevice[i])); - // checkGPUError(cudaFree(mTrackingFrameInfoDevice[i])); - checkGPUError(cudaFree(mClusterExternalIndicesDevice[i])); - checkGPUError(cudaFree(mIndexTablesDevice[i])); - if (i < nLayers - 1) { - checkGPUError(cudaFree(mTrackletsDevice[i])); - checkGPUError(cudaFree(mTrackletsLookupTablesDevice[i])); - if (i < nLayers - 2) { - checkGPUError(cudaFree(mCellsDevice[i])); - checkGPUError(cudaFree(mCellsLookupTablesDevice[i])); - checkGPUError(cudaFree(mRoadsLookupTablesDevice[i])); - if (i < nLayers - 3) { - checkGPUError(cudaFree(mNeighboursCellLookupTablesDevice[i])); - checkGPUError(cudaFree(mNeighboursCellDevice[i])); - } - } - } - } - // checkGPUError(cudaFree(mRoadsDevice)); - checkGPUError(cudaFree(mCUBTmpBufferDevice)); - checkGPUError(cudaFree(mFoundTrackletsDevice)); - checkGPUError(cudaFree(mNFoundCellsDevice)); - checkGPUError(cudaFree(mCellsDeviceArray)); - checkGPUError(cudaFree(mNeighboursCellDeviceArray)); - checkGPUError(cudaFree(mNeighboursCellLookupTablesDeviceArray)); - } + mIsGPU = true; + utils::getDeviceProp(0, true); } template -void GpuTimeFrameChunk::allocate(const size_t nrof, Stream& stream) -{ - RANGE("device_partition_allocation", 2); - mNRof = nrof; - // for (int i = 0; i < nLayers; ++i) { - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClustersDevice[i])), sizeof(Cluster) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackingFrameInfoDevice[i])), sizeof(TrackingFrameInfo) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mClusterExternalIndicesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mIndexTablesDevice[i])), sizeof(int) * (256 * 128 + 1) * nrof, &stream, true); - // if (i < nLayers - 1) { - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mTrackletsDevice[i])), sizeof(Tracklet) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // if (i < nLayers - 2) { - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->validatedTrackletsCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mCellsDevice[i])), sizeof(CellSeed) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsLookupTablesDevice[i]), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); - // if (i < nLayers - 3) { - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellLookupTablesDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNeighboursCellDevice[i])), sizeof(int) * mTFGPUParams->maxNeighboursSize * nrof, &stream, true); - // } - // if (i < 2) { - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&(mNTrackletsPerClusterDevice[i])), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // } - // } - // } - // } - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCUBTmpBufferDevice), mTFGPUParams->tmpCUBBufferSize * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mLinesDevice), sizeof(Line) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNExclusiveFoundLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * nrof + 1, &stream, true); // + 1 for cub::DeviceScan::ExclusiveSum, to cover cases where we have maximum number of clusters per ROF - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mUsedTrackletsDevice), sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mClusteredLinesDevice), sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * nrof, &stream, true); - // // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mRoadsDevice), sizeof(Road) * mTFGPUParams->maxRoadPerRofSize * nrof, &stream, true); - - // /// Invariant allocations - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mFoundTrackletsDevice), (nLayers - 1) * sizeof(int) * nrof, &stream, true); // No need to reset, we always read it after writing - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNFoundCellsDevice), (nLayers - 2) * sizeof(int) * nrof, &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); - // static_cast*>(mTimeFramePtr)->allocMemAsync(reinterpret_cast(&mNeighboursCellLookupTablesDeviceArray), (nLayers - 3) * sizeof(int*), &stream, true); - - // /// Copy pointers of allocated memory to regrouping arrays - // checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, stream.get())); - // checkGPUError(cudaMemcpyAsync(mNeighboursCellDeviceArray, mNeighboursCellDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); - // checkGPUError(cudaMemcpyAsync(mNeighboursCellLookupTablesDeviceArray, mNeighboursCellLookupTablesDevice.data(), (nLayers - 3) * sizeof(int*), cudaMemcpyHostToDevice, stream.get())); - - mAllocated = true; -} +TimeFrameGPU::~TimeFrameGPU() = default; template -void GpuTimeFrameChunk::reset(const Task task, Stream& stream) +void TimeFrameGPU::allocMemAsync(void** ptr, size_t size, Stream* strPtr, bool extAllocator) { - RANGE("buffer_reset", 0); - // if ((bool)task) { // Vertexer-only initialisation (cannot be constexpr: due to the presence of gpu raw calls can't be put in header) - // for (int i = 0; i < 2; i++) { - // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); - // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; - // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); - // checkGPUError(cudaMemsetAsync(mNTrackletsPerClusterDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - // } - // checkGPUError(cudaMemsetAsync(mUsedTrackletsDevice, false, sizeof(unsigned char) * mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - // checkGPUError(cudaMemsetAsync(mClusteredLinesDevice, -1, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mTFGPUParams->maxTrackletsPerCluster * mNRof, stream.get())); - // } else { - // for (int i = 0; i < nLayers; ++i) { - // if (i < nLayers - 1) { - // checkGPUError(cudaMemsetAsync(mTrackletsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->clustersPerROfCapacity * mNRof, stream.get())); - // auto thrustTrackletsBegin = thrust::device_ptr(mTrackletsDevice[i]); - // auto thrustTrackletsEnd = thrustTrackletsBegin + mTFGPUParams->maxTrackletsPerCluster * mTFGPUParams->clustersPerROfCapacity * mNRof; - // thrust::fill(THRUST_NAMESPACE::par.on(stream.get()), thrustTrackletsBegin, thrustTrackletsEnd, Tracklet{}); - // if (i < nLayers - 2) { - // checkGPUError(cudaMemsetAsync(mCellsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->cellsLUTsize * mNRof, stream.get())); - // checkGPUError(cudaMemsetAsync(mRoadsLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - // if (i < nLayers - 3) { - // checkGPUError(cudaMemsetAsync(mNeighboursCellLookupTablesDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - // checkGPUError(cudaMemsetAsync(mNeighboursCellDevice[i], 0, sizeof(int) * mTFGPUParams->maxNeighboursSize * mNRof, stream.get())); - // } - // } - // } - // } - // checkGPUError(cudaMemsetAsync(mNFoundCellsDevice, 0, (nLayers - 2) * sizeof(int), stream.get())); - // } + if (extAllocator) { + *ptr = mAllocator->allocate(size); + } else { + LOGP(info, "Calling default CUDA allocator"); + checkGPUError(cudaMallocAsync(reinterpret_cast(ptr), size, strPtr->get())); + } } template -size_t GpuTimeFrameChunk::computeScalingSizeBytes(const int nrof, const TimeFrameGPUParameters& config) +void TimeFrameGPU::setDevicePropagator(const o2::base::PropagatorImpl* propagator) { - size_t rofsize = nLayers * sizeof(int); // number of clusters per ROF - // rofsize += nLayers * sizeof(Cluster) * config.clustersPerROfCapacity; // clusters - // rofsize += nLayers * sizeof(TrackingFrameInfo) * config.clustersPerROfCapacity; // tracking frame info - // rofsize += nLayers * sizeof(int) * config.clustersPerROfCapacity; // external cluster indices - // rofsize += nLayers * sizeof(int) * (256 * 128 + 1); // index tables - // rofsize += (nLayers - 1) * sizeof(int) * config.clustersPerROfCapacity; // tracklets lookup tables - // rofsize += (nLayers - 1) * sizeof(Tracklet) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // tracklets - // rofsize += 2 * sizeof(int) * config.clustersPerROfCapacity; // tracklets found per cluster (vertexer) - // rofsize += sizeof(unsigned char) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // used tracklets (vertexer) - // rofsize += (nLayers - 2) * sizeof(int) * config.validatedTrackletsCapacity; // cells lookup tables - // rofsize += (nLayers - 2) * sizeof(CellSeed) * config.maxNeighboursSize; // cells - // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours lookup tables - // rofsize += (nLayers - 3) * sizeof(int) * config.maxNeighboursSize; // cell neighbours - // rofsize += sizeof(Road) * config.maxRoadPerRofSize; // roads - // rofsize += (nLayers - 2) * sizeof(int) * config.maxNeighboursSize; // road LUT - // rofsize += sizeof(Line) * config.maxTrackletsPerCluster * config.clustersPerROfCapacity; // lines - // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines - // rofsize += sizeof(int) * config.clustersPerROfCapacity; // found lines exclusive sum - // rofsize += sizeof(int) * config.clustersPerROfCapacity * config.maxTrackletsPerCluster; // lines used in clusterlines - - // rofsize += (nLayers - 1) * sizeof(int); // total found tracklets - // rofsize += (nLayers - 2) * sizeof(int); // total found cells - - return rofsize * nrof; + mPropagatorDevice = propagator; } template -size_t GpuTimeFrameChunk::computeFixedSizeBytes(const TimeFrameGPUParameters& config) +void TimeFrameGPU::loadUnsortedClustersDevice() { - size_t total = config.tmpCUBBufferSize; // CUB tmp buffers - total += sizeof(gpu::StaticTrackingParameters); // static parameters loaded once - return total; + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} unsorted clusters on layer {}, for {} MB.", mUnsortedClusters[iLayer].size(), iLayer, mUnsortedClusters[iLayer].size() * sizeof(Cluster) / MB); + allocMemAsync(reinterpret_cast(&mUnsortedClustersDevice[iLayer]), mUnsortedClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); + // Register and move data + checkGPUError(cudaHostRegister(mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mUnsortedClustersDevice[iLayer], mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mUnsortedClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mUnsortedClustersDeviceArray, mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -size_t GpuTimeFrameChunk::computeRofPerChunk(const TimeFrameGPUParameters& config, const size_t m) +void TimeFrameGPU::loadClustersDevice() { - return (m * GB / (float)(config.nTimeFrameChunks) - GpuTimeFrameChunk::computeFixedSizeBytes(config)) / (float)GpuTimeFrameChunk::computeScalingSizeBytes(1, config); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} clusters on layer {}, for {} MB.", mClusters[iLayer].size(), iLayer, mClusters[iLayer].size() * sizeof(Cluster) / MB); + allocMemAsync(reinterpret_cast(&mClustersDevice[iLayer]), mClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); + // Register and move data + checkGPUError(cudaHostRegister(mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mClustersDevice[iLayer], mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mClustersDeviceArray, mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } -/// Interface template -Cluster* GpuTimeFrameChunk::getDeviceClusters(const int layer) +void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) { - return mClustersDevice[layer]; + if (!iteration) { + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} tfinfo on layer {}, for {} MB.", mTrackingFrameInfo[iLayer].size(), iLayer, mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo) / MB); + allocMemAsync(reinterpret_cast(&mTrackingFrameInfoDevice[iLayer]), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), nullptr, getExtAllocator()); + // Register and move data + checkGPUError(cudaHostRegister(mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDevice[iLayer], mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mTrackingFrameInfoDeviceArray), nLayers * sizeof(TrackingFrameInfo*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDeviceArray, mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } } template -int* GpuTimeFrameChunk::getDeviceClusterExternalIndices(const int layer) +void TimeFrameGPU::loadTrackletsDevice() { - return mClusterExternalIndicesDevice[layer]; + for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} tracklets on layer {}, for {} MB.", mTracklets[iLayer].size(), iLayer, mTracklets[iLayer].size() * sizeof(Tracklet) / MB); + allocMemAsync(reinterpret_cast(&mTrackletsDevice[iLayer]), mTracklets[iLayer].size() * sizeof(Tracklet), nullptr, getExtAllocator()); + // Register and move data + checkGPUError(cudaHostRegister(mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsDevice[iLayer], mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mTrackletsDeviceArray), (nLayers - 1) * sizeof(Tracklet*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsDeviceArray, mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -int* GpuTimeFrameChunk::getDeviceIndexTables(const int layer) +void TimeFrameGPU::loadCellsDevice() { - return mIndexTablesDevice[layer]; + for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} cell seeds on layer {}, for {} MB.", mCells[iLayer].size(), iLayer, mCells[iLayer].size() * sizeof(CellSeed) / MB); + allocMemAsync(reinterpret_cast(&mCellsDevice[iLayer]), mCells[iLayer].size() * sizeof(CellSeed), nullptr, getExtAllocator()); + allocMemAsync(reinterpret_cast(&mNeighboursIndexTablesDevice[iLayer]), (mCells[iLayer].size() + 1) * sizeof(int), nullptr, getExtAllocator()); // accessory for the neigh. finding. + checkGPUError(cudaMemsetAsync(mNeighboursIndexTablesDevice[iLayer], 0, (mCells[iLayer].size() + 1) * sizeof(int), mGpuStreams[0].get())); + // Register and move data + checkGPUError(cudaHostRegister(mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsDevice[iLayer], mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -Tracklet* GpuTimeFrameChunk::getDeviceTracklets(const int layer) +void TimeFrameGPU::loadCellsLUT() { - return mTrackletsDevice[layer]; + for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} cell LUTs on layer {}, for {} MB.", mCellsLookupTable[iLayer].size(), iLayer, mCellsLookupTable[iLayer].size() * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&(mCellsLUTDevice[iLayer])), sizeof(int) * mCellsLookupTable[iLayer].size(), nullptr, getExtAllocator()); + // Register and move data + checkGPUError(cudaHostRegister(mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsLUTDevice[iLayer], mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mCellsLUTDeviceArray), (nLayers - 2) * sizeof(int*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mCellsLUTDevice.data(), mCellsLUTDevice.size() * sizeof(int*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsLUTDeviceArray, mCellsLUTDevice.data(), mCellsLUTDevice.size() * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -int* GpuTimeFrameChunk::getDeviceTrackletsLookupTables(const int layer) +void TimeFrameGPU::loadRoadsDevice() { - return mTrackletsLookupTablesDevice[layer]; + LOGP(debug, "gpu-transfer: loading {} roads, for {} MB.", mRoads.size(), mRoads.size() * sizeof(Road) / MB); + allocMemAsync(reinterpret_cast(&mRoadsDevice), mRoads.size() * sizeof(Road), &(mGpuStreams[0]), getExtAllocator()); + checkGPUError(cudaHostRegister(mRoads.data(), mRoads.size() * sizeof(Road), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mRoadsDevice, mRoads.data(), mRoads.size() * sizeof(Road), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -CellSeed* GpuTimeFrameChunk::getDeviceCells(const int layer) +void TimeFrameGPU::loadTrackSeedsDevice(std::vector& seeds) { - return mCellsDevice[layer]; + LOGP(debug, "gpu-transfer: loading {} track seeds, for {} MB.", seeds.size(), seeds.size() * sizeof(CellSeed) / MB); + allocMemAsync(reinterpret_cast(&mTrackSeedsDevice), seeds.size() * sizeof(CellSeed), &(mGpuStreams[0]), getExtAllocator()); + checkGPUError(cudaHostRegister(seeds.data(), seeds.size() * sizeof(CellSeed), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackSeedsDevice, seeds.data(), seeds.size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -int* GpuTimeFrameChunk::getDeviceCellsLookupTables(const int layer) +void TimeFrameGPU::createNeighboursDevice(const unsigned int& layer, std::vector>& neighbours) { - return mCellsLookupTablesDevice[layer]; + mCellsNeighbours[layer].clear(); + mCellsNeighbours[layer].resize(neighbours.size()); + LOGP(debug, "gpu-allocation: reserving {} neighbours, for {} MB.", neighbours.size(), neighbours.size() * sizeof(gpuPair) / MB); + allocMemAsync(reinterpret_cast(&mNeighboursDevice[layer]), neighbours.size() * sizeof(gpuPair), &(mGpuStreams[0]), getExtAllocator()); + checkGPUError(cudaMemsetAsync(mNeighboursDevice[layer], -1, neighbours.size() * sizeof(gpuPair), mGpuStreams[0].get())); } template -int* GpuTimeFrameChunk::getDeviceCellNeigboursLookupTables(const int layer) +void TimeFrameGPU::createNeighboursLUTDevice(const int layer, const unsigned int nCells) { - return mNeighboursCellLookupTablesDevice[layer]; + LOGP(debug, "gpu-allocation: reserving {} slots for neighbours LUT, for {} MB.", nCells + 1, (nCells + 1) * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mNeighboursLUTDevice[layer]), (nCells + 1) * sizeof(int), nullptr, getExtAllocator()); // We need one element more to move exc -> inc + checkGPUError(cudaMemsetAsync(mNeighboursLUTDevice[layer], 0, (nCells + 1) * sizeof(int), mGpuStreams[0].get())); } template -int* GpuTimeFrameChunk::getDeviceCellNeighbours(const int layer) +void TimeFrameGPU::createTrackITSExtDevice(std::vector& seeds) { - return mNeighboursCellDevice[layer]; + mTrackITSExt.clear(); + mTrackITSExt.resize(seeds.size()); + LOGP(debug, "gpu-allocation: reserving {} tracks, for {} MB.", seeds.size(), seeds.size() * sizeof(o2::its::TrackITSExt) / MB); + allocMemAsync(reinterpret_cast(&mTrackITSExtDevice), seeds.size() * sizeof(o2::its::TrackITSExt), &(mGpuStreams[0]), getExtAllocator()); + checkGPUError(cudaMemsetAsync(mTrackITSExtDevice, 0, seeds.size() * sizeof(o2::its::TrackITSExt), mGpuStreams[0].get())); + checkGPUError(cudaHostRegister(mTrackITSExt.data(), seeds.size() * sizeof(o2::its::TrackITSExt), cudaHostRegisterPortable)); } template -int* GpuTimeFrameChunk::getDeviceRoadsLookupTables(const int layer) +void TimeFrameGPU::downloadCellsDevice(const int layer) { - return mRoadsLookupTablesDevice[layer]; + LOGP(debug, "gpu-transfer: downloading {} cells on layer: {}, for {} MB.", mCells[layer].size(), layer, mCells[layer].size() * sizeof(CellSeed) / MB); + checkGPUError(cudaMemcpyAsync(mCells[layer].data(), mCellsDevice[layer], mCells[layer].size() * sizeof(CellSeed), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + checkGPUError(cudaHostUnregister(mCells[layer].data())); } -// Load data template -size_t GpuTimeFrameChunk::loadDataOnDevice(const size_t startRof, const size_t maxRof, const int maxLayers, Stream& stream) +void TimeFrameGPU::downloadCellsNeighbours(std::vector>>& neighbours, const int layer) { - RANGE("load_clusters_data", 5); - // auto nRofs = std::min(maxRof - startRof, mNRof); - // mNPopulatedRof = mTimeFramePtr->getNClustersROFrange(startRof, nRofs, 0).size(); - // for (int i = 0; i < maxLayers; ++i) { - // mHostClusters[i] = mTimeFramePtr->getClustersPerROFrange(startRof, nRofs, i); - // mHostIndexTables[i] = mTimeFramePtr->getIndexTablePerROFrange(startRof, nRofs, i); - // if (mHostClusters[i].size() > mTFGPUParams->clustersPerROfCapacity * nRofs) { - // LOGP(warning, "Clusters on layer {} exceed the expected value, resizing to config value: {}, will lose information!", i, mTFGPUParams->clustersPerROfCapacity * nRofs); - // } - // checkGPUError(cudaMemcpyAsync(mClustersDevice[i], - // mHostClusters[i].data(), - // (int)std::min(mHostClusters[i].size(), mTFGPUParams->clustersPerROfCapacity * nRofs) * sizeof(Cluster), - // cudaMemcpyHostToDevice, stream.get())); - // if (mHostIndexTables[i].data()) { - // checkGPUError(cudaMemcpyAsync(mIndexTablesDevice[i], - // mHostIndexTables[i].data(), - // mHostIndexTables[i].size() * sizeof(int), - // cudaMemcpyHostToDevice, stream.get())); - // } - // } - return mNPopulatedRof; // return the number of ROFs we loaded the data for. + LOGP(debug, "gpu-transfer: downloading {} neighbours, for {} MB.", neighbours[layer].size(), neighbours[layer].size() * sizeof(std::pair) / MB); + // TOOD: something less dangerous than assuming the same memory layout of std::pair and gpuPair... or not? :) + checkGPUError(cudaMemcpyAsync(neighbours[layer].data(), mNeighboursDevice[layer], neighbours[layer].size() * sizeof(gpuPair), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); } -///////////////////////////////////////////////////////////////////////////////////////// -// TimeFrameGPU -///////////////////////////////////////////////////////////////////////////////////////// template -TimeFrameGPU::TimeFrameGPU() +void TimeFrameGPU::downloadNeighboursLUT(std::vector& lut, const int layer) { - mIsGPU = true; - utils::getDeviceProp(0, true); + LOGP(debug, "gpu-transfer: downloading {} neighbours lut, for {} MB.", lut.size(), lut.size() * sizeof(int) / MB); + checkGPUError(cudaMemcpyAsync(lut.data(), mNeighboursLUTDevice[layer], lut.size() * sizeof(int), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); } template -TimeFrameGPU::~TimeFrameGPU() = default; - -template -void TimeFrameGPU::allocMemAsync(void** ptr, size_t size, Stream* strPtr, bool extAllocator) +void TimeFrameGPU::downloadTrackITSExtDevice(std::vector& seeds) { - if (extAllocator) { - *ptr = mAllocator->allocate(size); - } else { - LOGP(info, "Calling default CUDA allocator"); - checkGPUError(cudaMallocAsync(reinterpret_cast(ptr), size, strPtr->get())); - } + LOGP(debug, "gpu-transfer: downloading {} tracks, for {} MB.", mTrackITSExt.size(), mTrackITSExt.size() * sizeof(o2::its::TrackITSExt) / MB); + checkGPUError(cudaMemcpyAsync(mTrackITSExt.data(), mTrackITSExtDevice, seeds.size() * sizeof(o2::its::TrackITSExt), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + checkGPUError(cudaHostUnregister(mTrackITSExt.data())); + checkGPUError(cudaHostUnregister(seeds.data())); + // discardResult(cudaDeviceSynchronize()); } template -void TimeFrameGPU::setDevicePropagator(const o2::base::PropagatorImpl* propagator) +void TimeFrameGPU::unregisterRest() { - mPropagatorDevice = propagator; + LOGP(debug, "unregistering rest of the host memory..."); + checkGPUError(cudaHostUnregister(mCells[0].data())); + checkGPUError(cudaHostUnregister(mCellsDevice.data())); + checkGPUError(cudaHostUnregister(mCellsLUTDevice.data())); + for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { + checkGPUError(cudaHostUnregister(mCellsLookupTable[iLayer].data())); + } } - +//////////////////////////////////////////////////////////////////////// +/// Legacy template void TimeFrameGPU::registerHostMemory(const int maxLayers) { @@ -429,133 +362,6 @@ void TimeFrameGPU::initDevice(IndexTableUtils* utils, // checkGPUError(cudaMemcpy(mIndexTableUtilsDevice, &mIndexTableUtils, sizeof(IndexTableUtils), cudaMemcpyHostToDevice)); } -template -void TimeFrameGPU::loadUnsortedClustersDevice() -{ - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} unsorted clusters on layer {}, for {} MB.", mUnsortedClusters[iLayer].size(), iLayer, mUnsortedClusters[iLayer].size() * sizeof(Cluster) / MB); - allocMemAsync(reinterpret_cast(&mUnsortedClustersDevice[iLayer]), mUnsortedClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mUnsortedClustersDevice[iLayer], mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } - allocMemAsync(reinterpret_cast(&mUnsortedClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mUnsortedClustersDeviceArray, mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::loadClustersDevice() -{ - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} clusters on layer {}, for {} MB.", mClusters[iLayer].size(), iLayer, mClusters[iLayer].size() * sizeof(Cluster) / MB); - allocMemAsync(reinterpret_cast(&mClustersDevice[iLayer]), mClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mClustersDevice[iLayer], mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } - allocMemAsync(reinterpret_cast(&mClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mClustersDeviceArray, mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) -{ - if (!iteration) { - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - LOGP(info, "gpu-transfer: loading {} tfinfo on layer {}, for {} MB.", mTrackingFrameInfo[iLayer].size(), iLayer, mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo) / MB); - allocMemAsync(reinterpret_cast(&mTrackingFrameInfoDevice[iLayer]), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDevice[iLayer], mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } - allocMemAsync(reinterpret_cast(&mTrackingFrameInfoDeviceArray), nLayers * sizeof(TrackingFrameInfo*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDeviceArray, mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } -} - -template -void TimeFrameGPU::loadTrackletsDevice() -{ - for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} tracklets on layer {}, for {} MB.", mTracklets[iLayer].size(), iLayer, mTracklets[iLayer].size() * sizeof(Tracklet) / MB); - allocMemAsync(reinterpret_cast(&mTrackletsDevice[iLayer]), mTracklets[iLayer].size() * sizeof(Tracklet), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackletsDevice[iLayer], mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } - allocMemAsync(reinterpret_cast(&mTrackletsDeviceArray), (nLayers - 1) * sizeof(Tracklet*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackletsDeviceArray, mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::loadCellsDevice() -{ - for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} cell seeds on layer {}, for {} MB.", mCells[iLayer].size(), iLayer, mCells[iLayer].size() * sizeof(CellSeed) / MB); - allocMemAsync(reinterpret_cast(&mCellsDevice[iLayer]), mCells[iLayer].size() * sizeof(CellSeed), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mCellsDevice[iLayer], mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); - } - allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::loadRoadsDevice() -{ - LOGP(debug, "gpu-transfer: loading {} roads, for {} MB.", mRoads.size(), mRoads.size() * sizeof(Road) / MB); - allocMemAsync(reinterpret_cast(&mRoadsDevice), mRoads.size() * sizeof(Road), &(mGpuStreams[0]), getExtAllocator()); - checkGPUError(cudaHostRegister(mRoads.data(), mRoads.size() * sizeof(Road), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mRoadsDevice, mRoads.data(), mRoads.size() * sizeof(Road), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::loadTrackSeedsDevice(std::vector& seeds) -{ - LOGP(debug, "gpu-transfer: loading {} track seeds, for {} MB.", seeds.size(), seeds.size() * sizeof(CellSeed) / MB); - allocMemAsync(reinterpret_cast(&mTrackSeedsDevice), seeds.size() * sizeof(CellSeed), &(mGpuStreams[0]), getExtAllocator()); - checkGPUError(cudaHostRegister(seeds.data(), seeds.size() * sizeof(CellSeed), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackSeedsDevice, seeds.data(), seeds.size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); -} - -template -void TimeFrameGPU::createCellNeighboursDevice(const unsigned int& layer, std::vector>& neighbours) -{ - mCellsNeighbours[layer].clear(); - mCellsNeighbours[layer].resize(neighbours.size()); - LOGP(debug, "gpu-allocation: reserving {} neighbours, for {} MB.", neighbours.size(), neighbours.size() * sizeof(gpuPair) / MB); - allocMemAsync(reinterpret_cast(&mNeighboursDevice[layer]), neighbours.size() * sizeof(gpuPair), &(mGpuStreams[0]), getExtAllocator()); - checkGPUError(cudaMemsetAsync(mNeighboursDevice[layer], 0, neighbours.size() * sizeof(gpuPair), mGpuStreams[0].get())); - checkGPUError(cudaHostRegister(neighbours.data(), neighbours.size() * sizeof(std::pair), cudaHostRegisterPortable)); -} - -template -void TimeFrameGPU::createTrackITSExtDevice(std::vector& seeds) -{ - mTrackITSExt.clear(); - mTrackITSExt.resize(seeds.size()); - LOGP(debug, "gpu-allocation: reserving {} tracks, for {} MB.", seeds.size(), seeds.size() * sizeof(o2::its::TrackITSExt) / MB); - allocMemAsync(reinterpret_cast(&mTrackITSExtDevice), seeds.size() * sizeof(o2::its::TrackITSExt), &(mGpuStreams[0]), getExtAllocator()); - checkGPUError(cudaMemsetAsync(mTrackITSExtDevice, 0, seeds.size() * sizeof(o2::its::TrackITSExt), mGpuStreams[0].get())); - checkGPUError(cudaHostRegister(mTrackITSExt.data(), seeds.size() * sizeof(o2::its::TrackITSExt), cudaHostRegisterPortable)); -} - -template -void TimeFrameGPU::downloadTrackITSExtDevice(std::vector& seeds) -{ - LOGP(debug, "gpu-transfer: downloading {} tracks, for {} MB.", mTrackITSExt.size(), mTrackITSExt.size() * sizeof(o2::its::TrackITSExt) / MB); - checkGPUError(cudaMemcpyAsync(mTrackITSExt.data(), mTrackITSExtDevice, seeds.size() * sizeof(o2::its::TrackITSExt), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); - checkGPUError(cudaHostUnregister(mTrackITSExt.data())); - checkGPUError(cudaHostUnregister(seeds.data())); - discardResult(cudaDeviceSynchronize()); -} - template unsigned char* TimeFrameGPU::getDeviceUsedClusters(const int layer) { @@ -575,7 +381,6 @@ gsl::span TimeFrameGPU::getHostNCells(const int chunkId) } template class TimeFrameGPU<7>; -template class GpuTimeFrameChunk<7>; } // namespace gpu } // namespace its } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx index ac8b3f87b874c..45fee9976bca6 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx @@ -21,7 +21,6 @@ #include "ITStrackingGPU/TrackerTraitsGPU.h" #include "ITStrackingGPU/TrackingKernels.h" #include "ITStracking/TrackingConfigParam.h" - namespace o2::its { constexpr int UnusedIndex{-1}; @@ -324,45 +323,62 @@ void TrackerTraitsGPU::computeCellsHybrid(const int iteration) template void TrackerTraitsGPU::findCellsNeighboursHybrid(const int iteration) { - TrackerTraits::findCellsNeighbours(iteration); - // for (int iLayer{0}; iLayer < mTrkParams[iteration].CellsPerRoad() - 1; ++iLayer) { - // const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getCells()[iLayer + 1].size())}; - // mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].clear(); - // mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].resize(nextLayerCellsNum, 0); - // if (mTimeFrameGPU->getCells()[iLayer + 1].empty() || - // mTimeFrameGPU->getCellsLookupTable()[iLayer].empty()) { - // mTimeFrameGPU->getCellsNeighbours()[iLayer].clear(); - // continue; - // } - - // int layerCellsNum{static_cast(mTimeFrameGPU->getCells()[iLayer].size())}; - // std::vector> cellsNeighbours; - // cellsNeighbours.reserve(nextLayerCellsNum); - // mTimeFrameGPU->createCellNeighboursDevice(iLayer, cellsNeighbours); - - // // // [...] - // // cellNeighboursHandler(mTimeFrameGPU->getDeviceNeighbours(iLayer)); - // // // // Compute Cell Neighbours LUT - // // // checkGPUError(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), // d_temp_storage - // // // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, // temp_storage_bytes - // // // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), // d_in - // // // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), // d_out - // // // mTimeFrameGPU->getHostNCells(chunkId)[iLayer + 1], // num_items - // // // mTimeFrameGPU->getStream(chunkId).get())); - - // // cellsNeighboursHandler(mTimeFrameGPU->getDeviceNeighbours(iLayer)); - // // // [...] - - // std::sort(cellsNeighbours.begin(), cellsNeighbours.end(), [](const std::pair& a, const std::pair& b) { - // return a.second < b.second; - // }); - // mTimeFrameGPU->getCellsNeighbours()[iLayer].clear(); - // mTimeFrameGPU->getCellsNeighbours()[iLayer].reserve(cellsNeighbours.size()); - // for (auto& cellNeighboursIndex : cellsNeighbours) { - // mTimeFrameGPU->getCellsNeighbours()[iLayer].push_back(cellNeighboursIndex.first); - // } - // std::inclusive_scan(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].begin(), mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].end(), mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].begin()); - // } + auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); + mTimeFrameGPU->loadCellsDevice(); + mTimeFrameGPU->loadCellsLUT(); + std::vector>> cellsNeighboursLayer(mTrkParams[iteration].CellsPerRoad() - 1); + for (int iLayer{0}; iLayer < mTrkParams[iteration].CellsPerRoad() - 1; ++iLayer) { + const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getCells()[iLayer + 1].size())}; + mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].clear(); + mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].resize(nextLayerCellsNum, 0); + + if (mTimeFrameGPU->getCells()[iLayer + 1].empty() || + mTimeFrameGPU->getCellsLookupTable()[iLayer].empty()) { + mTimeFrameGPU->getCellsNeighbours()[iLayer].clear(); + continue; + } + + int layerCellsNum{static_cast(mTimeFrameGPU->getCells()[iLayer].size())}; + mTimeFrameGPU->createNeighboursLUTDevice(iLayer, nextLayerCellsNum); + countCellNeighboursHandler(mTimeFrameGPU->getDeviceArrayCells(), + mTimeFrameGPU->getDeviceNeighboursLUT(iLayer), // LUT is initialised here. + mTimeFrameGPU->getDeviceArrayCellsLUT(), + mTimeFrameGPU->getDeviceNeighbours(iLayer), + mTimeFrameGPU->getDeviceNeighboursIndexTables(iLayer), + mTrkParams[0].MaxChi2ClusterAttachment, + mBz, + iLayer, + layerCellsNum, + nextLayerCellsNum, + 1e2, + conf.nBlocks, + conf.nThreads); + mTimeFrameGPU->downloadNeighboursLUT(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer], iLayer); + // Get the number of found cells from LUT + cellsNeighboursLayer[iLayer].resize(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].back()); + mTimeFrameGPU->createNeighboursDevice(iLayer, cellsNeighboursLayer[iLayer]); + computeCellNeighboursHandler(mTimeFrameGPU->getDeviceArrayCells(), + mTimeFrameGPU->getDeviceNeighboursLUT(iLayer), + mTimeFrameGPU->getDeviceArrayCellsLUT(), + mTimeFrameGPU->getDeviceNeighbours(iLayer), + mTimeFrameGPU->getDeviceNeighboursIndexTables(iLayer), + mTrkParams[0].MaxChi2ClusterAttachment, + mBz, + iLayer, + layerCellsNum, + nextLayerCellsNum, + 1e2, + conf.nBlocks, + conf.nThreads); + mTimeFrameGPU->getCellsNeighbours()[iLayer].clear(); + mTimeFrameGPU->getCellsNeighbours()[iLayer].reserve(cellsNeighboursLayer[iLayer].size()); + mTimeFrameGPU->downloadCellsDevice(iLayer + 1); // Cells on layer 0 did not change. + + filterCellNeighboursHandler(mTimeFrameGPU->getCellsNeighbours()[iLayer], + mTimeFrameGPU->getDeviceNeighbours(iLayer), + cellsNeighboursLayer[iLayer].size()); + } + mTimeFrameGPU->unregisterRest(); }; template diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index 60683e5fea30b..9d00892f4b680 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -19,11 +19,13 @@ #include #include +#include #include #include #include #include #include +#include #include "ITStracking/Constants.h" #include "ITStracking/Configuration.h" @@ -40,6 +42,14 @@ #define THRUST_NAMESPACE thrust::hip #endif +#ifdef GPUCA_NO_FAST_MATH +#define GPU_BLOCKS 1 +#define GPU_THREADS 1 +#else +#define GPU_BLOCKS 99999 +#define GPU_THREADS 99999 +#endif + // O2 track model #include "ReconstructionDataFormats/Track.h" #include "DetectorsBase/Propagator.h" @@ -184,25 +194,25 @@ GPUg() void fitTrackSeedsKernel( template // Version for new tracker to supersede the old one GPUg() void computeLayerCellNeighboursKernel( - CellSeed* cellsCurrentLayer, - CellSeed* cellsNextLayer, + CellSeed** cellSeedArray, int* neighboursLUT, - const int* cellsNextLayerLUT, + int* neighboursIndexTable, + int** cellsLUTs, gpuPair* cellNeighbours, const float maxChi2ClusterAttachment, const float bz, const int layerIndex, - const int* nCells, + const unsigned int nCells, const int maxCellNeighbours = 1e2) { - for (int iCurrentCellIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentCellIndex < nCells[layerIndex]; iCurrentCellIndex += blockDim.x * gridDim.x) { - const auto& currentCellSeed{cellsCurrentLayer[iCurrentCellIndex]}; + for (int iCurrentCellIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentCellIndex < nCells; iCurrentCellIndex += blockDim.x * gridDim.x) { + const auto& currentCellSeed{cellSeedArray[layerIndex][iCurrentCellIndex]}; const int nextLayerTrackletIndex{currentCellSeed.getSecondTrackletIndex()}; - const int nextLayerFirstCellIndex{cellsNextLayerLUT[nextLayerTrackletIndex]}; - const int nextLayerLastCellIndex{cellsNextLayerLUT[nextLayerTrackletIndex + 1]}; + const int nextLayerFirstCellIndex{cellsLUTs[layerIndex][nextLayerTrackletIndex]}; + const int nextLayerLastCellIndex{cellsLUTs[layerIndex][nextLayerTrackletIndex + 1]}; int foundNeighbours{0}; for (int iNextCell{nextLayerFirstCellIndex}; iNextCell < nextLayerLastCellIndex; ++iNextCell) { - CellSeed nextCellSeed{cellsNextLayer[iNextCell]}; // Copy + CellSeed nextCellSeed{cellSeedArray[layerIndex + 1][iNextCell]}; // Copy if (nextCellSeed.getFirstTrackletIndex() != nextLayerTrackletIndex) { // Check if cells share the same tracklet break; } @@ -217,23 +227,54 @@ GPUg() void computeLayerCellNeighboursKernel( } if constexpr (initRun) { atomicAdd(neighboursLUT + iNextCell, 1); + foundNeighbours++; + neighboursIndexTable[iCurrentCellIndex]++; } else { - if (foundNeighbours >= maxCellNeighbours) { - printf("its-gpu-neighbours-finder: data loss on layer: %d: number of neightbours exceeded the threshold!\n"); - continue; - } - cellNeighbours[neighboursLUT[iNextCell] + foundNeighbours++] = {iCurrentCellIndex, iNextCell}; - + cellNeighbours[neighboursIndexTable[iCurrentCellIndex] + foundNeighbours] = {iCurrentCellIndex, iNextCell}; + foundNeighbours++; // FIXME: this is prone to race conditions: check on level is not atomic const int currentCellLevel{currentCellSeed.getLevel()}; if (currentCellLevel >= nextCellSeed.getLevel()) { - atomicExch(cellsNextLayer[iNextCell].getLevelPtr(), currentCellLevel + 1); // Update level on corresponding cell + // atomicExch(cellSeedArray[layerIndex + 1][iNextCell].getLevelPtr(), currentCellLevel + 1); // Update level on corresponding cell + cellSeedArray[layerIndex + 1][iNextCell].setLevel(currentCellLevel + 1); } } } } } +template +struct pair_to_first : public thrust::unary_function, T1> { + GPUhd() int operator()(const gpuPair& a) const + { + return a.first; + } +}; + +template +struct pair_to_second : public thrust::unary_function, T2> { + GPUhd() int operator()(const gpuPair& a) const + { + return a.second; + } +}; + +template +struct is_invalid_pair { + GPUhd() bool operator()(const gpuPair& p) const + { + return p.first == -1 && p.second == -1; + } +}; + +template +struct is_valid_pair { + GPUhd() bool operator()(const gpuPair& p) const + { + return !(p.first == -1 && p.second == -1); + } +}; + //////////////////////////////////////////////////////////////////////////////// // Legacy Kernels, to possibly take inspiration from //////////////////////////////////////////////////////////////////////////////// @@ -344,6 +385,18 @@ GPUg() void printTrackletsNotStrided(const Tracklet* t, } } +GPUg() void printNeighbours(const gpuPair* neighbours, + const int* nNeighboursIndexTable, + const unsigned int nCells, + const unsigned int tId = 0) +{ + for (unsigned int iNeighbour{0}; iNeighbour < nNeighboursIndexTable[nCells]; ++iNeighbour) { + if (threadIdx.x == tId) { + printf("%d -> %d\n", neighbours[iNeighbour].first, neighbours[iNeighbour].second); + } + } +} + // Compute the tracklets for a given layer template GPUg() void computeLayerTrackletsKernelSingleRof( @@ -597,7 +650,7 @@ GPUg() void computeLayerCellsKernel( const int* trackletsCurrentLayerLUT, const int nTrackletsCurrent, CellSeed* cells, - int* cellsLUT, + int* cellsLUTs, const StaticTrackingParameters* trkPars) { for (int iCurrentTrackletIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentTrackletIndex < nTrackletsCurrent; iCurrentTrackletIndex += blockDim.x * gridDim.x) { @@ -618,17 +671,17 @@ GPUg() void computeLayerCellsKernel( if (deltaTanLambda / trkPars->CellDeltaTanLambdaSigma < trkPars->NSigmaCut) { if constexpr (!initRun) { - new (cells + cellsLUT[iCurrentTrackletIndex] + foundCells) Cell{currentTracklet.firstClusterIndex, nextTracklet.firstClusterIndex, - nextTracklet.secondClusterIndex, - iCurrentTrackletIndex, - iNextTrackletIndex}; + new (cells + cellsLUTs[iCurrentTrackletIndex] + foundCells) Cell{currentTracklet.firstClusterIndex, nextTracklet.firstClusterIndex, + nextTracklet.secondClusterIndex, + iCurrentTrackletIndex, + iNextTrackletIndex}; } ++foundCells; } } if constexpr (initRun) { // Fill cell Lookup table - cellsLUT[iCurrentTrackletIndex] = foundCells; + cellsLUTs[iCurrentTrackletIndex] = foundCells; } } } @@ -683,29 +736,120 @@ GPUg() void computeLayerRoadsKernel( } } // namespace gpu -template -void cellNeighboursHandler(CellSeed* cellsCurrentLayer, - CellSeed* cellsNextLayer, - int* neighboursLUT, - const int* cellsNextLayerLUT, - gpuPair* cellNeighbours, - const float maxChi2ClusterAttachment, - const float bz, - const int layerIndex, - const int* nCells, - const int maxCellNeighbours = 1e2) +void countCellNeighboursHandler(CellSeed** cellsLayersDevice, + int* neighboursLUT, + int** cellsLUTs, + gpuPair* cellNeighbours, + int* neighboursIndexTable, + const float maxChi2ClusterAttachment, + const float bz, + const int layerIndex, + const unsigned int nCells, + const unsigned int nCellsNext, + const int maxCellNeighbours, + const int nBlocks, + const int nThreads) +{ + gpu::computeLayerCellNeighboursKernel<<>>( + cellsLayersDevice, + neighboursLUT, + neighboursIndexTable, + cellsLUTs, + cellNeighbours, + maxChi2ClusterAttachment, + bz, + layerIndex, + nCells, + maxCellNeighbours); + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); + void *d_temp_storage = nullptr, *d_temp_storage_2 = nullptr; + size_t temp_storage_bytes = 0, temp_storage_bytes_2 = 0; + gpuCheckError(cub::DeviceScan::InclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + neighboursLUT, // d_in + neighboursLUT, // d_out + nCellsNext)); // num_items + + discardResult(cudaMalloc(&d_temp_storage, temp_storage_bytes)); + gpuCheckError(cub::DeviceScan::InclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + neighboursLUT, // d_in + neighboursLUT, // d_out + nCellsNext)); // num_items + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage_2, // d_temp_storage + temp_storage_bytes_2, // temp_storage_bytes + neighboursIndexTable, // d_in + neighboursIndexTable, // d_out + nCells + 1, // num_items + 0)); + discardResult(cudaMalloc(&d_temp_storage_2, temp_storage_bytes_2)); + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage_2, // d_temp_storage + temp_storage_bytes_2, // temp_storage_bytes + neighboursIndexTable, // d_in + neighboursIndexTable, // d_out + nCells + 1, // num_items + 0)); + gpuCheckError(cudaFree(d_temp_storage)); + gpuCheckError(cudaFree(d_temp_storage_2)); + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); +} + +void computeCellNeighboursHandler(CellSeed** cellsLayersDevice, + int* neighboursLUT, + int** cellsLUTs, + gpuPair* cellNeighbours, + int* neighboursIndexTable, + const float maxChi2ClusterAttachment, + const float bz, + const int layerIndex, + const unsigned int nCells, + const unsigned int nCellsNext, + const int maxCellNeighbours, + const int nBlocks, + const int nThreads) +{ + + gpu::computeLayerCellNeighboursKernel<<>>( + cellsLayersDevice, + neighboursLUT, + neighboursIndexTable, + cellsLUTs, + cellNeighbours, + maxChi2ClusterAttachment, + bz, + layerIndex, + nCells, + maxCellNeighbours); + gpuCheckError(cudaPeekAtLastError()); + gpuCheckError(cudaDeviceSynchronize()); +} + +void filterCellNeighboursHandler(std::vector& neighHost, + gpuPair* cellNeighbours, + unsigned int nNeigh) { - gpu::computeLayerCellNeighboursKernel<<<20, 512>>>( - cellsCurrentLayer, // CellSeed* cellsCurrentLayer, - cellsNextLayer, // CellSeed* cellsNextLayer, - neighboursLUT, // int* neighboursLUT, - cellsNextLayerLUT, // const int* cellsNextLayerLUT, - cellNeighbours, // gpuPair* cellNeighbours, - maxChi2ClusterAttachment, // const float maxChi2ClusterAttachment, - bz, // const float bz, - layerIndex, // const int layerIndex, - nCells, // const int* nCells, - maxCellNeighbours); // const int maxCellNeighbours = 1e2 + thrust::device_ptr> neighVector(cellNeighbours); + thrust::device_vector keys(nNeigh); // TODO: externally allocate. + thrust::device_vector vals(nNeigh); // TODO: externally allocate. + thrust::copy(thrust::make_transform_iterator(neighVector, gpu::pair_to_second()), + thrust::make_transform_iterator(neighVector + nNeigh, gpu::pair_to_second()), + keys.begin()); + thrust::sequence(vals.begin(), vals.end()); + thrust::sort_by_key(keys.begin(), keys.end(), vals.begin()); + thrust::device_vector> sortedNeigh(nNeigh); + thrust::copy(thrust::make_permutation_iterator(neighVector, vals.begin()), + thrust::make_permutation_iterator(neighVector, vals.end()), + sortedNeigh.begin()); + discardResult(cudaDeviceSynchronize()); + auto trimmedBegin = thrust::find_if(sortedNeigh.begin(), sortedNeigh.end(), gpu::is_valid_pair()); // trim leading -1s + auto trimmedSize = sortedNeigh.end() - trimmedBegin; + thrust::device_vector validNeigh(trimmedSize); + neighHost.resize(trimmedSize); + thrust::transform(trimmedBegin, sortedNeigh.end(), validNeigh.begin(), gpu::pair_to_first()); + gpuCheckError(cudaMemcpy(neighHost.data(), thrust::raw_pointer_cast(validNeigh.data()), trimmedSize * sizeof(int), cudaMemcpyDeviceToHost)); } void trackSeedHandler(CellSeed* trackSeeds, diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt index f51544eaa970c..0b686273a159a 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/GPU/hip/CMakeLists.txt @@ -16,6 +16,7 @@ if(HIP_ENABLED) SOURCES ../cuda/ClusterLinesGPU.cu ../cuda/Context.cu ../cuda/TimeFrameGPU.cu + ../cuda/TimeFrameChunk.cu ../cuda/Stream.cu ../cuda/TrackerTraitsGPU.cxx ../cuda/TracerGPU.cu @@ -31,4 +32,4 @@ if(HIP_ENABLED) hip::host PRIVATE_LINK_LIBRARIES O2::GPUTrackingHIPExternalProvider TARGETVARNAME targetName) -endif() +endif() \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index 08e50cf9ea824..906eb0fa5c21e 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -288,6 +288,7 @@ class TimeFrame std::vector> mRoads; std::vector> mTracks; std::vector> mCellsNeighbours; + std::vector> mCellsLookupTable; const o2::base::PropagatorImpl* mPropagatorDevice = nullptr; // Needed only for GPU protected: @@ -315,7 +316,6 @@ class TimeFrame std::vector> mPValphaX; /// PV x and alpha for track propagation std::vector> mTrackletLabels; std::vector> mCellLabels; - std::vector> mCellsLookupTable; std::vector> mCellsNeighboursLUT; std::vector> mTracksLabel; std::vector mBogusClusters; /// keep track of clusters with wild coordinates From 8ec256cf36357a2c943c3f9f02b79a15469f4f18 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Thu, 31 Oct 2024 09:06:33 +0100 Subject: [PATCH 0399/2205] GenO2Kine: Event-pool developments Developments needed for event-pool feature, which relies on GenO2Kine for reading from the pool: - allow reading kine file from Alien - randomize event picking from file - possibility to phi-rotate events https://its.cern.ch/jira/browse/O2-5216 --- .../include/Generators/GeneratorFromFile.h | 6 ++++ .../Generators/GeneratorFromO2KineParam.h | 5 ++- Generators/src/GeneratorFromFile.cxx | 34 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Generators/include/Generators/GeneratorFromFile.h b/Generators/include/Generators/GeneratorFromFile.h index 42656baddd402..14a74db8dbc57 100644 --- a/Generators/include/Generators/GeneratorFromFile.h +++ b/Generators/include/Generators/GeneratorFromFile.h @@ -16,6 +16,8 @@ #include "FairGenerator.h" #include "Generators/Generator.h" +#include +#include class TBranch; class TFile; @@ -94,6 +96,10 @@ class GeneratorFromO2Kine : public o2::eventgen::Generator bool mSkipNonTrackable = true; //! whether to pass non-trackable (decayed particles) to the MC stack bool mContinueMode = false; //! whether we want to continue simulation of previously inhibited tracks bool mRoundRobin = false; //! whether we want to take events from file in a round robin fashion + bool mRandomize = false; //! whether we want to randomize the order of events in the input file + unsigned int mRngSeed = 0; //! randomizer seed, 0 for random value + bool mRandomPhi = false; //! whether we want to randomize the phi angle of the particles + TGrid* mAlienInstance = nullptr; // a cached connection to TGrid (needed for Alien locations) std::unique_ptr mOrigMCEventHeader; //! the MC event header of the original file diff --git a/Generators/include/Generators/GeneratorFromO2KineParam.h b/Generators/include/Generators/GeneratorFromO2KineParam.h index c0e032f740aba..298d52ba0a1f9 100644 --- a/Generators/include/Generators/GeneratorFromO2KineParam.h +++ b/Generators/include/Generators/GeneratorFromO2KineParam.h @@ -25,13 +25,16 @@ namespace eventgen /** ** a parameter class/struct to keep the settings of ** the FromO2Kine event generator and - ** allow the user to modify them + ** allow the user to modify them **/ struct GeneratorFromO2KineParam : public o2::conf::ConfigurableParamHelper { bool skipNonTrackable = true; bool continueMode = false; bool roundRobin = false; // read events with period boundary conditions + bool randomize = false; // randomize the order of events + unsigned int rngseed = 0; // randomizer seed, 0 for random value + bool randomphi = false; // randomize phi angle std::string fileName = ""; // filename to read from - takes precedence over SimConfig if given O2ParamDef(GeneratorFromO2KineParam, "GeneratorFromO2Kine"); }; diff --git a/Generators/src/GeneratorFromFile.cxx b/Generators/src/GeneratorFromFile.cxx index df8efc29bd1e4..d3cd7b967c4d5 100644 --- a/Generators/src/GeneratorFromFile.cxx +++ b/Generators/src/GeneratorFromFile.cxx @@ -175,6 +175,13 @@ GeneratorFromO2Kine::GeneratorFromO2Kine(const char* name) setPositionUnit(1.); setTimeUnit(1.); + if (strncmp(name, "alien:/", 7) == 0) { + mAlienInstance = TGrid::Connect("alien"); + if (!mAlienInstance) { + LOG(fatal) << "Could not connect to alien, did you check the alien token?"; + return; + } + } mEventFile = TFile::Open(name); if (mEventFile == nullptr) { LOG(fatal) << "EventFile " << name << " not found"; @@ -210,6 +217,12 @@ bool GeneratorFromO2Kine::Init() mSkipNonTrackable = param.skipNonTrackable; mContinueMode = param.continueMode; mRoundRobin = param.roundRobin; + mRandomize = param.randomize; + mRngSeed = param.rngseed; + mRandomPhi = param.randomphi; + if (mRandomize) { + gRandom->SetSeed(mRngSeed); + } return true; } @@ -229,6 +242,18 @@ bool GeneratorFromO2Kine::importParticles() // It might need some adjustment to make it work with secondaries or to continue // from a kinematics snapshot + // Randomize the order of events in the input file + if (mRandomize) { + mEventCounter = gRandom->Integer(mEventsAvailable); + } + + double dPhi = 0.; + // Phi rotation + if (mRandomPhi) { + dPhi = gRandom->Uniform(2 * TMath::Pi()); + LOG(info) << "Rotating phi by " << dPhi; + } + if (mEventCounter < mEventsAvailable) { int particlecounter = 0; @@ -253,6 +278,15 @@ bool GeneratorFromO2Kine::importParticles() auto pdg = t.GetPdgCode(); auto px = t.Px(); auto py = t.Py(); + if (mRandomPhi) { + // transformation applied through rotation matrix + auto cos = TMath::Cos(dPhi); + auto sin = TMath::Sin(dPhi); + auto newPx = px * cos - py * sin; + auto newPy = px * sin + py * cos; + px = newPx; + py = newPy; + } auto pz = t.Pz(); auto vx = t.Vx(); auto vy = t.Vy(); From 41d0ccf5c3920cf70e7bfd4fc2c89259ec28cc4f Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Thu, 31 Oct 2024 09:16:51 +0100 Subject: [PATCH 0400/2205] add track extras for run 2 + store SPD tracklet flag for free vs. shared clusters (#13637) --- Framework/Core/include/Framework/AnalysisDataModel.h | 5 +++++ Framework/Core/include/Framework/DataTypes.h | 1 + 2 files changed, 6 insertions(+) diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 2a1f9dbadf67f..b19552a14672d 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -250,6 +250,7 @@ DECLARE_SOA_COLUMN(ITSChi2NCl, itsChi2NCl, float); DECLARE_SOA_COLUMN(TPCChi2NCl, tpcChi2NCl, float); //! Chi2 / cluster for the TPC track segment DECLARE_SOA_COLUMN(TRDChi2, trdChi2, float); //! Chi2 for the TRD track segment DECLARE_SOA_COLUMN(TOFChi2, tofChi2, float); //! Chi2 for the TOF track segment +DECLARE_SOA_COLUMN(ITSSignal, itsSignal, float); //! dE/dx signal in the ITS (Run 2) DECLARE_SOA_COLUMN(TPCSignal, tpcSignal, float); //! dE/dx signal in the TPC DECLARE_SOA_COLUMN(TRDSignal, trdSignal, float); //! PID signal in the TRD DECLARE_SOA_COLUMN(Length, length, float); //! Track length @@ -604,6 +605,9 @@ DECLARE_SOA_EXTENDED_TABLE(TracksExtra_000, StoredTracksExtra_000, "TRACKEXTRA", DECLARE_SOA_EXTENDED_TABLE(TracksExtra_001, StoredTracksExtra_001, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) track::v001::DetectorMap); +DECLARE_SOA_TABLE(Run2TrackExtras, "AOD", "RUN2TRACKEXTRA", + track::ITSSignal); + using StoredTracksExtra = StoredTracksExtra_001; using TracksExtra = TracksExtra_001; @@ -612,6 +616,7 @@ using TrackIU = TracksIU::iterator; using TrackCov = TracksCov::iterator; using TrackCovIU = TracksCovIU::iterator; using TrackExtra = TracksExtra::iterator; +using Run2TrackExtra = Run2TrackExtras::iterator; } // namespace aod namespace soa diff --git a/Framework/Core/include/Framework/DataTypes.h b/Framework/Core/include/Framework/DataTypes.h index 312bbbe3c6f45..92af1f79e2314 100644 --- a/Framework/Core/include/Framework/DataTypes.h +++ b/Framework/Core/include/Framework/DataTypes.h @@ -53,6 +53,7 @@ enum TrackFlags : uint32_t { }; enum TrackFlagsRun2Enum { ITSrefit = 0x1, + FreeClsSPDTracklet = 0x1, // for SPD tracklets, tracklet from cluster not used in tracking TPCrefit = 0x2, GoldenChi2 = 0x4, // NOTE Highest 4 (29..32) bits reserved for PID hypothesis From 5933a9dc61b03a92ab9b6ee75e180cbbdea2260b Mon Sep 17 00:00:00 2001 From: yuanzhe <90246048+wang-yuanzhe@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:20:39 +0100 Subject: [PATCH 0401/2205] Add new particle: Hyper Helium4Sigma (#13642) * MC: Add new particle: Hyper He4Sigma --- .../CommonConstants/PhysicsConstants.h | 5 +- .../CommonConstants/make_pdg_header.py | 1 + .../SimulationDataFormat/O2DatabasePDG.h | 13 +++++ Steer/src/O2MCApplication.cxx | 53 +++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/Common/Constants/include/CommonConstants/PhysicsConstants.h b/Common/Constants/include/CommonConstants/PhysicsConstants.h index 10351c965af3a..6a8a791cffd22 100644 --- a/Common/Constants/include/CommonConstants/PhysicsConstants.h +++ b/Common/Constants/include/CommonConstants/PhysicsConstants.h @@ -75,7 +75,8 @@ enum Pdg { kHyperTriton = 1010010030, kHyperHydrogen4 = 1010010040, kHyperHelium4 = 1010020040, - kHyperHelium5 = 1010020050 + kHyperHelium5 = 1010020050, + kHyperHelium4Sigma = 1110020040 }; /// \brief Declarations of masses for additional particles @@ -124,6 +125,7 @@ constexpr double MassHyperTriton = 2.99131; constexpr double MassHyperHydrogen4 = 3.9226; constexpr double MassHyperHelium4 = 3.9217; constexpr double MassHyperHelium5 = 4.841; +constexpr double MassHyperHelium4Sigma = 3.995; /// \brief Declarations of masses for particles in ROOT PDG_t constexpr double MassDown = 0.00467; @@ -194,6 +196,7 @@ constexpr double MassKaonNeutral = MassK0; constexpr double MassLambda = MassLambda0; constexpr double MassHyperhydrog4 = MassHyperHydrogen4; constexpr double MassHyperhelium4 = MassHyperHelium4; +constexpr double MassHyperhelium4sigma = MassHyperHelium4Sigma; // Light speed constexpr float LightSpeedCm2S = 299792458.e2; // C in cm/s diff --git a/Common/Constants/include/CommonConstants/make_pdg_header.py b/Common/Constants/include/CommonConstants/make_pdg_header.py index b71bff40b0011..5c1e4602a9fbb 100755 --- a/Common/Constants/include/CommonConstants/make_pdg_header.py +++ b/Common/Constants/include/CommonConstants/make_pdg_header.py @@ -131,6 +131,7 @@ class Pdg(Enum): kHyperHydrogen4 = 1010010040 kHyperHelium4 = 1010020040 kHyperHelium5 = 1010020050 + kHyperHelium4Sigma = 1110020040 dbPdg = ROOT.o2.O2DatabasePDG diff --git a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h index d89443150e199..3487f7a0e5aef 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h +++ b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h @@ -331,6 +331,19 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db) 2.5e-15, 6, "Ion", ionCode); } + // hyper helium 4 sigma + ionCode = 1110020040; + if (!db->GetParticle(ionCode)) { + db->AddParticle("Hyperhelium4sigma", "Hyperhelium4sigma", 3.995, kFALSE, + 2.5e-15, 6, "Ion", ionCode); + } + // anti-hyper helium 4 sigma + ionCode = -1110020040; + if (!db->GetParticle(ionCode)) { + db->AddParticle("AntiHyperhelium4sigma", "AntiHyperhelium4sigma", 3.995, kFALSE, + 2.5e-15, 6, "Ion", ionCode); + } + ionCode = 1010000020; if (!db->GetParticle(ionCode)) { db->AddParticle("LambdaNeutron", "LambdaNeutron", 2.054, kFALSE, diff --git a/Steer/src/O2MCApplication.cxx b/Steer/src/O2MCApplication.cxx index ed4735b21b46a..240e56aba28c4 100644 --- a/Steer/src/O2MCApplication.cxx +++ b/Steer/src/O2MCApplication.cxx @@ -303,6 +303,11 @@ void addSpecialParticles() //Double Anti-Hyper hydrogen 4 TVirtualMC::GetMC()->DefineParticle(-1020010040, "DoubleAntiHyperhydrogen4", kPTHadron, 4.106, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // Hyper helium 4 sigma + TVirtualMC::GetMC()->DefineParticle(1110020040, "Hyperhelium4sigma", kPTHadron, 3.995, 2.0, 8.018e-11, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // Anti-Hyper helium 4 sigma + TVirtualMC::GetMC()->DefineParticle(-1110020040, "AntiHyperhelium4sigma", kPTHadron, 3.995, 2.0, 8.018e-11, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + //Lambda-Neutron TVirtualMC::GetMC()->DefineParticle(1010000020, "LambdaNeutron", kPTNeutron, 2.054, 0.0, 2.632e-10, "Hadron", 0.0, 0, 1, 0, 0, 0, 0, 0, 2, kFALSE); @@ -748,6 +753,54 @@ void addSpecialParticles() TVirtualMC::GetMC()->SetDecayMode(-1020010040, abratio42, amode42); + // Define the 2- and 3-body phase space decay for the Hyper Helium 4 sigma + Int_t mode4s[6][3]; + Float_t bratio4s[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + bratio4s[kz] = 0.; + mode4s[kz][0] = 0; + mode4s[kz][1] = 0; + mode4s[kz][2] = 0; + } + bratio4s[0] = 20.; + mode4s[0][0] = 1000020040; // Helium4 + mode4s[0][1] = 111; // pion0 + bratio4s[1] = 40.; + mode4s[1][0] = 1000010030; // tritium + mode4s[1][2] = 2212; // proton + mode4s[1][1] = 111; // pion0 + bratio4s[2] = 40.; + mode4s[2][0] = 1000010030; // tritium + mode4s[2][2] = 2212; // pion+ + mode4s[2][1] = 2112; // neutron + + TVirtualMC::GetMC()->SetDecayMode(1110020040, bratio4s, mode4s); + + // Define the 2- and 3-body phase space decay for the Anti Hyper Helium 4 sigma + Int_t amode4s[6][3]; + Float_t abratio4s[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + abratio4s[kz] = 0.; + amode4s[kz][0] = 0; + amode4s[kz][1] = 0; + amode4s[kz][2] = 0; + } + abratio4s[0] = 50.; + amode4s[0][0] = -1000020040; // anti-Helium4 + amode4s[0][1] = 111; // pion0 + abratio4s[1] = 50.; + amode4s[1][0] = -1000010030; // anti-tritium + amode4s[1][2] = -2212; // anti-proton + amode4s[1][1] = 111; // pion0 + abratio4s[2] = 50.; + amode4s[2][0] = -1000010030; // anti-tritium + amode4s[2][2] = -211; // pion- + amode4s[2][1] = -2112; // anti-neutron + + TVirtualMC::GetMC()->SetDecayMode(-1110020040, abratio4s, amode4s); + // Define the 2-body phase space decay for the Lambda-neutron boundstate Int_t mode1[6][3]; Float_t bratio1[6]; From 688eac2d64f30a85482e4b6e741cf1cbdbc28ebc Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:15:14 +0100 Subject: [PATCH 0402/2205] DPL: hide helper in an anonymous namespace (#13644) --- .../include/Framework/StructToTuple.h | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Framework/Foundation/include/Framework/StructToTuple.h b/Framework/Foundation/include/Framework/StructToTuple.h index c600e33883a74..5748329f6a50d 100644 --- a/Framework/Foundation/include/Framework/StructToTuple.h +++ b/Framework/Foundation/include/Framework/StructToTuple.h @@ -14,23 +14,26 @@ #include #include -namespace o2::framework +namespace { -struct any_type { - template - constexpr operator T(); // non explicit -}; - template decltype(void(T{std::declval()...}), std::true_type()) - test(int); + brace_test(int); template std::false_type - test(...); + brace_test(...); +} // namespace + +namespace o2::framework +{ +struct any_type { + template + constexpr operator T(); // non explicit +}; template -struct is_braces_constructible : decltype(test(0)) { +struct is_braces_constructible : decltype(brace_test(0)) { }; #define DPL_REPEAT_0(x) From 2a20074bb7c9812420361168be79bd0f0cdf4b54 Mon Sep 17 00:00:00 2001 From: swenzel Date: Tue, 29 Oct 2024 17:31:55 +0100 Subject: [PATCH 0403/2205] Allow to specify the starting orbit as a fractional value Allow to provide the start orbit as a fraction (e.g, 32.7). This will determine the starting bunch crossing relative to the integral orbit part. In result, this allows to construct collisions starting somewhere within an orbit ... not only at the start. --- Steer/src/CollisionContextTool.cxx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Steer/src/CollisionContextTool.cxx b/Steer/src/CollisionContextTool.cxx index db61343ddf586..f94fde22ef8ac 100644 --- a/Steer/src/CollisionContextTool.cxx +++ b/Steer/src/CollisionContextTool.cxx @@ -45,7 +45,9 @@ struct Options { bool printContext = false; std::string bcpatternfile; int tfid = 0; // tfid -> used to calculate start orbit for collisions + double firstFractionalOrbit; // capture orbit and bunch crossing via decimal number uint32_t firstOrbit = 0; // first orbit in run (orbit offset) + uint32_t firstBC = 0; // first bunch crossing (relative to firstOrbit) of the first interaction; int orbitsPerTF = 256; // number of orbits per timeframe --> used to calculate start orbit for collisions bool useexistingkinematics = false; bool noEmptyTF = false; // prevent empty timeframes; the first interaction will be shifted backwards to fall within the range given by Options.orbits @@ -196,7 +198,7 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) "orbitsPerTF", bpo::value(&optvalues.orbitsPerTF)->default_value(256), "Orbits per timeframes")( "use-existing-kine", "Read existing kinematics to adjust event counts")( "timeframeID", bpo::value(&optvalues.tfid)->default_value(0), "Timeframe id of the first timeframe int this context. Allows to generate contexts for different start orbits")( - "first-orbit", bpo::value(&optvalues.firstOrbit)->default_value(0), "First orbit in the run (HBFUtils.firstOrbit)")( + "first-orbit", bpo::value(&optvalues.firstFractionalOrbit)->default_value(0), "First (fractional) orbit in the run (HBFUtils.firstOrbit + BC from decimal)")( "maxCollsPerTF", bpo::value(&optvalues.maxCollsPerTF)->default_value(-1), "Maximal number of MC collisions to put into one timeframe. By default no constraint.")( "noEmptyTF", bpo::bool_switch(&optvalues.noEmptyTF), "Enforce to have at least one collision")("configKeyValues", bpo::value(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")("with-vertices", "Assign vertices to collisions.")("timestamp", bpo::value(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring"); @@ -221,6 +223,14 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) if (vm.count("with-vertices")) { optvalues.genVertices = true; } + + // fix the first orbit and bunch crossing + // auto orbitbcpair = parseOrbitAndBC(optvalues.firstIRString); + optvalues.firstOrbit = (uint32_t)optvalues.firstFractionalOrbit; + optvalues.firstBC = (uint32_t)((optvalues.firstFractionalOrbit - 1. * optvalues.firstOrbit) * o2::constants::lhc::LHCMaxBunches); + LOG(info) << "First orbit " << optvalues.firstOrbit; + LOG(info) << "First BC " << optvalues.firstBC; + } catch (const bpo::error& e) { std::cerr << e.what() << "\n\n"; std::cerr << "Error parsing options; Available options:\n"; @@ -285,7 +295,7 @@ int main(int argc, char* argv[]) o2::InteractionTimeRecord record; // this loop makes sure that the first collision is within the range of orbits asked (if noEmptyTF is enabled) do { - sampler.setFirstIR(o2::InteractionRecord(0, orbitstart)); + sampler.setFirstIR(o2::InteractionRecord(options.firstBC, orbitstart)); sampler.init(); record = sampler.generateCollisionTime(); } while (options.noEmptyTF && usetimeframelength && record.orbit >= orbitstart + options.orbits); From 8b67fc83a778f8bc47673964043427745e9a7495 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner <48915672+matthias-kleiner@users.noreply.github.com> Date: Fri, 1 Nov 2024 08:54:34 +0100 Subject: [PATCH 0404/2205] TPC: Adding option to make timegain calib with gausian fits (#13641) * TPC: Adding option to make timegain calib with gausian fits - setting tighter default momentum range for filtering MIPs to reject kaons and electrons - adding option to write CalibdEdx to local file by converting the boost histogram to a ROOT histogram - lowering minimum dEdx to 10 for better stabillity in A16 other changes: - TPC: make calculation of dedx parallelisable * TPC: Fixing variable names --- .../DataFormatsTPC/CalibdEdxCorrection.h | 4 +- .../Detectors/TPC/src/CalibdEdxCorrection.cxx | 8 +- .../include/TPCCalibration/CalculatedEdx.h | 5 +- .../include/TPCCalibration/CalibdEdx.h | 35 +- .../include/TPCCalibration/CalibratordEdx.h | 4 +- .../TPC/calibration/src/CalculatedEdx.cxx | 76 ++-- Detectors/TPC/calibration/src/CalibdEdx.cxx | 340 +++++++++++++++++- .../TPC/calibration/src/CalibratordEdx.cxx | 2 +- Detectors/TPC/workflow/src/CalibdEdxSpec.cxx | 12 +- .../TPC/workflow/src/CalibratordEdxSpec.cxx | 7 +- .../TPC/workflow/src/MIPTrackFilterSpec.cxx | 6 +- 11 files changed, 424 insertions(+), 75 deletions(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h index 482c577ec9083..22ee80992f432 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h @@ -91,8 +91,8 @@ class CalibdEdxCorrection void clear(); - void writeToFile(std::string_view fileName) const; - void loadFromFile(std::string_view fileName); + void writeToFile(std::string_view fileName, std::string_view objName = "CalibdEdxCorrection") const; + void loadFromFile(std::string_view fileName, std::string_view objName = "CalibdEdxCorrection"); /// \param outFileName name of the output file void dumpToTree(const char* outFileName = "calib_dedx.root") const; diff --git a/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx b/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx index 1a66eb962cdf0..c8224aca5b344 100644 --- a/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx +++ b/DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx @@ -36,16 +36,16 @@ void CalibdEdxCorrection::clear() mDims = -1; } -void CalibdEdxCorrection::writeToFile(std::string_view fileName) const +void CalibdEdxCorrection::writeToFile(std::string_view fileName, std::string_view objName) const { std::unique_ptr file(TFile::Open(fileName.data(), "recreate")); - file->WriteObject(this, "CalibdEdxCorrection"); + file->WriteObject(this, objName.data()); } -void CalibdEdxCorrection::loadFromFile(std::string_view fileName) +void CalibdEdxCorrection::loadFromFile(std::string_view fileName, std::string_view objName) { std::unique_ptr file(TFile::Open(fileName.data())); - auto tmp = file->Get("CalibdEdxCorrection"); + auto tmp = file->Get(objName.data()); if (tmp != nullptr) { *this = *tmp; } diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h index 701c840e060eb..3a744d2b1cfb4 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h @@ -130,7 +130,7 @@ class CalculatedEdx float getMinChargeMaxThreshold() { return mMinChargeMaxThreshold; } /// fill missing clusters with minimum charge (method=0) or minimum charge/2 (method=1) or Landau (method=2) - void fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method); + void fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method, std::array, 5>& chargeTotROC, std::array, 5>& chargeMaxROC); /// get the truncated mean for the input track with the truncation range, charge type, region and corrections /// the cluster charge is normalized by effective length*gain, you can turn off the normalization by setting all corrections to false @@ -242,9 +242,6 @@ class CalculatedEdx CalibdEdxContainer mCalibCont; ///< calibration container std::unique_ptr mStreamer{nullptr}; ///< debug streamer - std::array, 5> mChargeTotROC; - std::array, 5> mChargeMaxROC; - CorrectdEdxDistortions mSCdEdxCorrection; ///< for space-charge correction of dE/dx }; diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h b/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h index 470e2c84b5b60..b40daa7b6e61f 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h @@ -33,6 +33,8 @@ #include #include "THn.h" +class TLinearFitter; + namespace o2::tpc { @@ -74,7 +76,7 @@ class CalibdEdx /// \param angularBins number of bins for Tgl and Snp /// \param fitSnp enable Snp correction - CalibdEdx(int dEdxBins = 60, float mindEdx = 20, float maxdEdx = 90, int angularBins = 36, bool fitSnp = false); + CalibdEdx(int dEdxBins = 70, float mindEdx = 10, float maxdEdx = 90, int angularBins = 36, bool fitSnp = false); void setCuts(const TrackCuts& cuts) { mCuts = cuts; } void setApplyCuts(bool apply) { mApplyCuts = apply; } @@ -124,7 +126,8 @@ class CalibdEdx /// Compute MIP position from dEdx histograms and save result in the correction container. /// To retrieve the correction call `CalibdEdx::getCalib()` - void finalize(); + /// \param useGausFits make gaussian fits of dEdx vs tgl instead of fitting the mean dEdx + void finalize(const bool useGausFits = true); /// Return calib data histogram const Hist& getHist() const { return mHist; } @@ -170,6 +173,17 @@ class CalibdEdx constexpr static float scaleTgl(float tgl, GEMstack rocType) { return tgl / conf_dedx_corr::TglScale[rocType]; } constexpr static float recoverTgl(float scaledTgl, GEMstack rocType) { return scaledTgl * conf_dedx_corr::TglScale[rocType]; } + /// dump this object to a file - the boost histogram is converted to a ROOT histogram - + void dumpToFile(const char* outFile, const char* outName) const; + + /// read the object from a file + static CalibdEdx readFromFile(const char* inFile, const char* inName); + + /// set lower and upper range in units of sigma which are used for the gaussian fits + /// \param lowerSigma low sigma range + /// \param upperSigma upper sigma range + void setSigmaFitRange(const float lowerSigma, const float upperSigma); + private: // ATTENTION: Adjust copy constructor bool mFitSnp{}; @@ -182,15 +196,26 @@ class CalibdEdx float mFitLowCutFactor = 1.5; ///< dEdx cut multiplier for the lower dE/dx range int mFitPasses = 3; ///< number of fit passes used to remove electron tracks TFIDInfo mTFID{}; ///< current TFID + float mSigmaUpper = 1.; ///< mSigma*sigma_gaus used for cutting electrons in case gaussian fits are performed + float mSigmaLower = 1.5; ///< mSigma*sigma_gaus used for cutting electrons in case gaussian fits are performed - Hist mHist; ///< dEdx multidimensional histogram + Hist mHist; /// mDebugOutputStreamer; ///< Debug output streamer - ClassDefNV(CalibdEdx, 4); + std::unique_ptr mDebugOutputStreamer; /// values) { mElectronCut = values; } void setMaterialType(o2::base::Propagator::MatCorrType materialType) { mMatType = materialType; } + void setMakeGaussianFits(const bool makeGaussianFits) { mMakeGaussianFits = makeGaussianFits; } /// \brief Check if there are enough data to compute the calibration. /// \return false if any of the histograms has less entries than mMinEntries @@ -117,6 +118,7 @@ class CalibratordEdx final : public o2::calibration::TimeSlotCalibration mElectronCut{}; ///< Values passed to CalibdEdx::setElectronCut TrackCuts mCuts; ///< Cut object o2::base::Propagator::MatCorrType mMatType{}; ///< material type for track propagation + bool mMakeGaussianFits{}; ///< fit mean of gaussian fits instead of mean dedx TFinterval mTFIntervals; ///< start and end time frame IDs of each calibration time slots TimeInterval mTimeIntervals; ///< start and end times of each calibration time slots @@ -124,7 +126,7 @@ class CalibratordEdx final : public o2::calibration::TimeSlotCalibration mDebugOutputStreamer; ///< Debug output streamer - ClassDefOverride(CalibratordEdx, 2); + ClassDefOverride(CalibratordEdx, 3); }; } // namespace o2::tpc diff --git a/Detectors/TPC/calibration/src/CalculatedEdx.cxx b/Detectors/TPC/calibration/src/CalculatedEdx.cxx index 9809cc454e94f..2ac3b44938bce 100644 --- a/Detectors/TPC/calibration/src/CalculatedEdx.cxx +++ b/Detectors/TPC/calibration/src/CalculatedEdx.cxx @@ -53,7 +53,7 @@ void CalculatedEdx::setRefit(const unsigned int nHbfPerTf) mRefit = std::make_unique(mClusterIndex, &mTPCCorrMapsHelper, mFieldNominalGPUBz, mTPCTrackClIdxVecInput->data(), nHbfPerTf, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size()); } -void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method) +void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method, std::array, 5>& chargeTotROC, std::array, 5>& chargeMaxROC) { if (method != 0 && method != 1) { LOGP(info, "Unrecognized subthreshold cluster treatment. Not adding virtual charges to the track!"); @@ -65,11 +65,11 @@ void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeT float chargeTot = (method == 1) ? minChargeTot / 2.f : minChargeTot; float chargeMax = (method == 1) ? minChargeMax / 2.f : minChargeMax; - mChargeTotROC[roc].emplace_back(chargeTot); - mChargeTotROC[4].emplace_back(chargeTot); + chargeTotROC[roc].emplace_back(chargeTot); + chargeTotROC[4].emplace_back(chargeTot); - mChargeMaxROC[roc].emplace_back(chargeMax); - mChargeMaxROC[4].emplace_back(chargeMax); + chargeMaxROC[roc].emplace_back(chargeMax); + chargeMaxROC[4].emplace_back(chargeMax); } } } @@ -82,17 +82,13 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl int nClsROC[4] = {0, 0, 0, 0}; int nClsSubThreshROC[4] = {0, 0, 0, 0}; - mChargeTotROC[0].clear(); - mChargeTotROC[1].clear(); - mChargeTotROC[2].clear(); - mChargeTotROC[3].clear(); - mChargeTotROC[4].clear(); - - mChargeMaxROC[0].clear(); - mChargeMaxROC[1].clear(); - mChargeMaxROC[2].clear(); - mChargeMaxROC[3].clear(); - mChargeMaxROC[4].clear(); + const int nType = 5; + std::array, nType> chargeTotROC; + std::array, nType> chargeMaxROC; + for (int i = 0; i < nType; ++i) { + chargeTotROC[i].reserve(Mapper::PADROWS); + chargeMaxROC[i].reserve(Mapper::PADROWS); + } // debug vectors std::vector excludeClVector; @@ -356,25 +352,25 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl } if (stack == GEMstack::IROCgem) { - mChargeTotROC[0].emplace_back(chargeTot); - mChargeMaxROC[0].emplace_back(chargeMax); + chargeTotROC[0].emplace_back(chargeTot); + chargeMaxROC[0].emplace_back(chargeMax); nClsROC[0]++; } else if (stack == GEMstack::OROC1gem) { - mChargeTotROC[1].emplace_back(chargeTot); - mChargeMaxROC[1].emplace_back(chargeMax); + chargeTotROC[1].emplace_back(chargeTot); + chargeMaxROC[1].emplace_back(chargeMax); nClsROC[1]++; } else if (stack == GEMstack::OROC2gem) { - mChargeTotROC[2].emplace_back(chargeTot); - mChargeMaxROC[2].emplace_back(chargeMax); + chargeTotROC[2].emplace_back(chargeTot); + chargeMaxROC[2].emplace_back(chargeMax); nClsROC[2]++; } else if (stack == GEMstack::OROC3gem) { - mChargeTotROC[3].emplace_back(chargeTot); - mChargeMaxROC[3].emplace_back(chargeMax); + chargeTotROC[3].emplace_back(chargeTot); + chargeMaxROC[3].emplace_back(chargeMax); nClsROC[3]++; }; - mChargeTotROC[4].emplace_back(chargeTot); - mChargeMaxROC[4].emplace_back(chargeMax); + chargeTotROC[4].emplace_back(chargeTot); + chargeMaxROC[4].emplace_back(chargeMax); // for debugging if (mDebug) { @@ -418,7 +414,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl // fill subthreshold clusters if not excluded if (((clusterMask & ClusterFlags::ExcludeSubthresholdCl) == ClusterFlags::None)) { - fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, subthresholdMethod); + fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, subthresholdMethod, chargeTotROC, chargeMaxROC); } } else { output.NHitsIROC = nClsROC[0]; @@ -428,21 +424,21 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl } // copy corrected cluster charges - auto chargeTotVector = mChargeTotROC[4]; - auto chargeMaxVector = mChargeMaxROC[4]; + auto chargeTotVector = mDebug ? chargeTotROC[4] : std::vector(); + auto chargeMaxVector = mDebug ? chargeMaxROC[4] : std::vector(); // calculate dEdx - output.dEdxTotIROC = getTruncMean(mChargeTotROC[0], low, high); - output.dEdxTotOROC1 = getTruncMean(mChargeTotROC[1], low, high); - output.dEdxTotOROC2 = getTruncMean(mChargeTotROC[2], low, high); - output.dEdxTotOROC3 = getTruncMean(mChargeTotROC[3], low, high); - output.dEdxTotTPC = getTruncMean(mChargeTotROC[4], low, high); - - output.dEdxMaxIROC = getTruncMean(mChargeMaxROC[0], low, high); - output.dEdxMaxOROC1 = getTruncMean(mChargeMaxROC[1], low, high); - output.dEdxMaxOROC2 = getTruncMean(mChargeMaxROC[2], low, high); - output.dEdxMaxOROC3 = getTruncMean(mChargeMaxROC[3], low, high); - output.dEdxMaxTPC = getTruncMean(mChargeMaxROC[4], low, high); + output.dEdxTotIROC = getTruncMean(chargeTotROC[0], low, high); + output.dEdxTotOROC1 = getTruncMean(chargeTotROC[1], low, high); + output.dEdxTotOROC2 = getTruncMean(chargeTotROC[2], low, high); + output.dEdxTotOROC3 = getTruncMean(chargeTotROC[3], low, high); + output.dEdxTotTPC = getTruncMean(chargeTotROC[4], low, high); + + output.dEdxMaxIROC = getTruncMean(chargeMaxROC[0], low, high); + output.dEdxMaxOROC1 = getTruncMean(chargeMaxROC[1], low, high); + output.dEdxMaxOROC2 = getTruncMean(chargeMaxROC[2], low, high); + output.dEdxMaxOROC3 = getTruncMean(chargeMaxROC[3], low, high); + output.dEdxMaxTPC = getTruncMean(chargeMaxROC[4], low, high); // for debugging if (mDebug) { diff --git a/Detectors/TPC/calibration/src/CalibdEdx.cxx b/Detectors/TPC/calibration/src/CalibdEdx.cxx index 114081f57c2f0..bf86db78664d7 100644 --- a/Detectors/TPC/calibration/src/CalibdEdx.cxx +++ b/Detectors/TPC/calibration/src/CalibdEdx.cxx @@ -21,6 +21,7 @@ #include #include #include +#include // o2 includes #include "CommonConstants/PhysicsConstants.h" @@ -31,6 +32,7 @@ #include "Framework/Logger.h" #include "TPCBase/ParameterGas.h" #include "TPCBase/Utils.h" +#include "CommonUtils/BoostHistogramUtils.h" // root includes #include "TFile.h" @@ -139,7 +141,7 @@ void CalibdEdx::fill(const TrackTPC& track) static bool reported = false; if (!reported && mCalibIn.getDims() >= 0) { const auto meanParamTot = mCalibIn.getMeanParams(ChargeType::Tot); - LOGP(info, "Undoing previously apllied corrections with mean qTot Params {}", utils::elementsToString(meanParamTot)); + LOGP(info, "Undoing previously applied corrections with mean qTot Params {}", utils::elementsToString(meanParamTot)); reported = true; } @@ -179,9 +181,11 @@ void CalibdEdx::merge(const CalibdEdx* other) template void fitHist(const Hist& hist, CalibdEdxCorrection& corr, TLinearFitter& fitter, - const float dEdxCut, const float dEdxLowCutFactor, const int passes, const CalibdEdxCorrection* stackMean = nullptr) + const float dEdxCut, const float dEdxLowCutFactor, const int passes, const CalibdEdxCorrection* stackMean = nullptr, o2::utils::TreeStreamRedirector* streamer = nullptr) { + using timer = std::chrono::high_resolution_clock; using ax = CalibdEdx::Axis; + auto start = timer::now(); // number of bins per stack int stackBins = 1; @@ -242,6 +246,28 @@ void fitHist(const Hist& hist, CalibdEdxCorrection& corr, TLinearFitter& fitter, } const double error = 1. / sqrt(counts); fitter.AddPoint(inputs, dEdx, error); + + if (streamer) { + float oldCorr = corr.getCorrection(id, charge, inputs[0], inputs[1]); + float lowerCut = (1.f - dEdxLowCutFactor * dEdxCut) * oldCorr; + float upperCut = (1.f + dEdxCut) * oldCorr; + + (*streamer) << "fit_standard" + << "dedx=" << dEdx + << "itgl=" << hist.axis(ax::Tgl).index(entry->bin(ax::Tgl).center()) + << "snp=" << inputs[1] + << "iter=" << fitPass + << "ifit=" << fit + << "bin=" << bin + << "isector=" << int(id.sector) + << "istack=" << int(id.type) + << "icharge=" << int(charge) + << "counts=" << counts + << "oldCorr=" << oldCorr + << "lowerCut=" << lowerCut + << "upperCut=" << upperCut + << "\n"; + } } } fitter.Eval(); @@ -276,9 +302,201 @@ void fitHist(const Hist& hist, CalibdEdxCorrection& corr, TLinearFitter& fitter, id.sector, int(id.type), int(charge), fitPass, (float)outliers / (float)entries * 100, entries, fitter.GetNpoints(), params[0]); } } + auto stop = timer::now(); + std::chrono::duration time = stop - start; + LOGP(info, "Calibration fits took: {}", time.count()); } -void CalibdEdx::finalize() +template +auto ProjectBoostHistoXFast(const Hist& hist, std::vector& bin_indices, int axis) +{ + const unsigned int nbins = hist.axis(axis).size(); + const double binStartX = hist.axis(axis).bin(0).lower(); + const double binEndX = hist.axis(axis).bin(nbins - 1).upper(); + auto histoProj = boost::histogram::make_histogram(CalibdEdx::FloatAxis(nbins, binStartX, binEndX)); + + // loop over all bins of the requested axis + for (int i = 0; i < nbins; ++i) { + // setting bin of the requested axis + bin_indices[axis] = i; + + // access the bin content specified by bin_indices + histoProj.at(i) = hist.at(bin_indices); + } + + return histoProj; +} + +void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, const CalibdEdxCorrection* stackMean) +{ + using timer = std::chrono::high_resolution_clock; + using ax = CalibdEdx::Axis; + auto start = timer::now(); + const bool projSectors = stackMean != nullptr; + constexpr int sectors = SECTORSPERSIDE * SIDES; + for (int iSnp = 0; iSnp < mHist.axis(ax::Snp).size(); ++iSnp) { + for (int iSec = 0; iSec < mHist.axis(ax::Sector).size(); ++iSec) { + for (int iStack = 0; iStack < mHist.axis(ax::Stack).size(); ++iStack) { + for (int iCharge = 0; iCharge < mHist.axis(ax::Charge).size(); ++iCharge) { + + fitter.ClearPoints(); + StackID id{}; + id.type = static_cast(mHist.axis(ax::Stack).bin(iStack).center()); + id.sector = static_cast(mHist.axis(ax::Sector).bin(iSec).center()); + const auto charge = static_cast(mHist.axis(ax::Charge).bin(iCharge).center()); + int entries = 0; + + for (int iTgl = 0; iTgl < mHist.axis(ax::Tgl).size(); ++iTgl) { + // calculate sigma vs tgl in first iteration + // apply cut in n sigma in second iteration + float sigma_vs_tgl = 0; + float mean_vs_tgl = 0; + std::vector bin_indices(ax::Size); + bin_indices[ax::Tgl] = iTgl; + bin_indices[ax::Snp] = iSnp; + bin_indices[ax::Sector] = iSec; + bin_indices[ax::Stack] = iStack; + bin_indices[ax::Charge] = iCharge; + + for (int iter = 0; iter < 2; ++iter) { + auto boostHist1d = ProjectBoostHistoXFast(mHist, bin_indices, ax::dEdx); + + float lowerCut = 0; + float upperCut = 0; + + // make gaussian fit + if (iter == 0) { + int maxElementIndex = std::max_element(boostHist1d.begin(), boostHist1d.end()) - boostHist1d.begin() - 1; + if (maxElementIndex < 0) { + maxElementIndex = 0; + } + float maxElementCenter = 0.5 * (boostHist1d.axis(0).bin(maxElementIndex).upper() + boostHist1d.axis(0).bin(maxElementIndex).lower()); + + lowerCut = (1.f - mFitLowCutFactor * mFitCut) * maxElementCenter; + upperCut = (1.f + mFitCut) * maxElementCenter; + } else { + lowerCut = mean_vs_tgl - sigma_vs_tgl * mSigmaLower; + upperCut = mean_vs_tgl + sigma_vs_tgl * mSigmaUpper; + } + + // Restrict fit range to maximum +- restrictFitRangeToMax + double max_range = mHist.axis(ax::dEdx).bin(mHist.axis(ax::dEdx).size() - 1).lower(); + double min_range = mHist.axis(ax::dEdx).bin(0).lower(); + if ((upperCut <= lowerCut) || (lowerCut > max_range) || (upperCut < min_range)) { + break; + } + + // remove up and low bins + boostHist1d = boost::histogram::algorithm::reduce(boostHist1d, boost::histogram::algorithm::shrink(lowerCut, upperCut)); + + try { + auto fitValues = o2::utils::fitGaus(boostHist1d.begin(), boostHist1d.end(), o2::utils::BinCenterView(boostHist1d.axis(0).begin()), false); + + // add the mean from gaus fit to the fitter + double dEdx = fitValues[1]; + double inputs[] = { + CalibdEdx::recoverTgl(mHist.axis(ax::Tgl).bin(iTgl).center(), id.type), + mHist.axis(ax::Snp).bin(iSnp).center()}; + + // scale fitted dEdx using the stacks mean + if (stackMean != nullptr) { + dEdx /= stackMean->getCorrection(id, charge); + } + + const auto fitNPoints = fitValues[3]; + const float sigma = fitValues[2]; + const double fitMeanErr = (fitNPoints > 0) ? (sigma / std::sqrt(fitNPoints)) : -1; + if (iter == 0) { + sigma_vs_tgl = sigma; + mean_vs_tgl = dEdx; + } else { + entries += fitNPoints; + if (fitMeanErr > 0) { + fitter.AddPoint(inputs, dEdx, fitMeanErr); + } + } + + if (mDebugOutputStreamer) { + const int nbinsx = boostHist1d.axis(0).size(); + std::vector binCenter(nbinsx); + std::vector dedx(nbinsx); + for (int ix = 0; ix < nbinsx; ix++) { + binCenter[ix] = boostHist1d.axis(0).bin(ix).center(); + dedx[ix] = boostHist1d.at(ix); + } + + (*mDebugOutputStreamer) << "fit_gaus" + << "fitConstant=" << fitValues[0] + << "fitMean=" << dEdx + << "fitMeanErr=" << fitMeanErr + << "fitSigma=" << sigma_vs_tgl + << "fitSum=" << fitNPoints + << "dedx=" << binCenter + << "counts=" << dedx + << "itgl=" << bin_indices[1] + << "isnp=" << bin_indices[2] + << "isector=" << bin_indices[3] + << "istack=" << bin_indices[4] + << "icharge=" << bin_indices[5] + << "upperCut=" << upperCut + << "lowerCut=" << lowerCut + << "mFitCut=" << mFitCut + << "mFitLowCutFactor=" << mFitLowCutFactor + << "iter=" << iter + << "mSigmaLower=" << mSigmaLower + << "mSigmaUpper=" << mSigmaUpper + << "\n"; + } + } catch (o2::utils::FitGausError_t err) { + LOGP(warning, "Skipping bin: iTgl {} iSnp {} iSec {} iStack {} iCharge {} iter {}", iTgl, iSnp, iSec, iStack, iCharge, iter); + LOG(warning) << createErrorMessageFitGaus(err); + break; + } + } + } + + const int fitStatus = fitter.Eval(); + if (fitStatus > 0) { + LOGP(warning, "Fit failed"); + continue; + } + + const auto paramSize = CalibdEdxCorrection::ParamSize; + float params[paramSize] = {0}; + for (int param = 0; param < fitter.GetNumberFreeParameters(); ++param) { + params[param] = fitter.GetParameter(param); + } + + // with a projected hist, copy the fit to every sector + if (projSectors) { + for (int i = 0; i < sectors; ++i) { + id.sector = i; + const float mean = stackMean->getCorrection(id, charge); + + // rescale the params to get the true correction + float scaledParams[paramSize]; + for (int i = 0; i < paramSize; ++i) { + scaledParams[i] = params[i] * mean; + } + corr.setParams(id, charge, scaledParams); + corr.setChi2(id, charge, fitter.GetChisquare()); + corr.setEntries(id, charge, entries); + } + } else { + corr.setParams(id, charge, params); + corr.setChi2(id, charge, fitter.GetChisquare()); + corr.setEntries(id, charge, entries); + } + } + } + } + } + auto stop = timer::now(); + std::chrono::duration time = stop - start; + LOGP(info, "Calibration fits took: {}", time.count()); +} + +void CalibdEdx::finalize(const bool useGausFits) { const float entries = minStackEntries(); mCalib.clear(); @@ -295,11 +513,15 @@ void CalibdEdx::finalize() fitter.SetFormula("1"); mCalib.setDims(0); } - LOGP(info, "Fitting {}D dE/dx correction for GEM stacks", mCalib.getDims()); + LOGP(info, "Fitting {}D dE/dx correction for GEM stacks with gaussian fits {}", mCalib.getDims(), useGausFits); // if entries below minimum sector threshold, integrate all sectors if (mCalib.getDims() == 0 || entries >= mSectorThreshold) { - fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses); + if (!useGausFits) { + fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses, nullptr, mDebugOutputStreamer.get()); + } else { + fitHistGaus(fitter, mCalib, nullptr); + } } else { LOGP(info, "Integrating GEM stacks sectors in dE/dx correction due to low statistics"); @@ -308,10 +530,17 @@ void CalibdEdx::finalize() meanCorr.setDims(0); TLinearFitter meanFitter(0); meanFitter.SetFormula("1"); - fitHist(mHist, meanCorr, meanFitter, mFitCut, mFitLowCutFactor, mFitPasses); + if (!useGausFits) { + fitHist(mHist, meanCorr, meanFitter, mFitCut, mFitLowCutFactor, mFitPasses); - // get higher dimension corrections with projected sectors - fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses, &meanCorr); + // get higher dimension corrections with projected sectors + fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses, &meanCorr); + } else { + fitHistGaus(meanFitter, meanCorr, nullptr); + + // get higher dimension corrections with projected sectors + fitHistGaus(fitter, mCalib, &meanCorr); + } } } @@ -330,7 +559,7 @@ bool CalibdEdx::hasEnoughData(float minEntries) const return minStackEntries() >= minEntries; } -THnF* CalibdEdx::getRootHist() const +THnF* CalibdEdx::getTHnF() const { std::vector bins{}; std::vector axisMin{}; @@ -346,6 +575,13 @@ THnF* CalibdEdx::getRootHist() const } auto hn = new THnF("hdEdxMIP", "MIP dEdx per GEM stack", histRank, bins.data(), axisMin.data(), axisMax.data()); + return hn; +} + +THnF* CalibdEdx::getRootHist() const +{ + auto hn = getTHnF(); + const size_t histRank = mHist.rank(); std::vector xs(histRank); for (auto&& entry : bh::indexed(mHist)) { if (*entry == 0) { @@ -360,6 +596,60 @@ THnF* CalibdEdx::getRootHist() const return hn; } +void CalibdEdx::setFromRootHist(const THnF* hist) +{ + // Get the number of dimensions + int n_dim = hist->GetNdimensions(); + + // Vectors to store axis ranges and bin counts + std::vector> axis_ranges(n_dim); // Min and max of each axis + std::vector bin_counts(n_dim); // Number of bins in each dimension + + // Loop over each dimension to extract the bin edges and ranges + for (int dim = 0; dim < n_dim; ++dim) { + TAxis* axis = hist->GetAxis(dim); + int bins = axis->GetNbins(); + double min = axis->GetXmin(); + double max = axis->GetXmax(); + bin_counts[dim] = bins; + axis_ranges[dim] = {min, max}; // Store the min and max range for the axis + } + + // Define a Boost histogram using the bin edges + mHist = bh::make_histogram( + FloatAxis(bin_counts[0], axis_ranges[0].first, axis_ranges[0].second, "dEdx"), // dE/dx + FloatAxis(bin_counts[1], axis_ranges[1].first, axis_ranges[1].second, "Tgl"), // Tgl + FloatAxis(bin_counts[2], axis_ranges[2].first, axis_ranges[2].second, "Snp"), // snp + IntAxis(0, bin_counts[3], "sector"), // sector + IntAxis(0, bin_counts[4], "stackType"), // stack type + IntAxis(0, bin_counts[5], "charge") // charge type + ); + + // Fill the Boost histogram with the bin contents from the ROOT histogram + int total_bins = hist->GetNbins(); + for (int bin = 0; bin < total_bins; ++bin) { + std::vector bin_indices(n_dim); + double content = hist->GetBinContent(bin, bin_indices.data()); // Get bin coordinates + + // Check if any coordinate is in the underflow (0) or overflow (nbins+1) bins + bool is_underflow_or_overflow = false; + for (int dim = 0; dim < n_dim; ++dim) { + if ((bin_indices[dim] == 0) || (bin_indices[dim] == bin_counts[dim] + 1)) { + is_underflow_or_overflow = true; + break; + } + } + + // Skip underflow/overflow bins + if (is_underflow_or_overflow) { + continue; + } + + // Assign the content to the corresponding bin in the Boost histogram + mHist.at(bin_indices[0] - 1, bin_indices[1] - 1, bin_indices[2] - 1, bin_indices[3] - 1, bin_indices[4] - 1, bin_indices[5] - 1) = content; + } +} + void CalibdEdx::print() const { const int uniqueEntries = std::accumulate(mHist.begin(), mHist.end(), 0.0) / GEMSTACKSPERSECTOR / 2; @@ -418,3 +708,35 @@ void CalibdEdx::finalizeDebugOutput() const mDebugOutputStreamer->Close(); } } + +void CalibdEdx::dumpToFile(const char* outFile, const char* outName) const +{ + TFile f(outFile, "RECREATE"); + f.WriteObject(this, outName); + const auto* thn = getRootHist(); + f.WriteObject(thn, "histogram_data"); +} + +CalibdEdx CalibdEdx::readFromFile(const char* inFile, const char* inName) +{ + TFile f(inFile, "READ"); + auto* obj = (CalibdEdx*)f.Get(inName); + if (!obj) { + CalibdEdx calTmp; + return calTmp; + } + CalibdEdx cal(*obj); + THnF* hTmp = (THnF*)f.Get("histogram_data"); + if (!hTmp) { + CalibdEdx calTmp; + return calTmp; + } + cal.setFromRootHist(hTmp); + return cal; +} + +void CalibdEdx::setSigmaFitRange(const float lowerSigma, const float upperSigma) +{ + mSigmaUpper = upperSigma; + mSigmaLower = lowerSigma; +} diff --git a/Detectors/TPC/calibration/src/CalibratordEdx.cxx b/Detectors/TPC/calibration/src/CalibratordEdx.cxx index 15a7335ef90d3..7599e2f5d4472 100644 --- a/Detectors/TPC/calibration/src/CalibratordEdx.cxx +++ b/Detectors/TPC/calibration/src/CalibratordEdx.cxx @@ -40,7 +40,7 @@ void CalibratordEdx::finalizeSlot(Slot& slot) // compute calibration values from histograms CalibdEdx* container = slot.getContainer(); - container->finalize(); + container->finalize(mMakeGaussianFits); container->finalizeDebugOutput(); mCalibs.push_back(container->getCalib()); diff --git a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx index 046585e8c96b6..a32a4a1bb3089 100644 --- a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx @@ -57,6 +57,7 @@ class CalibdEdxDevice : public Task const auto maxdEdx = ic.options().get("max-dedx"); const auto angularBins = ic.options().get("angularbins"); const auto fitSnp = ic.options().get("fit-snp"); + mMakeGaussianFits = !ic.options().get("disable-gaussian-fits"); mDumpToFile = ic.options().get("file-dump"); @@ -103,12 +104,13 @@ class CalibdEdxDevice : public Task void endOfStream(EndOfStreamContext& eos) final { LOGP(info, "Finalizing calibration"); - mCalib->finalize(); + mCalib->finalize(mMakeGaussianFits); mCalib->print(); sendOutput(eos.outputs()); if (mDumpToFile) { - mCalib->getCalib().writeToFile("calibdEdx.root"); + mCalib->dumpToFile("calibdEdx_Obj.root", "calib"); + mCalib->getCalib().writeToFile("calibdEdx.root", "ccdb_object"); if (mDumpToFile > 1) { mCalib->writeTTree("calibdEdx.histo.tree.root"); } @@ -141,6 +143,7 @@ class CalibdEdxDevice : public Task uint64_t mRunNumber{0}; ///< processed run number uint64_t mTimeStampStart{0}; ///< time stamp for first TF for CCDB output std::unique_ptr mCalib; + bool mMakeGaussianFits{true}; ///< make gaussian fits or take the mean }; DataProcessorSpec getCalibdEdxSpec(const o2::base::Propagator::MatCorrType matType) @@ -175,11 +178,12 @@ DataProcessorSpec getCalibdEdxSpec(const o2::base::Propagator::MatCorrType matTy {"fit-threshold", VariantType::Float, 0.2f, {"dEdx width around the MIP peak used in the fit"}}, {"fit-threshold-low-factor", VariantType::Float, 1.5f, {"factor for low dEdx width around the MIP peak used in the fit"}}, - {"dedxbins", VariantType::Int, 60, {"number of dEdx bins"}}, - {"min-dedx", VariantType::Float, 20.0f, {"minimum value for dEdx histograms"}}, + {"dedxbins", VariantType::Int, 70, {"number of dEdx bins"}}, + {"min-dedx", VariantType::Float, 10.0f, {"minimum value for dEdx histograms"}}, {"max-dedx", VariantType::Float, 90.0f, {"maximum value for dEdx histograms"}}, {"angularbins", VariantType::Int, 36, {"number of angular bins: Tgl and Snp"}}, {"fit-snp", VariantType::Bool, false, {"enable Snp correction"}}, + {"disable-gaussian-fits", VariantType::Bool, false, {"disable calibration with gaussian fits and use mean instead"}}, {"file-dump", VariantType::Int, 0, {"directly dump calibration to file"}}}}; } diff --git a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx index 70b27443018bb..6e477084d992c 100644 --- a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx @@ -69,6 +69,7 @@ class CalibratordEdxDevice : public Task const auto dumpData = ic.options().get("file-dump"); const auto dumpHistograms = ic.options().get("dump-histograms"); const auto trackDebug = ic.options().get("track-debug"); + const bool makeGaussianFits = !ic.options().get("disable-gaussian-fits"); mCalibrator = std::make_unique(); mCalibrator->setHistParams(dEdxBins, mindEdx, maxdEdx, angularBins, fitSnp); @@ -82,6 +83,7 @@ class CalibratordEdxDevice : public Task mCalibrator->setMaterialType(mMatType); mCalibrator->setDumpHistograms(dumpHistograms); mCalibrator->setTrackDebug(trackDebug); + mCalibrator->setMakeGaussianFits(makeGaussianFits); if (dumpData) { const auto dumpDataName = ic.options().get("file-dump-name"); @@ -218,8 +220,8 @@ DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType {"fit-threshold", VariantType::Float, 0.2f, {"dEdx width around the MIP peak used in the fit"}}, {"fit-threshold-low-factor", VariantType::Float, 1.5f, {"factor for low dEdx width around the MIP peak used in the fit"}}, - {"dedxbins", VariantType::Int, 60, {"number of dEdx bins"}}, - {"min-dedx", VariantType::Float, 20.0f, {"minimum value for dEdx histograms"}}, + {"dedxbins", VariantType::Int, 70, {"number of dEdx bins"}}, + {"min-dedx", VariantType::Float, 10.0f, {"minimum value for dEdx histograms"}}, {"max-dedx", VariantType::Float, 90.0f, {"maximum value for dEdx histograms"}}, {"angularbins", VariantType::Int, 36, {"number of angular bins: Tgl and Snp"}}, {"fit-snp", VariantType::Bool, false, {"enable Snp correction"}}, @@ -228,6 +230,7 @@ DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType {"file-dump", VariantType::Bool, false, {"directly dump calibration to file"}}, {"file-dump-name", VariantType::String, "calibratordEdx.root", {"name of the file dump output file"}}, {"track-debug", VariantType::Bool, false, {"track dEdx debugging"}}, + {"disable-gaussian-fits", VariantType::Bool, false, {"disable calibration with gaussian fits and use mean instead"}}, }}; } diff --git a/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx b/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx index 7d8d2439e7295..e3970012d1373 100644 --- a/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx +++ b/Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx @@ -163,9 +163,9 @@ DataProcessorSpec getMIPTrackFilterSpec() outputs, adaptFromTask(), Options{ - {"min-momentum", VariantType::Double, 0.3, {"minimum momentum cut"}}, - {"max-momentum", VariantType::Double, 0.7, {"maximum momentum cut"}}, - {"min-dedx", VariantType::Double, 20., {"minimum dEdx cut"}}, + {"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}}, + {"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}}, + {"min-dedx", VariantType::Double, 10., {"minimum dEdx cut"}}, {"max-dedx", VariantType::Double, 200., {"maximum dEdx cut"}}, {"min-clusters", VariantType::Int, 60, {"minimum number of clusters in a track"}}, {"processEveryNthTF", VariantType::Int, 1, {"Using only a fraction of the data: 1: Use every TF, 10: Process only every tenth TF."}}, From 42122b5e8eca31c4cb17f0ca1b2bbc08a9e1d1bc Mon Sep 17 00:00:00 2001 From: Marvin Hemmer Date: Wed, 30 Oct 2024 18:27:55 +0100 Subject: [PATCH 0405/2205] [EMCAL-670] EMCAL Clusterizer: change behaviour for no gradient cut - Changed `getClusterFromNeighbours` so that when gradient gut is off, it now still adds neighbouring cells. Before this change when gradient cut was set to `false` all clusters were single cell cluster made only from the seed cell. --- Detectors/EMCAL/reconstruction/src/Clusterizer.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Detectors/EMCAL/reconstruction/src/Clusterizer.cxx b/Detectors/EMCAL/reconstruction/src/Clusterizer.cxx index cc5624eacba54..96541aaff09f4 100644 --- a/Detectors/EMCAL/reconstruction/src/Clusterizer.cxx +++ b/Detectors/EMCAL/reconstruction/src/Clusterizer.cxx @@ -68,12 +68,13 @@ void Clusterizer::getClusterFromNeighbours(std::vectorgetEnergy() > mInputMap[row][column].mInput->getEnergy() + mGradientCut)) { - if (not(TMath::Abs(mInputMap[row + rowDiffs[dir]][column + colDiffs[dir]].mInput->getTimeStamp() - mInputMap[row][column].mInput->getTimeStamp()) > mTimeCut)) { - getClusterFromNeighbours(clusterInputs, row + rowDiffs[dir], column + colDiffs[dir]); - // Add the cell/digit to the current cluster -- if we end up here, the selected cluster fulfills the condition - clusterInputs.emplace_back(mInputMap[row + rowDiffs[dir]][column + colDiffs[dir]]); - } + if (mDoEnergyGradientCut && (mInputMap[row + rowDiffs[dir]][column + colDiffs[dir]].mInput->getEnergy() > mInputMap[row][column].mInput->getEnergy() + mGradientCut)) { + continue; + } + if (not(TMath::Abs(mInputMap[row + rowDiffs[dir]][column + colDiffs[dir]].mInput->getTimeStamp() - mInputMap[row][column].mInput->getTimeStamp()) > mTimeCut)) { + getClusterFromNeighbours(clusterInputs, row + rowDiffs[dir], column + colDiffs[dir]); + // Add the cell/digit to the current cluster -- if we end up here, the selected cluster fulfills the condition + clusterInputs.emplace_back(mInputMap[row + rowDiffs[dir]][column + colDiffs[dir]]); } } } From d740a69baf572603b81eaa0b3d26208957b6b2c4 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 1 Nov 2024 09:18:12 +0100 Subject: [PATCH 0406/2205] Update CODEOWNERS --- CODEOWNERS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 91af5306f247a..603895b8b8ce4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,7 +18,7 @@ /Common/Constants @shahor02 /Common/Field @shahor02 /Common/MathUtils @shahor02 -/Common/SimConfig @sawenzel @benedikt-voelkel +/Common/SimConfig @sawenzel #/Common/Topologies #/Common/Types /Common/Utils @sawenzel @@ -37,7 +37,7 @@ /DataFormats/Detectors/ITSMFT @mcoquet642 @mconcas @shahor02 /DataFormats/Detectors/MUON @AliceO2Group/muon-experts @shahor02 /DataFormats/Detectors/PHOS @peressounko @kharlov -/DataFormats/Detectors/Passive @sawenzel @benedikt-voelkel +/DataFormats/Detectors/Passive @sawenzel /DataFormats/Detectors/TOF @noferini /DataFormats/Detectors/TPC @davidrohr @wiechula @shahor02 /DataFormats/Detectors/TRD @f3sch @bazinski @martenole @wille10 @@ -53,22 +53,22 @@ /DataFormats/Reconstruction @shahor02 #/DataFormats/TimeFrame /DataFormats/common @shahor02 -/DataFormats/simulation @sawenzel @benedikt-voelkel +/DataFormats/simulation @sawenzel -/Detectors/Base @sawenzel @shahor02 @benedikt-voelkel +/Detectors/Base @sawenzel @shahor02 /Detectors/Calibration @chiarazampolli @shahor02 /Detectors/CPV @peressounko @kharlov /Detectors/EMCAL @mfasDa @jokonig /Detectors/FIT @jotwinow @afurs @andreasmolander @arvindkhuntia @mslupeck /Detectors/FOCAL @maxrauch @mfasDa @iarsene @matthiasrichter -/Detectors/Geometry @sawenzel @shahor02 @benedikt-voelkel +/Detectors/Geometry @sawenzel @shahor02 /Detectors/GlobalTracking @shahor02 /Detectors/GlobalTrackingWorkflow @shahor02 /Detectors/HMPID @gvolpe79 /Detectors/ITSMFT @mcoquet642 @mconcas @shahor02 /Detectors/MUON @AliceO2Group/muon-experts @shahor02 /Detectors/PHOS @peressounko @kharlov -/Detectors/Passive @sawenzel @benedikt-voelkel +/Detectors/Passive @sawenzel /Detectors/TOF @noferini /Detectors/TPC @davidrohr @wiechula @shahor02 /Detectors/TRD @f3sch @bazinski @martenole @wille10 @@ -114,9 +114,9 @@ /GPU/TPCFastTransformation @davidrohr @sgorbuno /GPU/TPCSpaceChargeBase @davidrohr @ehellbar -/Generators @sawenzel @benedikt-voelkel +/Generators @sawenzel @jackal1-66 -/Steer @sawenzel @shahor02 @benedikt-voelkel +/Steer @sawenzel @shahor02 /Testing From cf2d2beb24c2c3a9dc170e2fd97deb795496c803 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 1 Nov 2024 09:21:41 +0100 Subject: [PATCH 0407/2205] Update CODEOWNERS --- CODEOWNERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 603895b8b8ce4..92999185d6f31 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -40,7 +40,7 @@ /DataFormats/Detectors/Passive @sawenzel /DataFormats/Detectors/TOF @noferini /DataFormats/Detectors/TPC @davidrohr @wiechula @shahor02 -/DataFormats/Detectors/TRD @f3sch @bazinski @martenole @wille10 +/DataFormats/Detectors/TRD @f3sch @bazinski @wille10 /DataFormats/Detectors/Upgrades @mconcas /DataFormats/Detectors/Upgrades/ITS3 @fgrosa @arossi81 /DataFormats/Detectors/ZDC @coppedis @@ -71,7 +71,7 @@ /Detectors/Passive @sawenzel /Detectors/TOF @noferini /Detectors/TPC @davidrohr @wiechula @shahor02 -/Detectors/TRD @f3sch @bazinski @martenole @wille10 +/Detectors/TRD @f3sch @bazinski @wille10 /Detectors/Upgrades @mconcas /Detectors/Upgrades/ITS3 @fgrosa @arossi81 @mconcas @f3sch /Detectors/ZDC @coppedis @@ -110,7 +110,7 @@ /GPU @davidrohr #/GPU/Common #/GPU/GPUTracking -/GPU/GPUTracking/TRDTracking @davidrohr @martenole +/GPU/GPUTracking/TRDTracking @davidrohr /GPU/TPCFastTransformation @davidrohr @sgorbuno /GPU/TPCSpaceChargeBase @davidrohr @ehellbar From 032b9eb03b0e6abbf3cfdb7715d8a0fc0b09b780 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Fri, 1 Nov 2024 18:04:41 +0100 Subject: [PATCH 0408/2205] TPC: Fixing time gain calib in case of low statistics --- Detectors/TPC/calibration/src/CalibdEdx.cxx | 58 ++++++++++++++++----- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/Detectors/TPC/calibration/src/CalibdEdx.cxx b/Detectors/TPC/calibration/src/CalibdEdx.cxx index bf86db78664d7..f53749ba8621b 100644 --- a/Detectors/TPC/calibration/src/CalibdEdx.cxx +++ b/Detectors/TPC/calibration/src/CalibdEdx.cxx @@ -327,6 +327,45 @@ auto ProjectBoostHistoXFast(const Hist& hist, std::vector& bin_indices, int return histoProj; } +template +auto ProjectBoostHistoXFastAllSectors(const Hist& hist, std::vector& bin_indices, StackID id, const CalibdEdxCorrection* stackMean) +{ + // get an average histogram over all stacks of the same type + using ax = CalibdEdx::Axis; + const unsigned int nbinsdedx = hist.axis(ax::dEdx).size(); + const double binStartX = hist.axis(ax::dEdx).bin(0).lower(); + const double binEndX = hist.axis(ax::dEdx).bin(nbinsdedx - 1).upper(); + + // make fine histogram to be able to correctly store normalized dEdx values + auto histoProj = boost::histogram::make_histogram(CalibdEdx::FloatAxis(nbinsdedx, binStartX, binEndX)); + + // loop over sectors for merging the histograms + for (int iSec = 0; iSec < hist.axis(ax::Sector).size(); ++iSec) { + bin_indices[ax::Sector] = iSec; + id.sector = static_cast(hist.axis(ax::Sector).bin(iSec).center()); + + // loop over all bins of the requested axis + for (int i = 0; i < nbinsdedx; ++i) { + // setting bin of the requested axis + bin_indices[ax::dEdx] = i; + + // access the bin content specified by bin_indices + const float counts = hist.at(bin_indices); + float dEdx = hist.axis(ax::dEdx).value(i); + + // scale the dedx to the mean + if (stackMean != nullptr) { + const auto charge = static_cast(bin_indices[ax::Charge]); + dEdx /= stackMean->getCorrection(id, charge); + } + + // fill the histogram with dedx as the bin center and the counts as the weight + histoProj(dEdx, bh::weight(counts)); + } + } + return histoProj; +} + void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, const CalibdEdxCorrection* stackMean) { using timer = std::chrono::high_resolution_clock; @@ -335,7 +374,8 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co const bool projSectors = stackMean != nullptr; constexpr int sectors = SECTORSPERSIDE * SIDES; for (int iSnp = 0; iSnp < mHist.axis(ax::Snp).size(); ++iSnp) { - for (int iSec = 0; iSec < mHist.axis(ax::Sector).size(); ++iSec) { + const int iSecEnd = projSectors ? 1 : mHist.axis(ax::Sector).size(); + for (int iSec = 0; iSec < iSecEnd; ++iSec) { for (int iStack = 0; iStack < mHist.axis(ax::Stack).size(); ++iStack) { for (int iCharge = 0; iCharge < mHist.axis(ax::Charge).size(); ++iCharge) { @@ -359,7 +399,7 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co bin_indices[ax::Charge] = iCharge; for (int iter = 0; iter < 2; ++iter) { - auto boostHist1d = ProjectBoostHistoXFast(mHist, bin_indices, ax::dEdx); + auto boostHist1d = projSectors ? ProjectBoostHistoXFastAllSectors(mHist, bin_indices, id, stackMean) : ProjectBoostHistoXFast(mHist, bin_indices, ax::dEdx); float lowerCut = 0; float upperCut = 0; @@ -398,11 +438,6 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co CalibdEdx::recoverTgl(mHist.axis(ax::Tgl).bin(iTgl).center(), id.type), mHist.axis(ax::Snp).bin(iSnp).center()}; - // scale fitted dEdx using the stacks mean - if (stackMean != nullptr) { - dEdx /= stackMean->getCorrection(id, charge); - } - const auto fitNPoints = fitValues[3]; const float sigma = fitValues[2]; const double fitMeanErr = (fitNPoints > 0) ? (sigma / std::sqrt(fitNPoints)) : -1; @@ -445,6 +480,7 @@ void CalibdEdx::fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, co << "iter=" << iter << "mSigmaLower=" << mSigmaLower << "mSigmaUpper=" << mSigmaUpper + << "projSectors=" << projSectors << "\n"; } } catch (o2::utils::FitGausError_t err) { @@ -530,14 +566,12 @@ void CalibdEdx::finalize(const bool useGausFits) meanCorr.setDims(0); TLinearFitter meanFitter(0); meanFitter.SetFormula("1"); + // get the mean dEdx for each stack + fitHist(mHist, meanCorr, meanFitter, mFitCut, mFitLowCutFactor, mFitPasses); if (!useGausFits) { - fitHist(mHist, meanCorr, meanFitter, mFitCut, mFitLowCutFactor, mFitPasses); - // get higher dimension corrections with projected sectors - fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses, &meanCorr); + fitHist(mHist, mCalib, fitter, mFitCut, mFitLowCutFactor, mFitPasses, &meanCorr, mDebugOutputStreamer.get()); } else { - fitHistGaus(meanFitter, meanCorr, nullptr); - // get higher dimension corrections with projected sectors fitHistGaus(fitter, mCalib, &meanCorr); } From b0e6623bcc69bc087077cd2141d5c0747a599f30 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 2 Nov 2024 21:26:21 +0100 Subject: [PATCH 0409/2205] Fix angular variations in derivatives calculations. --- Detectors/Align/src/AlignableSensor.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/Align/src/AlignableSensor.cxx b/Detectors/Align/src/AlignableSensor.cxx index 00b637efdd164..91658eba0a196 100644 --- a/Detectors/Align/src/AlignableSensor.cxx +++ b/Detectors/Align/src/AlignableSensor.cxx @@ -47,7 +47,7 @@ void AlignableSensor::dPosTraDParGeomLOC(const AlignmentPoint* pnt, double* deri // Jacobian of position in sensor tracking frame (tra) vs sensor LOCAL frame // parameters in TGeoHMatrix convention. // Result is stored in array deriv as linearized matrix 6x3 - const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5, 0.5, 0.5}; + const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3]; TGeoHMatrix matMod; // @@ -94,7 +94,7 @@ void AlignableSensor::dPosTraDParGeomLOC(const AlignmentPoint* pnt, double* deri // Jacobian of position in sensor tracking frame (tra) vs parent volume LOCAL frame parameters. // NO check of parentship is done! // Result is stored in array deriv as linearized matrix 6x3 - const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5, 0.5, 0.5}; + const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3]; TGeoHMatrix matMod; // this is the matrix for transition from sensor to parent volume local frames: LOC=matRel*loc @@ -193,7 +193,7 @@ void AlignableSensor::dPosTraDParGeomTRA(const AlignmentPoint* pnt, double* deri // tra' = tau*tra // // Result is stored in array deriv as linearized matrix 6x3 - const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5, 0.5, 0.5}; + const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3]; TGeoHMatrix matMod; // From 7c0b93e33101bc1b58e06d12039c6cbce4f88fea Mon Sep 17 00:00:00 2001 From: Ruben Shahoyan Date: Sun, 3 Nov 2024 01:08:38 +0100 Subject: [PATCH 0410/2205] Fix in the cluster stat. extraction + clusters sigmas (#13648) * Fix in the cluster stat. extraction * Add clusters sigmas to the output --- .../study/CMakeLists.txt | 2 +- .../GlobalTrackingStudy/TrackInfoExt.h | 11 ++++--- .../GlobalTrackingStudy/TrackMCStudyTypes.h | 12 +++++++- .../study/src/TrackMCStudy.cxx | 30 ++++++++++++++----- .../study/src/TrackingStudy.cxx | 27 +++++++++++++++++ 5 files changed, 69 insertions(+), 13 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt index 950f071c80232..398e7eb215f2e 100644 --- a/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt +++ b/Detectors/GlobalTrackingWorkflow/study/CMakeLists.txt @@ -9,7 +9,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -# add_compile_options(-O0 -g -fPIC) +#add_compile_options(-O0 -g -fPIC) o2_add_library(GlobalTrackingStudy SOURCES src/TPCTrackStudy.cxx diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h index 90db0ca4ee37c..754c08388abdb 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h @@ -37,10 +37,13 @@ struct TrackInfoExt { float q2ptTPC = 0.f; float q2ptITSTPC = 0.f; float q2ptITSTPCTRD = 0.f; - int nClTPC = 0; - int nClITS = 0; - int pattITS = 0; - ClassDefNV(TrackInfoExt, 1); + uint16_t nClTPC = 0; + uint8_t pattITS = 0; + uint8_t nClITS = 0; + uint8_t rowMinTPC = 0; + uint8_t rowMaxTPC = 0; + uint8_t rowCountTPC = 0; + ClassDefNV(TrackInfoExt, 2); }; } // namespace dataformats diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h index 43dac1ca1b4e7..c13ecf266fa3e 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h @@ -46,12 +46,13 @@ struct MCTrackInfo { int8_t parentDecID = -1; uint8_t minTPCRow = -1; uint8_t maxTPCRow = 0; + uint8_t nUsedPadRows = 0; uint8_t maxTPCRowInner = 0; // highest row in the sector containing the lowest one uint8_t minTPCRowSect = -1; uint8_t maxTPCRowSect = -1; int8_t nITSCl = 0; int8_t pattITSCl = 0; - ClassDefNV(MCTrackInfo, 3); + ClassDefNV(MCTrackInfo, 4); }; struct RecTrack { @@ -127,6 +128,10 @@ struct ClResTPCCont { int getNExt() const { return (below[0] > 1.) + (above[0] > 1.); } + float getClX() const { return xyz[0]; } + float getClY() const { return xyz[1]; } + float getClZ() const { return xyz[2]; } + float getDY() const { return xyz[1] - getYRef(); } float getDZ() const { return xyz[2] - getZRef(); } @@ -195,9 +200,14 @@ struct ClResTPC { uint8_t row = 0; uint8_t ncont = 0; uint8_t flags = 0; + uint8_t sigmaTimePacked; + uint8_t sigmaPadPacked; float qmax = 0; float qtot = 0; float occ = 0; + float occBin = 0; + float getSigmaPad() const { return float(sigmaPadPacked) * (1.f / 32); } + float getSigmaTime() const { return float(sigmaTimePacked) * (1.f / 32); } std::vector contTracks; int getNCont() const { return contTracks.size(); } diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx index bfcc84180d82c..d380a4f05cedf 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx @@ -117,6 +117,7 @@ class TrackMCStudy : public Task std::shared_ptr mGGCCDBRequest; std::unique_ptr mDBGOut; std::vector mTBinClOcc; ///< TPC occupancy histo: i-th entry is the integrated occupancy for ~1 orbit starting from the TB = i*mNTPCOccBinLength + std::vector mTBinClOccHist; //< original occupancy std::vector mIntBC; ///< interaction global BC wrt TF start std::vector mTPCOcc; ///< TPC occupancy for this interaction time std::vector mITSOcc; //< N ITS clusters in the ROF containing collision @@ -620,15 +621,15 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData) } } + // collect ITS/TPC cluster info for selected MC particles + fillMCClusterInfo(recoData); + // single tracks for (auto& entry : mSelMCTracks) { auto& trackFam = entry.second; (*mDBGOut) << "tracks" << "tr=" << trackFam << "\n"; } - // collect ITS/TPC cluster info for selected MC particles - fillMCClusterInfo(recoData); - // decays std::vector decFam; for (int id = 0; id < mNCheckDecays; id++) { @@ -735,6 +736,7 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re ncontLb++; } const auto& clus = TPCClusterIdxStruct.clusters[sector][row][icl0]; + int tbinH = int(clus.getTime() * mNTPCOccBinLengthInv); // time bin converted to slot of the occ. histo clRes.contTracks.clear(); bool doClusRes = (params.minTPCRefsToExtractClRes > 0) && (params.rejectClustersResStat <= 0. || gRandom->Rndm() < params.rejectClustersResStat); for (auto lbl : labels) { @@ -749,6 +751,9 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re if (row > mctr.maxTPCRow) { mctr.maxTPCRow = row; mctr.maxTPCRowSect = sector; + mctr.nUsedPadRows++; + } else if (row == 0 && mctr.nUsedPadRows == 0) { + mctr.nUsedPadRows++; } if (row < mctr.minTPCRow) { mctr.minTPCRow = row; @@ -838,8 +843,18 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re clRes.qtot = clus.getQtot(); clRes.qmax = clus.getQmax(); clRes.flags = clus.getFlags(); + clRes.sigmaTimePacked = clus.sigmaTimePacked; + clRes.sigmaPadPacked = clus.sigmaPadPacked; clRes.ncont = ncontLb; clRes.sortCont(); + + if (tbinH < 0) { + tbinH = 0; + } else if (tbinH >= int(mTBinClOccHist.size())) { + tbinH = (int)mTBinClOccHist.size() - 1; + } + clRes.occBin = mTBinClOccHist[tbinH]; + (*mDBGOut) << "clres" << "clr=" << clRes << "\n"; } } @@ -1147,21 +1162,22 @@ void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoDa int nTPCBins = NHBPerTF * o2::constants::lhc::LHCMaxBunches / 8, ninteg = 0; int nTPCOccBins = nTPCBins * mNTPCOccBinLengthInv, sumBins = std::max(1, int(o2::constants::lhc::LHCMaxBunches / 8 * mNTPCOccBinLengthInv)); mTBinClOcc.resize(nTPCOccBins); - std::vector mltHistTB(nTPCOccBins); + mTBinClOccHist.resize(nTPCOccBins); float sm = 0., tb = 0.5 * mNTPCOccBinLength; for (int i = 0; i < nTPCOccBins; i++) { - mltHistTB[i] = TPCRefitter->getParam()->GetUnscaledMult(tb); + mTBinClOccHist[i] = TPCRefitter->getParam()->GetUnscaledMult(tb); tb += mNTPCOccBinLength; } for (int i = nTPCOccBins; i--;) { - sm += mltHistTB[i]; + sm += mTBinClOccHist[i]; if (i + sumBins < nTPCOccBins) { - sm -= mltHistTB[i + sumBins]; + sm -= mTBinClOccHist[i + sumBins]; } mTBinClOcc[i] = sm; } } else { mTBinClOcc.resize(1); + mTBinClOccHist.resize(1); } } diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx index e2ccfd88566fe..378d2b9dcfacc 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx @@ -248,6 +248,28 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) auto vdrit = mTPCVDriftHelper.getVDriftObject().getVDrift(); bool tpcTrackOK = recoData.isTrackSourceLoaded(GTrackID::TPC); + auto getTPCClInfo = [&recoData](const o2::tpc::TrackTPC& trc) { + const auto clRefs = recoData.getTPCTracksClusterRefs(); + std::array clinfo = {}; + if (recoData.inputsTPCclusters) { + uint8_t clSect = 0, clRow = 0, clRowP = -1; + uint32_t clIdx = 0; + for (int ic = 0; ic < trc.getNClusterReferences(); ic++) { + trc.getClusterReference(clRefs, ic, clSect, clRow, clIdx); + if (clRow != clRowP) { + clinfo[2]++; + clRowP = clRow; + } + } + const auto clRefs = recoData.getTPCTracksClusterRefs(); + trc.getClusterReference(clRefs, trc.getNClusterReferences() - 1, clSect, clRow, clIdx); + clinfo[0] = clRow; + trc.getClusterReference(clRefs, 0, clSect, clRow, clIdx); + clinfo[1] = clRow; + } + return clinfo; + }; + for (int iv = 0; iv < nv; iv++) { LOGP(debug, "processing PV {} of {}", iv, nv); const auto& vtref = vtxRefs[iv]; @@ -297,6 +319,7 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) GTrackID tpcTrID; const o2::tpc::TrackTPC* tpcTr = nullptr; int nclTPC = 0; + std::array tpcClInfo{}; if (dm[DetID::TPC] && tpcTrackOK) { tpcTrID = recoData.getTPCContributorGID(vid); tpcTr = &recoData.getTPCTrack(tpcTrID); @@ -304,6 +327,7 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) if (nclTPC < mMinTPCClusters) { continue; } + tpcClInfo = getTPCClInfo(*tpcTr); } bool ambig = vid.isAmbiguous(); auto trc = recoData.getTrackParam(vid); @@ -368,6 +392,9 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) if (gidRefs[GTrackID::TPC].isIndexSet()) { trcExt.q2ptTPC = recoData.getTrackParam(gidRefs[GTrackID::TPC]).getQ2Pt(); trcExt.nClTPC = nclTPC; + trcExt.rowMinTPC = tpcClInfo[0]; + trcExt.rowMaxTPC = tpcClInfo[1]; + trcExt.rowCountTPC = tpcClInfo[2]; } if (gidRefs[GTrackID::ITSTPC].isIndexSet()) { const auto& trTPCITS = recoData.getTPCITSTrack(gidRefs[GTrackID::ITSTPC]); From 2249241d1543cbb57f6e34c6f0f3238b32dad630 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 3 Nov 2024 21:36:10 +0100 Subject: [PATCH 0411/2205] DPL: example on how to use the Arrow Dataset API (#13646) --- Framework/Core/CMakeLists.txt | 2 + .../include/Framework/RootArrowFilesystem.h | 203 ++++++++ Framework/Core/src/RootArrowFilesystem.cxx | 454 ++++++++++++++++++ Framework/Core/test/test_Root2ArrowTable.cxx | 176 +++++++ dependencies/O2Dependencies.cmake | 27 ++ 5 files changed, 862 insertions(+) create mode 100644 Framework/Core/include/Framework/RootArrowFilesystem.h create mode 100644 Framework/Core/src/RootArrowFilesystem.cxx diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index c01ef534eb212..02367afdcc556 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -117,6 +117,7 @@ o2_add_library(Framework src/ResourcesMonitoringHelper.cxx src/ResourcePolicy.cxx src/ResourcePolicyHelpers.cxx + src/RootArrowFilesystem.cxx src/SendingPolicy.cxx src/ServiceRegistry.cxx src/ServiceSpec.cxx @@ -166,6 +167,7 @@ o2_add_library(Framework O2::X9 RapidJSON::RapidJSON Arrow::arrow_shared + ArrowDataset::arrow_dataset_shared Microsoft.GSL::GSL O2::FrameworkLogger Gandiva::gandiva_shared diff --git a/Framework/Core/include/Framework/RootArrowFilesystem.h b/Framework/Core/include/Framework/RootArrowFilesystem.h new file mode 100644 index 0000000000000..e1787dae69f31 --- /dev/null +++ b/Framework/Core/include/Framework/RootArrowFilesystem.h @@ -0,0 +1,203 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_ROOT_ARROW_FILESYSTEM_H_ +#define O2_FRAMEWORK_ROOT_ARROW_FILESYSTEM_H_ + +#include +#include +#include +#include + +class TTree; +class TBufferFile; +class TDirectoryFile; + +namespace o2::framework +{ + +class TTreeFileWriteOptions : public arrow::dataset::FileWriteOptions +{ + public: + TTreeFileWriteOptions(std::shared_ptr format) + : FileWriteOptions(format) + { + } +}; + +// This is a virtual filesystem based on a ttree, where branches with the +// same prefix get grouped into a fragment +class TTreeFileSystem : public arrow::fs::FileSystem +{ + public: + arrow::Result GetFileInfo(const std::string& path) override; + arrow::Result GetFileInfo(const arrow::fs::FileSelector& select) override; + + bool Equals(const FileSystem& other) const override + { + return this->type_name() == other.type_name(); + } + + arrow::Status CreateDir(const std::string& path, bool recursive) override; + + arrow::Status DeleteDir(const std::string& path) override; + + arrow::Status CopyFile(const std::string& src, const std::string& dest) override; + + arrow::Status Move(const std::string& src, const std::string& dest) override; + + arrow::Status DeleteDirContents(const std::string& path, bool missing_dir_ok) override; + + arrow::Status DeleteRootDirContents() override; + + arrow::Status DeleteFile(const std::string& path) override; + + arrow::Result> OpenInputStream(const std::string& path) override; + + arrow::Result> OpenInputFile(const std::string& path) override; + + arrow::Result> OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) override; + + arrow::Result> OpenAppendStream( + const std::string& path, + const std::shared_ptr& metadata) override; + + virtual TTree* GetTree(arrow::dataset::FileSource) = 0; +}; + +class SingleTreeFileSystem : public TTreeFileSystem +{ + public: + SingleTreeFileSystem(TTree* tree) + : TTreeFileSystem(), + mTree(tree) + { + } + + std::string type_name() const override + { + return "ttree"; + } + + TTree* GetTree(arrow::dataset::FileSource) override + { + // Simply return the only TTree we have + return mTree; + } + + private: + TTree* mTree; +}; + +class TFileFileSystem : public TTreeFileSystem +{ + public: + TFileFileSystem(TDirectoryFile* f, size_t readahead); + + std::string type_name() const override + { + return "TDirectoryFile"; + } + + TTree* GetTree(arrow::dataset::FileSource source) override; + + // We can go back to the TFile in case this is needed. + TDirectoryFile* GetFile() + { + return mFile; + } + + private: + TDirectoryFile* mFile; +}; + +class TBufferFileFS : public TTreeFileSystem +{ + public: + TBufferFileFS(TBufferFile* f); + + std::string type_name() const override + { + return "tbufferfile"; + } + + TTree* GetTree(arrow::dataset::FileSource) override + { + // Simply return the only TTree we have + return mTree; + } + + private: + TTree* mTree; +}; + +class TTreeFileFragment : public arrow::dataset::FileFragment +{ + public: + TTreeFileFragment(arrow::dataset::FileSource source, + std::shared_ptr format, + arrow::compute::Expression partition_expression, + std::shared_ptr physical_schema) + : FileFragment(std::move(source), std::move(format), std::move(partition_expression), std::move(physical_schema)) + { + } +}; + +class TTreeFileFormat : public arrow::dataset::FileFormat +{ + size_t& mTotCompressedSize; + size_t& mTotUncompressedSize; + + public: + TTreeFileFormat(size_t& totalCompressedSize, size_t& totalUncompressedSize) + : FileFormat({}), + mTotCompressedSize(totalCompressedSize), + mTotUncompressedSize(totalUncompressedSize) + { + } + + ~TTreeFileFormat() override = default; + + std::string type_name() const override + { + return "ttree"; + } + + bool Equals(const FileFormat& other) const override + { + return other.type_name() == this->type_name(); + } + + arrow::Result IsSupported(const arrow::dataset::FileSource& source) const override + { + auto fs = std::dynamic_pointer_cast(source.filesystem()); + return fs != nullptr; + } + + arrow::Result> Inspect(const arrow::dataset::FileSource& source) const override; + /// \brief Create a FileFragment for a FileSource. + arrow::Result> MakeFragment( + arrow::dataset::FileSource source, arrow::compute::Expression partition_expression, + std::shared_ptr physical_schema) override; + + arrow::Result> MakeWriter(std::shared_ptr destination, std::shared_ptr schema, std::shared_ptr options, arrow::fs::FileLocator destination_locator) const override; + + std::shared_ptr DefaultWriteOptions() override; + + arrow::Result ScanBatchesAsync( + const std::shared_ptr& options, + const std::shared_ptr& fragment) const override; +}; + +} // namespace o2::framework + +#endif // O2_FRAMEWORK_ROOT_ARROW_FILESYSTEM_H_ diff --git a/Framework/Core/src/RootArrowFilesystem.cxx b/Framework/Core/src/RootArrowFilesystem.cxx new file mode 100644 index 0000000000000..a130f51f7e5a9 --- /dev/null +++ b/Framework/Core/src/RootArrowFilesystem.cxx @@ -0,0 +1,454 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/RootArrowFilesystem.h" +#include "Framework/Endian.h" +#include "Framework/RuntimeError.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +struct BranchInfo { + std::string name; + TBranch* ptr; + bool mVLA; +}; +} // namespace + +auto arrowTypeFromROOT(EDataType type, int size) +{ + auto typeGenerator = [](std::shared_ptr const& type, int size) -> std::shared_ptr { + switch (size) { + case -1: + return arrow::list(type); + case 1: + return std::move(type); + default: + return arrow::fixed_size_list(type, size); + } + }; + + switch (type) { + case EDataType::kBool_t: + return typeGenerator(arrow::boolean(), size); + case EDataType::kUChar_t: + return typeGenerator(arrow::uint8(), size); + case EDataType::kUShort_t: + return typeGenerator(arrow::uint16(), size); + case EDataType::kUInt_t: + return typeGenerator(arrow::uint32(), size); + case EDataType::kULong64_t: + return typeGenerator(arrow::uint64(), size); + case EDataType::kChar_t: + return typeGenerator(arrow::int8(), size); + case EDataType::kShort_t: + return typeGenerator(arrow::int16(), size); + case EDataType::kInt_t: + return typeGenerator(arrow::int32(), size); + case EDataType::kLong64_t: + return typeGenerator(arrow::int64(), size); + case EDataType::kFloat_t: + return typeGenerator(arrow::float32(), size); + case EDataType::kDouble_t: + return typeGenerator(arrow::float64(), size); + default: + throw o2::framework::runtime_error_f("Unsupported branch type: %d", static_cast(type)); + } +} +namespace o2::framework +{ + +TFileFileSystem::TFileFileSystem(TDirectoryFile* f, size_t readahead) + : TTreeFileSystem(), + mFile(f) +{ + ((TFile*)mFile)->SetReadaheadSize(50 * 1024 * 1024); +} + +TTree* TFileFileSystem::GetTree(arrow::dataset::FileSource source) +{ + // Simply return the only TTree we have + return (TTree*)mFile->Get(source.path().c_str()); +} + +arrow::Result TTreeFileSystem::GetFileInfo(const std::string& path) +{ + arrow::fs::FileInfo result; + result.set_type(arrow::fs::FileType::NotFound); + result.set_path(path); + arrow::dataset::FileSource source(path, shared_from_this()); + + for (auto branch : *GetTree(source)->GetListOfBranches()) { + if (strncmp(branch->GetName(), result.path().c_str(), path.size()) == 0) { + result.set_type(arrow::fs::FileType::File); + return result; + } + } + return result; +} + +arrow::Result TTreeFileSystem::GetFileInfo(const arrow::fs::FileSelector& select) +{ + arrow::fs::FileInfoVector results; + auto selected = this->GetFileInfo(select.base_dir); + if (selected.ok()) { + results.emplace_back(*selected); + } + return results; +} + +arrow::Status TTreeFileSystem::CreateDir(const std::string& path, bool recursive) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::DeleteDir(const std::string& path) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::CopyFile(const std::string& src, const std::string& dest) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::Move(const std::string& src, const std::string& dest) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::DeleteDirContents(const std::string& path, bool missing_dir_ok) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::DeleteRootDirContents() +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Status TTreeFileSystem::DeleteFile(const std::string& path) +{ + return arrow::Status::NotImplemented("Read only filesystem"); +} + +arrow::Result> TTreeFileSystem::OpenInputStream(const std::string& path) +{ + return arrow::Status::NotImplemented("Non streamable filesystem"); +} + +arrow::Result> TTreeFileSystem::OpenInputFile(const std::string& path) +{ + return arrow::Status::NotImplemented("No random access file system"); +} + +arrow::Result> TTreeFileSystem::OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) +{ + return arrow::Status::NotImplemented("Non streamable filesystem"); +} + +arrow::Result> TTreeFileSystem::OpenAppendStream( + const std::string& path, + const std::shared_ptr& metadata) +{ + return arrow::Status::NotImplemented("No random access file system"); +} + +arrow::Result> TTreeFileFormat::Inspect(const arrow::dataset::FileSource& source) const +{ + arrow::Schema schema{{}}; + auto fs = std::dynamic_pointer_cast(source.filesystem()); + TTree* tree = fs->GetTree(source); + + auto branches = tree->GetListOfBranches(); + auto n = branches->GetEntries(); + + std::vector branchInfos; + for (auto i = 0; i < n; ++i) { + auto branch = static_cast(branches->At(i)); + auto name = std::string{branch->GetName()}; + auto pos = name.find("_size"); + if (pos != std::string::npos) { + name.erase(pos); + branchInfos.emplace_back(BranchInfo{name, (TBranch*)nullptr, true}); + } else { + auto lookup = std::find_if(branchInfos.begin(), branchInfos.end(), [&](BranchInfo const& bi) { + return bi.name == name; + }); + if (lookup == branchInfos.end()) { + branchInfos.emplace_back(BranchInfo{name, branch, false}); + } else { + lookup->ptr = branch; + } + } + } + + std::vector> fields; + tree->SetCacheSize(25000000); + for (auto& bi : branchInfos) { + static TClass* cls; + EDataType type; + bi.ptr->GetExpectedType(cls, type); + auto listSize = -1; + if (!bi.mVLA) { + listSize = static_cast(bi.ptr->GetListOfLeaves()->At(0))->GetLenStatic(); + } + auto field = std::make_shared(bi.ptr->GetName(), arrowTypeFromROOT(type, listSize)); + fields.push_back(field); + + tree->AddBranchToCache(bi.ptr); + if (strncmp(bi.ptr->GetName(), "fIndexArray", strlen("fIndexArray")) == 0) { + std::string sizeBranchName = bi.ptr->GetName(); + sizeBranchName += "_size"; + auto* sizeBranch = (TBranch*)tree->GetBranch(sizeBranchName.c_str()); + if (sizeBranch) { + tree->AddBranchToCache(sizeBranch); + } + } + } + tree->StopCacheLearningPhase(); + + return std::make_shared(fields); +} + +/// \brief Create a FileFragment for a FileSource. +arrow::Result> TTreeFileFormat::MakeFragment( + arrow::dataset::FileSource source, arrow::compute::Expression partition_expression, + std::shared_ptr physical_schema) +{ + std::shared_ptr format = std::make_shared(mTotCompressedSize, mTotUncompressedSize); + + auto fragment = std::make_shared(std::move(source), std::move(format), + std::move(partition_expression), + std::move(physical_schema)); + return std::dynamic_pointer_cast(fragment); +} + +arrow::Result> TTreeFileFormat::MakeWriter(std::shared_ptr destination, std::shared_ptr schema, std::shared_ptr options, arrow::fs::FileLocator destination_locator) const +{ + throw std::runtime_error("Unsupported operation"); +} + +std::shared_ptr TTreeFileFormat::DefaultWriteOptions() +{ + std::shared_ptr options( + new TTreeFileWriteOptions(shared_from_this())); + return options; +} + +arrow::Result TTreeFileFormat::ScanBatchesAsync( + const std::shared_ptr& options, + const std::shared_ptr& fragment) const +{ + // Get the fragment as a TTreeFragment. This might be PART of a TTree. + auto treeFragment = std::dynamic_pointer_cast(fragment); + // This is the schema we want to read + auto dataset_schema = options->dataset_schema; + + auto generator = [pool = options->pool, treeFragment, dataset_schema, &totalCompressedSize = mTotCompressedSize, + &totalUncompressedSize = mTotUncompressedSize]() -> arrow::Future> { + auto schema = treeFragment->format()->Inspect(treeFragment->source()); + + std::vector> columns; + std::vector> fields = dataset_schema->fields(); + auto physical_schema = *treeFragment->ReadPhysicalSchema(); + + static TBufferFile buffer{TBuffer::EMode::kWrite, 4 * 1024 * 1024}; + auto fs = std::dynamic_pointer_cast(treeFragment->source().filesystem()); + int64_t rows = -1; + TTree* tree = fs->GetTree(treeFragment->source()); + for (auto& field : fields) { + // The field actually on disk + auto physicalField = physical_schema->GetFieldByName(field->name()); + TBranch* branch = tree->GetBranch(physicalField->name().c_str()); + assert(branch); + buffer.Reset(); + auto totalEntries = branch->GetEntries(); + if (rows == -1) { + rows = totalEntries; + } + if (rows != totalEntries) { + throw runtime_error_f("Unmatching number of rows for branch %s", branch->GetName()); + } + arrow::Status status; + int readEntries = 0; + std::shared_ptr array; + auto listType = std::dynamic_pointer_cast(physicalField->type()); + if (physicalField->type() == arrow::boolean() || + (listType && physicalField->type()->field(0)->type() == arrow::boolean())) { + if (listType) { + std::unique_ptr builder = nullptr; + auto status = arrow::MakeBuilder(pool, physicalField->type()->field(0)->type(), &builder); + if (!status.ok()) { + throw runtime_error("Cannot create value builder"); + } + auto listBuilder = std::make_unique(pool, std::move(builder), listType->list_size()); + auto valueBuilder = listBuilder.get()->value_builder(); + // boolean array special case: we need to use builder to create the bitmap + status = valueBuilder->Reserve(totalEntries * listType->list_size()); + status &= listBuilder->Reserve(totalEntries); + if (!status.ok()) { + throw runtime_error("Failed to reserve memory for array builder"); + } + while (readEntries < totalEntries) { + auto readLast = branch->GetBulkRead().GetBulkEntries(readEntries, buffer); + readEntries += readLast; + status &= static_cast(valueBuilder)->AppendValues(reinterpret_cast(buffer.GetCurrent()), readLast * listType->list_size()); + } + status &= static_cast(listBuilder.get())->AppendValues(readEntries); + if (!status.ok()) { + throw runtime_error("Failed to append values to array"); + } + status &= listBuilder->Finish(&array); + if (!status.ok()) { + throw runtime_error("Failed to create array"); + } + } else if (listType == nullptr) { + std::unique_ptr builder = nullptr; + auto status = arrow::MakeBuilder(pool, physicalField->type(), &builder); + if (!status.ok()) { + throw runtime_error("Cannot create builder"); + } + auto valueBuilder = static_cast(builder.get()); + // boolean array special case: we need to use builder to create the bitmap + status = valueBuilder->Reserve(totalEntries); + if (!status.ok()) { + throw runtime_error("Failed to reserve memory for array builder"); + } + while (readEntries < totalEntries) { + auto readLast = branch->GetBulkRead().GetBulkEntries(readEntries, buffer); + readEntries += readLast; + status &= valueBuilder->AppendValues(reinterpret_cast(buffer.GetCurrent()), readLast); + } + if (!status.ok()) { + throw runtime_error("Failed to append values to array"); + } + status &= valueBuilder->Finish(&array); + if (!status.ok()) { + throw runtime_error("Failed to create array"); + } + } + } else { + // other types: use serialized read to build arrays directly. + auto typeSize = physicalField->type()->byte_width(); + // This is needed for branches which have not been persisted. + auto bytes = branch->GetTotBytes(); + auto branchSize = bytes ? bytes : 1000000; + auto&& result = arrow::AllocateResizableBuffer(branchSize, pool); + if (!result.ok()) { + throw runtime_error("Cannot allocate values buffer"); + } + std::shared_ptr arrowValuesBuffer = std::move(result).ValueUnsafe(); + auto ptr = arrowValuesBuffer->mutable_data(); + if (ptr == nullptr) { + throw runtime_error("Invalid buffer"); + } + + std::unique_ptr offsetBuffer = nullptr; + + uint32_t offset = 0; + int count = 0; + std::shared_ptr arrowOffsetBuffer; + std::span offsets; + int size = 0; + uint32_t totalSize = 0; + TBranch* mSizeBranch = nullptr; + int64_t listSize = 1; + if (auto fixedSizeList = std::dynamic_pointer_cast(physicalField->type())) { + listSize = fixedSizeList->list_size(); + } else if (auto vlaListType = std::dynamic_pointer_cast(physicalField->type())) { + listSize = -1; + } + if (listSize == -1) { + mSizeBranch = branch->GetTree()->GetBranch((std::string{branch->GetName()} + "_size").c_str()); + offsetBuffer = std::make_unique(TBuffer::EMode::kWrite, 4 * 1024 * 1024); + result = arrow::AllocateResizableBuffer((totalEntries + 1) * (int64_t)sizeof(int), pool); + if (!result.ok()) { + throw runtime_error("Cannot allocate offset buffer"); + } + arrowOffsetBuffer = std::move(result).ValueUnsafe(); + unsigned char* ptrOffset = arrowOffsetBuffer->mutable_data(); + auto* tPtrOffset = reinterpret_cast(ptrOffset); + offsets = std::span{tPtrOffset, tPtrOffset + totalEntries + 1}; + + // read sizes first + while (readEntries < totalEntries) { + auto readLast = mSizeBranch->GetBulkRead().GetEntriesSerialized(readEntries, *offsetBuffer); + readEntries += readLast; + for (auto i = 0; i < readLast; ++i) { + offsets[count++] = (int)offset; + offset += swap32_(reinterpret_cast(offsetBuffer->GetCurrent())[i]); + } + } + offsets[count] = (int)offset; + totalSize = offset; + readEntries = 0; + } + + while (readEntries < totalEntries) { + auto readLast = branch->GetBulkRead().GetEntriesSerialized(readEntries, buffer); + if (listSize == -1) { + size = offsets[readEntries + readLast] - offsets[readEntries]; + } else { + size = readLast * listSize; + } + readEntries += readLast; + swapCopy(ptr, buffer.GetCurrent(), size, typeSize); + ptr += (ptrdiff_t)(size * typeSize); + } + if (listSize >= 1) { + totalSize = readEntries * listSize; + } + std::shared_ptr varray; + switch (listSize) { + case -1: + varray = std::make_shared(physicalField->type()->field(0)->type(), totalSize, arrowValuesBuffer); + array = std::make_shared(physicalField->type(), readEntries, arrowOffsetBuffer, varray); + break; + case 1: + array = std::make_shared(physicalField->type(), readEntries, arrowValuesBuffer); + break; + default: + varray = std::make_shared(physicalField->type()->field(0)->type(), totalSize, arrowValuesBuffer); + array = std::make_shared(physicalField->type(), readEntries, varray); + } + } + + branch->SetStatus(false); + branch->DropBaskets("all"); + branch->Reset(); + branch->GetTransientBuffer(0)->Expand(0); + + columns.push_back(array); + } + auto batch = arrow::RecordBatch::Make(dataset_schema, rows, columns); + totalCompressedSize += tree->GetZipBytes(); + totalUncompressedSize += tree->GetTotBytes(); + return batch; + }; + return generator; +} + +TBufferFileFS::TBufferFileFS(TBufferFile* f) + : TTreeFileSystem(), + mTree((TTree*)f->ReadObject(TTree::Class())) +{ +} + +} // namespace o2::framework diff --git a/Framework/Core/test/test_Root2ArrowTable.cxx b/Framework/Core/test/test_Root2ArrowTable.cxx index 109d9718f5f09..69d39f193c7df 100644 --- a/Framework/Core/test/test_Root2ArrowTable.cxx +++ b/Framework/Core/test/test_Root2ArrowTable.cxx @@ -18,13 +18,20 @@ #include #include +#include +#include +#include #include #include +#include + +#include #include #include #include #include #include +#include "Framework/RootArrowFilesystem.h" using namespace o2::framework; @@ -181,3 +188,172 @@ TEST_CASE("RootTree2TableViaASoA") REQUIRE(row.ij()[1] == row.ev()); } } + +TEST_CASE("RootTree2Fragment") +{ + using namespace o2::framework; + /// A directory holding a tree + + /// Create a simple TTree + TBufferFile* file = new TBufferFile(TBuffer::kWrite); + + TTree t1("t1", "a simple Tree with simple variables"); + Float_t xyz[3]; + Int_t ij[2]; + Float_t px = 0, py = 1, pz = 2; + Double_t random; + Int_t ev; + t1.Branch("px", &px, "px/F"); + t1.Branch("py", &py, "py/F"); + t1.Branch("pz", &pz, "pz/F"); + t1.Branch("random", &random, "random/D"); + t1.Branch("ev", &ev, "ev/I"); + t1.Branch("xyz", xyz, "xyz[3]/F"); + t1.Branch("ij", ij, "ij[2]/I"); + // fill the tree + for (Int_t i = 0; i < 1000; i++) { + xyz[0] = 1; + xyz[1] = 2; + xyz[2] = 3; + gRandom->Rannor(px, py); + pz = px * px + py * py; + xyz[2] = i + 1; + ij[0] = i; + ij[1] = i + 1; + random = gRandom->Rndm(); + ev = i + 1; + t1.Fill(); + } + file->WriteObjectAny(&t1, t1.Class()); + auto* fileRead = new TBufferFile(TBuffer::kRead, file->BufferSize(), file->Buffer(), false, nullptr); + + size_t totalSizeCompressed = 0; + size_t totalSizeUncompressed = 0; + auto format = std::make_shared(totalSizeCompressed, totalSizeUncompressed); + auto fs = std::make_shared(fileRead); + arrow::dataset::FileSource source("p", fs); + REQUIRE(format->IsSupported(source) == true); + auto schemaOpt = format->Inspect(source); + REQUIRE(schemaOpt.ok()); + auto schema = *schemaOpt; + REQUIRE(schema->num_fields() == 7); + REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(3)->type()->id() == arrow::float64()->id()); + REQUIRE(schema->field(4)->type()->id() == arrow::int32()->id()); + REQUIRE(schema->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); + REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + auto fragment = format->MakeFragment(source, {}, schema); + REQUIRE(fragment.ok()); + auto options = std::make_shared(); + options->dataset_schema = schema; + auto scanner = format->ScanBatchesAsync(options, *fragment); + REQUIRE(scanner.ok()); + auto batches = (*scanner)(); + auto result = batches.result(); + REQUIRE(result.ok()); + REQUIRE((*result)->columns().size() == 7); + REQUIRE((*result)->num_rows() == 1000); +} + +TEST_CASE("RootTree2Dataset") +{ + using namespace o2::framework; + /// A directory holding a tree + // auto *f = new TFile("Foo.root", "RECREATE"); + auto* f = new TMemFile("foo", "RECREATE"); + f->mkdir("DF_1"); + f->mkdir("DF_2"); + + f->cd("DF_1"); + auto* t = new TTree("tracks", "a simple Tree with simple variables"); + { + Float_t xyz[3]; + Int_t ij[2]; + Float_t px = 0, py = 1, pz = 2; + Double_t random; + Int_t ev; + t->Branch("px", &px, "px/F"); + t->Branch("py", &py, "py/F"); + t->Branch("pz", &pz, "pz/F"); + t->Branch("random", &random, "random/D"); + t->Branch("ev", &ev, "ev/I"); + t->Branch("xyz", xyz, "xyz[3]/F"); + t->Branch("ij", ij, "ij[2]/I"); + // fill the tree + for (Int_t i = 0; i < 1000; i++) { + xyz[0] = 1; + xyz[1] = 2; + xyz[2] = 3; + gRandom->Rannor(px, py); + pz = px * px + py * py; + xyz[2] = i + 1; + ij[0] = i; + ij[1] = i + 1; + random = gRandom->Rndm(); + ev = i + 1; + t->Fill(); + } + } + + f->cd("DF_2"); + t = new TTree("tracks", "a simple Tree with simple variables"); + { + Float_t xyz[3]; + Int_t ij[2]; + Float_t px = 0, py = 1, pz = 2; + Double_t random; + Int_t ev; + t->Branch("px", &px, "px/F"); + t->Branch("py", &py, "py/F"); + t->Branch("pz", &pz, "pz/F"); + t->Branch("random", &random, "random/D"); + t->Branch("ev", &ev, "ev/I"); + t->Branch("xyz", xyz, "xyz[3]/F"); + t->Branch("ij", ij, "ij[2]/I"); + // fill the tree + for (Int_t i = 0; i < 100; i++) { + xyz[0] = 1; + xyz[1] = 2; + xyz[2] = 3; + gRandom->Rannor(px, py); + pz = px * px + py * py; + xyz[2] = i + 1; + ij[0] = i; + ij[1] = i + 1; + random = gRandom->Rndm(); + ev = i + 1; + t->Fill(); + } + } + + size_t totalSizeCompressed = 0; + size_t totalSizeUncompressed = 0; + auto format = std::make_shared(totalSizeCompressed, totalSizeUncompressed); + auto fs = std::make_shared(f, 50 * 1024 * 1024); + arrow::dataset::FileSource source("DF_2/tracks", fs); + REQUIRE(format->IsSupported(source) == true); + auto schemaOpt = format->Inspect(source); + REQUIRE(schemaOpt.ok()); + auto schema = *schemaOpt; + REQUIRE(schema->num_fields() == 7); + REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(3)->type()->id() == arrow::float64()->id()); + REQUIRE(schema->field(4)->type()->id() == arrow::int32()->id()); + REQUIRE(schema->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); + REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + auto fragment = format->MakeFragment(source, {}, schema); + REQUIRE(fragment.ok()); + auto options = std::make_shared(); + options->dataset_schema = schema; + auto scanner = format->ScanBatchesAsync(options, *fragment); + REQUIRE(scanner.ok()); + auto batches = (*scanner)(); + auto result = batches.result(); + REQUIRE(result.ok()); + REQUIRE((*result)->columns().size() == 7); + REQUIRE((*result)->num_rows() == 100); +} diff --git a/dependencies/O2Dependencies.cmake b/dependencies/O2Dependencies.cmake index 48a5d57d17c96..c5c22b3a79097 100644 --- a/dependencies/O2Dependencies.cmake +++ b/dependencies/O2Dependencies.cmake @@ -38,6 +38,33 @@ if (NOT TARGET Arrow::arrow_shared) add_library(Arrow::arrow_shared ALIAS arrow_shared) endif() +if(NOT TARGET ArrowDataset::arrow_dataset_shared) + # ArrowDataset::arrow_dataset_shared is linked for no reason to parquet + # so we cannot use it because we do not want to build parquet itself. + # For that reason at the moment we need to do the lookup by hand. + get_target_property(ARROW_SHARED_LOCATION Arrow::arrow_shared LOCATION) + get_filename_component(ARROW_SHARED_DIR ${ARROW_SHARED_LOCATION} DIRECTORY) + + find_library(ARROW_DATASET_SHARED arrow_dataset + PATHS ${ARROW_SHARED_DIR} + NO_DEFAULT_PATH + ) + + if(ARROW_DATASET_SHARED) + message(STATUS + "Found arrow_dataset_shared library at: ${ARROW_DATASET_SHARED}") + else() + message(FATAL_ERROR + "arrow_dataset_shared library not found in ${ARROW_SHARED_DIR}") + endif() + + # Step 3: Create a target for ArrowDataset::arrow_dataset_shared + add_library(ArrowDataset::arrow_dataset_shared SHARED IMPORTED) + set_target_properties(ArrowDataset::arrow_dataset_shared PROPERTIES + IMPORTED_LOCATION ${ARROW_DATASET_SHARED} + ) +endif() + if (NOT TARGET Gandiva::gandiva_shared) add_library(Gandiva::gandiva_shared ALIAS gandiva_shared) endif() From 495ca6c730ad9dbea54f68c21e55cc4ea305407d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Tue, 5 Nov 2024 12:56:34 +0100 Subject: [PATCH 0412/2205] [TOF] update matcher (#13621) * [TOF] update matcher * Update MatchInfoTOF.h * Please consider the following formatting changes (#33) * Update MatchInfoTOF.h --------- Co-authored-by: ALICE Builder --- .../ReconstructionDataFormats/MatchInfoTOF.h | 11 +++++++++- Detectors/GlobalTracking/src/MatchTOF.cxx | 20 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h index c3cdae54823e6..1a29be70ec990 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h @@ -41,6 +41,12 @@ class MatchInfoTOF void setChi2(float chi2) { mChi2 = chi2; } float getChi2() const { return mChi2; } + void setHitPatternUpDown(bool v) { mHitUpDown = v; } + bool getHitPatternUpDown() const { return mHitUpDown; } + + void setHitPatternLeftRight(bool v) { mHitLeftRight = v; } + bool getHitPatternLeftRight() const { return mHitLeftRight; } + o2::track::TrackLTIntegral& getLTIntegralOut() { return mIntLT; } const o2::track::TrackLTIntegral& getLTIntegralOut() const { return mIntLT; } void print() const; @@ -76,8 +82,11 @@ class MatchInfoTOF double mSignal = 0.0; ///< TOF time in ps float mVz = 0.0; ///< Vz from TOF match int mChannel = -1; ///< channel + // Hit pattern information + bool mHitUpDown = false; ///< hit pattern in TOF up-down + bool mHitLeftRight = false; ///< hit pattern in TOF left-right - ClassDefNV(MatchInfoTOF, 6); + ClassDefNV(MatchInfoTOF, 7); }; } // namespace dataformats } // namespace o2 diff --git a/Detectors/GlobalTracking/src/MatchTOF.cxx b/Detectors/GlobalTracking/src/MatchTOF.cxx index 9bb741ee4443f..8a90251353123 100644 --- a/Detectors/GlobalTracking/src/MatchTOF.cxx +++ b/Detectors/GlobalTracking/src/MatchTOF.cxx @@ -1556,7 +1556,7 @@ void MatchTOF::BestMatches(std::vector& match int i = 0; // then we take discard the pairs if their track or cluster was already matched (since they are ordered in chi2, we will take the best matching) - for (const o2::dataformats::MatchInfoTOFReco& matchingPair : matchedTracksPairs) { + for (o2::dataformats::MatchInfoTOFReco& matchingPair : matchedTracksPairs) { int trkType = (int)matchingPair.getTrackType(); int itrk = matchingPair.getIdLocal(); @@ -1610,6 +1610,24 @@ void MatchTOF::BestMatches(std::vector& match matchedTracksIndex[trkType][itrk] = matchedTracks[trkTypeSplitted].size(); // index of the MatchInfoTOF correspoding to this track matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[trkType][itrk]; // index of the track that was matched to this cluster + // let's check if cluster has multiple-hits (noferini) + if (TOFClusWork[matchingPair.getTOFClIndex()].getNumOfContributingChannels() > 1) { + const auto& tofcl = TOFClusWork[matchingPair.getTOFClIndex()]; + // has an additional hit Up or Down (Z-dir) + matchingPair.setHitPatternUpDown(tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUp) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpLeft) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpRight) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDown) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownLeft) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownRight)); + // has an additional hit Left or Right (X-dir) + matchingPair.setHitPatternLeftRight(tofcl.isAdditionalChannelSet(o2::tof::Cluster::kLeft) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownLeft) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpLeft) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kRight) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownRight) || + tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpRight)); + } matchedTracks[trkTypeSplitted].push_back(matchingPair); // array of MatchInfoTOF // get fit info From 5934a6aa51844bfca7d4eb13c47e5378e8dd2052 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 4 Nov 2024 17:01:47 +0100 Subject: [PATCH 0413/2205] Fix input and exit condition of ReaderDriverSpec --- Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx | 2 +- Detectors/Raw/src/HBFUtilsInitializer.cxx | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx index d02d321201936..d53bbf9a30690 100644 --- a/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/ReaderDriverSpec.cxx @@ -75,7 +75,7 @@ void ReadeDriverSpec::run(ProcessingContext& pc) LOGP(debug, "OUTVEC {}/{}", v.back().getMin().asString(), v.back().getMax().asString()); } count++; - if ((HBFINI::LastIRFrameIndex == -1 && count == mNTF) || (v.size() && v.back().isLast())) { + if ((HBFINI::LastIRFrameIndex == -1 && count >= mNTF) || (v.size() && v.back().isLast())) { pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); } diff --git a/Detectors/Raw/src/HBFUtilsInitializer.cxx b/Detectors/Raw/src/HBFUtilsInitializer.cxx index dc46b9baeabc9..1f89d9725b397 100644 --- a/Detectors/Raw/src/HBFUtilsInitializer.cxx +++ b/Detectors/Raw/src/HBFUtilsInitializer.cxx @@ -58,6 +58,7 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext bool helpasked = configcontext.helpOnCommandLine(); // if help is asked, don't take for granted that the ini file is there, don't produce an error if it is not! auto conf = configcontext.options().isSet(HBFConfOpt) ? configcontext.options().get(HBFConfOpt) : ""; if (!conf.empty()) { + int nopts = 0; auto vopts = o2::utils::Str::tokenize(conf, ','); for (const auto& optStr : vopts) { if (optStr == UpstreamOpt) { @@ -65,6 +66,7 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext continue; } HBFOpt opt = getOptType(optStr); + nopts++; if ((opt == HBFOpt::INI || opt == HBFOpt::JSON) && !helpasked) { o2::conf::ConfigurableParam::updateFromFile(optStr, "HBFUtils", true); // update only those values which were not touched yet (provenance == kCODE) const auto& hbfu = o2::raw::HBFUtils::Instance(); @@ -76,8 +78,13 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext hbfuInput = optStr; } else if (opt == HBFOpt::ROOT) { rootFileInput = optStr; + } else { + LOGP(fatal, "uknown hbfutils-config option {}", optStr); } } + if (!nopts && !helpasked) { + LOGP(fatal, "No source was provided for timing input of --hbfutils-config"); + } } done = true; /* RSS From 831670fec819fe6a766e37c9f6a20b551310c35f Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 1 Nov 2024 17:46:17 +0100 Subject: [PATCH 0414/2205] Simplify eve options, shift TPC tracks by PV time and apply dca cuts --- EventVisualisation/Base/CMakeLists.txt | 5 +- .../EventVisualisationBase/EveConfParam.h | 48 ++++++ EventVisualisation/Base/src/EveConfParam.cxx | 14 ++ .../Base/src/EventVisualisationBaseLinkDef.h | 22 +++ .../include/EveWorkflow/EveWorkflowHelper.h | 37 ++--- .../include/EveWorkflow/O2DPLDisplay.h | 35 +---- .../Workflow/src/EveWorkflowHelper.cxx | 137 +++++++++++++----- .../Workflow/src/O2DPLDisplay.cxx | 134 +++++------------ prodtests/full-system-test/dpl-workflow.sh | 18 ++- 9 files changed, 250 insertions(+), 200 deletions(-) create mode 100644 EventVisualisation/Base/include/EventVisualisationBase/EveConfParam.h create mode 100644 EventVisualisation/Base/src/EveConfParam.cxx create mode 100644 EventVisualisation/Base/src/EventVisualisationBaseLinkDef.h diff --git a/EventVisualisation/Base/CMakeLists.txt b/EventVisualisation/Base/CMakeLists.txt index 9b7a5a231de67..2595288b7dcc3 100644 --- a/EventVisualisation/Base/CMakeLists.txt +++ b/EventVisualisation/Base/CMakeLists.txt @@ -17,9 +17,12 @@ o2_add_library(EventVisualisationBase src/GeometryManager.cxx src/FileWatcher.cxx src/DirectoryLoader.cxx - + src/EveConfParam.cxx PUBLIC_LINK_LIBRARIES ROOT::Eve O2::CCDB O2::EventVisualisationDataConverter O2::DetectorsBase ) + +o2_target_root_dictionary(EventVisualisationBase + HEADERS include/EventVisualisationBase/EveConfParam.h) diff --git a/EventVisualisation/Base/include/EventVisualisationBase/EveConfParam.h b/EventVisualisation/Base/include/EventVisualisationBase/EveConfParam.h new file mode 100644 index 0000000000000..d47c34a02a21b --- /dev/null +++ b/EventVisualisation/Base/include/EventVisualisationBase/EveConfParam.h @@ -0,0 +1,48 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ALICE_O2_EVENTVISUALISATION_CONFIG_H +#define ALICE_O2_EVENTVISUALISATION_CONFIG_H +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2::event_visualisation +{ +struct EveConfParam : o2::conf::ConfigurableParamHelper { + float EMCCellTimeMax = 100.f; // Max. EMCAL cell time (in ns) + float EMCCellEnergyMin = 0.3f; // Min. EMCAL cell energy (in GeV) + + float timeMinMax[2] = {-999.f, -999.f}; // if min 0: enable PV mode and limit max number of vertices + int minTracks = -1; // don't create file if less than the specified number of all tracks is present + int minITSTracks = -1; // don't create file if less than the specified number of ITS tracks is present + int onlyNthEvent = -1; // process only every nth event (if > 1) + float PVXYZMin[3] = {-999.f, -999.f, -999.f}; // primary vertex min x,y,z + float PVXYZMax[3] = {999.f, 999.f, 999.f}; // primary vertex max x,y,z + float TPCOnlyMaxDCARZ[2] = {-999.f, -999.f}; // max DCA r,z (if positive) for TPC only tracks in the primary vertex mode + float TPCEtaAbsMax = -1.f; // if positive, show TPC tracks only below this abs eta + + bool PVMode = false; // produce jsons with individual primary vertices, not total time frame data + bool PVTriggersMode = false; // instead of drawing vertices with tracks (and maybe calorimeter triggers), draw vertices with calorimeter triggers (and maybe tracks)" + bool trackSorting = false; // sort track by track time before applying filters + bool filterITSROF = false; // don't display tracks outside ITS readout frame + bool calibrateEMC = true; // apply on-the-fly EMCAL calibration + + O2ParamDef(EveConfParam, "eveconf"); +}; +} // namespace o2::event_visualisation + +#endif diff --git a/EventVisualisation/Base/src/EveConfParam.cxx b/EventVisualisation/Base/src/EveConfParam.cxx new file mode 100644 index 0000000000000..00c55e9597bcc --- /dev/null +++ b/EventVisualisation/Base/src/EveConfParam.cxx @@ -0,0 +1,14 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "EventVisualisationBase/EveConfParam.h" + +O2ParamImpl(o2::event_visualisation::EveConfParam); diff --git a/EventVisualisation/Base/src/EventVisualisationBaseLinkDef.h b/EventVisualisation/Base/src/EventVisualisationBaseLinkDef.h new file mode 100644 index 0000000000000..73a260616cda7 --- /dev/null +++ b/EventVisualisation/Base/src/EventVisualisationBaseLinkDef.h @@ -0,0 +1,22 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::event_visualisation::EveConfParam + ; + +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::event_visualisation::EveConfParam> + ; + +#endif diff --git a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h index 66bf6a38987b9..1043ed5c303e0 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h @@ -29,6 +29,7 @@ #include "ITSBase/GeometryTGeo.h" #include "TPCFastTransform.h" #include "TPCReconstruction/TPCFastTransformHelperO2.h" +#include "DataFormatsTPC/VDriftCorrFact.h" #include "Framework/AnalysisDataModel.h" #include "DetectorsVertexing/PVertexerParams.h" @@ -124,27 +125,17 @@ class EveWorkflowHelper using AODMFTTracks = aod::MFTTracks; using AODMFTTrack = AODMFTTracks::iterator; - - enum Filter : uint8_t { - ITSROF, - TimeBracket, - EtaBracket, - TotalNTracks, - NFilters - }; - - using FilterSet = std::bitset; - using Bracket = o2::math_utils::Bracketf_t; - EveWorkflowHelper(const FilterSet& enabledFilters = {}, std::size_t maxNTracks = -1, const Bracket& timeBracket = {}, const Bracket& etaBracket = {}, bool primaryVertexMode = false); + EveWorkflowHelper(); static std::vector getTrackPoints(const o2::track::TrackPar& trc, float minR, float maxR, float maxStep, float minZ = -25000, float maxZ = 25000); + void setTPCVDrift(const o2::tpc::VDriftCorrFact* v); void selectTracks(const CalibObjectsConst* calib, GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch); void selectTowers(); void setITSROFs(); void addTrackToEvent(const o2::track::TrackPar& tr, GID gid, float trackTime, float dz, GID::Source source = GID::NSources, float maxStep = 4.f); void draw(std::size_t primaryVertexIdx, bool sortTracks); - void drawTPC(GID gid, float trackTime); + void drawTPC(GID gid, float trackTime, float dz = 0.f); void drawITS(GID gid, float trackTime); void drawMFT(GID gid, float trackTime); void drawMCH(GID gid, float trackTime); @@ -170,7 +161,7 @@ class EveWorkflowHelper void drawMFTTrack(GID gid, o2::track::TrackParFwd track, float trackTime); void drawForwardTrack(GID gid, mch::TrackParam track, float startZ, float endZ, float trackTime); void drawITSClusters(GID gid); - void drawTPCClusters(GID gid); + void drawTPCClusters(GID gid, float trackTimeTB = -2.e9); // if trackTimeTB<-1.e9, then use tpcTrack.getTime0() void drawMFTClusters(GID gid); void drawMCHClusters(GID gid); void drawMIDClusters(GID gid); @@ -194,17 +185,14 @@ class EveWorkflowHelper void save(const std::string& jsonPath, const std::string& ext, int numberOfFiles); - FilterSet mEnabledFilters; - std::size_t mMaxNTracks; - Bracket mTimeBracket; - Bracket mEtaBracket; - bool mPrimaryVertexMode; + bool mUseTimeBracket = false; + bool mUseEtaBracketTPC = false; + Bracket mTimeBracket{}; + Bracket mEtaBracketTPC; const o2::globaltracking::RecoContainer* mRecoCont = nullptr; const o2::globaltracking::RecoContainer* getRecoContainer() const { return mRecoCont; } void setRecoContainer(const o2::globaltracking::RecoContainer* rc) { mRecoCont = rc; } void setEMCALCellRecalibrator(o2::emcal::CellRecalibrator* calibrator) { mEMCALCalib = calibrator; } - void setMaxEMCALCellTime(float maxtime) { mEMCALMaxCellTime = maxtime; } - void setMinEMCALCellEnergy(float minenergy) { mEMCALMinCellEnergy = minenergy; } TracksSet mTrackSet; o2::event_visualisation::VisualisationEvent mEvent; std::unordered_map mTotalDataTypes; @@ -220,13 +208,12 @@ class EveWorkflowHelper o2::phos::Geometry* mPHOSGeom; o2::emcal::Geometry* mEMCALGeom; o2::emcal::CellRecalibrator* mEMCALCalib = nullptr; - - float mMUS2TPCTimeBins = 5.0098627; + const o2::tpc::VDriftCorrFact* mTPCVDrift = nullptr; + float mMUS2TPCTimeBins = 5.0098627f; + float mTPCTimeBins2MUS = 0.199606f; float mITSROFrameLengthMUS = 0; ///< ITS RO frame in mus float mMFTROFrameLengthMUS = 0; ///< MFT RO frame in mus float mTPCBin2MUS = 0; - float mEMCALMaxCellTime = 100.; ///< EMCAL cell time cut (in ns) - float mEMCALMinCellEnergy = 0.3; ///< EMCAL cell energy cut (in GeV) static int BCDiffErrCount; const o2::vertexing::PVertexerParams* mPVParams = nullptr; }; diff --git a/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h b/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h index 0204782a67b34..1156d31d190ea 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h @@ -18,6 +18,7 @@ #include "ReconstructionDataFormats/GlobalTrackID.h" #include "DataFormatsGlobalTracking/RecoContainer.h" +#include "TPCCalibration/VDriftHelper.h" #include "DetectorsBase/GRPGeomHelper.h" #include "EMCALCalib/CellRecalibrator.h" #include "EMCALWorkflow/CalibLoader.h" @@ -58,14 +59,9 @@ class O2DPLDisplaySpec : public o2::framework::Task std::shared_ptr gr, std::shared_ptr emcCalibLoader, const std::string& jsonPath, const std::string& ext, - std::chrono::milliseconds timeInterval, int numberOfFiles, int numberOfTracks, int numberOfBytes, - bool eveHostNameMatch, int minITSTracks, int minTracks, bool filterITSROF, bool filterTime, - const EveWorkflowHelper::Bracket& timeBracket, bool removeTPCEta, - const EveWorkflowHelper::Bracket& etaBracket, bool trackSorting, int onlyNthEvent, - bool primaryVertex, int maxPrimaryVertices, bool primaryVertexTriggers, - float primaryVertexMinZ, float primaryVertexMaxZ, float primaryVertexMinX, float primaryVertexMaxX, float primaryVertexMinY, float primaryVertexMaxY, - float maxEMCALCellTime, float minEMCALCellEnergy) - : mDisableWrite(disableWrite), mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mGGCCDBRequest(gr), mEMCALCalibLoader(emcCalibLoader), mJsonPath(jsonPath), mExt(ext), mTimeInterval(timeInterval), mNumberOfFiles(numberOfFiles), mNumberOfTracks(numberOfTracks), mNumberOfBytes(numberOfBytes), mEveHostNameMatch(eveHostNameMatch), mMinITSTracks(minITSTracks), mMinTracks(minTracks), mFilterITSROF(filterITSROF), mFilterTime(filterTime), mTimeBracket(timeBracket), mRemoveTPCEta(removeTPCEta), mEtaBracket(etaBracket), mTrackSorting(trackSorting), mOnlyNthEvent(onlyNthEvent), mPrimaryVertexMode(primaryVertex), mMaxPrimaryVertices(maxPrimaryVertices), mPrimaryVertexTriggers(primaryVertexTriggers), mPrimaryVertexMinZ(primaryVertexMinZ), mPrimaryVertexMaxZ(primaryVertexMaxZ), mPrimaryVertexMinX(primaryVertexMinX), mPrimaryVertexMaxX(primaryVertexMaxX), mPrimaryVertexMinY(primaryVertexMinY), mPrimaryVertexMaxY(primaryVertexMaxY), mEMCALMaxCellTime(maxEMCALCellTime), mEMCALMinCellEnergy(minEMCALCellEnergy), mRunType(o2::parameters::GRPECS::NONE) + std::chrono::milliseconds timeInterval, + bool eveHostNameMatch) + : mDisableWrite(disableWrite), mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mGGCCDBRequest(gr), mEMCALCalibLoader(emcCalibLoader), mJsonPath(jsonPath), mExt(ext), mTimeInterval(timeInterval), mEveHostNameMatch(eveHostNameMatch), mRunType(o2::parameters::GRPECS::NONE) { this->mTimeStamp = std::chrono::high_resolution_clock::now() - timeInterval; // first run meets condition @@ -82,32 +78,10 @@ class O2DPLDisplaySpec : public o2::framework::Task bool mDisableWrite = false; // skip writing result (for testing performance) bool mUseMC = false; bool mEveHostNameMatch; // empty or correct hostname - int mMinITSTracks; // minimum number of ITS tracks to produce a file - int mMinTracks; // minimum number of all tracks to produce a file - bool mFilterITSROF; // don't display tracks outside ITS readout frame - bool mFilterTime; // don't display tracks outside [min, max] range in TF time - bool mRemoveTPCEta; // don't display TPC tracks inside [min, max] eta range - bool mPrimaryVertexMode; // produce files per primary vertex - EveWorkflowHelper::Bracket mTimeBracket; // [min, max] range in TF time for the filter - EveWorkflowHelper::Bracket mEtaBracket; // [min, max] eta range for the TPC tracks removal std::string mJsonPath; // folder where files are stored std::string mExt; // extension of created files (".json" or ".root") std::chrono::milliseconds mTimeInterval; // minimal interval between files in milliseconds - int mNumberOfFiles; // maximum number of files in folder - newer replaces older - int mNumberOfTracks; // maximum number of track in single file (0 means no limit) - int mNumberOfBytes; // number of bytes stored in period which causes stopping saving a new file - bool mTrackSorting; // perform sorting tracks by track time before applying filters - int mOnlyNthEvent; // process only every nth event. - int mMaxPrimaryVertices; // max number of primary vertices to draw per time frame bool mPrimaryVertexTriggers; // instead of drawing vertices with tracks (and maybe calorimeter triggers), draw vertices with calorimeter triggers (and maybe tracks) - float mPrimaryVertexMinZ; // minimum z position of the primary vertex - float mPrimaryVertexMaxZ; // maximum z position of the primary vertex - float mPrimaryVertexMinX; // minimum x position of the primary vertex - float mPrimaryVertexMaxX; // maximum x position of the primary vertex - float mPrimaryVertexMinY; // minimum y position of the primary vertex - float mPrimaryVertexMaxY; // maximum y position of the primary vertex - float mEMCALMaxCellTime; // max abs EMCAL cell time (in ns) - float mEMCALMinCellEnergy; // min EMCAL cell energy (in GeV) int mEventCounter = 0; std::chrono::time_point mTimeStamp; @@ -119,6 +93,7 @@ class O2DPLDisplaySpec : public o2::framework::Task std::shared_ptr mGGCCDBRequest; std::shared_ptr mEMCALCalibLoader; std::unique_ptr mEMCALCalibrator; + o2::tpc::VDriftHelper mTPCVDriftHelper{}; }; } // namespace o2::event_visualisation diff --git a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx index 4a8fe684d9f29..8c795dd01c79f 100644 --- a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx +++ b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx @@ -14,6 +14,7 @@ #include #include "EventVisualisationBase/ConfigurationManager.h" +#include "EventVisualisationBase/EveConfParam.h" #include "EventVisualisationDataConverter/VisualisationEventSerializer.h" #include "ReconstructionDataFormats/GlobalTrackID.h" #include "ReconstructionDataFormats/VtxTrackRef.h" @@ -22,6 +23,7 @@ #include "ITStracking/IOUtils.h" #include "MFTTracking/IOUtils.h" #include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" #include "DetectorsBase/GRPGeomHelper.h" #include "DetectorsBase/Propagator.h" #include "TPCBase/ParameterElectronics.h" @@ -152,6 +154,8 @@ bool EveWorkflowHelper::isInsideTimeBracket(float t) void EveWorkflowHelper::selectTracks(const CalibObjectsConst* calib, GID::mask_t maskCl, GID::mask_t maskTrk, GID::mask_t maskMatch) { + const auto& conf = EveConfParam::Instance(); + auto correctTrackTime = [this](auto& _tr, float t0, float terr) { if constexpr (isTPCTrack()) { // unconstrained TPC track, with t0 = TrackTPC.getTime0+0.5*(DeltaFwd-DeltaBwd) and terr = 0.5*(DeltaFwd+DeltaBwd) in TimeBins @@ -193,8 +197,7 @@ void EveWorkflowHelper::selectTracks(const CalibObjectsConst* calib, } } }; - - auto creator = [maskTrk, this, &correctTrackTime, &flagTime, &fixMFTMCHMIDLabel](auto& trk, GID gid, float time, float terr) { + auto creator = [&conf, maskTrk, this, &correctTrackTime, &flagTime, &fixMFTMCHMIDLabel](auto& trk, GID gid, float time, float terr) { fixMFTMCHMIDLabel(gid); const auto src = gid.getSource(); @@ -206,11 +209,11 @@ void EveWorkflowHelper::selectTracks(const CalibObjectsConst* calib, auto bracket = correctTrackTime(trk, time, terr); - if (mEnabledFilters.test(Filter::TimeBracket) && !isInsideTimeBracket(bracket)) { + if (mUseTimeBracket && !isInsideTimeBracket(bracket)) { return true; } - if (mEnabledFilters.test(Filter::ITSROF) && !isInsideITSROF(bracket)) { + if (conf.filterITSROF && !isInsideITSROF(bracket)) { return true; } @@ -218,36 +221,58 @@ void EveWorkflowHelper::selectTracks(const CalibObjectsConst* calib, // If the mode is disabled, // add every track to a symbolic "zero" primary vertex - if (!mPrimaryVertexMode) { + if (!conf.PVMode) { mPrimaryVertexTrackGIDs[0].push_back(gid); } return true; }; + auto prop = o2::base::Propagator::Instance(); this->mRecoCont->createTracksVariadic(creator); - - if (mPrimaryVertexMode) { + if (conf.PVMode) { + bool checkTPCDCA = conf.TPCOnlyMaxDCARZ[0] > 0.f || conf.TPCOnlyMaxDCARZ[1] > 0.f; const auto trackIndex = mRecoCont->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks const auto vtxRefs = mRecoCont->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs const auto totalPrimaryVertices = vtxRefs.size() - 1; // The last entry is for unassigned tracks, ignore them for (std::size_t iv = 0; iv < totalPrimaryVertices; iv++) { + const auto& pv = mRecoCont->getPrimaryVertex(iv); + if (pv.getX() < conf.PVXYZMin[0] || pv.getX() > conf.PVXYZMax[0] || + pv.getY() < conf.PVXYZMin[1] || pv.getY() > conf.PVXYZMax[1] || + pv.getZ() < conf.PVXYZMin[2] || pv.getZ() > conf.PVXYZMax[2]) { + continue; // skip vertex + } + + o2::math_utils::Point3D pvXYZ(pv.getX(), pv.getY(), pv.getZ()); const auto& vtref = vtxRefs[iv]; const gsl::span tracksForVertex(trackIndex.data() + vtref.getFirstEntry(), vtref.getEntries()); for (const auto& tvid : tracksForVertex) { - if (!mRecoCont->isTrackSourceLoaded(tvid.getSource())) { continue; } - - // TODO: fix TPC tracks? - - GID gid = tvid; + GID gid(tvid); fixMFTMCHMIDLabel(gid); - // If a track was not rejected, associate it with its primary vertex if (mGIDTrackTime.find(gid) != mGIDTrackTime.end()) { + // add optional cut on TPC-only tracks DCAz (corrected for the vertex time) + if (gid.getSource() == o2::dataformats::GlobalTrackID::TPC && checkTPCDCA) { + const auto& tpcTr = mRecoCont->getTPCTrack(gid); + o2::track::TrackPar trc{tpcTr}; + if (!tpcTr.hasBothSidesClusters()) { // need to correct track Z with this vertex time + float dz = (tpcTr.getTime0() * mTPCTimeBins2MUS - (pv.getTimeStamp().getTimeStamp() + mTPCVDrift->getTimeOffset())) * mTPCVDrift->getVDrift(); + if (tpcTr.hasCSideClustersOnly()) { + dz = -dz; + } + trc.setZ(trc.getZ() + dz); + } + std::array dca; + if (!prop->propagateToDCA(pvXYZ, trc, prop->getNominalBz(), 10., o2::base::PropagatorF::MatCorrType::USEMatCorrNONE, &dca) || + (conf.TPCOnlyMaxDCARZ[1] > 0. && std::abs(dca[1]) > conf.TPCOnlyMaxDCARZ[1]) || + (conf.TPCOnlyMaxDCARZ[0] > 0. && std::abs(dca[0]) > conf.TPCOnlyMaxDCARZ[0])) { + continue; + } + } mPrimaryVertexTrackGIDs[iv].push_back(gid); } } @@ -260,22 +285,22 @@ void EveWorkflowHelper::selectTowers() const auto& allTriggersPHOS = mRecoCont->getPHOSTriggers(); const auto& allTriggersEMCAL = mRecoCont->getEMCALTriggers(); const auto& allTriggersHMP = mRecoCont->getHMPClusterTriggers(); - + const auto& conf = EveConfParam::Instance(); auto filterTrigger = [&](const auto& trig) { const auto time = bcDiffToTFTimeMUS(trig.getBCData()); - if (mEnabledFilters.test(Filter::TimeBracket) && !isInsideTimeBracket(time)) { + if (mUseTimeBracket && !isInsideTimeBracket(time)) { return false; } - if (mEnabledFilters.test(Filter::ITSROF) && !isInsideITSROF(time)) { + if (EveConfParam::Instance().filterITSROF && !isInsideITSROF(time)) { return false; } return true; }; - if (mPrimaryVertexMode) { + if (conf.PVMode) { const auto trackIndex = mRecoCont->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks const auto vtxRefs = mRecoCont->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs const auto totalPrimaryVertices = vtxRefs.size() - 1; // The last entry is for unassigned tracks, ignore them @@ -345,7 +370,7 @@ void EveWorkflowHelper::selectTowers() void EveWorkflowHelper::setITSROFs() { - if (mEnabledFilters.test(Filter::ITSROF)) { + if (EveConfParam::Instance().filterITSROF) { const auto& irFrames = mRecoCont->getIRFramesITS(); for (const auto& irFrame : irFrames) { @@ -356,6 +381,7 @@ void EveWorkflowHelper::setITSROFs() void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks) { + const auto& conf = EveConfParam::Instance(); if (mPrimaryVertexTrackGIDs.find(primaryVertexIdx) == mPrimaryVertexTrackGIDs.end()) { LOGF(info, "Primary vertex %d has no tracks", primaryVertexIdx); } else { @@ -364,6 +390,7 @@ void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks) }; auto& tracks = mPrimaryVertexTrackGIDs.at(primaryVertexIdx); + float pvTime = conf.PVMode ? mRecoCont->getPrimaryVertex(primaryVertexIdx).getTimeStamp().getTimeStamp() : -1e9; if (sortTracks) { std::sort(tracks.begin(), tracks.end(), @@ -374,8 +401,8 @@ void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks) auto trackCount = tracks.size(); - if (mEnabledFilters.test(Filter::TotalNTracks) && trackCount >= mMaxNTracks) { - trackCount = mMaxNTracks; + if (conf.maxTracks > 0 && trackCount >= conf.maxTracks) { + trackCount = conf.maxTracks; } for (std::size_t it = 0; it < trackCount; it++) { @@ -387,9 +414,20 @@ void EveWorkflowHelper::draw(std::size_t primaryVertexIdx, bool sortTracks) case GID::ITS: drawITS(gid, tim); break; - case GID::TPC: - drawTPC(gid, tim); - break; + case GID::TPC: { + float dz = 0.f; + if (conf.PVMode) { // for TPC the nominal time (center of the bracket) is stored but in the PVMode we correct it by the PV time + tim = pvTime; + const auto& tpcTr = mRecoCont->getTPCTrack(gid); + if (!tpcTr.hasBothSidesClusters()) { // need to correct track Z with this vertex time + float dz = (tpcTr.getTime0() * mTPCTimeBins2MUS - (pvTime + mTPCVDrift->getTimeOffset())) * mTPCVDrift->getVDrift(); + if (tpcTr.hasCSideClustersOnly()) { + dz = -dz; + } + } + } + drawTPC(gid, tim, dz); + } break; case GID::MFT: drawMFT(gid, tim); break; @@ -628,6 +666,7 @@ void EveWorkflowHelper::drawEMC(GID gid) const auto& trig = mRecoCont->getEMCALTriggers()[gid.getIndex()]; const auto time = bcDiffToTFTimeMUS(trig.getBCData()); const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects()); + const auto& conf = EveConfParam::Instance(); for (const auto& cell : cellsForTrigger) { if (!(cell.getType() == o2::emcal::ChannelType_t::HIGH_GAIN || cell.getType() == o2::emcal::ChannelType_t::LOW_GAIN)) { @@ -646,11 +685,11 @@ void EveWorkflowHelper::drawEMC(GID gid) cellTime = calibCell->getTimeStamp(); cellEnergy = calibCell->getEnergy(); } - if (std::abs(cellTime) > mEMCALMaxCellTime) { + if (std::abs(cellTime) > conf.EMCCellTimeMax) { // cell rejected by time cut (pileup or noise) continue; } - if (cellEnergy < mEMCALMinCellEnergy) { + if (cellEnergy < conf.EMCCellEnergyMin) { // cell rejected by energy cut (rejection of soft cells) continue; } @@ -681,7 +720,7 @@ void EveWorkflowHelper::drawITSTPC(GID gid, float trackTime, GID::Source source) const auto& track = mRecoCont->getTPCITSTrack(gid); addTrackToEvent(track, gid, trackTime, 0., source); drawITSClusters(track.getRefITS()); // trackTime - drawTPCClusters(track.getRefTPC()); // trackTime * mMUS2TPCTimeBins + drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins); } void EveWorkflowHelper::drawITSTPCTOF(GID gid, float trackTime, GID::Source source) @@ -689,7 +728,7 @@ void EveWorkflowHelper::drawITSTPCTOF(GID gid, float trackTime, GID::Source sour const auto& track = mRecoCont->getITSTPCTOFTrack(gid); addTrackToEvent(track, gid, trackTime, 0., source); drawITSClusters(track.getRefITS()); // trackTime - drawTPCClusters(track.getRefTPC()); // trackTime * mMUS2TPCTimeBins + drawTPCClusters(track.getRefTPC(), trackTime * mMUS2TPCTimeBins); drawTOFClusters(gid); } @@ -698,7 +737,7 @@ void EveWorkflowHelper::drawTPCTRD(GID gid, float trackTime, GID::Source source) // LOG(info) << "EveWorkflowHelper::drawTPCTRD " << gid; const auto& tpcTrdTrack = mRecoCont->getTPCTRDTrack(gid); addTrackToEvent(tpcTrdTrack, gid, trackTime, 0., source); - drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId()); // trackTime * mMUS2TPCTimeBins + drawTPCClusters(tpcTrdTrack.getRefGlobalTrackId(), trackTime * mMUS2TPCTimeBins); drawTRDClusters(tpcTrdTrack); // tracktime } @@ -734,7 +773,7 @@ void EveWorkflowHelper::drawTPCTOF(GID gid, float trackTime) const auto& trTPCTOF = mRecoCont->getTPCTOFTrack(gid); const auto& match = mRecoCont->getTPCTOFMatch(gid.getIndex()); addTrackToEvent(trTPCTOF, gid, trackTime, 0); - drawTPCClusters(match.getTrackRef()); // trackTime * mMUS2TPCTimeBins + drawTPCClusters(match.getTrackRef(), trackTime * mMUS2TPCTimeBins); drawTOFClusters(gid); // trackTime } @@ -937,19 +976,21 @@ void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime } // TPC cluseters for given TPC track (gid) -void EveWorkflowHelper::drawTPCClusters(GID gid) // , float trackTimeTB +void EveWorkflowHelper::drawTPCClusters(GID gid, float trackTimeTB) { const auto& trc = mRecoCont->getTPCTrack(gid); auto mTPCTracksClusIdx = mRecoCont->getTPCTracksClusterRefs(); auto mTPCClusterIdxStruct = &mRecoCont->getTPCClusters(); - + if (trackTimeTB < -1e9) { + trackTimeTB = trc.getTime0(); + } // store the TPC cluster positions for (int iCl = trc.getNClusterReferences(); iCl--;) { uint8_t sector, row; const auto& clTPC = trc.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector, row); std::array xyz; - this->mTPCFastTransform->TransformIdeal(sector, row, clTPC.getPad(), clTPC.getTime(), xyz[0], xyz[1], xyz[2], trc.getTime0()); // in sector coordinate + this->mTPCFastTransform->TransformIdeal(sector, row, clTPC.getPad(), clTPC.getTime(), xyz[0], xyz[1], xyz[2], trackTimeTB); // in sector coordinate o2::math_utils::rotateZ(xyz, o2::math_utils::sector2Angle(sector % o2::tpc::SECTORSPERSIDE)); // lab coordinate (global) mEvent.addCluster(xyz.data()); // trackTimeTB / mMUS2TPCTimeBins } @@ -968,23 +1009,23 @@ void EveWorkflowHelper::drawMFTClusters(GID gid) // float trackTime } } -void EveWorkflowHelper::drawTPC(GID gid, float trackTime) +void EveWorkflowHelper::drawTPC(GID gid, float trackTime, float dz) { const auto& tr = mRecoCont->getTPCTrack(gid); - if (mEnabledFilters.test(Filter::EtaBracket) && mEtaBracket.isOutside(tr.getEta()) == Bracket::Relation::Inside) { + if (mUseEtaBracketTPC && mEtaBracketTPC.isOutside(tr.getEta()) == Bracket::Relation::Inside) { return; } - addTrackToEvent(tr, gid, trackTime, 4.f, GID::TPC); - - drawTPCClusters(gid); // trackTime + addTrackToEvent(tr, gid, trackTime, dz, GID::TPC); + float clTime0 = EveConfParam::Instance().PVMode ? trackTime * mMUS2TPCTimeBins : -2e9; // in PVMode use supplied real time converted to TB, otherwise pass dummy time to use tpcTrack.getTime0 + drawTPCClusters(gid, clTime0); // trackTime } void EveWorkflowHelper::drawITS(GID gid, float trackTime) { const auto& tr = mRecoCont->getITSTrack(gid); - addTrackToEvent(tr, gid, trackTime, 1.f, GID::ITS); + addTrackToEvent(tr, gid, trackTime, 0.f, GID::ITS); drawITSClusters(gid); // tracktime } @@ -1095,8 +1136,17 @@ void EveWorkflowHelper::drawTRDClusters(const o2::trd::TrackTRD& tpcTrdTrack) // } } -EveWorkflowHelper::EveWorkflowHelper(const FilterSet& enabledFilters, std::size_t maxNTracks, const Bracket& timeBracket, const Bracket& etaBracket, bool primaryVertexMode) : mEnabledFilters(enabledFilters), mMaxNTracks(maxNTracks), mTimeBracket(timeBracket), mEtaBracket(etaBracket), mPrimaryVertexMode(primaryVertexMode) +EveWorkflowHelper::EveWorkflowHelper() { + const auto& conf = EveConfParam::Instance(); + if (conf.timeMinMax[0] >= 0.f && conf.timeMinMax[0] < conf.timeMinMax[1]) { + mUseTimeBracket = true; + mTimeBracket = {conf.timeMinMax[0], conf.timeMinMax[1]}; + } + if (conf.TPCEtaAbsMax > 0.f) { + mUseEtaBracketTPC = true; + mEtaBracketTPC = {-conf.TPCEtaAbsMax, conf.TPCEtaAbsMax}; + } o2::mch::TrackExtrap::setField(); this->mMFTGeom = o2::mft::GeometryTGeo::Instance(); this->mMFTGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); @@ -1106,6 +1156,7 @@ EveWorkflowHelper::EveWorkflowHelper(const FilterSet& enabledFilters, std::size_ this->mPHOSGeom = o2::phos::Geometry::GetInstance(""); this->mTPCFastTransform = (o2::tpc::TPCFastTransformHelperO2::instance()->create(0)); const auto& elParams = o2::tpc::ParameterElectronics::Instance(); + mTPCTimeBins2MUS = elParams.ZbinWidth; mMUS2TPCTimeBins = 1. / elParams.ZbinWidth; mTPCBin2MUS = elParams.ZbinWidth; const auto grp = o2::base::GRPGeomHelper::instance().getGRPECS(); @@ -1122,6 +1173,14 @@ EveWorkflowHelper::EveWorkflowHelper(const FilterSet& enabledFilters, std::size_ } } +void EveWorkflowHelper::setTPCVDrift(const o2::tpc::VDriftCorrFact* v) +{ + mTPCVDrift = v; + if (v) { + o2::tpc::TPCFastTransformHelperO2::instance()->updateCalibration(*mTPCFastTransform.get(), 0, v->corrFact, v->refVDrift, v->getTimeOffset()); + } +} + GID::Source EveWorkflowHelper::detectorMapToGIDSource(uint8_t dm) { switch (dm) { diff --git a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx index af8c8a353514d..414d70c443541 100644 --- a/EventVisualisation/Workflow/src/O2DPLDisplay.cxx +++ b/EventVisualisation/Workflow/src/O2DPLDisplay.cxx @@ -17,6 +17,7 @@ #include "Framework/CompletionPolicyHelpers.h" #include "EveWorkflow/O2DPLDisplay.h" #include "EveWorkflow/EveWorkflowHelper.h" +#include "EventVisualisationBase/EveConfParam.h" #include "EventVisualisationBase/ConfigurationManager.h" #include "DetectorsBase/Propagator.h" #include "DataFormatsGlobalTracking/RecoContainer.h" @@ -63,37 +64,15 @@ void customize(std::vector& workflowOptions) {"use-root-format", VariantType::Bool, false, {"instead of eve format (default) use root format"}}, {"eve-hostname", VariantType::String, "", {"name of the host allowed to produce files (empty means no limit)"}}, {"eve-dds-collection-index", VariantType::Int, -1, {"number of dpl collection allowed to produce files (-1 means no limit)"}}, - {"number-of_files", VariantType::Int, 150, {"maximum number of json files in folder"}}, - {"number-of_tracks", VariantType::Int, -1, {"maximum number of track stored in json file (-1 means no limit)"}}, - {"number-of_bytes", VariantType::Int, 3000000, {"number of bytes stored in time interval which stops producing new data file (-1 means no limit)"}}, {"time-interval", VariantType::Int, 5000, {"time interval in milliseconds between stored files"}}, {"disable-mc", VariantType::Bool, false, {"disable visualization of MC data"}}, {"disable-write", VariantType::Bool, false, {"disable writing output files"}}, {"display-clusters", VariantType::String, "ITS,TPC,TRD,TOF", {"comma-separated list of clusters to display"}}, {"display-tracks", VariantType::String, "TPC,ITS,ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF", {"comma-separated list of tracks to display"}}, {"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}}, - {"configKeyValues", VariantType::String, "", {"semicolon separated key=value strings ..."}}, + {"configKeyValues", VariantType::String, "", {"semicolon separated key=value strings, e.g. EveConfParam content..."}}, {"skipOnEmptyInput", VariantType::Bool, false, {"don't run the ED when no input is provided"}}, - {"min-its-tracks", VariantType::Int, -1, {"don't create file if less than the specified number of ITS tracks is present"}}, - {"min-tracks", VariantType::Int, 1, {"don't create file if less than the specified number of all tracks is present"}}, - {"filter-its-rof", VariantType::Bool, false, {"don't display tracks outside ITS readout frame"}}, - {"filter-time-min", VariantType::Float, -1.f, {"display tracks only in [min, max] microseconds time range in each time frame, requires --filter-time-max to be specified as well"}}, - {"filter-time-max", VariantType::Float, -1.f, {"display tracks only in [min, max] microseconds time range in each time frame, requires --filter-time-min to be specified as well"}}, - {"remove-tpc-abs-eta", VariantType::Float, 0.f, {"remove TPC tracks in [-eta, +eta] range"}}, - {"track-sorting", VariantType::Bool, true, {"sort track by track time before applying filters"}}, - {"only-nth-event", VariantType::Int, 0, {"process only every nth event"}}, - {"primary-vertex-mode", VariantType::Bool, false, {"produce jsons with individual primary vertices, not total time frame data"}}, - {"max-primary-vertices", VariantType::Int, 5, {"maximum number of primary vertices to draw per time frame"}}, - {"primary-vertex-triggers", VariantType::Bool, false, {"instead of drawing vertices with tracks (and maybe calorimeter triggers), draw vertices with calorimeter triggers (and maybe tracks)"}}, - {"no-calibrate-emcal", VariantType::Bool, false, {"Do not apply on-the-fly EMCAL calibration"}}, - {"emcal-max-celltime", VariantType::Float, 100.f, {"Max. EMCAL cell time (in ns)"}}, - {"emcal-min-cellenergy", VariantType::Float, 0.3f, {"Min. EMCAL cell energy (in GeV)"}}, - {"primary-vertex-min-z", VariantType::Float, -o2::constants::math::VeryBig, {"minimum z position for primary vertex"}}, - {"primary-vertex-max-z", VariantType::Float, o2::constants::math::VeryBig, {"maximum z position for primary vertex"}}, - {"primary-vertex-min-x", VariantType::Float, -o2::constants::math::VeryBig, {"minimum x position for primary vertex"}}, - {"primary-vertex-max-x", VariantType::Float, o2::constants::math::VeryBig, {"maximum x position for primary vertex"}}, - {"primary-vertex-min-y", VariantType::Float, -o2::constants::math::VeryBig, {"minimum y position for primary vertex"}}, - {"primary-vertex-max-y", VariantType::Float, o2::constants::math::VeryBig, {"maximum y position for primary vertex"}}}; + }; o2::raw::HBFUtilsInitializer::addConfigOption(options); std::swap(workflowOptions, options); @@ -112,10 +91,12 @@ void O2DPLDisplaySpec::init(InitContext& ic) void O2DPLDisplaySpec::run(ProcessingContext& pc) { - if (!this->mEveHostNameMatch) { + const auto& conf = EveConfParam::Instance(); + + if (!mEveHostNameMatch) { return; } - if (this->mOnlyNthEvent && this->mEventCounter++ % this->mOnlyNthEvent != 0) { + if (conf.onlyNthEvent > 1 && mEventCounter++ % conf.onlyNthEvent) { return; } LOGF(info, "------------------------ O2DPLDisplay::run version ", o2_eve_version, " ------------------------------------"); @@ -142,19 +123,12 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) } } - EveWorkflowHelper::FilterSet enabledFilters; - - enabledFilters.set(EveWorkflowHelper::Filter::ITSROF, this->mFilterITSROF); - enabledFilters.set(EveWorkflowHelper::Filter::TimeBracket, this->mFilterTime); - enabledFilters.set(EveWorkflowHelper::Filter::EtaBracket, this->mRemoveTPCEta); - enabledFilters.set(EveWorkflowHelper::Filter::TotalNTracks, this->mNumberOfTracks != -1); - EveWorkflowHelper helper(enabledFilters, this->mNumberOfTracks, this->mTimeBracket, this->mEtaBracket, this->mPrimaryVertexMode); + EveWorkflowHelper helper; + helper.setTPCVDrift(&mTPCVDriftHelper.getVDriftObject()); helper.setRecoContainer(&recoCont); if (mEMCALCalibrator) { helper.setEMCALCellRecalibrator(mEMCALCalibrator.get()); } - helper.setMaxEMCALCellTime(mEMCALMaxCellTime); - helper.setMinEMCALCellEnergy(mEMCALMinCellEnergy); helper.setITSROFs(); helper.selectTracks(&(mData.mConfig.configCalib), mClMask, mTrkMask, mTrkMask); @@ -167,43 +141,35 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) std::size_t filesSaved = 0; const std::vector dirs = o2::event_visualisation::DirectoryLoader::allFolders(this->mJsonPath); const std::string marker = "_"; - const std::vector exts = { - ".json", ".root", ".eve"}; + const std::vector exts = {".json", ".root", ".eve"}; auto processData = [&](const auto& dataMap) { for (const auto& keyVal : dataMap) { - if (filesSaved >= mMaxPrimaryVertices) { + if (conf.maxPVs > 0 && filesSaved >= conf.maxPVs) { break; } - if (this->mNumberOfBytes != -1) { + if (conf.maxBytes > 0) { auto periodStart = duration_cast(system_clock::now().time_since_epoch()).count() - this->mTimeInterval.count(); - if (!DirectoryLoader::canCreateNextFile( - dirs, marker, exts, periodStart, this->mNumberOfBytes)) { - LOGF(info, "Already too much data (> %d) to transfer in this period - event will not be not saved ...", this->mNumberOfBytes); + if (!DirectoryLoader::canCreateNextFile(dirs, marker, exts, periodStart, conf.maxBytes)) { + LOGF(info, "Already too much data (> %d) to transfer in this period - event will not be not saved ...", conf.maxBytes); break; } } const auto pv = keyVal.first; bool save = false; - if (mPrimaryVertexMode) { - auto primaryVertex = recoCont.getPrimaryVertices()[pv]; - auto primaryVertex_X = primaryVertex.getX(); - auto primaryVertex_Y = primaryVertex.getY(); - auto primaryVertex_Z = primaryVertex.getZ(); - if ((primaryVertex_X >= mPrimaryVertexMinX) & (primaryVertex_X <= mPrimaryVertexMaxX) & (primaryVertex_Y >= mPrimaryVertexMinY) & (primaryVertex_Y <= mPrimaryVertexMaxY) & (primaryVertex_Z >= mPrimaryVertexMinZ) & (primaryVertex_Z <= mPrimaryVertexMaxZ)) { - helper.draw(pv, mTrackSorting); - save = true; - } + if (conf.PVMode) { + helper.draw(pv, conf.trackSorting); + save = true; } else { - helper.draw(pv, mTrackSorting); + helper.draw(pv, conf.trackSorting); save = true; } - if (this->mMinITSTracks != -1 && helper.mEvent.getDetectorTrackCount(detectors::DetID::ITS) < this->mMinITSTracks) { + if (conf.minITSTracks > -1 && helper.mEvent.getDetectorTrackCount(detectors::DetID::ITS) < conf.minITSTracks) { save = false; } - if (this->mMinTracks != -1 && helper.mEvent.getTrackCount() < this->mMinTracks) { + if (conf.minTracks > -1 && helper.mEvent.getTrackCount() < conf.minTracks) { save = false; } @@ -220,7 +186,7 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) helper.mEvent.setRunType(this->mRunType); helper.mEvent.setPrimaryVertex(pv); helper.mEvent.setCreationTime(tinfo.creation); - helper.save(this->mJsonPath, this->mExt, this->mNumberOfFiles); + helper.save(this->mJsonPath, this->mExt, conf.maxFiles); filesSaved++; currentTime = std::chrono::high_resolution_clock::now(); // time AFTER save this->mTimeStamp = currentTime; // next run AFTER period counted from last save @@ -229,7 +195,7 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc) helper.clear(); } }; - if (mPrimaryVertexTriggers) { + if (conf.PVTriggersMode) { processData(helper.mPrimaryVertexTriggerGIDs); } else { processData(helper.mPrimaryVertexTrackGIDs); @@ -274,6 +240,10 @@ void O2DPLDisplaySpec::updateTimeDependentParams(ProcessingContext& pc) { o2::base::GRPGeomHelper::instance().checkUpdates(pc); static bool initOnceDone = false; + mTPCVDriftHelper.extractCCDBInputs(pc); + if (mTPCVDriftHelper.isUpdated()) { + mTPCVDriftHelper.acknowledgeUpdate(); + } if (!initOnceDone) { // this params need to be queried only once initOnceDone = true; auto grpECS = o2::base::GRPGeomHelper::instance().getGRPECS(); // RS @@ -302,6 +272,10 @@ void O2DPLDisplaySpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) mData.setMFTDict((const o2::itsmft::TopologyDictionary*)obj); return; } + if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) { + + return; + } } WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) @@ -322,6 +296,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) } auto eveHostName = cfgc.options().get("eve-hostname"); o2::conf::ConfigurableParam::updateFromString(cfgc.options().get("configKeyValues")); + const auto& conf = EveConfParam::Instance(); + bool useMC = !cfgc.options().get("disable-mc"); bool disableWrite = cfgc.options().get("disable-write"); @@ -342,9 +318,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) } std::chrono::milliseconds timeInterval(cfgc.options().get("time-interval")); - int numberOfFiles = cfgc.options().get("number-of_files"); - int numberOfTracks = cfgc.options().get("number-of_tracks"); - int numberOfBytes = cfgc.options().get("number-of_bytes"); GlobalTrackID::mask_t srcTrk = GlobalTrackID::getSourcesMask(cfgc.options().get("display-tracks")); GlobalTrackID::mask_t srcCl = GlobalTrackID::getSourcesMask(cfgc.options().get("display-clusters")); @@ -386,55 +359,22 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return std::make_tuple(optEnabled, bracket); }; - const auto [filterTime, timeBracket] = isRangeEnabled("filter-time-min", "filter-time-max"); - - const auto etaRange = cfgc.options().get("remove-tpc-abs-eta"); - - bool removeTPCEta = false; - EveWorkflowHelper::Bracket etaBracket; - - if (etaRange != 0.f) { - etaBracket = EveWorkflowHelper::Bracket{-etaRange, etaRange}; - removeTPCEta = true; - } - std::shared_ptr dataRequest = std::make_shared(); dataRequest->requestTracks(srcTrk, useMC); dataRequest->requestClusters(srcCl, useMC); - auto filterITSROF = cfgc.options().get("filter-its-rof"); - - if (filterITSROF) { + if (conf.filterITSROF) { dataRequest->requestIRFramesITS(); InputHelper::addInputSpecsIRFramesITS(cfgc, specs); } - auto primaryVertexMode = cfgc.options().get("primary-vertex-mode"); - auto maxPrimaryVertices = cfgc.options().get("max-primary-vertices"); - InputHelper::addInputSpecs(cfgc, specs, srcCl, srcTrk, srcTrk, useMC); - if (primaryVertexMode) { + if (conf.PVMode) { dataRequest->requestPrimaryVertices(useMC); InputHelper::addInputSpecsPVertex(cfgc, specs, useMC); } + o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs); - auto minITSTracks = cfgc.options().get("min-its-tracks"); - auto minTracks = cfgc.options().get("min-tracks"); - auto onlyNthEvent = cfgc.options().get("only-nth-event"); - auto tracksSorting = cfgc.options().get("track-sorting"); - auto primaryVertexTriggers = cfgc.options().get("primary-vertex-triggers"); - auto primaryVertexMinZ = cfgc.options().get("primary-vertex-min-z"); - auto primaryVertexMaxZ = cfgc.options().get("primary-vertex-max-z"); - auto primaryVertexMinX = cfgc.options().get("primary-vertex-min-x"); - auto primaryVertexMaxX = cfgc.options().get("primary-vertex-max-x"); - auto primaryVertexMinY = cfgc.options().get("primary-vertex-min-y"); - auto primaryVertexMaxY = cfgc.options().get("primary-vertex-max-y"); - auto maxEMCALCellTime = cfgc.options().get("emcal-max-celltime"); - auto minEMCALCellEnergy = cfgc.options().get("emcal-min-cellenergy"); - - if (numberOfTracks == -1) { - tracksSorting = false; // do not sort if all tracks are allowed - } auto ggRequest = std::make_shared(false, // orbitResetTime true, // GRPECS=true false, // GRPLHCIF @@ -445,7 +385,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) true); // query only once all objects except mag.field std::shared_ptr emcalCalibLoader; - if (!cfgc.options().get("no-calibrate-emcal")) { + if (conf.calibrateEMC) { emcalCalibLoader = std::make_shared(); emcalCalibLoader->enableTimeCalib(true); emcalCalibLoader->enableBadChannelMap(true); @@ -457,7 +397,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) "o2-eve-export", dataRequest->inputs, {}, - AlgorithmSpec{adaptFromTask(disableWrite, useMC, srcTrk, srcCl, dataRequest, ggRequest, emcalCalibLoader, jsonFolder, ext, timeInterval, numberOfFiles, numberOfTracks, numberOfBytes, eveHostNameMatch, minITSTracks, minTracks, filterITSROF, filterTime, timeBracket, removeTPCEta, etaBracket, tracksSorting, onlyNthEvent, primaryVertexMode, maxPrimaryVertices, primaryVertexTriggers, primaryVertexMinZ, primaryVertexMaxZ, primaryVertexMinX, primaryVertexMaxX, primaryVertexMinY, primaryVertexMaxY, maxEMCALCellTime, minEMCALCellEnergy)}}); + AlgorithmSpec{adaptFromTask(disableWrite, useMC, srcTrk, srcCl, dataRequest, ggRequest, emcalCalibLoader, jsonFolder, ext, timeInterval, eveHostNameMatch)}}); // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit o2::raw::HBFUtilsInitializer hbfIni(cfgc, specs); diff --git a/prodtests/full-system-test/dpl-workflow.sh b/prodtests/full-system-test/dpl-workflow.sh index 4811c0970131c..77f16c2ea51fd 100755 --- a/prodtests/full-system-test/dpl-workflow.sh +++ b/prodtests/full-system-test/dpl-workflow.sh @@ -81,7 +81,6 @@ TRD_CONFIG= TRD_CONFIG_KEY= TRD_FILTER_CONFIG= CPV_INPUT=raw -EVE_CONFIG=" --jsons-folder $EDJSONS_DIR" MIDDEC_CONFIG= EMCRAW2C_CONFIG= PHS_CONFIG= @@ -90,6 +89,8 @@ CTP_CONFIG= TPC_CORR_OPT= TPC_CORR_KEY= INTERACTION_TAG_CONFIG_KEY= +EVE_OPT=" --jsons-folder $EDJSONS_DIR" +: ${EVE_CONFIG:=} : ${STRTRACKING:=} : ${ITSEXTRAERR:=} : ${TRACKTUNETPCINNER:=} @@ -202,7 +203,7 @@ has_detector_flp_processing CPV && CPV_INPUT=digits ! has_detector_flp_processing TOF && TOF_CONFIG+=" --local-cmp" if [[ $EPNSYNCMODE == 1 ]]; then - EVE_CONFIG+=" --eve-dds-collection-index 0" + EVE_OPT+=" --eve-dds-collection-index 0" MIDDEC_CONFIG+=" --feeId-config-file \"$MID_FEEID_MAP\"" if [[ $EXTINPUT == 1 ]] && [[ $GPUTYPE != "CPU" ]] && [[ -z "$GPU_NUM_MEM_REG_CALLBACKS" ]]; then if [[ $NUMAGPUIDS == 1 ]]; then @@ -225,17 +226,18 @@ if [[ $SYNCRAWMODE == 1 ]] || [[ $SYNCMODE == 0 && $CTFINPUT == 1 && $GPUTYPE != fi if [[ $SYNCMODE == 1 && "0${ED_NO_ITS_ROF_FILTER:-}" != "01" && $BEAMTYPE == "PbPb" ]] && has_detector ITS; then - EVE_CONFIG+=" --filter-its-rof" + EVE_CONFIG+=";eveconf.filterITSROF=true;" fi if [[ ! -z ${EVE_NTH_EVENT:-} ]]; then - EVE_CONFIG+=" --only-nth-event=$EVE_NTH_EVENT" + EVE_CONFIG+=";eveconf.onlyNthEvent=$EVE_NTH_EVENT;" fi +EVE_CONFIG+=";eveconf.maxTracks=5000;" if [[ $RUNTYPE == "SYNTHETIC" ]]; then - EVE_CONFIG+=" --number-of_files 20" + EVE_CONFIG+=";eveconf.maxFiles=20;" elif [[ $RUNTYPE == "PHYSICS" ]]; then - EVE_CONFIG+=" --primary-vertex-triggers" + EVE_CONFIG+=";eveconf.PVTriggersMode=true;" fi if [[ $GPUTYPE != "CPU" && $NUMAGPUIDS != 0 ]] && [[ -z ${ROCR_VISIBLE_DEVICES:-} || ${ROCR_VISIBLE_DEVICES:-} = "0,1,2,3,4,5,6,7" || ${ROCR_VISIBLE_DEVICES:-} = "0,1,2,3" || ${ROCR_VISIBLE_DEVICES:-} = "4,5,6,7" ]]; then @@ -352,7 +354,7 @@ if has_processing_step MUON_SYNC_RECO; then [[ $RUNTYPE == "COSMICS" ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow:-} ]] && CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow="MFTTracking.FullClusterScan=true" fi [[ $SYNCRAWMODE == 1 ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_zdc_digits_reco:-} ]] && CONFIG_EXTRA_PROCESS_o2_zdc_digits_reco='RecoParamZDC.tdc_calib[9]=1;RecoParamZDC.tdc_calib[0]=1;RecoParamZDC.tdc_calib[8]=1;RecoParamZDC.tdc_calib[1]=1;RecoParamZDC.tdc_calib[3]=1;RecoParamZDC.tdc_calib[6]=1;RecoParamZDC.tdc_calib[5]=1;RecoParamZDC.tdc_calib[4]=1;RecoParamZDC.tdc_calib[2]=1;RecoParamZDC.tdc_calib[7]=1;RecoParamZDC.energy_calib[13]=1;RecoParamZDC.energy_calib[12]=1;RecoParamZDC.energy_calib[11]=1;RecoParamZDC.energy_calib[6]=1;RecoParamZDC.energy_calib[25]=1;RecoParamZDC.energy_calib[14]=1;RecoParamZDC.energy_calib[20]=1;RecoParamZDC.energy_calib[5]=1;RecoParamZDC.energy_calib[0]=1;RecoParamZDC.energy_calib[19]=1;RecoParamZDC.tower_calib[1]=1;RecoParamZDC.tower_calib[2]=1;RecoParamZDC.tower_calib[3]=1;RecoParamZDC.tower_calib[4]=1;RecoParamZDC.tower_calib[24]=1;RecoParamZDC.tower_calib[21]=1;RecoParamZDC.tower_calib[22]=1;RecoParamZDC.tower_calib[23]=1;RecoParamZDC.tower_calib[18]=1;RecoParamZDC.tower_calib[16]=1;RecoParamZDC.tower_calib[17]=1;RecoParamZDC.tower_calib[15]=1;RecoParamZDC.tower_calib[8]=1;RecoParamZDC.tower_calib[9]=1;RecoParamZDC.tower_calib[7]=1;RecoParamZDC.tower_calib[10]=1' -[[ $RUNTYPE != "COSMICS" ]] && [[ $RUNTYPE != "TECHNICAL" ]] && has_detectors_reco ITS && has_detector_matching PRIMVTX && [[ ! -z "$VERTEXING_SOURCES" ]] && EVE_CONFIG+=" --primary-vertex-mode" +[[ $RUNTYPE != "COSMICS" ]] && [[ $RUNTYPE != "TECHNICAL" ]] && has_detectors_reco ITS && has_detector_matching PRIMVTX && [[ ! -z "$VERTEXING_SOURCES" ]] && EVE_CONFIG+=";eveconf.PVMode=true;" [[ $SYNCRAWMODE == 1 ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_trd_global_tracking:-} ]] && CONFIG_EXTRA_PROCESS_o2_trd_global_tracking='GPU_rec_trd.maxChi2=25;GPU_rec_trd.penaltyChi2=20;GPU_rec_trd.extraRoadY=4;GPU_rec_trd.extraRoadZ=10;GPU_rec_trd.applyDeflectionCut=0;GPU_rec_trd.trkltResRPhiIdeal=1' [[ $SYNCRAWMODE == 1 ]] && [[ -z ${ARGS_EXTRA_PROCESS_o2_phos_reco_workflow:-} ]] && ARGS_EXTRA_PROCESS_o2_phos_reco_workflow='--presamples 2 --fitmethod semigaus' [[ $SYNCRAWMODE == 1 ]] && [[ $BEAMTYPE == "PbPb" ]] && [[ -z ${CONFIG_EXTRA_PROCESS_o2_calibration_emcal_channel_calib_workflow:-} ]] && CONFIG_EXTRA_PROCESS_o2_calibration_emcal_channel_calib_workflow='EMCALCalibParams.selectedClassMasks=C0TVX-NONE-NOPF-EMC:c0tvxtsc-b-nopf-emc:C0TVXTCE-B-NOPF-EMC;EMCALCalibParams.fractionEvents_bc=0.3' @@ -628,7 +630,7 @@ workflow_has_parameters CALIB CALIB_LOCAL_INTEGRATED_AGGREGATOR && { source ${CA # RS this is a temporary setting : ${ED_TRACKS:=$TRACK_SOURCES} : ${ED_CLUSTERS:=$TRACK_SOURCES} -workflow_has_parameter EVENT_DISPLAY && [[ $NUMAID == 0 ]] && [[ ! -z "$ED_TRACKS" ]] && [[ ! -z "$ED_CLUSTERS" ]] && [[ $EPNSYNCMODE == 0 || ${EPN_NODE_MI100:-0} == 0 ]] && add_W o2-eve-export-workflow "--display-tracks $ED_TRACKS --display-clusters $ED_CLUSTERS --skipOnEmptyInput $DISABLE_ROOT_INPUT --number-of_tracks 50000 $EVE_CONFIG $DISABLE_MC" "$ITSMFT_STROBES" +workflow_has_parameter EVENT_DISPLAY && [[ $NUMAID == 0 ]] && [[ ! -z "$ED_TRACKS" ]] && [[ ! -z "$ED_CLUSTERS" ]] && [[ $EPNSYNCMODE == 0 || ${EPN_NODE_MI100:-0} == 0 ]] && add_W o2-eve-export-workflow "--display-tracks $ED_TRACKS --display-clusters $ED_CLUSTERS --skipOnEmptyInput $DISABLE_ROOT_INPUT $EVE_OPT $DISABLE_MC" "$ITSMFT_STROBES;$EVE_CONFIG" workflow_has_parameter GPU_DISPLAY && [[ $NUMAID == 0 ]] && add_W o2-gpu-display "${ED_TRACKS+--display-tracks} $ED_TRACKS ${ED_CLUSTERS+--display-clusters} $ED_CLUSTERS" From 3615d30d967849c89499d7b5e13ac6f0b8dba1b5 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 5 Nov 2024 18:54:10 +0100 Subject: [PATCH 0415/2205] ITSGPU: Run CellFinding on GPU (#13653) --- .../TrackParametrizationWithError.h | 4 +- Detectors/ITSMFT/ITS/tracking/CMakeLists.txt | 1 - .../GPU/ITStrackingGPU/TimeFrameGPU.h | 43 +- .../GPU/ITStrackingGPU/TrackingKernels.h | 35 ++ .../ITS/tracking/GPU/cuda/CMakeLists.txt | 1 + .../ITS/tracking/GPU/cuda/TimeFrameGPU.cu | 314 +++++++------- .../tracking/GPU/cuda/TrackerTraitsGPU.cxx | 89 +++- .../ITS/tracking/GPU/cuda/TrackingKernels.cu | 410 ++++++++++++------ .../ITS/tracking/include/ITStracking/Cell.h | 1 + 9 files changed, 584 insertions(+), 314 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h index 015b5d37e258c..dd155e7f55569 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h @@ -42,7 +42,7 @@ class TrackParametrizationWithError : public TrackParametrization using MatrixDSym5 = o2::math_utils::SMatrix>; using MatrixD5 = o2::math_utils::SMatrix>; - GPUd() TrackParametrizationWithError(); + GPUhd() TrackParametrizationWithError(); GPUd() TrackParametrizationWithError(value_t x, value_t alpha, const params_t& par, const covMat_t& cov, int charge = 1, const PID pid = PID::Pion); GPUd() TrackParametrizationWithError(const dim3_t& xyz, const dim3_t& pxpypz, const gpu::gpustd::array& cv, int sign, bool sectorAlpha = true, const PID pid = PID::Pion); @@ -145,7 +145,7 @@ class TrackParametrizationWithError : public TrackParametrization //__________________________________________________________________________ template -GPUdi() TrackParametrizationWithError::TrackParametrizationWithError() : TrackParametrization{} +GPUhdi() TrackParametrizationWithError::TrackParametrizationWithError() : TrackParametrization{} { } diff --git a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt index d3667294d6c61..f8c71e27d0058 100644 --- a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt @@ -37,7 +37,6 @@ o2_add_library(ITStracking O2::ITSMFTReconstruction O2::DataFormatsITS) - if (OpenMP_CXX_FOUND) target_compile_definitions(${targetName} PRIVATE WITH_OPENMP) target_link_libraries(${targetName} PRIVATE OpenMP::OpenMP_CXX) diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h index db1bfd836e8e6..ad8724f315ec8 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h @@ -52,22 +52,28 @@ class TimeFrameGPU : public TimeFrame void initDevice(IndexTableUtils*, const TrackingParameters& trkParam, const TimeFrameGPUParameters&, const int, const int); void initDeviceSAFitting(); void loadTrackingFrameInfoDevice(const int); - void loadUnsortedClustersDevice(); - void loadClustersDevice(); + void loadUnsortedClustersDevice(const int); + void loadClustersDevice(const int); void loadTrackletsDevice(); + void loadTrackletsLUTDevice(); void loadCellsDevice(); - void loadCellsLUT(); + void loadCellsLUTDevice(); void loadTrackSeedsDevice(); void loadTrackSeedsChi2Device(); void loadRoadsDevice(); void loadTrackSeedsDevice(std::vector&); + void createCellsBuffers(const int); + void createCellsDevice(); + void createCellsLUTDevice(); + void createNeighboursDevice(); void createNeighboursDevice(const unsigned int& layer, std::vector>& neighbours); void createNeighboursLUTDevice(const int, const unsigned int); void createTrackITSExtDevice(std::vector&); void downloadTrackITSExtDevice(std::vector&); - void downloadCellsNeighbours(std::vector>>&, const int); - void downloadNeighboursLUT(std::vector&, const int); - void downloadCellsDevice(const int); + void downloadCellsNeighboursDevice(std::vector>>&, const int); + void downloadNeighboursLUTDevice(std::vector&, const int); + void downloadCellsDevice(); + void downloadCellsLUTDevice(); void unregisterRest(); void initDeviceChunks(const int, const int); template @@ -98,11 +104,11 @@ class TimeFrameGPU : public TimeFrame int* getDeviceNeighboursLUT(const int layer) { return mNeighboursLUTDevice[layer]; } gpuPair* getDeviceNeighbours(const int layer) { return mNeighboursDevice[layer]; } TrackingFrameInfo* getDeviceTrackingFrameInfo(const int); - // TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() { return mTrackingFrameInfoDeviceArray; } const TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() const { return mTrackingFrameInfoDeviceArray; } - Cluster** getDeviceArrayClusters() const { return mClustersDeviceArray; } - Cluster** getDeviceArrayUnsortedClusters() const { return mUnsortedClustersDeviceArray; } - Tracklet** getDeviceArrayTracklets() const { return mTrackletsDeviceArray; } + const Cluster** getDeviceArrayClusters() const { return mClustersDeviceArray; } + const Cluster** getDeviceArrayUnsortedClusters() const { return mUnsortedClustersDeviceArray; } + const Tracklet** getDeviceArrayTracklets() const { return mTrackletsDeviceArray; } + const int** getDeviceArrayTrackletsLUT() const { return mTrackletsLUTDeviceArray; } int** getDeviceArrayCellsLUT() const { return mCellsLUTDeviceArray; } int** getDeviceArrayNeighboursCellLUT() const { return mNeighboursCellLUTDeviceArray; } CellSeed** getDeviceArrayCells() const { return mCellsDeviceArray; } @@ -117,6 +123,11 @@ class TimeFrameGPU : public TimeFrame gsl::span getHostNTracklets(const int chunkId); gsl::span getHostNCells(const int chunkId); + // Host-available device getters + gsl::span getDeviceCellLUTs() { return mCellsLUTDevice; } + gsl::span getDeviceCells() { return mCellsDevice; } + gsl::span getNCellsDevice() { return mNCells; } + private: void allocMemAsync(void**, size_t, Stream*, bool); // Abstract owned and unowned memory allocations bool mHostRegistered = false; @@ -124,6 +135,9 @@ class TimeFrameGPU : public TimeFrame TimeFrameGPUParameters mGpuParams; StaticTrackingParameters mStaticTrackingParams; + // Host-available device buffer sizes + std::array mNCells; + // Device pointers StaticTrackingParameters* mTrackingParamsDevice; IndexTableUtils* mIndexTableUtilsDevice; @@ -135,12 +149,15 @@ class TimeFrameGPU : public TimeFrame // Hybrid pref std::array mClustersDevice; std::array mUnsortedClustersDevice; - Cluster** mClustersDeviceArray; - Cluster** mUnsortedClustersDeviceArray; + const Cluster** mClustersDeviceArray; + const Cluster** mUnsortedClustersDeviceArray; std::array mTrackletsDevice; - Tracklet** mTrackletsDeviceArray; + const Tracklet** mTrackletsDeviceArray; + const int** mTrackletsLUTDeviceArray; + std::array mTrackletsLUTDevice; std::array mCellsLUTDevice; std::array mNeighboursLUTDevice; + int** mCellsLUTDeviceArray; int** mNeighboursCellDeviceArray; int** mNeighboursCellLUTDeviceArray; diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h index 167baa905f790..34e6165b9530f 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h @@ -49,6 +49,41 @@ GPUg() void fitTrackSeedsKernel( const o2::base::PropagatorF::MatCorrType matCorrType = o2::base::PropagatorF::MatCorrType::USEMatCorrLUT); #endif } // namespace gpu + +void countCellsHandler(const Cluster** sortedClusters, + const Cluster** unsortedClusters, + const TrackingFrameInfo** tfInfo, + const Tracklet** tracklets, + const int** trackletsLUT, + const int nTracklets, + const int layer, + CellSeed* cells, + int** cellsLUTsDeviceArray, + int* cellsLUTsHost, + const float bz, + const float maxChi2ClusterAttachment, + const float cellDeltaTanLambdaSigma, + const float nSigmaCut, + const int nBlocks, + const int nThreads); + +void computeCellsHandler(const Cluster** sortedClusters, + const Cluster** unsortedClusters, + const TrackingFrameInfo** tfInfo, + const Tracklet** tracklets, + const int** trackletsLUT, + const int nTracklets, + const int layer, + CellSeed* cells, + int** cellsLUTsDeviceArray, + int* cellsLUTsHost, + const float bz, + const float maxChi2ClusterAttachment, + const float cellDeltaTanLambdaSigma, + const float nSigmaCut, + const int nBlocks, + const int nThreads); + void countCellNeighboursHandler(CellSeed** cellsLayersDevice, int* neighboursLUTs, int** cellsLUTs, diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt index c8e1d0a910e5b..3cdb107e07438 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/CMakeLists.txt @@ -14,6 +14,7 @@ if(CUDA_ENABLED) find_package(CUDAToolkit) message(STATUS "Building ITS CUDA tracker") # add_compile_options(-O0 -g -lineinfo -fPIC) +# add_compile_definitions(ITS_MEASURE_GPU_TIME) o2_add_library(ITStrackingCUDA SOURCES ClusterLinesGPU.cu Context.cu diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu index c9c6792b5417b..67144ba2c98ea 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu @@ -21,15 +21,31 @@ #include #include +#include #include "GPUCommonDef.h" #include "GPUCommonMath.h" #include "GPUCommonLogger.h" -#ifndef __HIPCC__ -#define THRUST_NAMESPACE thrust::cuda +#ifdef ITS_MEASURE_GPU_TIME +#define START_GPU_STREAM_TIMER(stream, name) \ + cudaEvent_t event_start, event_stop; \ + checkGPUError(cudaEventCreate(&event_start)); \ + checkGPUError(cudaEventCreate(&event_stop)); \ + checkGPUError(cudaEventRecord(event_start, stream)); \ + const std::string task_name = name; + +#define STOP_GPU_STREAM_TIMER(stream) \ + checkGPUError(cudaEventRecord(event_stop, stream)); \ + checkGPUError(cudaEventSynchronize(event_stop)); \ + float ms; \ + checkGPUError(cudaEventElapsedTime(&ms, event_start, event_stop)); \ + std::cout << "Elapsed time for " << task_name << ": " << ms << " ms" << std::endl; \ + checkGPUError(cudaEventDestroy(event_start)); \ + checkGPUError(cudaEventDestroy(event_stop)); #else -#define THRUST_NAMESPACE thrust::hip +#define START_GPU_STREAM_TIMER(stream, name) +#define STOP_GPU_STREAM_TIMER(stream) #endif namespace o2 @@ -65,7 +81,7 @@ void TimeFrameGPU::allocMemAsync(void** ptr, size_t size, Stream* strPt if (extAllocator) { *ptr = mAllocator->allocate(size); } else { - LOGP(info, "Calling default CUDA allocator"); + LOGP(debug, "Calling default CUDA allocator"); checkGPUError(cudaMallocAsync(reinterpret_cast(ptr), size, strPtr->get())); } } @@ -77,43 +93,49 @@ void TimeFrameGPU::setDevicePropagator(const o2::base::PropagatorImpl -void TimeFrameGPU::loadUnsortedClustersDevice() +void TimeFrameGPU::loadUnsortedClustersDevice(const int iteration) { - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} unsorted clusters on layer {}, for {} MB.", mUnsortedClusters[iLayer].size(), iLayer, mUnsortedClusters[iLayer].size() * sizeof(Cluster) / MB); - allocMemAsync(reinterpret_cast(&mUnsortedClustersDevice[iLayer]), mUnsortedClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mUnsortedClustersDevice[iLayer], mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading unsorted clusters"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} unsorted clusters on layer {}, for {} MB.", mUnsortedClusters[iLayer].size(), iLayer, mUnsortedClusters[iLayer].size() * sizeof(Cluster) / MB); + allocMemAsync(reinterpret_cast(&mUnsortedClustersDevice[iLayer]), mUnsortedClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mUnsortedClustersDevice[iLayer], mUnsortedClusters[iLayer].data(), mUnsortedClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mUnsortedClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mUnsortedClustersDeviceArray, mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } - allocMemAsync(reinterpret_cast(&mUnsortedClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mUnsortedClustersDeviceArray, mUnsortedClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template -void TimeFrameGPU::loadClustersDevice() +void TimeFrameGPU::loadClustersDevice(const int iteration) { - for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} clusters on layer {}, for {} MB.", mClusters[iLayer].size(), iLayer, mClusters[iLayer].size() * sizeof(Cluster) / MB); - allocMemAsync(reinterpret_cast(&mClustersDevice[iLayer]), mClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mClustersDevice[iLayer], mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading sorted clusters"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} clusters on layer {}, for {} MB.", mClusters[iLayer].size(), iLayer, mClusters[iLayer].size() * sizeof(Cluster) / MB); + allocMemAsync(reinterpret_cast(&mClustersDevice[iLayer]), mClusters[iLayer].size() * sizeof(Cluster), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mClustersDevice[iLayer], mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mClustersDeviceArray, mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } - allocMemAsync(reinterpret_cast(&mClustersDeviceArray), nLayers * sizeof(Cluster*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mClustersDeviceArray, mClustersDevice.data(), nLayers * sizeof(Cluster*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } template void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading trackingframeinfo"); if (!iteration) { for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { LOGP(debug, "gpu-transfer: loading {} tfinfo on layer {}, for {} MB.", mTrackingFrameInfo[iLayer].size(), iLayer, mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo) / MB); allocMemAsync(reinterpret_cast(&mTrackingFrameInfoDevice[iLayer]), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), nullptr, getExtAllocator()); - // Register and move data checkGPUError(cudaHostRegister(mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDevice[iLayer], mTrackingFrameInfo[iLayer].data(), mTrackingFrameInfo[iLayer].size() * sizeof(TrackingFrameInfo), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } @@ -121,53 +143,108 @@ void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) checkGPUError(cudaHostRegister(mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackingFrameInfoDeviceArray, mTrackingFrameInfoDevice.data(), nLayers * sizeof(TrackingFrameInfo*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::loadTrackletsDevice() { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading tracklets"); for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { LOGP(debug, "gpu-transfer: loading {} tracklets on layer {}, for {} MB.", mTracklets[iLayer].size(), iLayer, mTracklets[iLayer].size() * sizeof(Tracklet) / MB); allocMemAsync(reinterpret_cast(&mTrackletsDevice[iLayer]), mTracklets[iLayer].size() * sizeof(Tracklet), nullptr, getExtAllocator()); - // Register and move data checkGPUError(cudaHostRegister(mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackletsDevice[iLayer], mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } allocMemAsync(reinterpret_cast(&mTrackletsDeviceArray), (nLayers - 1) * sizeof(Tracklet*), nullptr, getExtAllocator()); checkGPUError(cudaHostRegister(mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackletsDeviceArray, mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::loadTrackletsLUTDevice() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading tracklets"); + for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { + LOGP(debug, "gpu-transfer: loading tracklets LUT for {} elements on layer {}, for {} MB", mTrackletsLookupTable[iLayer].size(), iLayer, mTrackletsLookupTable[iLayer].size() * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mTrackletsLUTDevice[iLayer]), mTrackletsLookupTable[iLayer].size() * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mTrackletsLookupTable[iLayer].data(), mTrackletsLookupTable[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsLUTDevice[iLayer], mTrackletsLookupTable[iLayer].data(), mTrackletsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); + } + allocMemAsync(reinterpret_cast(&mTrackletsLUTDeviceArray), (nLayers - 2) * sizeof(int*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mTrackletsLUTDevice.data(), (nLayers - 2) * sizeof(int*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsLUTDeviceArray, mTrackletsLUTDevice.data(), (nLayers - 2) * sizeof(int*), cudaMemcpyHostToDevice)); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::createNeighboursDevice() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading cell seeds"); + for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { + LOGP(debug, "gpu-transfer: loading neighbours LUT for {} elements on layer {}, for {} MB.", mNCells[iLayer], iLayer, mNCells[iLayer] * sizeof(CellSeed) / MB); + allocMemAsync(reinterpret_cast(&mNeighboursIndexTablesDevice[iLayer]), (mNCells[iLayer] + 1) * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemsetAsync(mNeighboursIndexTablesDevice[iLayer], 0, (mNCells[iLayer] + 1) * sizeof(int), mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::loadCellsDevice() { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading cell seeds"); for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { LOGP(debug, "gpu-transfer: loading {} cell seeds on layer {}, for {} MB.", mCells[iLayer].size(), iLayer, mCells[iLayer].size() * sizeof(CellSeed) / MB); allocMemAsync(reinterpret_cast(&mCellsDevice[iLayer]), mCells[iLayer].size() * sizeof(CellSeed), nullptr, getExtAllocator()); allocMemAsync(reinterpret_cast(&mNeighboursIndexTablesDevice[iLayer]), (mCells[iLayer].size() + 1) * sizeof(int), nullptr, getExtAllocator()); // accessory for the neigh. finding. checkGPUError(cudaMemsetAsync(mNeighboursIndexTablesDevice[iLayer], 0, (mCells[iLayer].size() + 1) * sizeof(int), mGpuStreams[0].get())); - // Register and move data - checkGPUError(cudaHostRegister(mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mCellsDevice[iLayer], mCells[iLayer].data(), mCells[iLayer].size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } allocMemAsync(reinterpret_cast(&mCellsDeviceArray), (nLayers - 2) * sizeof(CellSeed*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mCellsDeviceArray, mCellsDevice.data(), (nLayers - 2) * sizeof(CellSeed*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template -void TimeFrameGPU::loadCellsLUT() +void TimeFrameGPU::createCellsLUTDevice() { - for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { - LOGP(debug, "gpu-transfer: loading {} cell LUTs on layer {}, for {} MB.", mCellsLookupTable[iLayer].size(), iLayer, mCellsLookupTable[iLayer].size() * sizeof(int) / MB); - allocMemAsync(reinterpret_cast(&(mCellsLUTDevice[iLayer])), sizeof(int) * mCellsLookupTable[iLayer].size(), nullptr, getExtAllocator()); - // Register and move data - checkGPUError(cudaHostRegister(mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mCellsLUTDevice[iLayer], mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating cells LUTs"); + for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { + LOGP(debug, "gpu-transfer: creating cell LUT for {} elements on layer {}, for {} MB.", mTracklets[iLayer].size() + 1, iLayer, (mTracklets[iLayer].size() + 1) * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mCellsLUTDevice[iLayer]), (mTracklets[iLayer].size() + 1) * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemsetAsync(mCellsLUTDevice[iLayer], 0, (mTracklets[iLayer].size() + 1) * sizeof(int), mGpuStreams[0].get())); } allocMemAsync(reinterpret_cast(&mCellsLUTDeviceArray), (nLayers - 2) * sizeof(int*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mCellsLUTDevice.data(), mCellsLUTDevice.size() * sizeof(int*), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mCellsLUTDeviceArray, mCellsLUTDevice.data(), mCellsLUTDevice.size() * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::createCellsBuffers(const int layer) +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating cells buffers"); + mNCells[layer] = 0; + checkGPUError(cudaMemcpyAsync(&mNCells[layer], mCellsLUTDevice[layer] + mTracklets[layer].size(), sizeof(int), cudaMemcpyDeviceToHost)); + LOGP(debug, "gpu-transfer: creating cell buffer for {} elements on layer {}, for {} MB.", mNCells[layer], layer, mNCells[layer] * sizeof(CellSeed) / MB); + allocMemAsync(reinterpret_cast(&mCellsDevice[layer]), mNCells[layer] * sizeof(CellSeed), nullptr, getExtAllocator()); + + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::loadCellsLUTDevice() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading cells LUTs"); + for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { + LOGP(debug, "gpu-transfer: loading cell LUT for {} elements on layer {}, for {} MB.", mCellsLookupTable[iLayer].size(), iLayer, mCellsLookupTable[iLayer].size() * sizeof(int) / MB); + checkGPUError(cudaHostRegister(mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mCellsLUTDevice[iLayer + 1], mCellsLookupTable[iLayer].data(), mCellsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template @@ -182,111 +259,130 @@ void TimeFrameGPU::loadRoadsDevice() template void TimeFrameGPU::loadTrackSeedsDevice(std::vector& seeds) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading track seeds"); LOGP(debug, "gpu-transfer: loading {} track seeds, for {} MB.", seeds.size(), seeds.size() * sizeof(CellSeed) / MB); allocMemAsync(reinterpret_cast(&mTrackSeedsDevice), seeds.size() * sizeof(CellSeed), &(mGpuStreams[0]), getExtAllocator()); checkGPUError(cudaHostRegister(seeds.data(), seeds.size() * sizeof(CellSeed), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackSeedsDevice, seeds.data(), seeds.size() * sizeof(CellSeed), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::createNeighboursDevice(const unsigned int& layer, std::vector>& neighbours) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "reserving neighbours"); mCellsNeighbours[layer].clear(); mCellsNeighbours[layer].resize(neighbours.size()); LOGP(debug, "gpu-allocation: reserving {} neighbours, for {} MB.", neighbours.size(), neighbours.size() * sizeof(gpuPair) / MB); allocMemAsync(reinterpret_cast(&mNeighboursDevice[layer]), neighbours.size() * sizeof(gpuPair), &(mGpuStreams[0]), getExtAllocator()); checkGPUError(cudaMemsetAsync(mNeighboursDevice[layer], -1, neighbours.size() * sizeof(gpuPair), mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::createNeighboursLUTDevice(const int layer, const unsigned int nCells) { - LOGP(debug, "gpu-allocation: reserving {} slots for neighbours LUT, for {} MB.", nCells + 1, (nCells + 1) * sizeof(int) / MB); + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "reserving neighboursLUT"); + LOGP(debug, "gpu-allocation: reserving neighbours LUT for {} elements on layer {} , for {} MB.", nCells + 1, layer, (nCells + 1) * sizeof(int) / MB); allocMemAsync(reinterpret_cast(&mNeighboursLUTDevice[layer]), (nCells + 1) * sizeof(int), nullptr, getExtAllocator()); // We need one element more to move exc -> inc checkGPUError(cudaMemsetAsync(mNeighboursLUTDevice[layer], 0, (nCells + 1) * sizeof(int), mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::createTrackITSExtDevice(std::vector& seeds) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "reserving tracks"); mTrackITSExt.clear(); mTrackITSExt.resize(seeds.size()); LOGP(debug, "gpu-allocation: reserving {} tracks, for {} MB.", seeds.size(), seeds.size() * sizeof(o2::its::TrackITSExt) / MB); allocMemAsync(reinterpret_cast(&mTrackITSExtDevice), seeds.size() * sizeof(o2::its::TrackITSExt), &(mGpuStreams[0]), getExtAllocator()); checkGPUError(cudaMemsetAsync(mTrackITSExtDevice, 0, seeds.size() * sizeof(o2::its::TrackITSExt), mGpuStreams[0].get())); checkGPUError(cudaHostRegister(mTrackITSExt.data(), seeds.size() * sizeof(o2::its::TrackITSExt), cudaHostRegisterPortable)); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template -void TimeFrameGPU::downloadCellsDevice(const int layer) +void TimeFrameGPU::downloadCellsDevice() { - LOGP(debug, "gpu-transfer: downloading {} cells on layer: {}, for {} MB.", mCells[layer].size(), layer, mCells[layer].size() * sizeof(CellSeed) / MB); - checkGPUError(cudaMemcpyAsync(mCells[layer].data(), mCellsDevice[layer], mCells[layer].size() * sizeof(CellSeed), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); - checkGPUError(cudaHostUnregister(mCells[layer].data())); + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "downloading cells"); + for (int iLayer{0}; iLayer < nLayers - 2; ++iLayer) { + LOGP(debug, "gpu-transfer: downloading {} cells on layer: {}, for {} MB.", mNCells[iLayer], iLayer, mNCells[iLayer] * sizeof(CellSeed) / MB); + mCells[iLayer].resize(mNCells[iLayer]); + checkGPUError(cudaMemcpyAsync(mCells[iLayer].data(), mCellsDevice[iLayer], mNCells[iLayer] * sizeof(CellSeed), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::downloadCellsLUTDevice() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "downloading cell luts"); + for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { + LOGP(debug, "gpu-transfer: downloading cells lut on layer {} for {} elements", iLayer, (mTracklets[iLayer + 1].size() + 1)); + mCellsLookupTable[iLayer].resize(mTracklets[iLayer + 1].size() + 1); + checkGPUError(cudaMemcpyAsync(mCellsLookupTable[iLayer].data(), mCellsLUTDevice[iLayer + 1], (mTracklets[iLayer + 1].size() + 1) * sizeof(int), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template -void TimeFrameGPU::downloadCellsNeighbours(std::vector>>& neighbours, const int layer) +void TimeFrameGPU::downloadCellsNeighboursDevice(std::vector>>& neighbours, const int layer) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), fmt::format("downloading neighbours from layer {}", layer)); LOGP(debug, "gpu-transfer: downloading {} neighbours, for {} MB.", neighbours[layer].size(), neighbours[layer].size() * sizeof(std::pair) / MB); - // TOOD: something less dangerous than assuming the same memory layout of std::pair and gpuPair... or not? :) + // TODO: something less dangerous than assuming the same memory layout of std::pair and gpuPair... or not? :) checkGPUError(cudaMemcpyAsync(neighbours[layer].data(), mNeighboursDevice[layer], neighbours[layer].size() * sizeof(gpuPair), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); } template -void TimeFrameGPU::downloadNeighboursLUT(std::vector& lut, const int layer) +void TimeFrameGPU::downloadNeighboursLUTDevice(std::vector& lut, const int layer) { - LOGP(debug, "gpu-transfer: downloading {} neighbours lut, for {} MB.", lut.size(), lut.size() * sizeof(int) / MB); + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), fmt::format("downloading neighbours LUT from layer {}", layer)); + LOGP(debug, "gpu-transfer: downloading neighbours LUT for {} elements on layer {}, for {} MB.", lut.size(), layer, lut.size() * sizeof(int) / MB); checkGPUError(cudaMemcpyAsync(lut.data(), mNeighboursLUTDevice[layer], lut.size() * sizeof(int), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::downloadTrackITSExtDevice(std::vector& seeds) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "downloading tracks"); LOGP(debug, "gpu-transfer: downloading {} tracks, for {} MB.", mTrackITSExt.size(), mTrackITSExt.size() * sizeof(o2::its::TrackITSExt) / MB); checkGPUError(cudaMemcpyAsync(mTrackITSExt.data(), mTrackITSExtDevice, seeds.size() * sizeof(o2::its::TrackITSExt), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); checkGPUError(cudaHostUnregister(mTrackITSExt.data())); checkGPUError(cudaHostUnregister(seeds.data())); - // discardResult(cudaDeviceSynchronize()); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::unregisterRest() { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "unregistering rest of the host memory"); LOGP(debug, "unregistering rest of the host memory..."); - checkGPUError(cudaHostUnregister(mCells[0].data())); checkGPUError(cudaHostUnregister(mCellsDevice.data())); - checkGPUError(cudaHostUnregister(mCellsLUTDevice.data())); - for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { - checkGPUError(cudaHostUnregister(mCellsLookupTable[iLayer].data())); - } -} -//////////////////////////////////////////////////////////////////////// -/// Legacy -template -void TimeFrameGPU::registerHostMemory(const int maxLayers) -{ - if (mHostRegistered) { - return; - } else { - mHostRegistered = true; - } - for (auto iLayer{0}; iLayer < maxLayers; ++iLayer) { - checkGPUError(cudaHostRegister(mClusters[iLayer].data(), mClusters[iLayer].size() * sizeof(Cluster), cudaHostRegisterPortable)); - checkGPUError(cudaHostRegister(mNClustersPerROF[iLayer].data(), mNClustersPerROF[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); - checkGPUError(cudaHostRegister(mIndexTables[iLayer].data(), (mStaticTrackingParams.ZBins * mStaticTrackingParams.PhiBins + 1) * mNrof * sizeof(int), cudaHostRegisterPortable)); + checkGPUError(cudaHostUnregister(mTrackletsDevice.data())); + checkGPUError(cudaHostUnregister(mTrackletsLUTDevice.data())); + for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { + if (iLayer < nLayers - 2) { + checkGPUError(cudaHostUnregister(mTrackletsLookupTable[iLayer].data())); + } + checkGPUError(cudaHostUnregister(mTracklets[iLayer].data())); } - checkGPUError(cudaHostRegister(mHostNTracklets.data(), (nLayers - 1) * mGpuParams.nTimeFrameChunks * sizeof(int), cudaHostRegisterPortable)); - checkGPUError(cudaHostRegister(mHostNCells.data(), (nLayers - 2) * mGpuParams.nTimeFrameChunks * sizeof(int), cudaHostRegisterPortable)); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } template void TimeFrameGPU::unregisterHostMemory(const int maxLayers) { for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + checkGPUError(cudaHostUnregister(mUnsortedClusters[iLayer].data())); + checkGPUError(cudaHostUnregister(mClusters[iLayer].data())); checkGPUError(cudaHostUnregister(mTrackingFrameInfo[iLayer].data())); } checkGPUError(cudaHostUnregister(mTrackingFrameInfoDevice.data())); + checkGPUError(cudaHostUnregister(mUnsortedClustersDevice.data())); + checkGPUError(cudaHostUnregister(mClustersDevice.data())); } template @@ -300,86 +396,6 @@ void TimeFrameGPU::initialise(const int iteration, o2::its::TimeFrame::initialise(iteration, trkParam, maxLayers); } -template -void TimeFrameGPU::wipe(const int maxLayers) -{ - unregisterHostMemory(maxLayers); -} - -template -void TimeFrameGPU::initDevice(IndexTableUtils* utils, - const TrackingParameters& trkParam, - const TimeFrameGPUParameters& gpuParam, - const int maxLayers, - const int iteration) -{ - // mStaticTrackingParams.ZBins = trkParam.ZBins; - // mStaticTrackingParams.PhiBins = trkParam.PhiBins; - // if (mFirstInit) { - // mGpuParams = gpuParam; - // allocMemAsync(reinterpret_cast(&mTrackingParamsDevice), sizeof(gpu::StaticTrackingParameters), nullptr, true); - // checkGPUError(cudaMemcpy(mTrackingParamsDevice, &mStaticTrackingParams, sizeof(gpu::StaticTrackingParameters), cudaMemcpyHostToDevice)); - // if (utils) { // If utils is not nullptr, then its gpu vertexing - // mIndexTableUtils = *utils; - // allocMemAsync(reinterpret_cast(&mIndexTableUtilsDevice), sizeof(IndexTableUtils), nullptr, true); - // } else { // GPU tracking otherwise - // mIndexTableUtils.setTrackingParameters(trkParam); - // } - - // mMemChunks.resize(mGpuParams.nTimeFrameChunks, GpuTimeFrameChunk{static_cast(this), mGpuParams}); - // mVerticesInChunks.resize(mGpuParams.nTimeFrameChunks); - // mNVerticesInChunks.resize(mGpuParams.nTimeFrameChunks); - // mLabelsInChunks.resize(mGpuParams.nTimeFrameChunks); - // LOGP(info, "Size of fixed part is: {} MB", GpuTimeFrameChunk::computeFixedSizeBytes(mGpuParams) / MB); - // LOGP(info, "Size of scaling part is: {} MB", GpuTimeFrameChunk::computeScalingSizeBytes(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mAvailMemGB), mGpuParams) / MB); - // LOGP(info, "Allocating {} chunks of {} rofs capacity each.", mGpuParams.nTimeFrameChunks, mGpuParams.nROFsPerChunk); - - // for (int iChunk{0}; iChunk < mMemChunks.size(); ++iChunk) { - // mMemChunks[iChunk].allocate(GpuTimeFrameChunk::computeRofPerChunk(mGpuParams, mGpuParams.maxGPUMemoryGB), mGpuStreams[iChunk]); - // } - // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - // allocMemAsync(reinterpret_cast(&mROframesClustersDevice[iLayer]), mROframesClusters[iLayer].size() * sizeof(int), nullptr, true); - // allocMemAsync(reinterpret_cast(&(mUsedClustersDevice[iLayer])), sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof, nullptr, true); - // } - // allocMemAsync(reinterpret_cast(&mVerticesDevice), sizeof(Vertex) * mGpuParams.maxVerticesCapacity, nullptr, true); - // allocMemAsync(reinterpret_cast(&mROframesPVDevice), sizeof(int) * (mNrof + 1), nullptr, true); - - // mFirstInit = false; - // } - // if (maxLayers < nLayers) { // Vertexer - // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - // checkGPUError(cudaMemcpy(mROframesClustersDevice[iLayer], mROframesClusters[iLayer].data(), mROframesClusters[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); - // } - // } else { // Tracker - // checkGPUError(cudaMemcpy(mVerticesDevice, mPrimaryVertices.data(), sizeof(Vertex) * mPrimaryVertices.size(), cudaMemcpyHostToDevice)); - // checkGPUError(cudaMemcpy(mROframesPVDevice, mROframesPV.data(), sizeof(int) * mROframesPV.size(), cudaMemcpyHostToDevice)); - // if (!iteration) { - // for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { - // checkGPUError(cudaMemset(mUsedClustersDevice[iLayer], 0, sizeof(unsigned char) * mGpuParams.clustersPerROfCapacity * mNrof)); - // } - // } - // } - // checkGPUError(cudaMemcpy(mIndexTableUtilsDevice, &mIndexTableUtils, sizeof(IndexTableUtils), cudaMemcpyHostToDevice)); -} - -template -unsigned char* TimeFrameGPU::getDeviceUsedClusters(const int layer) -{ - return mUsedClustersDevice[layer]; -} - -template -gsl::span TimeFrameGPU::getHostNTracklets(const int chunkId) -{ - return gsl::span(mHostNTracklets.data() + (nLayers - 1) * chunkId, nLayers - 1); -} - -template -gsl::span TimeFrameGPU::getHostNCells(const int chunkId) -{ - return gsl::span(mHostNCells.data() + (nLayers - 2) * chunkId, nLayers - 2); -} - template class TimeFrameGPU<7>; } // namespace gpu } // namespace its diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx index 45fee9976bca6..3c6a307fc4ff6 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx @@ -29,6 +29,8 @@ template void TrackerTraitsGPU::initialiseTimeFrame(const int iteration) { mTimeFrameGPU->initialise(iteration, mTrkParams[iteration], nLayers); + mTimeFrameGPU->loadClustersDevice(iteration); + mTimeFrameGPU->loadUnsortedClustersDevice(iteration); mTimeFrameGPU->loadTrackingFrameInfoDevice(iteration); } @@ -317,18 +319,66 @@ void TrackerTraitsGPU::computeTrackletsHybrid(const int iteration, int template void TrackerTraitsGPU::computeCellsHybrid(const int iteration) { - TrackerTraits::computeLayerCells(iteration); -}; + mTimeFrameGPU->loadTrackletsDevice(); + mTimeFrameGPU->loadTrackletsLUTDevice(); + mTimeFrameGPU->createCellsLUTDevice(); + auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); + + // #pragma omp parallel for num_threads(nLayers) + for (int iLayer = 0; iLayer < mTrkParams[iteration].CellsPerRoad(); ++iLayer) { + if (mTimeFrameGPU->getTracklets()[iLayer + 1].empty() || + mTimeFrameGPU->getTracklets()[iLayer].empty()) { + continue; + } + + const int currentLayerTrackletsNum{static_cast(mTimeFrameGPU->getTracklets()[iLayer].size())}; + countCellsHandler(mTimeFrameGPU->getDeviceArrayClusters(), + mTimeFrameGPU->getDeviceArrayUnsortedClusters(), + mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), + mTimeFrameGPU->getDeviceArrayTracklets(), + mTimeFrameGPU->getDeviceArrayTrackletsLUT(), + mTimeFrameGPU->getTracklets()[iLayer].size(), + iLayer, + nullptr, + mTimeFrameGPU->getDeviceArrayCellsLUT(), + mTimeFrameGPU->getDeviceCellLUTs()[iLayer], + mBz, + mTrkParams[iteration].MaxChi2ClusterAttachment, + mTrkParams[iteration].CellDeltaTanLambdaSigma, + mTrkParams[iteration].NSigmaCut, + conf.nBlocks, + conf.nThreads); + mTimeFrameGPU->createCellsBuffers(iLayer); + computeCellsHandler(mTimeFrameGPU->getDeviceArrayClusters(), + mTimeFrameGPU->getDeviceArrayUnsortedClusters(), + mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), + mTimeFrameGPU->getDeviceArrayTracklets(), + mTimeFrameGPU->getDeviceArrayTrackletsLUT(), + mTimeFrameGPU->getTracklets()[iLayer].size(), + iLayer, + mTimeFrameGPU->getDeviceCells()[iLayer], + mTimeFrameGPU->getDeviceArrayCellsLUT(), + mTimeFrameGPU->getDeviceCellLUTs()[iLayer], + mBz, + mTrkParams[iteration].MaxChi2ClusterAttachment, + mTrkParams[iteration].CellDeltaTanLambdaSigma, + mTrkParams[iteration].NSigmaCut, + conf.nBlocks, + conf.nThreads); + } + // Needed for processNeighbours() which is still on CPU. + mTimeFrameGPU->downloadCellsDevice(); + mTimeFrameGPU->downloadCellsLUTDevice(); +} template void TrackerTraitsGPU::findCellsNeighboursHybrid(const int iteration) { + mTimeFrameGPU->createNeighboursDevice(); auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); - mTimeFrameGPU->loadCellsDevice(); - mTimeFrameGPU->loadCellsLUT(); std::vector>> cellsNeighboursLayer(mTrkParams[iteration].CellsPerRoad() - 1); for (int iLayer{0}; iLayer < mTrkParams[iteration].CellsPerRoad() - 1; ++iLayer) { - const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getCells()[iLayer + 1].size())}; + const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getNCellsDevice()[iLayer + 1])}; mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].clear(); mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].resize(nextLayerCellsNum, 0); @@ -353,7 +403,7 @@ void TrackerTraitsGPU::findCellsNeighboursHybrid(const int iteration) 1e2, conf.nBlocks, conf.nThreads); - mTimeFrameGPU->downloadNeighboursLUT(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer], iLayer); + mTimeFrameGPU->downloadNeighboursLUTDevice(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer], iLayer); // Get the number of found cells from LUT cellsNeighboursLayer[iLayer].resize(mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].back()); mTimeFrameGPU->createNeighboursDevice(iLayer, cellsNeighboursLayer[iLayer]); @@ -372,12 +422,12 @@ void TrackerTraitsGPU::findCellsNeighboursHybrid(const int iteration) conf.nThreads); mTimeFrameGPU->getCellsNeighbours()[iLayer].clear(); mTimeFrameGPU->getCellsNeighbours()[iLayer].reserve(cellsNeighboursLayer[iLayer].size()); - mTimeFrameGPU->downloadCellsDevice(iLayer + 1); // Cells on layer 0 did not change. filterCellNeighboursHandler(mTimeFrameGPU->getCellsNeighbours()[iLayer], mTimeFrameGPU->getDeviceNeighbours(iLayer), cellsNeighboursLayer[iLayer].size()); } + mTimeFrameGPU->downloadCellsDevice(); mTimeFrameGPU->unregisterRest(); }; @@ -415,19 +465,18 @@ void TrackerTraitsGPU::findRoads(const int iteration) mTimeFrameGPU->createTrackITSExtDevice(trackSeeds); mTimeFrameGPU->loadTrackSeedsDevice(trackSeeds); auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); - trackSeedHandler( - mTimeFrameGPU->getDeviceTrackSeeds(), // CellSeed* trackSeeds, - mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), // TrackingFrameInfo** foundTrackingFrameInfo, - mTimeFrameGPU->getDeviceTrackITSExt(), // o2::its::TrackITSExt* tracks, - trackSeeds.size(), // const size_t nSeeds, - mBz, // const float Bz, - startLevel, // const int startLevel, - mTrkParams[0].MaxChi2ClusterAttachment, // float maxChi2ClusterAttachment, - mTrkParams[0].MaxChi2NDF, // float maxChi2NDF, - mTimeFrameGPU->getDevicePropagator(), // const o2::base::Propagator* propagator - mCorrType, // o2::base::PropagatorImpl::MatCorrType - conf.nBlocks, - conf.nThreads); + trackSeedHandler(mTimeFrameGPU->getDeviceTrackSeeds(), // CellSeed* trackSeeds, + mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), // TrackingFrameInfo** foundTrackingFrameInfo, + mTimeFrameGPU->getDeviceTrackITSExt(), // o2::its::TrackITSExt* tracks, + trackSeeds.size(), // const size_t nSeeds, + mBz, // const float Bz, + startLevel, // const int startLevel, + mTrkParams[0].MaxChi2ClusterAttachment, // float maxChi2ClusterAttachment, + mTrkParams[0].MaxChi2NDF, // float maxChi2NDF, + mTimeFrameGPU->getDevicePropagator(), // const o2::base::Propagator* propagator + mCorrType, // o2::base::PropagatorImpl::MatCorrType + conf.nBlocks, + conf.nThreads); mTimeFrameGPU->downloadTrackITSExtDevice(trackSeeds); diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index 9d00892f4b680..e31e3f378298b 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -130,6 +130,72 @@ GPUd() bool fitTrack(TrackITSExt& track, return o2::gpu::GPUCommonMath::Abs(track.getQ2Pt()) < maxQoverPt && track.getChi2() < chi2ndfcut * (nCl * 2 - 5); } +GPUd() o2::track::TrackParCov buildTrackSeed(const Cluster& cluster1, + const Cluster& cluster2, + const TrackingFrameInfo& tf3, + const float bz) +{ + const float ca = o2::gpu::CAMath::Cos(tf3.alphaTrackingFrame), sa = o2::gpu::CAMath::Sin(tf3.alphaTrackingFrame); + const float x1 = cluster1.xCoordinate * ca + cluster1.yCoordinate * sa; + const float y1 = -cluster1.xCoordinate * sa + cluster1.yCoordinate * ca; + const float z1 = cluster1.zCoordinate; + const float x2 = cluster2.xCoordinate * ca + cluster2.yCoordinate * sa; + const float y2 = -cluster2.xCoordinate * sa + cluster2.yCoordinate * ca; + const float z2 = cluster2.zCoordinate; + const float x3 = tf3.xTrackingFrame; + const float y3 = tf3.positionTrackingFrame[0]; + const float z3 = tf3.positionTrackingFrame[1]; + + const bool zeroField{o2::gpu::GPUCommonMath::Abs(bz) < o2::constants::math::Almost0}; + const float tgp = zeroField ? o2::gpu::CAMath::ATan2(y3 - y1, x3 - x1) : 1.f; + const float crv = zeroField ? 1.f : math_utils::computeCurvature(x3, y3, x2, y2, x1, y1); + const float snp = zeroField ? tgp / o2::gpu::CAMath::Sqrt(1.f + tgp * tgp) : crv * (x3 - math_utils::computeCurvatureCentreX(x3, y3, x2, y2, x1, y1)); + const float tgl12 = math_utils::computeTanDipAngle(x1, y1, x2, y2, z1, z2); + const float tgl23 = math_utils::computeTanDipAngle(x2, y2, x3, y3, z2, z3); + const float q2pt = zeroField ? 1.f / o2::track::kMostProbablePt : crv / (bz * o2::constants::math::B2C); + const float q2pt2 = crv * crv; + const float sg2q2pt = o2::track::kC1Pt2max * (q2pt2 > 0.0005 ? (q2pt2 < 1 ? q2pt2 : 1) : 0.0005); + return track::TrackParCov(tf3.xTrackingFrame, tf3.alphaTrackingFrame, + {y3, z3, snp, 0.5f * (tgl12 + tgl23), q2pt}, + {tf3.covarianceTrackingFrame[0], + tf3.covarianceTrackingFrame[1], tf3.covarianceTrackingFrame[2], + 0.f, 0.f, track::kCSnp2max, + 0.f, 0.f, 0.f, track::kCTgl2max, + 0.f, 0.f, 0.f, 0.f, sg2q2pt}); +} + +template +struct pair_to_first : public thrust::unary_function, T1> { + GPUhd() int operator()(const gpuPair& a) const + { + return a.first; + } +}; + +template +struct pair_to_second : public thrust::unary_function, T2> { + GPUhd() int operator()(const gpuPair& a) const + { + return a.second; + } +}; + +template +struct is_invalid_pair { + GPUhd() bool operator()(const gpuPair& p) const + { + return p.first == -1 && p.second == -1; + } +}; + +template +struct is_valid_pair { + GPUhd() bool operator()(const gpuPair& p) const + { + return !(p.first == -1 && p.second == -1); + } +}; + template GPUg() void fitTrackSeedsKernel( CellSeed* trackSeeds, @@ -208,8 +274,8 @@ GPUg() void computeLayerCellNeighboursKernel( for (int iCurrentCellIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentCellIndex < nCells; iCurrentCellIndex += blockDim.x * gridDim.x) { const auto& currentCellSeed{cellSeedArray[layerIndex][iCurrentCellIndex]}; const int nextLayerTrackletIndex{currentCellSeed.getSecondTrackletIndex()}; - const int nextLayerFirstCellIndex{cellsLUTs[layerIndex][nextLayerTrackletIndex]}; - const int nextLayerLastCellIndex{cellsLUTs[layerIndex][nextLayerTrackletIndex + 1]}; + const int nextLayerFirstCellIndex{cellsLUTs[layerIndex + 1][nextLayerTrackletIndex]}; + const int nextLayerLastCellIndex{cellsLUTs[layerIndex + 1][nextLayerTrackletIndex + 1]}; int foundNeighbours{0}; for (int iNextCell{nextLayerFirstCellIndex}; iNextCell < nextLayerLastCellIndex; ++iNextCell) { CellSeed nextCellSeed{cellSeedArray[layerIndex + 1][iNextCell]}; // Copy @@ -243,41 +309,94 @@ GPUg() void computeLayerCellNeighboursKernel( } } -template -struct pair_to_first : public thrust::unary_function, T1> { - GPUhd() int operator()(const gpuPair& a) const - { - return a.first; - } -}; +template +GPUg() void computeLayerCellsKernel( + const Cluster** sortedClusters, + const Cluster** unsortedClusters, + const TrackingFrameInfo** tfInfo, + const Tracklet** tracklets, + const int** trackletsLUT, + const int nTrackletsCurrent, + const int layer, + CellSeed* cells, + int** cellsLUTs, + const float bz, + const float maxChi2ClusterAttachment, + const float cellDeltaTanLambdaSigma, + const float nSigmaCut) +{ + constexpr float radl = 9.36f; // Radiation length of Si [cm]. + constexpr float rho = 2.33f; // Density of Si [g/cm^3]. + constexpr float layerxX0[7] = {5.e-3f, 5.e-3f, 5.e-3f, 1.e-2f, 1.e-2f, 1.e-2f, 1.e-2f}; // Hardcoded here for the moment. + for (int iCurrentTrackletIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentTrackletIndex < nTrackletsCurrent; iCurrentTrackletIndex += blockDim.x * gridDim.x) { + const Tracklet& currentTracklet = tracklets[layer][iCurrentTrackletIndex]; + const int nextLayerClusterIndex{currentTracklet.secondClusterIndex}; + const int nextLayerFirstTrackletIndex{trackletsLUT[layer][nextLayerClusterIndex]}; + const int nextLayerLastTrackletIndex{trackletsLUT[layer][nextLayerClusterIndex + 1]}; + if (nextLayerFirstTrackletIndex == nextLayerLastTrackletIndex) { + continue; + } + int foundCells{0}; + for (int iNextTrackletIndex{nextLayerFirstTrackletIndex}; iNextTrackletIndex < nextLayerLastTrackletIndex; ++iNextTrackletIndex) { + if (tracklets[layer + 1][iNextTrackletIndex].firstClusterIndex != nextLayerClusterIndex) { + break; + } + const Tracklet& nextTracklet = tracklets[layer + 1][iNextTrackletIndex]; + const float deltaTanLambda{o2::gpu::GPUCommonMath::Abs(currentTracklet.tanLambda - nextTracklet.tanLambda)}; -template -struct pair_to_second : public thrust::unary_function, T2> { - GPUhd() int operator()(const gpuPair& a) const - { - return a.second; - } -}; + if (deltaTanLambda / cellDeltaTanLambdaSigma < nSigmaCut) { + const int clusId[3]{ + sortedClusters[layer][currentTracklet.firstClusterIndex].clusterId, + sortedClusters[layer + 1][nextTracklet.firstClusterIndex].clusterId, + sortedClusters[layer + 2][nextTracklet.secondClusterIndex].clusterId}; -template -struct is_invalid_pair { - GPUhd() bool operator()(const gpuPair& p) const - { - return p.first == -1 && p.second == -1; - } -}; + const auto& cluster1_glo = unsortedClusters[layer][clusId[0]]; + const auto& cluster2_glo = unsortedClusters[layer + 1][clusId[1]]; + const auto& cluster3_tf = tfInfo[layer + 2][clusId[2]]; + auto track{buildTrackSeed(cluster1_glo, cluster2_glo, cluster3_tf, bz)}; + float chi2{0.f}; + bool good{false}; + for (int iC{2}; iC--;) { + const TrackingFrameInfo& trackingHit = tfInfo[layer + iC][clusId[iC]]; + if (!track.rotate(trackingHit.alphaTrackingFrame)) { + break; + } + if (!track.propagateTo(trackingHit.xTrackingFrame, bz)) { + break; + } -template -struct is_valid_pair { - GPUhd() bool operator()(const gpuPair& p) const - { - return !(p.first == -1 && p.second == -1); + if (!track.correctForMaterial(layerxX0[layer + iC], layerxX0[layer] * radl * rho, true)) { + break; + } + + const auto predChi2{track.getPredictedChi2Quiet(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)}; + if (!track.o2::track::TrackParCov::update(trackingHit.positionTrackingFrame, trackingHit.covarianceTrackingFrame)) { + break; + } + if (!iC && predChi2 > maxChi2ClusterAttachment) { + break; + } + good = !iC; + chi2 += predChi2; + } + if (!good) { + continue; + } + if constexpr (!initRun) { + new (cells + cellsLUTs[layer][iCurrentTrackletIndex] + foundCells) CellSeed{layer, clusId[0], clusId[1], clusId[2], iCurrentTrackletIndex, iNextTrackletIndex, track, chi2}; + } + ++foundCells; + if constexpr (initRun) { + cellsLUTs[layer][iCurrentTrackletIndex] = foundCells; + } + } + } } -}; +} -//////////////////////////////////////////////////////////////////////////////// -// Legacy Kernels, to possibly take inspiration from -//////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////// +// Debug Kernels +///////////////////////////////////////// GPUd() const int4 getBinsRect(const Cluster& currentCluster, const int layerIndex, const o2::its::IndexTableUtils& utils, const float z1, const float z2, float maxdeltaz, float maxdeltaphi) @@ -304,6 +423,20 @@ GPUhd() float Sq(float q) return q * q; } +template +GPUd() void pPointer(T* ptr) +{ + printf("[%p]\t", ptr); +} +template +GPUg() void printPointersKernel(std::tuple args) +{ + auto print_all = [&](auto... ptrs) { + (pPointer(ptrs), ...); + }; + std::apply(print_all, args); +} + // Functors to sort tracklets template struct trackletSortEmptyFunctor : public thrust::binary_function { @@ -335,6 +468,32 @@ GPUg() void printBufferLayerOnThread(const int layer, const int* v, unsigned int } } +GPUg() void printMatrixRow(const int row, int** mat, const unsigned int rowLength, const int len = 150, const unsigned int tId = 0) +{ + if (blockIdx.x * blockDim.x + threadIdx.x == tId) { + for (int i{0}; i < rowLength; ++i) { + if (!(i % len)) { + printf("\n row %d: ===> %d/%d\t", row, i, (int)rowLength); + } + printf("%d\t", mat[row][i]); + } + printf("\n"); + } +} + +GPUg() void printBufferPointersLayerOnThread(const int layer, void** v, unsigned int size, const int len = 150, const unsigned int tId = 0) +{ + if (blockIdx.x * blockDim.x + threadIdx.x == tId) { + for (int i{0}; i < size; ++i) { + if (!(i % len)) { + printf("\n layer %d: ===> %d/%d\t", layer, i, (int)size); + } + printf("%p\t", (void*)v[i]); + } + printf("\n"); + } +} + // Dump vertices GPUg() void printVertices(const Vertex* v, unsigned int size, const unsigned int tId = 0) { @@ -642,99 +801,92 @@ GPUg() void removeDuplicateTrackletsEntriesLUTKernel( } } -// Compute cells kernel -template -GPUg() void computeLayerCellsKernel( - const Tracklet* trackletsCurrentLayer, - const Tracklet* trackletsNextLayer, - const int* trackletsCurrentLayerLUT, - const int nTrackletsCurrent, +} // namespace gpu + +void countCellsHandler( + const Cluster** sortedClusters, + const Cluster** unsortedClusters, + const TrackingFrameInfo** tfInfo, + const Tracklet** tracklets, + const int** trackletsLUT, + const int nTracklets, + const int layer, CellSeed* cells, - int* cellsLUTs, - const StaticTrackingParameters* trkPars) + int** cellsLUTsArrayDevice, + int* cellsLUTsHost, + const float bz, + const float maxChi2ClusterAttachment, + const float cellDeltaTanLambdaSigma, + const float nSigmaCut, + const int nBlocks, + const int nThreads) { - for (int iCurrentTrackletIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentTrackletIndex < nTrackletsCurrent; iCurrentTrackletIndex += blockDim.x * gridDim.x) { - const Tracklet& currentTracklet = trackletsCurrentLayer[iCurrentTrackletIndex]; - const int nextLayerClusterIndex{currentTracklet.secondClusterIndex}; - const int nextLayerFirstTrackletIndex{trackletsCurrentLayerLUT[nextLayerClusterIndex]}; - const int nextLayerLastTrackletIndex{trackletsCurrentLayerLUT[nextLayerClusterIndex + 1]}; - if (nextLayerFirstTrackletIndex == nextLayerLastTrackletIndex) { - continue; - } - int foundCells{0}; - for (int iNextTrackletIndex{nextLayerFirstTrackletIndex}; iNextTrackletIndex < nextLayerLastTrackletIndex; ++iNextTrackletIndex) { - if (trackletsNextLayer[iNextTrackletIndex].firstClusterIndex != nextLayerClusterIndex) { - break; - } - const Tracklet& nextTracklet = trackletsNextLayer[iNextTrackletIndex]; - const float deltaTanLambda{o2::gpu::GPUCommonMath::Abs(currentTracklet.tanLambda - nextTracklet.tanLambda)}; - - if (deltaTanLambda / trkPars->CellDeltaTanLambdaSigma < trkPars->NSigmaCut) { - if constexpr (!initRun) { - new (cells + cellsLUTs[iCurrentTrackletIndex] + foundCells) Cell{currentTracklet.firstClusterIndex, nextTracklet.firstClusterIndex, - nextTracklet.secondClusterIndex, - iCurrentTrackletIndex, - iNextTrackletIndex}; - } - ++foundCells; - } - } - if constexpr (initRun) { - // Fill cell Lookup table - cellsLUTs[iCurrentTrackletIndex] = foundCells; - } - } + gpu::computeLayerCellsKernel<<>>( + sortedClusters, // const Cluster** + unsortedClusters, // const Cluster** + tfInfo, // const TrackingFrameInfo** + tracklets, // const Tracklets** + trackletsLUT, // const int** + nTracklets, // const int + layer, // const int + cells, // CellSeed* + cellsLUTsArrayDevice, // int** + bz, // const float + maxChi2ClusterAttachment, // const float + cellDeltaTanLambdaSigma, // const float + nSigmaCut); // const float + void* d_temp_storage = nullptr; + size_t temp_storage_bytes = 0; + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + cellsLUTsHost, // d_in + cellsLUTsHost, // d_out + nTracklets + 1, // num_items + 0)); + discardResult(cudaMalloc(&d_temp_storage, temp_storage_bytes)); + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + cellsLUTsHost, // d_in + cellsLUTsHost, // d_out + nTracklets + 1, // num_items + 0)); + // gpu::printBufferLayerOnThread<<<1, 1>>>(layer, cellsLUTsHost, nTracklets + 1); + gpuCheckError(cudaFree(d_temp_storage)); } -template -GPUg() void computeLayerRoadsKernel( - const int level, - const int layerIndex, - CellSeed** cells, - const int* nCells, - int** neighbours, - int** neighboursLUT, - Road* roads, - int* roadsLookupTable) +void computeCellsHandler( + const Cluster** sortedClusters, + const Cluster** unsortedClusters, + const TrackingFrameInfo** tfInfo, + const Tracklet** tracklets, + const int** trackletsLUT, + const int nTracklets, + const int layer, + CellSeed* cells, + int** cellsLUTsArrayDevice, + int* cellsLUTsHost, + const float bz, + const float maxChi2ClusterAttachment, + const float cellDeltaTanLambdaSigma, + const float nSigmaCut, + const int nBlocks, + const int nThreads) { - for (int iCurrentCellIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentCellIndex < nCells[layerIndex]; iCurrentCellIndex += blockDim.x * gridDim.x) { - auto& currentCell{cells[layerIndex][iCurrentCellIndex]}; - if (currentCell.getLevel() != level) { - continue; - } - int nRoadsCurrentCell{0}; - if constexpr (dryRun) { - roadsLookupTable[iCurrentCellIndex]++; - } else { - roads[roadsLookupTable[iCurrentCellIndex] + nRoadsCurrentCell++] = Road{layerIndex, iCurrentCellIndex}; - } - if (level == 1) { - continue; - } - - const auto currentCellNeighOffset{neighboursLUT[layerIndex - 1][iCurrentCellIndex]}; - const int cellNeighboursNum{neighboursLUT[layerIndex - 1][iCurrentCellIndex + 1] - currentCellNeighOffset}; - bool isFirstValidNeighbour{true}; - for (int iNeighbourCell{0}; iNeighbourCell < cellNeighboursNum; ++iNeighbourCell) { - const int neighbourCellId = neighbours[layerIndex - 1][currentCellNeighOffset + iNeighbourCell]; - const CellSeed& neighbourCell = cells[layerIndex - 1][neighbourCellId]; - if (level - 1 != neighbourCell.getLevel()) { - continue; - } - if (isFirstValidNeighbour) { - isFirstValidNeighbour = false; - } else { - if constexpr (dryRun) { - roadsLookupTable[iCurrentCellIndex]++; // dry run we just count the number of roads - } else { - roads[roadsLookupTable[iCurrentCellIndex] + nRoadsCurrentCell++] = Road{layerIndex, iCurrentCellIndex}; - } - } - // traverseCellsTreeDevice(neighbourCellId, layerIndex - 1, iCurrentCellIndex, nRoadsCurrentCell, roadsLookupTable, cells, roads); - } - } + gpu::computeLayerCellsKernel<<>>( + sortedClusters, // const Cluster** + unsortedClusters, // const Cluster** + tfInfo, // const TrackingFrameInfo** + tracklets, // const Tracklets** + trackletsLUT, // const int** + nTracklets, // const int + layer, // const int + cells, // CellSeed* + cellsLUTsArrayDevice, // int** + bz, // const float + maxChi2ClusterAttachment, // const float + cellDeltaTanLambdaSigma, // const float + nSigmaCut); // const float } -} // namespace gpu void countCellNeighboursHandler(CellSeed** cellsLayersDevice, int* neighboursLUT, @@ -866,16 +1018,16 @@ void trackSeedHandler(CellSeed* trackSeeds, const int nThreads) { gpu::fitTrackSeedsKernel<<>>( - trackSeeds, // CellSeed* trackSeeds, - foundTrackingFrameInfo, // TrackingFrameInfo** foundTrackingFrameInfo, - tracks, // o2::its::TrackITSExt* tracks, - nSeeds, // const unsigned int nSeeds, - Bz, // const float Bz, - startLevel, // const int startLevel, - maxChi2ClusterAttachment, // float maxChi2ClusterAttachment, - maxChi2NDF, // float maxChi2NDF, - propagator, // const o2::base::Propagator* propagator - matCorrType); // o2::base::PropagatorF::MatCorrType matCorrType + trackSeeds, // CellSeed* + foundTrackingFrameInfo, // TrackingFrameInfo** + tracks, // TrackITSExt* + nSeeds, // const unsigned int + Bz, // const float + startLevel, // const int + maxChi2ClusterAttachment, // float + maxChi2NDF, // float + propagator, // const o2::base::Propagator* + matCorrType); // o2::base::PropagatorF::MatCorrType gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Cell.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Cell.h index 482bb38b19bad..cb9f28665cf07 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Cell.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Cell.h @@ -80,6 +80,7 @@ class CellSeed final : public o2::track::TrackParCovF public: GPUhdDefault() CellSeed() = default; GPUhdDefault() CellSeed(const CellSeed&) = default; + GPUhdDefault() ~CellSeed() = default; GPUd() CellSeed(int innerL, int cl0, int cl1, int cl2, int trkl0, int trkl1, o2::track::TrackParCovF& tpc, float chi2) : o2::track::TrackParCovF{tpc}, mLevel{1}, mChi2{chi2} { setUserField(innerL); From b2e9ae6e623ac3e1c448e21cdf269fa179e45430 Mon Sep 17 00:00:00 2001 From: ehellbar Date: Wed, 6 Nov 2024 09:23:18 +0100 Subject: [PATCH 0416/2205] DPL: quit on error by default in no-batch mode without GUI window (#13654) --- Framework/Core/src/runDataProcessing.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 58e669e127f03..ed682a5f92fb8 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -1445,6 +1445,9 @@ int runStateMachine(DataProcessorSpecs const& workflow, if (driverConfig.batch == false && window == nullptr && frameworkId.empty()) { LOG(warn) << "Could not create GUI. Switching to batch mode. Do you have GLFW on your system?"; driverConfig.batch = true; + if (varmap["error-policy"].defaulted()) { + driverInfo.processingPolicies.error = TerminationPolicy::QUIT; + } } bool guiQuitRequested = false; bool hasError = false; From 1a84ee5a5a1984b1c754e03dbefc71d432f55adb Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:55:40 +0100 Subject: [PATCH 0417/2205] Merger: add ability to configure compression level (#13656) --- Framework/AODMerger/src/aodMerger.cxx | 13 +++++++++---- Framework/AODMerger/src/aodStrainer.cxx | 9 +++++++-- Framework/AODMerger/src/aodThinner.cxx | 8 +++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Framework/AODMerger/src/aodMerger.cxx b/Framework/AODMerger/src/aodMerger.cxx index feb945e7176f3..aa27d4f617b3b 100644 --- a/Framework/AODMerger/src/aodMerger.cxx +++ b/Framework/AODMerger/src/aodMerger.cxx @@ -39,6 +39,7 @@ int main(int argc, char* argv[]) bool skipParentFilesList = false; int verbosity = 2; int exitCode = 0; // 0: success, >0: failure + int compression = 505; int option_index = 0; static struct option long_options[] = { @@ -47,8 +48,9 @@ int main(int argc, char* argv[]) {"max-size", required_argument, nullptr, 2}, {"skip-non-existing-files", no_argument, nullptr, 3}, {"skip-parent-files-list", no_argument, nullptr, 4}, - {"verbosity", required_argument, nullptr, 5}, - {"help", no_argument, nullptr, 6}, + {"compression", no_argument, nullptr, 5}, + {"verbosity", required_argument, nullptr, 'v'}, + {"help", no_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}}; while (true) { @@ -66,14 +68,17 @@ int main(int argc, char* argv[]) } else if (c == 4) { skipParentFilesList = true; } else if (c == 5) { + compression = atoi(optarg); + } else if (c == 'v') { verbosity = atoi(optarg); - } else if (c == 6) { + } else if (c == 'h') { printf("AO2D merging tool. Options: \n"); printf(" --input Contains path to files to be merged. Default: %s\n", inputCollection.c_str()); printf(" --output Target output ROOT file. Default: %s\n", outputFileName.c_str()); printf(" --max-size Target directory size. Default: %ld. Set to 0 if file is not self-contained.\n", maxDirSize); printf(" --skip-non-existing-files Flag to allow skipping of non-existing files in the input list.\n"); printf(" --skip-parent-files-list Flag to allow skipping the merging of the parent files list.\n"); + printf(" --compression Compression algorithm / level to use (default: %d)\n", compression); printf(" --verbosity Verbosity of output (default: %d).\n", verbosity); return -1; } else { @@ -95,7 +100,7 @@ int main(int argc, char* argv[]) std::map offsets; std::map unassignedIndexOffset; - auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", 505); + auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", compression); TDirectory* outputDir = nullptr; long currentDirSize = 0; diff --git a/Framework/AODMerger/src/aodStrainer.cxx b/Framework/AODMerger/src/aodStrainer.cxx index a8c83d23e7361..0ecb8d0d81659 100644 --- a/Framework/AODMerger/src/aodStrainer.cxx +++ b/Framework/AODMerger/src/aodStrainer.cxx @@ -39,6 +39,7 @@ int main(int argc, char* argv[]) double downsampling = 1.0; int verbosity = 2; int exitCode = 0; // 0: success, >0: failure + int compression = 505; std::random_device rd; // Seed generator std::mt19937 gen(rd()); // Mersenne Twister generator @@ -51,7 +52,8 @@ int main(int argc, char* argv[]) {"verbosity", required_argument, nullptr, 2}, {"tables", required_argument, nullptr, 3}, {"downsampling", required_argument, nullptr, 4}, - {"help", no_argument, nullptr, 5}, + {"compression", required_argument, nullptr, 5}, + {"help", no_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}}; while (true) { @@ -69,12 +71,15 @@ int main(int argc, char* argv[]) } else if (c == 4) { downsampling = atof(optarg); } else if (c == 5) { + compression = atof(optarg); + } else if (c == 'h') { printf("AO2D strainer tool. Options: \n"); printf(" --input <%s> Contains path to files to be merged. Default: %s\n", inputAO2D.c_str(), inputAO2D.c_str()); printf(" --output <%s> Target output ROOT file. Default: %s\n", outputFileName.c_str(), outputFileName.c_str()); printf(" --verbosity Verbosity of output (default: %d).\n", verbosity); printf(" --tables Comma separated list of tables (default: %s).\n", tables.c_str()); printf(" --downsampling Fraction of DF to be kept (default: %f)\n", downsampling); + printf(" --compression Compression algorithm / level to use (default: %d)\n", compression); return -1; } else { return -2; @@ -95,7 +100,7 @@ int main(int argc, char* argv[]) listOfTables.push_back(token); } - auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", 505); + auto outputFile = TFile::Open(outputFileName.c_str(), "RECREATE", "", compression); TDirectory* outputDir = nullptr; TString line(inputAO2D.c_str()); if (line.BeginsWith("alien://") && !gGrid && !TGrid::Connect("alien:")) { diff --git a/Framework/AODMerger/src/aodThinner.cxx b/Framework/AODMerger/src/aodThinner.cxx index 8459167195ea8..f9fb31f9ad08d 100644 --- a/Framework/AODMerger/src/aodThinner.cxx +++ b/Framework/AODMerger/src/aodThinner.cxx @@ -42,6 +42,7 @@ int main(int argc, char* argv[]) std::string outputFileName("AO2D_thinned.root"); int exitCode = 0; // 0: success, !=0: failure bool bOverwrite = false; + int compression = 505; int option_index = 1; @@ -50,6 +51,7 @@ int main(int argc, char* argv[]) {"input", required_argument, nullptr, 'i'}, {"output", required_argument, nullptr, 'o'}, {"overwrite", no_argument, nullptr, 'O'}, + {"compression", no_argument, nullptr, 'c'}, {"help", no_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}}; @@ -69,12 +71,16 @@ int main(int argc, char* argv[]) bOverwrite = true; printf("Overwriting existing output file if existing\n"); break; + case 'c': + compression = atoi(optarg); + break; case 'h': case '?': default: printf("AO2D thinning tool. Options: \n"); printf(" --input/-i Contains input file path to the file to be thinned. Default: %s\n", inputFileName.c_str()); printf(" --output/-o Target output ROOT file. Default: %s\n", outputFileName.c_str()); + printf(" --compression/-c ROOT compression algorithm / level. Default: %d\n", compression); printf("\n"); printf(" Optional Arguments:\n"); printf(" --overwrite/-O Overwrite existing output file\n"); @@ -89,7 +95,7 @@ int main(int argc, char* argv[]) TStopwatch clock; clock.Start(kTRUE); - auto outputFile = TFile::Open(outputFileName.c_str(), (bOverwrite) ? "RECREATE" : "CREATE", "", 505); + auto outputFile = TFile::Open(outputFileName.c_str(), (bOverwrite) ? "RECREATE" : "CREATE", "", compression); if (outputFile == nullptr) { printf("Error: File %s exists or cannot be created!\n", outputFileName.c_str()); return 1; From 27422f6e17ccb39b3cb06a740e22572d4debf40f Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:11:21 +0100 Subject: [PATCH 0418/2205] DPL: make arrow::FileSystem layered (#13655) This allows distinguishing the navigation of a ROOT file from accessing the actual contents (TTree or eventually, RNTuple). --- .../include/Framework/RootArrowFilesystem.h | 50 +++++--- Framework/Core/src/RootArrowFilesystem.cxx | 116 ++++++++++++++---- Framework/Core/test/test_Root2ArrowTable.cxx | 2 + 3 files changed, 126 insertions(+), 42 deletions(-) diff --git a/Framework/Core/include/Framework/RootArrowFilesystem.h b/Framework/Core/include/Framework/RootArrowFilesystem.h index e1787dae69f31..df00ce4fa8a76 100644 --- a/Framework/Core/include/Framework/RootArrowFilesystem.h +++ b/Framework/Core/include/Framework/RootArrowFilesystem.h @@ -15,6 +15,7 @@ #include #include #include +#include class TTree; class TBufferFile; @@ -32,11 +33,13 @@ class TTreeFileWriteOptions : public arrow::dataset::FileWriteOptions } }; -// This is a virtual filesystem based on a ttree, where branches with the -// same prefix get grouped into a fragment -class TTreeFileSystem : public arrow::fs::FileSystem +// This is to avoid having to implement a bunch of unimplemented methods +// for all the possible virtual filesystem we can invent on top of ROOT +// data structures. +class VirtualRootFileSystemBase : public arrow::fs::FileSystem { public: + // Dummy implementation to avoid arrow::Result GetFileInfo(const std::string& path) override; arrow::Result GetFileInfo(const arrow::fs::FileSelector& select) override; @@ -45,6 +48,8 @@ class TTreeFileSystem : public arrow::fs::FileSystem return this->type_name() == other.type_name(); } + virtual std::shared_ptr GetSubFilesystem(arrow::dataset::FileSource source) = 0; + arrow::Status CreateDir(const std::string& path, bool recursive) override; arrow::Status DeleteDir(const std::string& path) override; @@ -70,8 +75,19 @@ class TTreeFileSystem : public arrow::fs::FileSystem arrow::Result> OpenAppendStream( const std::string& path, const std::shared_ptr& metadata) override; +}; + +// A filesystem which allows me to get a TTree +class TTreeFileSystem : public VirtualRootFileSystemBase +{ + public: + ~TTreeFileSystem() override; - virtual TTree* GetTree(arrow::dataset::FileSource) = 0; + std::shared_ptr GetSubFilesystem(arrow::dataset::FileSource source) override + { + return std::dynamic_pointer_cast(shared_from_this()); + }; + virtual TTree* GetTree(arrow::dataset::FileSource source) = 0; }; class SingleTreeFileSystem : public TTreeFileSystem @@ -98,9 +114,11 @@ class SingleTreeFileSystem : public TTreeFileSystem TTree* mTree; }; -class TFileFileSystem : public TTreeFileSystem +class TFileFileSystem : public VirtualRootFileSystemBase { public: + arrow::Result GetFileInfo(const std::string& path) override; + TFileFileSystem(TDirectoryFile* f, size_t readahead); std::string type_name() const override @@ -108,7 +126,7 @@ class TFileFileSystem : public TTreeFileSystem return "TDirectoryFile"; } - TTree* GetTree(arrow::dataset::FileSource source) override; + std::shared_ptr GetSubFilesystem(arrow::dataset::FileSource source) override; // We can go back to the TFile in case this is needed. TDirectoryFile* GetFile() @@ -120,24 +138,22 @@ class TFileFileSystem : public TTreeFileSystem TDirectoryFile* mFile; }; -class TBufferFileFS : public TTreeFileSystem +class TBufferFileFS : public VirtualRootFileSystemBase { public: TBufferFileFS(TBufferFile* f); + arrow::Result GetFileInfo(const std::string& path) override; std::string type_name() const override { return "tbufferfile"; } - TTree* GetTree(arrow::dataset::FileSource) override - { - // Simply return the only TTree we have - return mTree; - } + std::shared_ptr GetSubFilesystem(arrow::dataset::FileSource source) override; private: - TTree* mTree; + TBufferFile* mBuffer; + std::shared_ptr mFilesystem; }; class TTreeFileFragment : public arrow::dataset::FileFragment @@ -179,8 +195,12 @@ class TTreeFileFormat : public arrow::dataset::FileFormat arrow::Result IsSupported(const arrow::dataset::FileSource& source) const override { - auto fs = std::dynamic_pointer_cast(source.filesystem()); - return fs != nullptr; + auto fs = std::dynamic_pointer_cast(source.filesystem()); + auto subFs = fs->GetSubFilesystem(source); + if (std::dynamic_pointer_cast(subFs)) { + return true; + } + return false; } arrow::Result> Inspect(const arrow::dataset::FileSource& source) const override; diff --git a/Framework/Core/src/RootArrowFilesystem.cxx b/Framework/Core/src/RootArrowFilesystem.cxx index a130f51f7e5a9..46489141c3173 100644 --- a/Framework/Core/src/RootArrowFilesystem.cxx +++ b/Framework/Core/src/RootArrowFilesystem.cxx @@ -11,14 +11,19 @@ #include "Framework/RootArrowFilesystem.h" #include "Framework/Endian.h" #include "Framework/RuntimeError.h" +#include +#include #include #include +#include #include #include #include #include #include #include +#include +#include namespace { @@ -73,35 +78,52 @@ namespace o2::framework { TFileFileSystem::TFileFileSystem(TDirectoryFile* f, size_t readahead) - : TTreeFileSystem(), + : VirtualRootFileSystemBase(), mFile(f) { ((TFile*)mFile)->SetReadaheadSize(50 * 1024 * 1024); } -TTree* TFileFileSystem::GetTree(arrow::dataset::FileSource source) +std::shared_ptr TFileFileSystem::GetSubFilesystem(arrow::dataset::FileSource source) { - // Simply return the only TTree we have - return (TTree*)mFile->Get(source.path().c_str()); + auto tree = (TTree*)mFile->GetObjectChecked(source.path().c_str(), TClass::GetClass()); + if (tree) { + return std::shared_ptr(new SingleTreeFileSystem(tree)); + } + + + auto directory = (TDirectoryFile*)mFile->GetObjectChecked(source.path().c_str(), TClass::GetClass()); + if (directory) { + return std::shared_ptr(new TFileFileSystem(directory, 50 * 1024 * 1024)); + } + throw runtime_error_f("Unsupported file layout"); } -arrow::Result TTreeFileSystem::GetFileInfo(const std::string& path) +arrow::Result TFileFileSystem::GetFileInfo(const std::string& path) { arrow::fs::FileInfo result; result.set_type(arrow::fs::FileType::NotFound); result.set_path(path); arrow::dataset::FileSource source(path, shared_from_this()); - for (auto branch : *GetTree(source)->GetListOfBranches()) { - if (strncmp(branch->GetName(), result.path().c_str(), path.size()) == 0) { - result.set_type(arrow::fs::FileType::File); - return result; - } + auto fs = GetSubFilesystem(source); + + // For now we only support single trees. + if (std::dynamic_pointer_cast(fs)) { + result.set_type(arrow::fs::FileType::File); + return result; } return result; } -arrow::Result TTreeFileSystem::GetFileInfo(const arrow::fs::FileSelector& select) +arrow::Result VirtualRootFileSystemBase::GetFileInfo(std::string const&) +{ + arrow::fs::FileInfo result; + result.set_type(arrow::fs::FileType::NotFound); + return result; +} + +arrow::Result VirtualRootFileSystemBase::GetFileInfo(const arrow::fs::FileSelector& select) { arrow::fs::FileInfoVector results; auto selected = this->GetFileInfo(select.base_dir); @@ -111,59 +133,59 @@ arrow::Result TTreeFileSystem::GetFileInfo(const arro return results; } -arrow::Status TTreeFileSystem::CreateDir(const std::string& path, bool recursive) +arrow::Status VirtualRootFileSystemBase::CreateDir(const std::string& path, bool recursive) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::DeleteDir(const std::string& path) +arrow::Status VirtualRootFileSystemBase::DeleteDir(const std::string& path) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::CopyFile(const std::string& src, const std::string& dest) +arrow::Status VirtualRootFileSystemBase::CopyFile(const std::string& src, const std::string& dest) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::Move(const std::string& src, const std::string& dest) +arrow::Status VirtualRootFileSystemBase::Move(const std::string& src, const std::string& dest) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::DeleteDirContents(const std::string& path, bool missing_dir_ok) +arrow::Status VirtualRootFileSystemBase::DeleteDirContents(const std::string& path, bool missing_dir_ok) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::DeleteRootDirContents() +arrow::Status VirtualRootFileSystemBase::DeleteRootDirContents() { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Status TTreeFileSystem::DeleteFile(const std::string& path) +arrow::Status VirtualRootFileSystemBase::DeleteFile(const std::string& path) { return arrow::Status::NotImplemented("Read only filesystem"); } -arrow::Result> TTreeFileSystem::OpenInputStream(const std::string& path) +arrow::Result> VirtualRootFileSystemBase::OpenInputStream(const std::string& path) { return arrow::Status::NotImplemented("Non streamable filesystem"); } -arrow::Result> TTreeFileSystem::OpenInputFile(const std::string& path) +arrow::Result> VirtualRootFileSystemBase::OpenInputFile(const std::string& path) { return arrow::Status::NotImplemented("No random access file system"); } -arrow::Result> TTreeFileSystem::OpenOutputStream( +arrow::Result> VirtualRootFileSystemBase::OpenOutputStream( const std::string& path, const std::shared_ptr& metadata) { return arrow::Status::NotImplemented("Non streamable filesystem"); } -arrow::Result> TTreeFileSystem::OpenAppendStream( +arrow::Result> VirtualRootFileSystemBase::OpenAppendStream( const std::string& path, const std::shared_ptr& metadata) { @@ -173,8 +195,13 @@ arrow::Result> TTreeFileSystem::OpenApp arrow::Result> TTreeFileFormat::Inspect(const arrow::dataset::FileSource& source) const { arrow::Schema schema{{}}; - auto fs = std::dynamic_pointer_cast(source.filesystem()); - TTree* tree = fs->GetTree(source); + auto fs = std::dynamic_pointer_cast(source.filesystem()); + // Actually get the TTree from the ROOT file. + auto treeFs = std::dynamic_pointer_cast(fs->GetSubFilesystem(source)); + if (!treeFs.get()) { + throw runtime_error_f("Unknown filesystem %s\n", source.filesystem()->type_name().c_str()); + } + TTree* tree = treeFs->GetTree(source); auto branches = tree->GetListOfBranches(); auto n = branches->GetEntries(); @@ -270,7 +297,9 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( auto physical_schema = *treeFragment->ReadPhysicalSchema(); static TBufferFile buffer{TBuffer::EMode::kWrite, 4 * 1024 * 1024}; - auto fs = std::dynamic_pointer_cast(treeFragment->source().filesystem()); + auto containerFS = std::dynamic_pointer_cast(treeFragment->source().filesystem()); + auto fs = std::dynamic_pointer_cast(containerFS->GetSubFilesystem(treeFragment->source())); + int64_t rows = -1; TTree* tree = fs->GetTree(treeFragment->source()); for (auto& field : fields) { @@ -446,9 +475,42 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( } TBufferFileFS::TBufferFileFS(TBufferFile* f) - : TTreeFileSystem(), - mTree((TTree*)f->ReadObject(TTree::Class())) + : VirtualRootFileSystemBase(), + mBuffer(f), + mFilesystem(nullptr) +{ +} + +TTreeFileSystem::~TTreeFileSystem() = default; + + +arrow::Result TBufferFileFS::GetFileInfo(const std::string& path) +{ + arrow::fs::FileInfo result; + result.set_type(arrow::fs::FileType::NotFound); + result.set_path(path); + arrow::dataset::FileSource source(path, shared_from_this()); + + // Only once to avoid rereading the streamed tree. + if (!mFilesystem.get()) { + return result; + } + + // For now we only support single trees. + if (std::dynamic_pointer_cast(mFilesystem)) { + result.set_type(arrow::fs::FileType::File); + return result; + } + return result; +} + +std::shared_ptr TBufferFileFS::GetSubFilesystem(arrow::dataset::FileSource source) { + if (!mFilesystem.get()) { + auto tree = ((TTree*)mBuffer->ReadObject(TTree::Class())); + mFilesystem = std::make_shared(tree); + } + return mFilesystem; } } // namespace o2::framework diff --git a/Framework/Core/test/test_Root2ArrowTable.cxx b/Framework/Core/test/test_Root2ArrowTable.cxx index 69d39f193c7df..599f1062c63a0 100644 --- a/Framework/Core/test/test_Root2ArrowTable.cxx +++ b/Framework/Core/test/test_Root2ArrowTable.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -231,6 +232,7 @@ TEST_CASE("RootTree2Fragment") size_t totalSizeUncompressed = 0; auto format = std::make_shared(totalSizeCompressed, totalSizeUncompressed); auto fs = std::make_shared(fileRead); + arrow::dataset::FileSource source("p", fs); REQUIRE(format->IsSupported(source) == true); auto schemaOpt = format->Inspect(source); From 7df15eb7a082aedc353d85852cdf8a113c02cd55 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 6 Nov 2024 18:15:22 +0100 Subject: [PATCH 0419/2205] Update TPC scaling when MeanLumiRef changed --- GPU/TPCFastTransformation/CorrectionMapsHelper.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GPU/TPCFastTransformation/CorrectionMapsHelper.h b/GPU/TPCFastTransformation/CorrectionMapsHelper.h index e9ee5c793cc3b..7a35077f04aef 100644 --- a/GPU/TPCFastTransformation/CorrectionMapsHelper.h +++ b/GPU/TPCFastTransformation/CorrectionMapsHelper.h @@ -90,10 +90,11 @@ class CorrectionMapsHelper } } - void setMeanLumiRef(float v) + void setMeanLumiRef(float v, bool report = false) { - if (v != mMeanLumi) { + if (v != mMeanLumiRef) { mMeanLumiRef = v; + updateLumiScale(report); } } From 5af5498f16d77025f3b404c2182f70ffa414e459 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 7 Nov 2024 00:19:45 +0100 Subject: [PATCH 0420/2205] Connect CTP digit-reader to MCStudy if TPC corrections asked --- .../study/src/trackMCStudy-workflow.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx index 7ad11068f8a64..7aa53e2190a9e 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx @@ -71,7 +71,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) GID::mask_t srcTrc = allowedSourcesTrc & GID::getSourcesMask(configcontext.options().get("track-sources")); GID::mask_t srcCls = allowedSourcesClus & GID::getSourcesMask(configcontext.options().get("cluster-sources")); srcCls |= GID::getSourcesMask("ITS,TPC"); - + if (sclOpt.requestCTPLumi) { + srcTrc = srcTrc | GID::getSourcesMask("CTP"); + srcCls = srcCls | GID::getSourcesMask("CTP"); + } o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, true); // P-vertex is always needed if (checkSV) { From 096694b4a397ca5505cc867bd6db79252b2e1c38 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 06:54:40 +0100 Subject: [PATCH 0421/2205] DPL: allow larger grace period for dispatching non-DPL incoming messages (#13639) --- Framework/Core/src/ExternalFairMQDeviceProxy.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx index 5a88be2dde6e1..823ef8f5fd5a0 100644 --- a/Framework/Core/src/ExternalFairMQDeviceProxy.cxx +++ b/Framework/Core/src/ExternalFairMQDeviceProxy.cxx @@ -108,8 +108,8 @@ void sendOnChannel(fair::mq::Device& device, fair::mq::Parts& messages, std::str } // FIXME: we need a better logic for avoiding message spam - if (timeout > 1 && timeout <= maxTimeout) { - LOG(warning) << "dispatching on channel " << channel << " was delayed by " << timeout << " ms"; + if (timeout > 100 && timeout <= maxTimeout) { + LOG(warning) << "dispatching on channel " << channel << " was delayed by " << timeout / 1000.f << " s"; } // TODO: feeling this is a bit awkward, but the interface of fair::mq::Parts does not provide a // method to clear the content. From fec521f180c79e416b137acb8358a624b0e2fd83 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 7 Nov 2024 07:04:40 +0100 Subject: [PATCH 0422/2205] ITSMFT: Protect CCDB querying in case we don't need IRFrames (#13661) --- Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx index 5b0a6204ae3e6..3c7a86fe173d6 100644 --- a/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/DigitReaderSpec.cxx @@ -70,7 +70,7 @@ void DigitReader::init(InitContext& ic) void DigitReader::run(ProcessingContext& pc) { const auto& tinfo = pc.services().get(); - if (tinfo.globalRunNumberChanged) { // new run is starting: 1st call + if (tinfo.globalRunNumberChanged && mUseIRFrames) { // new run is starting: 1st call // TODO: we have to find a way define CCDBInput for IRFrames mode only using DPL fetcher auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); auto rlim = ccdb.getRunDuration(tinfo.runNumber); From 2475cbcb0a4a26c920b4ecfd2eeab91f039695ba Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:20:05 +0100 Subject: [PATCH 0423/2205] DPL: allow configuring compression for the AOD writer (#13659) --- .../include/Framework/DataOutputDirector.h | 2 +- Framework/Core/src/AnalysisSupportHelpers.cxx | 18 +++--- Framework/Core/src/AnalysisSupportHelpers.h | 2 +- Framework/Core/src/ArrowSupport.cxx | 7 ++- Framework/Core/src/ConfigParamDiscovery.cxx | 1 + Framework/Core/src/DataOutputDirector.cxx | 4 +- Framework/Core/src/Plugin.cxx | 61 +++++++++++++++++++ Framework/Core/src/WorkflowHelpers.cxx | 6 +- .../TestWorkflows/src/o2TestHistograms.cxx | 17 ++++++ 9 files changed, 103 insertions(+), 15 deletions(-) diff --git a/Framework/Core/include/Framework/DataOutputDirector.h b/Framework/Core/include/Framework/DataOutputDirector.h index bdcb8faf976c0..e2554c9730ba5 100644 --- a/Framework/Core/include/Framework/DataOutputDirector.h +++ b/Framework/Core/include/Framework/DataOutputDirector.h @@ -84,7 +84,7 @@ struct DataOutputDirector { std::vector getDataOutputDescriptors(InputSpec spec); // get the matching TFile - FileAndFolder getFileFolder(DataOutputDescriptor* dodesc, uint64_t folderNumber, std::string parentFileName); + FileAndFolder getFileFolder(DataOutputDescriptor* dodesc, uint64_t folderNumber, std::string parentFileName, int compression); // check file sizes bool checkFileSizes(); diff --git a/Framework/Core/src/AnalysisSupportHelpers.cxx b/Framework/Core/src/AnalysisSupportHelpers.cxx index 3613bfedb887a..e949f27a6eed6 100644 --- a/Framework/Core/src/AnalysisSupportHelpers.cxx +++ b/Framework/Core/src/AnalysisSupportHelpers.cxx @@ -318,10 +318,10 @@ DataProcessorSpec AnalysisSupportHelpers::getOutputObjHistSink(std::vector dod, - std::vector const& outputInputs) + std::vector const& outputInputs, int compressionLevel) { - auto writerFunction = [dod, outputInputs](InitContext& ic) -> std::function { + auto writerFunction = [dod, outputInputs, compressionLevel](InitContext& ic) -> std::function { LOGP(debug, "======== getGlobalAODSink::Init =========="); // find out if any table needs to be saved @@ -363,7 +363,7 @@ DataProcessorSpec std::vector aodMetaDataVals; // this functor is called once per time frame - return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals](ProcessingContext& pc) mutable -> void { + return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals, compressionLevel](ProcessingContext& pc) mutable -> void { LOGP(debug, "======== getGlobalAODSink::processing =========="); LOGP(debug, " processing data set with {} entries", pc.inputs().size()); @@ -457,7 +457,7 @@ DataProcessorSpec // a table can be saved in multiple ways // e.g. different selections of columns to different files for (auto d : ds) { - auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile); + auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile, compressionLevel); auto treename = fileAndFolder.folderName + "/" + d->treename; TableToTree ta2tr(table, fileAndFolder.file, @@ -495,11 +495,11 @@ DataProcessorSpec // the command line options relevant for the writer are global // see runDataProcessing.h DataProcessorSpec spec{ - "internal-dpl-aod-writer", - outputInputs, - Outputs{}, - AlgorithmSpec(writerFunction), - {}}; + .name = "internal-dpl-aod-writer", + .inputs = outputInputs, + .outputs = {}, + .algorithm = AlgorithmSpec{writerFunction}, + }; return spec; } diff --git a/Framework/Core/src/AnalysisSupportHelpers.h b/Framework/Core/src/AnalysisSupportHelpers.h index 43ce7ab85b96d..ba5bcedb4bc67 100644 --- a/Framework/Core/src/AnalysisSupportHelpers.h +++ b/Framework/Core/src/AnalysisSupportHelpers.h @@ -78,7 +78,7 @@ struct AnalysisSupportHelpers { std::vector const& tskmap); /// writes inputs of kind AOD to file static DataProcessorSpec getGlobalAODSink(std::shared_ptr dod, - std::vector const& outputInputs); + std::vector const& outputInputs, int compression); }; }; // namespace o2::framework diff --git a/Framework/Core/src/ArrowSupport.cxx b/Framework/Core/src/ArrowSupport.cxx index 5c1a9050c4e40..1a656e4d60080 100644 --- a/Framework/Core/src/ArrowSupport.cxx +++ b/Framework/Core/src/ArrowSupport.cxx @@ -37,6 +37,7 @@ #include "Headers/DataHeader.h" #include "Headers/DataHeaderHelpers.h" +#include #include #include @@ -536,7 +537,11 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // add TFNumber and TFFilename as input to the writer outputsInputsAOD.emplace_back("tfn", "TFN", "TFNumber"); outputsInputsAOD.emplace_back("tff", "TFF", "TFFilename"); - workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD)); + int compression = 505; + if (ctx.options().hasOption("aod-writer-compression")) { + compression = ctx.options().get("aod-writer-compression"); + } + workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD, compression)); } // Move the dummy sink at the end, if needed for (size_t i = 0; i < workflow.size(); ++i) { diff --git a/Framework/Core/src/ConfigParamDiscovery.cxx b/Framework/Core/src/ConfigParamDiscovery.cxx index 6c24a44bac566..9673f77ed0e42 100644 --- a/Framework/Core/src/ConfigParamDiscovery.cxx +++ b/Framework/Core/src/ConfigParamDiscovery.cxx @@ -27,6 +27,7 @@ std::vector ConfigParamDiscovery::discover(ConfigParamRegistry& std::vector capabilitiesSpecs = { "O2Framework:DiscoverMetadataInAODCapability", "O2Framework:DiscoverMetadataInCommandLineCapability", + "O2Framework:DiscoverAODOptionsInCommandLineCapability", }; // Load all the requested plugins and discover what we can do. diff --git a/Framework/Core/src/DataOutputDirector.cxx b/Framework/Core/src/DataOutputDirector.cxx index 4b803e1050817..cfee1a4b8e8a9 100644 --- a/Framework/Core/src/DataOutputDirector.cxx +++ b/Framework/Core/src/DataOutputDirector.cxx @@ -455,7 +455,7 @@ std::vector DataOutputDirector::getDataOutputDescriptors( return result; } -FileAndFolder DataOutputDirector::getFileFolder(DataOutputDescriptor* dodesc, uint64_t folderNumber, std::string parentFileName) +FileAndFolder DataOutputDirector::getFileFolder(DataOutputDescriptor* dodesc, uint64_t folderNumber, std::string parentFileName, int compression) { // initialisation FileAndFolder fileAndFolder; @@ -488,7 +488,7 @@ FileAndFolder DataOutputDirector::getFileFolder(DataOutputDescriptor* dodesc, ui auto fn = resdirname + "/" + mfilenameBases[ind] + ".root"; delete mfilePtrs[ind]; mParentMaps[ind]->Clear(); - mfilePtrs[ind] = TFile::Open(fn.c_str(), mfileMode.c_str(), "", 505); + mfilePtrs[ind] = TFile::Open(fn.c_str(), mfileMode.c_str(), "", compression); } fileAndFolder.file = mfilePtrs[ind]; diff --git a/Framework/Core/src/Plugin.cxx b/Framework/Core/src/Plugin.cxx index 2edf2e62a3633..a98771a913d01 100644 --- a/Framework/Core/src/Plugin.cxx +++ b/Framework/Core/src/Plugin.cxx @@ -15,6 +15,7 @@ #include "Framework/Capability.h" #include "Framework/Signpost.h" #include "Framework/VariantJSONHelpers.h" +#include #include O2_DECLARE_DYNAMIC_LOG(capabilities); @@ -47,6 +48,19 @@ auto lookForCommandLineOptions = [](ConfigParamRegistry& registry, int argc, cha return false; }; +auto lookForCommandLineAODOptions = [](ConfigParamRegistry& registry, int argc, char** argv) -> bool { + O2_SIGNPOST_ID_GENERATE(sid, capabilities); + // If one of the options for aod-writer is specified, we should allow configuring compression. + for (size_t i = 0; i < argc; i++) { + std::string_view arg = argv[i]; + if (arg.starts_with("--aod-writer-")) { + O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLineCapability", "AOD options found in arguments. Populating from them."); + return true; + } + } + return false; +}; + struct DiscoverMetadataInAODCapability : o2::framework::CapabilityPlugin { Capability* create() override { @@ -68,6 +82,16 @@ struct DiscoverMetadataInCommandLineCapability : o2::framework::CapabilityPlugin } }; +struct DiscoverAODOptionsInCommandLineCapability : o2::framework::CapabilityPlugin { + Capability* create() override + { + return new Capability{ + .name = "DiscoverAODOptionsInCommandLineCapability", + .checkIfNeeded = lookForCommandLineAODOptions, + .requiredPlugin = "O2Framework:DiscoverAODOptionsInCommandLine"}; + } +}; + struct DiscoverMetadataInCommandLine : o2::framework::ConfigDiscoveryPlugin { ConfigDiscovery* create() override { @@ -99,9 +123,46 @@ struct DiscoverMetadataInCommandLine : o2::framework::ConfigDiscoveryPlugin { }}; } }; + +struct DiscoverAODOptionsInCommandLine : o2::framework::ConfigDiscoveryPlugin { + ConfigDiscovery* create() override + { + return new ConfigDiscovery{ + .init = []() {}, + .discover = [](ConfigParamRegistry& registry, int argc, char** argv) -> std::vector { + O2_SIGNPOST_ID_GENERATE(sid, capabilities); + O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLine", + "Discovering AOD handling related options in commandline arguments."); + std::vector results; + bool injectOption = true; + for (size_t i = 0; i < argc; i++) { + std::string_view arg = argv[i]; + if (!arg.starts_with("--aod-writer-")) { + continue; + } + std::string key = arg.data() + 2; + std::string value = argv[i + 1]; + O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLine", + "Found %{public}s with value %{public}s.", key.c_str(), value.c_str()); + if (key == "aod-writer-compression") { + int numericValue = std::stoi(value); + results.push_back(ConfigParamSpec{"aod-writer-compression", VariantType::Int, numericValue, {"AOD Compression options"}}); + injectOption = false; + } + } + if (injectOption) { + results.push_back(ConfigParamSpec{"aod-writer-compression", VariantType::Int, 505, {"AOD Compression options"}}); + } + return results; + }}; + } +}; + DEFINE_DPL_PLUGINS_BEGIN DEFINE_DPL_PLUGIN_INSTANCE(DiscoverMetadataInAODCapability, Capability); DEFINE_DPL_PLUGIN_INSTANCE(DiscoverMetadataInCommandLineCapability, Capability); +DEFINE_DPL_PLUGIN_INSTANCE(DiscoverAODOptionsInCommandLineCapability, Capability); DEFINE_DPL_PLUGIN_INSTANCE(DiscoverMetadataInCommandLine, ConfigDiscovery); +DEFINE_DPL_PLUGIN_INSTANCE(DiscoverAODOptionsInCommandLine, ConfigDiscovery); DEFINE_DPL_PLUGINS_END } // namespace o2::framework diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 6349bd5889eba..3fe8fae19a3b5 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -606,7 +606,11 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // add TFNumber and TFFilename as input to the writer outputsInputsAOD.emplace_back(InputSpec{"tfn", "TFN", "TFNumber"}); outputsInputsAOD.emplace_back(InputSpec{"tff", "TFF", "TFFilename"}); - auto fileSink = AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD); + int compressionLevel = 505; + if (ctx.options().hasOption("aod-writer-compression")) { + compressionLevel = ctx.options().get("aod-writer-compression"); + } + auto fileSink = AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD, compressionLevel); extraSpecs.push_back(fileSink); auto it = std::find_if(outputsInputs.begin(), outputsInputs.end(), [](InputSpec& spec) -> bool { diff --git a/Framework/TestWorkflows/src/o2TestHistograms.cxx b/Framework/TestWorkflows/src/o2TestHistograms.cxx index e32149a8bfdc1..9986f52a1d940 100644 --- a/Framework/TestWorkflows/src/o2TestHistograms.cxx +++ b/Framework/TestWorkflows/src/o2TestHistograms.cxx @@ -22,26 +22,43 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +namespace o2::aod +{ +namespace skimmedExampleTrack +{ +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +} // namespace skimmedExampleTrack + +DECLARE_SOA_TABLE(SkimmedExampleTrack, "AOD", "SKIMEXTRK", //! + skimmedExampleTrack::Pt, + skimmedExampleTrack::Eta); +} // namespace o2::aod + struct EtaAndClsHistogramsSimple { OutputObj etaClsH{TH2F("eta_vs_pt", "#eta vs pT", 102, -2.01, 2.01, 100, 0, 10)}; + Produces skimEx; void process(aod::Tracks const& tracks) { LOGP(info, "Invoking the simple one"); for (auto& track : tracks) { etaClsH->Fill(track.eta(), track.pt(), 0); + skimEx(track.pt(), track.eta()); } } }; struct EtaAndClsHistogramsIUSimple { OutputObj etaClsH{TH2F("eta_vs_pt", "#eta vs pT", 102, -2.01, 2.01, 100, 0, 10)}; + Produces skimEx; void process(aod::TracksIU const& tracks) { LOGP(info, "Invoking the simple one"); for (auto& track : tracks) { etaClsH->Fill(track.eta(), track.pt(), 0); + skimEx(track.pt(), track.eta()); } } }; From be3f6b23b6f05e635d8a440cc071e8d33a72f5e1 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 6 Nov 2024 14:33:48 +0100 Subject: [PATCH 0424/2205] GPU: Fix forwarding of exit code when using doublePipelined processing --- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 5 +++-- GPU/GPUTracking/Definitions/GPUSettingsList.h | 2 +- GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx | 2 +- GPU/Workflow/src/GPUWorkflowSpec.cxx | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index 1acbb99973b43..537c3cf63a628 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -216,8 +216,9 @@ int32_t GPUReconstructionCPU::RunChains() timerTotal.Start(); if (mProcessingSettings.doublePipeline) { - if (EnqueuePipeline()) { - return 1; + int32_t retVal = EnqueuePipeline(); + if (retVal) { + return retVal; } } else { if (mThreadId != GetThread()) { diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index be843b01610e8..224e7c720c334 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -89,7 +89,7 @@ AddOptionRTC(extraClusterErrorSplitPadSharedSingleY2, float, 0.03f, "", 0, "Addi AddOptionRTC(extraClusterErrorFactorSplitPadSharedSingleY2, float, 3.0f, "", 0, "Multiplicative extra cluster error for Y2 if splitpad, shared, or single set") AddOptionRTC(extraClusterErrorSplitTimeSharedSingleZ2, float, 0.03f, "", 0, "Additive extra cluster error for Z2 if splittime, shared, or single set") AddOptionRTC(extraClusterErrorFactorSplitTimeSharedSingleZ2, float, 3.0f, "", 0, "Multiplicative extra cluster error for Z2 if splittime, shared, or single set") -AddOptionArray(errorsCECrossing, float, 5, (0.f, 0.f, 0.f, 0.f, 0.f), "", 0, "Extra errors to add to track when crossing CE, depending on addErrorsCECrossing") // BUG: CUDA cannot yet hand AddOptionArrayRTC +AddOptionArray(errorsCECrossing, float, 5, (0.f, 0.f, 0.f, 0.f, 0.f), "", 0, "Extra errors to add to track when crossing CE, depending on addErrorsCECrossing") // BUG: CUDA cannot yet handle AddOptionArrayRTC AddOptionRTC(globalTrackingYRangeUpper, float, 0.85f, "", 0, "Inner portion of y-range in slice that is not used in searching for global track candidates") AddOptionRTC(globalTrackingYRangeLower, float, 0.85f, "", 0, "Inner portion of y-range in slice that is not used in searching for global track candidates") AddOptionRTC(trackFollowingYFactor, float, 4.f, "", 0, "Weight of y residual vs z residual in tracklet constructor") diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index 7a4aa73ae13d1..f8a64e9d4faaa 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -302,7 +302,7 @@ void GPUChainTracking::SanityCheck() void GPUChainTracking::RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* clusters, std::function allocator, bool applyClusterCuts) { GPUTPCClusterFilter clusterFilter(*clusters); - o2::tpc::ClusterNative* outputBuffer; + o2::tpc::ClusterNative* outputBuffer = nullptr; for (int32_t iPhase = 0; iPhase < 2; iPhase++) { uint32_t countTotal = 0; for (uint32_t iSector = 0; iSector < GPUCA_NSLICES; iSector++) { diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index f16082cb6c0da..4549d895c26b9 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -851,7 +851,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) } createEmptyOutput = !mConfParam->partialOutputForNonFatalErrors; } else { - throw std::runtime_error("tracker returned error code " + std::to_string(retVal)); + throw std::runtime_error("GPU Reconstruction error: error code " + std::to_string(retVal)); } } From 8be37ef626f3ccae7c760884eef263cb39df123e Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 6 Nov 2024 14:54:13 +0100 Subject: [PATCH 0425/2205] TPC: Make number of lanes and threads for TPC IDC factorize configurable --- prodtests/full-system-test/aggregator-workflow.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index 4e5f6f2a4c8ad..4c20e901a2978 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -295,7 +295,8 @@ fi # TPC IDCs and SAC crus="0-359" # to be used with $AGGREGATOR_TASKS == TPC_IDCBOTH_SAC or ALL -lanesFactorize=10 +lanesFactorize=${O2_TPC_IDC_FACTORIZE_NLANES:-10} +threadFactorize=${O2_TPC_IDC_FACTORIZE_NTHREADS:-8} nTFs=$((1000 * 128 / ${NHBPERTF})) nTFs_SAC=$((1000 * 128 / ${NHBPERTF})) nBuffer=$((100 * 128 / ${NHBPERTF})) @@ -309,7 +310,7 @@ if [[ "${DISABLE_IDC_PAD_MAP_WRITING:-}" == 1 ]]; then TPC_WRITING_PAD_STATUS_MA if ! workflow_has_parameter CALIB_LOCAL_INTEGRATED_AGGREGATOR; then if [[ $CALIB_TPC_IDC == 1 ]] && [[ $AGGREGATOR_TASKS == TPC_IDCBOTH_SAC || $AGGREGATOR_TASKS == ALL ]]; then add_W o2-tpc-idc-distribute "--crus ${crus} --timeframes ${nTFs} --output-lanes ${lanesFactorize} --send-precise-timestamp true --condition-tf-per-query ${nTFs} --n-TFs-buffer ${nBuffer}" - add_W o2-tpc-idc-factorize "--n-TFs-buffer ${nBuffer} --input-lanes ${lanesFactorize} --crus ${crus} --timeframes ${nTFs} --nthreads-grouping 8 --nthreads-IDC-factorization 8 --sendOutputFFT true --enable-CCDB-output true --enablePadStatusMap true ${TPC_WRITING_PAD_STATUS_MAP} --use-precise-timestamp true $IDC_DELTA" "TPCIDCGroupParam.groupPadsSectorEdges=32211" + add_W o2-tpc-idc-factorize "--n-TFs-buffer ${nBuffer} --input-lanes ${lanesFactorize} --crus ${crus} --timeframes ${nTFs} --nthreads-grouping ${threadFactorize} --nthreads-IDC-factorization ${threadFactorize} --sendOutputFFT true --enable-CCDB-output true --enablePadStatusMap true ${TPC_WRITING_PAD_STATUS_MAP} --use-precise-timestamp true $IDC_DELTA" "TPCIDCGroupParam.groupPadsSectorEdges=32211" add_W o2-tpc-idc-ft-aggregator "--rangeIDC 200 --inputLanes ${lanesFactorize} --nFourierCoeff 40 --nthreads 8" fi if [[ $CALIB_TPC_SAC == 1 ]] && [[ $AGGREGATOR_TASKS == TPC_IDCBOTH_SAC || $AGGREGATOR_TASKS == ALL ]]; then From f56b4f89779f67d3306c58ab661acb83e4d90dcc Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:45:53 +0100 Subject: [PATCH 0426/2205] DPL: do not leak metadata file descriptor (#13663) --- Framework/AnalysisSupport/src/Plugin.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index baa1b36dd41a5..32a86d37aebb9 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -142,6 +142,7 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { if (tables.empty() == false) { results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}}); } + currentFile->Close(); return results; }}; } From 09d925cca5402c41eebf10452add910202ac2ce4 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:40:41 +0100 Subject: [PATCH 0427/2205] DPL: pass ConfigContext to the PluginManager when creating AlgorithmSpec This way a plugin can create more complex AlgorithmSpecs which depend on the workflow options. This will be needed to properly read metadata from parent files, and it opens the way to more service devices to be moved in a plugin. --- Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx | 3 ++- Framework/AnalysisSupport/src/AODJAlienReaderHelpers.h | 2 +- Framework/AnalysisSupport/src/Plugin.cxx | 4 ++-- Framework/CCDBSupport/src/Plugin.cxx | 2 +- Framework/Core/include/Framework/AlgorithmSpec.h | 2 +- Framework/Core/include/Framework/PluginManager.h | 5 +++-- Framework/Core/src/PluginManager.cxx | 6 +++--- Framework/Core/src/WorkflowHelpers.cxx | 4 ++-- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx index a8b708668dae1..016ed4f1df1ef 100644 --- a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx +++ b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx @@ -22,6 +22,7 @@ #include "Framework/DeviceSpec.h" #include "Framework/RawDeviceService.h" #include "Framework/DataSpecUtils.h" +#include "Framework/ConfigContext.h" #include "DataInputDirector.h" #include "Framework/SourceInfoHeader.h" #include "Framework/ChannelInfo.h" @@ -117,7 +118,7 @@ static inline auto extractOriginalsTuple(framework::pack, ProcessingConte return std::make_tuple(extractTypedOriginal(pc)...); } -AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback() +AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const& config) { auto callback = AlgorithmSpec{adaptStateful([](ConfigParamRegistry const& options, DeviceSpec const& spec, diff --git a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.h b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.h index 4b9fd710aca14..e8d663d8fe0bb 100644 --- a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.h +++ b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.h @@ -24,7 +24,7 @@ namespace o2::framework::readers { struct AODJAlienReaderHelpers { - static AlgorithmSpec rootFileReaderCallback(); + static AlgorithmSpec rootFileReaderCallback(ConfigContext const&context); static void dumpFileMetrics(o2::monitoring::Monitoring& monitoring, TFile* currentFile, uint64_t startedAt, uint64_t ioTime, int tfPerFile, int tfRead); }; diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index 32a86d37aebb9..9ab4dfa0a2a9f 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -26,9 +26,9 @@ O2_DECLARE_DYNAMIC_LOG(analysis_support); struct ROOTFileReader : o2::framework::AlgorithmPlugin { - o2::framework::AlgorithmSpec create() override + o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const& config) override { - return o2::framework::readers::AODJAlienReaderHelpers::rootFileReaderCallback(); + return o2::framework::readers::AODJAlienReaderHelpers::rootFileReaderCallback(config); } }; diff --git a/Framework/CCDBSupport/src/Plugin.cxx b/Framework/CCDBSupport/src/Plugin.cxx index 8769511f4849a..18aabc07ae4a4 100644 --- a/Framework/CCDBSupport/src/Plugin.cxx +++ b/Framework/CCDBSupport/src/Plugin.cxx @@ -13,7 +13,7 @@ #include "CCDBHelpers.h" struct CCDBFetcherPlugin : o2::framework::AlgorithmPlugin { - o2::framework::AlgorithmSpec create() final + o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const&) final { return o2::framework::CCDBHelpers::fetchFromCCDB(); } diff --git a/Framework/Core/include/Framework/AlgorithmSpec.h b/Framework/Core/include/Framework/AlgorithmSpec.h index e08d829e489bd..7d56ba9f6ce68 100644 --- a/Framework/Core/include/Framework/AlgorithmSpec.h +++ b/Framework/Core/include/Framework/AlgorithmSpec.h @@ -81,7 +81,7 @@ struct AlgorithmSpec { /// Helper class for an algorithm which is loaded as a plugin. struct AlgorithmPlugin { - virtual AlgorithmSpec create() = 0; + virtual AlgorithmSpec create(ConfigContext const&) = 0; }; // Allow fetching inputs from the context using a string literal. template diff --git a/Framework/Core/include/Framework/PluginManager.h b/Framework/Core/include/Framework/PluginManager.h index 4c6e965502500..d6b16f01ad713 100644 --- a/Framework/Core/include/Framework/PluginManager.h +++ b/Framework/Core/include/Framework/PluginManager.h @@ -51,8 +51,9 @@ struct PluginManager { /// the DPLPluginHandle provided by the library. static void load(std::vector& infos, const char* dso, std::function& onSuccess); /// Load an called @plugin from a library called @a library and - /// return the associtated AlgorithmSpec. - static auto loadAlgorithmFromPlugin(std::string library, std::string plugin) -> AlgorithmSpec; + /// @return the associated AlgorithmSpec. + /// The config @a context can be used to determine the workflow options which affect such plugin. + static auto loadAlgorithmFromPlugin(std::string library, std::string plugin, ConfigContext const& context) -> AlgorithmSpec; /// Wrap an algorithm with some lambda @wrapper which will be called /// with the original callback and the ProcessingContext. static auto wrapAlgorithm(AlgorithmSpec const& spec, WrapperProcessCallback&& wrapper) -> AlgorithmSpec; diff --git a/Framework/Core/src/PluginManager.cxx b/Framework/Core/src/PluginManager.cxx index 96666722fc169..9faea85ad65e7 100644 --- a/Framework/Core/src/PluginManager.cxx +++ b/Framework/Core/src/PluginManager.cxx @@ -101,10 +101,10 @@ void PluginManager::load(std::vector& libs, const char* dso, std::fu onSuccess(pluginInstance); } -auto PluginManager::loadAlgorithmFromPlugin(std::string library, std::string plugin) -> AlgorithmSpec +auto PluginManager::loadAlgorithmFromPlugin(std::string library, std::string plugin, ConfigContext const& context) -> AlgorithmSpec { std::shared_ptr algorithm{nullptr}; - return AlgorithmSpec{[algorithm, library, plugin](InitContext& ic) mutable -> AlgorithmSpec::ProcessCallback { + return AlgorithmSpec{[algorithm, library, plugin, &context](InitContext& ic) mutable -> AlgorithmSpec::ProcessCallback { if (algorithm.get()) { return algorithm->onInit(ic); } @@ -134,7 +134,7 @@ auto PluginManager::loadAlgorithmFromPlugin(std::string library, std::string plu if (!creator) { LOGP(fatal, "Could not find the {} plugin in {}.", plugin, libName); } - algorithm = std::make_shared(creator->create()); + algorithm = std::make_shared(creator->create(context)); return algorithm->onInit(ic); }}; }; diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 3fe8fae19a3b5..0366e39cf8976 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -432,7 +432,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext auto mctracks2aod = std::find_if(workflow.begin(), workflow.end(), [](auto const& x) { return x.name == "mctracks-to-aod"; }); if (mctracks2aod == workflow.end()) { // add normal reader - auto&& algo = PluginManager::loadAlgorithmFromPlugin("O2FrameworkAnalysisSupport", "ROOTFileReader"); + auto&& algo = PluginManager::loadAlgorithmFromPlugin("O2FrameworkAnalysisSupport", "ROOTFileReader", ctx); if (internalRateLimiting) { aodReader.algorithm = CommonDataProcessors::wrapWithRateLimiting(algo); } else { @@ -520,7 +520,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext } // Load the CCDB backend from the plugin - ccdbBackend.algorithm = PluginManager::loadAlgorithmFromPlugin("O2FrameworkCCDBSupport", "CCDBFetcherPlugin"); + ccdbBackend.algorithm = PluginManager::loadAlgorithmFromPlugin("O2FrameworkCCDBSupport", "CCDBFetcherPlugin", ctx); extraSpecs.push_back(ccdbBackend); } else { // If there is no CCDB requested, but we still ask for a FLP/DISTSUBTIMEFRAME/0xccdb From 8f506c80c893200df1865321da165d4852159b01 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:53:03 +0100 Subject: [PATCH 0428/2205] DPL: allow plugins to know about discoveries of other plugins --- Framework/Core/include/Framework/runDataProcessing.h | 1 - Framework/Core/src/ConfigParamDiscovery.cxx | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/runDataProcessing.h b/Framework/Core/include/Framework/runDataProcessing.h index fbf2843d4db01..eee4c4b6583d3 100644 --- a/Framework/Core/include/Framework/runDataProcessing.h +++ b/Framework/Core/include/Framework/runDataProcessing.h @@ -197,7 +197,6 @@ int mainNoCatch(int argc, char** argv) for (auto& extra : extraOptions) { workflowOptions.push_back(extra); } - workflowOptionsRegistry.loadExtra(extraOptions); ConfigContext configContext(workflowOptionsRegistry, argc, argv); o2::framework::WorkflowSpec specs = defineDataProcessing(configContext); diff --git a/Framework/Core/src/ConfigParamDiscovery.cxx b/Framework/Core/src/ConfigParamDiscovery.cxx index 9673f77ed0e42..63c38b7f0ac6c 100644 --- a/Framework/Core/src/ConfigParamDiscovery.cxx +++ b/Framework/Core/src/ConfigParamDiscovery.cxx @@ -75,6 +75,7 @@ std::vector ConfigParamDiscovery::discover(ConfigParamRegistry& for (auto& extra : extras) { result.push_back(extra); } + registry.loadExtra(extras); } return result; } From 2c1efe45eb36be258aef262bf771daf7a0188671 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:53:21 +0100 Subject: [PATCH 0429/2205] DPL: read metadata from parent files If the metadata is not found in the main file and if there is a list of parent files, try those as well. --- .../src/AODJAlienReaderHelpers.cxx | 20 ++-- Framework/AnalysisSupport/src/Plugin.cxx | 102 +++++++++++++----- Framework/Core/src/ConfigParamDiscovery.cxx | 2 +- Framework/Core/src/Plugin.cxx | 9 +- Framework/Core/src/WorkflowHelpers.cxx | 1 - 5 files changed, 96 insertions(+), 38 deletions(-) diff --git a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx index 016ed4f1df1ef..90d88cb43626e 100644 --- a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx +++ b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx @@ -120,10 +120,17 @@ static inline auto extractOriginalsTuple(framework::pack, ProcessingConte AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const& config) { - auto callback = AlgorithmSpec{adaptStateful([](ConfigParamRegistry const& options, - DeviceSpec const& spec, - Monitoring& monitoring, - DataProcessingStats& stats) { + // aod-parent-base-path-replacement is now a workflow option, so it needs to be + // retrieved from the ConfigContext. This is because we do not allow workflow options + // to change over start-stop-start because they can affect the topology generation. + std::string parentFileReplacement; + if (config.options().isSet("aod-parent-base-path-replacement")) { + parentFileReplacement = config.options().get("aod-parent-base-path-replacement"); + } + auto callback = AlgorithmSpec{adaptStateful([parentFileReplacement](ConfigParamRegistry const& options, + DeviceSpec const& spec, + Monitoring& monitoring, + DataProcessingStats& stats) { // FIXME: not actually needed, since data processing stats can specify that we should // send the initial value. stats.updateStats({static_cast(ProcessingStatsId::ARROW_BYTES_CREATED), DataProcessingStats::Op::Set, 0}); @@ -141,11 +148,6 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const auto maxRate = options.get("aod-max-io-rate"); - std::string parentFileReplacement; - if (options.isSet("aod-parent-base-path-replacement")) { - parentFileReplacement = options.get("aod-parent-base-path-replacement"); - } - int parentAccessLevel = 0; if (options.isSet("aod-parent-access-level")) { parentAccessLevel = options.get("aod-parent-access-level"); diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index 9ab4dfa0a2a9f..b899a52206422 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -22,6 +22,7 @@ #include #include #include +#include O2_DECLARE_DYNAMIC_LOG(analysis_support); @@ -65,7 +66,7 @@ struct RunSummary : o2::framework::ServicePlugin { } }; -std::vector getListOfTables(TFile* f) +std::vector getListOfTables(std::unique_ptr& f) { std::vector r; TList* keyList = f->GetListOfKeys(); @@ -83,6 +84,32 @@ std::vector getListOfTables(TFile* f) } return r; } +auto readMetadata(std::unique_ptr& currentFile) -> std::vector +{ + // Get the metadata, if any + auto m = (TMap*)currentFile->Get("metaData"); + if (!m) { + return {}; + } + std::vector results; + auto it = m->MakeIterator(); + + // Serialise metadata into a ; separated string with : separating key and value + bool first = true; + while (auto obj = it->Next()) { + if (first) { + LOGP(info, "Metadata for file \"{}\":", currentFile->GetName()); + first = false; + } + auto objString = (TObjString*)m->GetValue(obj); + LOGP(info, "- {}: {}", obj->GetName(), objString->String().Data()); + std::string key = "aod-metadata-" + std::string(obj->GetName()); + char const* value = strdup(objString->String()); + results.push_back(ConfigParamSpec{key, VariantType::String, value, {"Metadata in AOD"}}); + } + + return results; +} struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { ConfigDiscovery* create() override @@ -94,8 +121,6 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { if (filename.empty()) { return {}; } - std::vector results; - TFile* currentFile = nullptr; if (filename.at(0) == '@') { filename.erase(0, 1); // read the text file and set filename to the contents of the first line @@ -110,39 +135,64 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { TGrid::Connect("alien://"); } LOGP(info, "Loading metadata from file {} in PID {}", filename, getpid()); - currentFile = TFile::Open(filename.c_str()); - if (!currentFile) { + std::unique_ptr currentFile{TFile::Open(filename.c_str())}; + if (currentFile.get() == nullptr) { LOGP(fatal, "Couldn't open file \"{}\"!", filename); } + std::vector results = readMetadata(currentFile); + // Found metadata already in the main file. + if (!results.empty()) { + auto tables = getListOfTables(currentFile); + if (tables.empty() == false) { + results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}}); + } + results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}}); + return results; + } - // Get the metadata, if any - auto m = (TMap*)currentFile->Get("metaData"); - if (!m) { + // Lets try in parent files + auto parentFiles = (TMap*)currentFile->Get("parentFiles"); + if (!parentFiles) { LOGP(info, "No metadata found in file \"{}\"", filename); results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}}); return results; } - auto it = m->MakeIterator(); - - // Serialise metadata into a ; separated string with : separating key and value - bool first = true; - while (auto obj = it->Next()) { - if (first) { - LOGP(info, "Metadata for file \"{}\":", filename); - first = false; + for (auto* p : *parentFiles) { + std::string parentFilename = ((TPair*)p)->Value()->GetName(); + // Do the replacement. Notice this will require changing aod-parent-base-path-replacement to be + // a workflow option (because the metadata itself is potentially changing the topology). + if (registry.isSet("aod-parent-base-path-replacement")) { + auto parentFileReplacement = registry.get("aod-parent-base-path-replacement"); + auto pos = parentFileReplacement.find(';'); + if (pos == std::string::npos) { + throw std::runtime_error(fmt::format("Invalid syntax in aod-parent-base-path-replacement: \"{}\"", parentFileReplacement.c_str())); + } + auto from = parentFileReplacement.substr(0, pos); + auto to = parentFileReplacement.substr(pos + 1); + pos = parentFilename.find(from); + if (pos != std::string::npos) { + parentFilename.replace(pos, from.length(), to); + } } - auto objString = (TObjString*)m->GetValue(obj); - LOGP(info, "- {}: {}", obj->GetName(), objString->String().Data()); - std::string key = "aod-metadata-" + std::string(obj->GetName()); - char const* value = strdup(objString->String()); - results.push_back(ConfigParamSpec{key, VariantType::String, value, {"Metadata in AOD"}}); - } - auto tables = getListOfTables(currentFile); - if (tables.empty() == false) { - results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}}); + std::unique_ptr parentFile{TFile::Open(parentFilename.c_str())}; + if (parentFile.get() == nullptr) { + LOGP(fatal, "Couldn't open derived file \"{}\"!", parentFilename); + } + results = readMetadata(parentFile); + // Found metadata already in the main file. + if (!results.empty()) { + auto tables = getListOfTables(parentFile); + if (tables.empty() == false) { + results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}}); + } + results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}}); + return results; + } + LOGP(info, "No metadata found in file \"{}\" nor in its parent file \"{}\"", filename, parentFilename); + break; } - currentFile->Close(); + results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}}); return results; }}; } diff --git a/Framework/Core/src/ConfigParamDiscovery.cxx b/Framework/Core/src/ConfigParamDiscovery.cxx index 63c38b7f0ac6c..fc8d6f2600bb4 100644 --- a/Framework/Core/src/ConfigParamDiscovery.cxx +++ b/Framework/Core/src/ConfigParamDiscovery.cxx @@ -25,9 +25,9 @@ namespace o2::framework std::vector ConfigParamDiscovery::discover(ConfigParamRegistry& registry, int argc, char** argv) { std::vector capabilitiesSpecs = { + "O2Framework:DiscoverAODOptionsInCommandLineCapability", "O2Framework:DiscoverMetadataInAODCapability", "O2Framework:DiscoverMetadataInCommandLineCapability", - "O2Framework:DiscoverAODOptionsInCommandLineCapability", }; // Load all the requested plugins and discover what we can do. diff --git a/Framework/Core/src/Plugin.cxx b/Framework/Core/src/Plugin.cxx index a98771a913d01..91c74bafff5ad 100644 --- a/Framework/Core/src/Plugin.cxx +++ b/Framework/Core/src/Plugin.cxx @@ -57,6 +57,10 @@ auto lookForCommandLineAODOptions = [](ConfigParamRegistry& registry, int argc, O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLineCapability", "AOD options found in arguments. Populating from them."); return true; } + if (arg.starts_with("--aod-parent-base-path-replacement")) { + O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLineCapability", "AOD options found in arguments. Populating from them."); + return true; + } } return false; }; @@ -137,7 +141,7 @@ struct DiscoverAODOptionsInCommandLine : o2::framework::ConfigDiscoveryPlugin { bool injectOption = true; for (size_t i = 0; i < argc; i++) { std::string_view arg = argv[i]; - if (!arg.starts_with("--aod-writer-")) { + if (!arg.starts_with("--aod-writer-") && arg != "--aod-parent-base-path-replacement") { continue; } std::string key = arg.data() + 2; @@ -149,6 +153,9 @@ struct DiscoverAODOptionsInCommandLine : o2::framework::ConfigDiscoveryPlugin { results.push_back(ConfigParamSpec{"aod-writer-compression", VariantType::Int, numericValue, {"AOD Compression options"}}); injectOption = false; } + if (key == "aod-parent-base-path-replacement") { + results.push_back(ConfigParamSpec{"aod-parent-base-path-replacement", VariantType::String, value, {R"(Replace base path of parent files. Syntax: FROM;TO. E.g. "alien:///path/in/alien;/local/path". Enclose in "" on the command line.)"}}); + } } if (injectOption) { results.push_back(ConfigParamSpec{"aod-writer-compression", VariantType::Int, 505, {"AOD Compression options"}}); diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 0366e39cf8976..56e9930e3b655 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -217,7 +217,6 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext ConfigParamSpec{"aod-max-io-rate", VariantType::Float, 0.f, {"Maximum I/O rate in MB/s"}}, ConfigParamSpec{"aod-reader-json", VariantType::String, {"json configuration file"}}, ConfigParamSpec{"aod-parent-access-level", VariantType::String, {"Allow parent file access up to specified level. Default: no (0)"}}, - ConfigParamSpec{"aod-parent-base-path-replacement", VariantType::String, {R"(Replace base path of parent files. Syntax: FROM;TO. E.g. "alien:///path/in/alien;/local/path". Enclose in "" on the command line.)"}}, ConfigParamSpec{"time-limit", VariantType::Int64, 0ll, {"Maximum run time limit in seconds"}}, ConfigParamSpec{"orbit-offset-enumeration", VariantType::Int64, 0ll, {"initial value for the orbit"}}, ConfigParamSpec{"orbit-multiplier-enumeration", VariantType::Int64, 0ll, {"multiplier to get the orbit from the counter"}}, From 71711a52b76dc181f1b62ac525054246da12d896 Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 20 Jun 2024 17:07:43 +0200 Subject: [PATCH 0430/2205] Improvements for CollisionContextTool * important step to create collision contexts for all timeframes in one step - complete digi context is created - individual tf-collisioncontexts can be extracted * needed to have "pregencollcontext" in O2DPG work with embedding * smaller fixes (firstOrbit) --- .../DigitizationContext.h | 12 +- .../simulation/src/DigitizationContext.cxx | 105 +++++++++++++++++- Steer/src/CollisionContextTool.cxx | 81 +++++++++++++- 3 files changed, 187 insertions(+), 11 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h index de8d89e6b1b72..4149b32683060 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h +++ b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h @@ -113,6 +113,11 @@ class DigitizationContext /// Check collision parts for vertex consistency. bool checkVertexCompatibility(bool verbose = false) const; + /// retrieves collision context for a single timeframe-id (which may be needed by simulation) + /// (Only copies collision context without QED information. This can be added to the result with the fillQED method + /// in a second step. As a pre-condition, one should have called finalizeTimeframeStructure) + DigitizationContext extractSingleTimeframe(int timeframeid, std::vector const& sources_to_offset); + /// function reading the hits from a chain (previously initialized with initSimChains /// The hits pointer will be initialized (what to we do about ownership??) template @@ -128,8 +133,9 @@ class DigitizationContext // apply collision number cuts and potential relabeling of eventID void applyMaxCollisionFilter(long startOrbit, long orbitsPerTF, int maxColl); - // finalize timeframe structure (fixes the indices in mTimeFrameStartIndex) - void finalizeTimeframeStructure(long startOrbit, long orbitsPerTF); + /// finalize timeframe structure (fixes the indices in mTimeFrameStartIndex) + // returns the number of timeframes + int finalizeTimeframeStructure(long startOrbit, long orbitsPerTF); // Sample and fix interaction vertices (according to some distribution). Makes sure that same event ids // have to have same vertex, as well as event ids associated to same collision. @@ -173,7 +179,7 @@ class DigitizationContext // for each collision we may record/fix the interaction vertex (to be used in event generation) std::vector> mInteractionVertices; - // the collision records _with_ QED interleaved; + // the collision records **with** QED interleaved; std::vector mEventRecordsWithQED; std::vector> mEventPartsWithQED; diff --git a/DataFormats/simulation/src/DigitizationContext.cxx b/DataFormats/simulation/src/DigitizationContext.cxx index f3f40d77042a5..ba1fda53e179b 100644 --- a/DataFormats/simulation/src/DigitizationContext.cxx +++ b/DataFormats/simulation/src/DigitizationContext.cxx @@ -19,6 +19,7 @@ #include // for iota #include #include +#include using namespace o2::steer; @@ -196,10 +197,52 @@ o2::parameters::GRPObject const& DigitizationContext::getGRP() const void DigitizationContext::saveToFile(std::string_view filename) const { + // checks if the path content of filename exists ... otherwise it is created before creating the ROOT file + auto ensure_path_exists = [](std::string_view filename) { + try { + // Extract the directory path from the filename + std::filesystem::path file_path(filename); + std::filesystem::path dir_path = file_path.parent_path(); + + // Check if the directory path is empty (which means filename was just a name without path) + if (dir_path.empty()) { + // nothing to do + return true; + } + + // Create directories if they do not exist + if (!std::filesystem::exists(dir_path)) { + if (std::filesystem::create_directories(dir_path)) { + // std::cout << "Directories created successfully: " << dir_path.string() << std::endl; + return true; + } else { + std::cerr << "Failed to create directories: " << dir_path.string() << std::endl; + return false; + } + } + return true; + } catch (const std::filesystem::filesystem_error& ex) { + std::cerr << "Filesystem error: " << ex.what() << std::endl; + return false; + } catch (const std::exception& ex) { + std::cerr << "General error: " << ex.what() << std::endl; + return false; + } + }; + + if (!ensure_path_exists(filename)) { + LOG(error) << "Filename contains path component which could not be created"; + return; + } + TFile file(filename.data(), "RECREATE"); - auto cl = TClass::GetClass(typeid(*this)); - file.WriteObjectAny(this, cl, "DigitizationContext"); - file.Close(); + if (file.IsOpen()) { + auto cl = TClass::GetClass(typeid(*this)); + file.WriteObjectAny(this, cl, "DigitizationContext"); + file.Close(); + } else { + LOG(error) << "Could not write to file " << filename.data(); + } } DigitizationContext* DigitizationContext::loadFromFile(std::string_view filename) @@ -391,13 +434,15 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe mEventParts = newparts; } -void DigitizationContext::finalizeTimeframeStructure(long startOrbit, long orbitsPerTF) +int DigitizationContext::finalizeTimeframeStructure(long startOrbit, long orbitsPerTF) { mTimeFrameStartIndex = getTimeFrameBoundaries(mEventRecords, startOrbit, orbitsPerTF); LOG(info) << "Fixed " << mTimeFrameStartIndex.size() << " timeframes "; for (auto p : mTimeFrameStartIndex) { LOG(info) << p.first << " " << p.second; } + + return mTimeFrameStartIndex.size(); } std::unordered_map DigitizationContext::getCollisionIndicesForSource(int source) const @@ -483,3 +528,55 @@ void DigitizationContext::sampleInteractionVertices(o2::dataformats::MeanVertexO } } } + +DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid, std::vector const& sources_to_offset) +{ + DigitizationContext r; // make a return object + if (mTimeFrameStartIndex.size() == 0) { + LOG(error) << "No timeframe structure determined; Returning empty object. Please call ::finalizeTimeframeStructure before calling this function"; + return r; + } + r.mSimPrefixes = mSimPrefixes; + r.mMuBC = mMuBC; + try { + auto startend = mTimeFrameStartIndex.at(timeframeid); + + auto startindex = startend.first; + auto endindex = startend.second; + + std::copy(mEventRecords.begin() + startindex, mEventRecords.begin() + endindex, std::back_inserter(r.mEventRecords)); + std::copy(mEventParts.begin() + startindex, mEventParts.begin() + endindex, std::back_inserter(r.mEventParts)); + if (mInteractionVertices.size() > endindex) { + std::copy(mInteractionVertices.begin() + startindex, mInteractionVertices.begin() + endindex, std::back_inserter(r.mInteractionVertices)); + } + + // let's assume we want to fix the ids for source = source_id + // Then we find the first index that has this source_id and take the corresponding number + // as offset. Thereafter we subtract this offset from all known event parts. + auto perform_offsetting = [&r](int source_id) { + auto indices_for_source = r.getCollisionIndicesForSource(source_id); + int minvalue = std::numeric_limits::max(); + for (auto& p : indices_for_source) { + if (p.first < minvalue) { + minvalue = p.first; + } + } + // now fix them + for (auto& p : indices_for_source) { + auto index_into_mEventParts = p.second; + for (auto& part : r.mEventParts[index_into_mEventParts]) { + if (part.sourceID == source_id) { + part.entryID -= minvalue; + } + } + } + }; + for (auto source_id : sources_to_offset) { + perform_offsetting(source_id); + } + + } catch (std::exception) { + LOG(warn) << "No such timeframe id in collision context. Returing empty object"; + } + return r; +} diff --git a/Steer/src/CollisionContextTool.cxx b/Steer/src/CollisionContextTool.cxx index f94fde22ef8ac..af2f607b88774 100644 --- a/Steer/src/CollisionContextTool.cxx +++ b/Steer/src/CollisionContextTool.cxx @@ -55,6 +55,8 @@ struct Options { bool genVertices = false; // whether to assign vertices to collisions std::string configKeyValues = ""; // string to init config key values long timestamp = -1; // timestamp for CCDB queries + std::string individualTFextraction = ""; // triggers extraction of individuel timeframe components when non-null + // format is path prefix }; enum class InteractionLockMode { @@ -200,7 +202,10 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) "timeframeID", bpo::value(&optvalues.tfid)->default_value(0), "Timeframe id of the first timeframe int this context. Allows to generate contexts for different start orbits")( "first-orbit", bpo::value(&optvalues.firstFractionalOrbit)->default_value(0), "First (fractional) orbit in the run (HBFUtils.firstOrbit + BC from decimal)")( "maxCollsPerTF", bpo::value(&optvalues.maxCollsPerTF)->default_value(-1), "Maximal number of MC collisions to put into one timeframe. By default no constraint.")( - "noEmptyTF", bpo::bool_switch(&optvalues.noEmptyTF), "Enforce to have at least one collision")("configKeyValues", bpo::value(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")("with-vertices", "Assign vertices to collisions.")("timestamp", bpo::value(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring"); + "noEmptyTF", bpo::bool_switch(&optvalues.noEmptyTF), "Enforce to have at least one collision")( + "configKeyValues", bpo::value(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")("with-vertices", "Assign vertices to collisions.")("timestamp", bpo::value(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring")( + "extract-per-timeframe", bpo::value(&optvalues.individualTFextraction)->default_value(""), + "Extract individual timeframe contexts. Format required: time_frame_prefix[:comma_separated_list_of_signals_to_offset]"); options.add_options()("help,h", "Produce help message."); @@ -283,6 +288,8 @@ int main(int argc, char* argv[]) } }; + auto orbitstart = options.firstOrbit + options.tfid * options.orbitsPerTF; + for (int id = 0; id < ispecs.size(); ++id) { auto mode = ispecs[id].syncmode; if (mode == InteractionLockMode::NOLOCK) { @@ -291,7 +298,6 @@ int main(int argc, char* argv[]) if (!options.bcpatternfile.empty()) { setBCFillingHelper(sampler, options.bcpatternfile); } - auto orbitstart = options.firstOrbit + options.tfid * options.orbitsPerTF; o2::InteractionTimeRecord record; // this loop makes sure that the first collision is within the range of orbits asked (if noEmptyTF is enabled) do { @@ -439,9 +445,9 @@ int main(int argc, char* argv[]) digicontext.setSimPrefixes(prefixes); // apply max collision per timeframe filters + reindexing of event id (linearisation and compactification) - digicontext.applyMaxCollisionFilter(options.tfid * options.orbitsPerTF, options.orbitsPerTF, options.maxCollsPerTF); + digicontext.applyMaxCollisionFilter(orbitstart, options.orbitsPerTF, options.maxCollsPerTF); - digicontext.finalizeTimeframeStructure(options.tfid * options.orbitsPerTF, options.orbitsPerTF); + auto numTimeFrames = digicontext.finalizeTimeframeStructure(orbitstart, options.orbitsPerTF); if (options.genVertices) { // TODO: offer option taking meanVertex directly from CCDB ! "GLO/Calib/MeanVertex" @@ -466,5 +472,72 @@ int main(int argc, char* argv[]) } digicontext.saveToFile(options.outfilename); + // extract individual timeframes + if (options.individualTFextraction.size() > 0) { + // we are asked to extract individual timeframe components + + LOG(info) << "Extracting individual timeframe collision contexts"; + // extract prefix path to store these collision contexts + // Function to check the pattern and extract tokens from b + auto check_and_extract_tokens = [](const std::string& input, std::vector& tokens) { + // the regular expression pattern for expected input format + const std::regex pattern(R"(^([a-zA-Z0-9]+)(:([a-zA-Z0-9]+(,[a-zA-Z0-9]+)*))?$)"); + std::smatch matches; + + // Check if the input matches the pattern + if (std::regex_match(input, matches, pattern)) { + // Clear any existing tokens in the vector + tokens.clear(); + + // matches[1] contains the part before the colon which we save first + tokens.push_back(matches[1].str()); + // matches[2] contains the comma-separated list + std::string b = matches[2].str(); + std::regex token_pattern(R"([a-zA-Z0-9]+)"); + auto tokens_begin = std::sregex_iterator(b.begin(), b.end(), token_pattern); + auto tokens_end = std::sregex_iterator(); + + // Iterate over the tokens and add them to the vector + for (std::sregex_iterator i = tokens_begin; i != tokens_end; ++i) { + tokens.push_back((*i).str()); + } + return true; + } + LOG(error) << "Argument for --extract-per-timeframe does not match specification"; + return false; + }; + + std::vector tokens; + if (check_and_extract_tokens(options.individualTFextraction, tokens)) { + auto path_prefix = tokens[0]; + std::vector sources_to_offset{}; + + LOG(info) << "PREFIX is " << path_prefix; + + for (int i = 1; i < tokens.size(); ++i) { + LOG(info) << "Offsetting " << tokens[i]; + sources_to_offset.push_back(digicontext.findSimPrefix(tokens[i])); + } + + // now we are ready to loop over all timeframes + for (int tf_id = 0; tf_id < numTimeFrames; ++tf_id) { + auto copy = digicontext.extractSingleTimeframe(tf_id, sources_to_offset); + + // each individual case gets QED interactions injected + // This should probably be done inside the extraction itself + if (digicontext.isQEDProvided()) { + auto qedSpec = parseInteractionSpec(options.qedInteraction, ispecs, options.useexistingkinematics); + copy.fillQED(qedSpec.name, qedSpec.mcnumberasked, qedSpec.interactionRate); + } + + std::stringstream str; + str << path_prefix << (tf_id + 1) << "/collisioncontext.root"; + copy.saveToFile(str.str()); + LOG(info) << "----"; + copy.printCollisionSummary(options.qedInteraction.size() > 0); + } + } + } + return 0; } From 2a8c9c0c5b39994a598bc7c5ea61dd381ac1b7b9 Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 7 Nov 2024 16:30:10 +0100 Subject: [PATCH 0431/2205] Add TPC-only DCA to trackStudy output --- .../GlobalTrackingStudy/TrackInfoExt.h | 1 + .../study/src/TrackingStudy.cxx | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h index 754c08388abdb..b988eddfa861f 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h @@ -27,6 +27,7 @@ namespace dataformats struct TrackInfoExt { o2::track::TrackParCov track; DCA dca{}; + DCA dcaTPC{}; VtxTrackIndex gid; MatchInfoTOF infoTOF; float ttime = 0; diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx index 378d2b9dcfacc..1e605e308f4ab 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx @@ -364,10 +364,30 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) continue; } { + o2::dataformats::DCA dcaTPC; + dcaTPC.set(-999.f, -999.f); + if (tpcTr) { + if (is == GTrackID::TPC) { + dcaTPC = dca; + } else { + o2::track::TrackParCov tmpTPC(*tpcTr); + if (iv < nv - 1 && is == GTrackID::TPC && tpcTr && !tpcTr->hasBothSidesClusters()) { // for unconstrained TPC tracks correct track Z + float corz = vdrit * (tpcTr->getTime0() * mTPCTBinMUS - pvvec[iv].getTimeStamp().getTimeStamp()); + if (tpcTr->hasASideClustersOnly()) { + corz = -corz; // A-side + } + tmpTPC.setZ(tmpTPC.getZ() + corz); + } + if (!prop->propagateToDCA(iv == nv - 1 ? vtxDummy : pvvec[iv], tmpTPC, prop->getNominalBz(), 2., o2::base::PropagatorF::MatCorrType::USEMatCorrLUT, &dcaTPC)) { + dcaTPC.set(-999.f, -999.f); + } + } + } auto& trcExt = trcExtVec.emplace_back(); recoData.getTrackTime(vid, trcExt.ttime, trcExt.ttimeE); trcExt.track = trc; trcExt.dca = dca; + trcExt.dcaTPC = dcaTPC; trcExt.gid = vid; trcExt.xmin = xmin; auto gidRefs = recoData.getSingleDetectorRefs(vid); From b345d0fd3ff81fe854bc96ea881c3bacf54c2275 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:43:29 +0100 Subject: [PATCH 0432/2205] DPL: drop need for has_root_setowner Simple inline constrain is much better. --- Framework/Core/include/Framework/DataRefUtils.h | 4 ++-- Framework/Core/include/Framework/TypeTraits.h | 17 ----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/Framework/Core/include/Framework/DataRefUtils.h b/Framework/Core/include/Framework/DataRefUtils.h index c63b06357b8ed..4c1bd0ed7ed10 100644 --- a/Framework/Core/include/Framework/DataRefUtils.h +++ b/Framework/Core/include/Framework/DataRefUtils.h @@ -122,7 +122,7 @@ struct DataRefUtils { // object only depends on the state at serialization of the original object. However, // all objects created during deserialization are new and must be owned by the collection // to avoid memory leak. So we call SetOwner if it is available for the type. - if constexpr (has_root_setowner::value) { + if constexpr (requires(T t) { t.SetOwner(true); }) { result->SetOwner(true); } }); @@ -159,7 +159,7 @@ struct DataRefUtils { throw runtime_error_f("Unable to extract class %s", cl == nullptr ? "" : cl->GetName()); } // workaround for ROOT feature, see above - if constexpr (has_root_setowner::value) { + if constexpr (requires(T t) { t.SetOwner(true); }) { result->SetOwner(true); } }); diff --git a/Framework/Core/include/Framework/TypeTraits.h b/Framework/Core/include/Framework/TypeTraits.h index 19ca548835cdd..faa9055de3280 100644 --- a/Framework/Core/include/Framework/TypeTraits.h +++ b/Framework/Core/include/Framework/TypeTraits.h @@ -147,22 +147,5 @@ class has_root_dictionary::value>::ty { }; -// Detect whether a class is a ROOT class implementing SetOwner -// This member detector idiom is implemented using SFINAE idiom to look for -// a 'SetOwner()' method. -template -struct has_root_setowner : std::false_type { -}; - -template -struct has_root_setowner< - T, - std::conditional_t< - false, - class_member_checker< - decltype(std::declval().SetOwner(true))>, - void>> : public std::true_type { -}; - } // namespace o2::framework #endif // FRAMEWORK_TYPETRAITS_H From d2c347f1fa6abb1339d6bffc93dbd6c75ce9c657 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:57:25 +0100 Subject: [PATCH 0433/2205] DPL Analysis: fix missing connection to the grid It's not a given that parent files and the original data are on the same support, so we need to connect to the grid if needed. --- Framework/AnalysisSupport/src/Plugin.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index b899a52206422..e2a9a98ab90d3 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -175,6 +175,10 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { } } + if (parentFilename.starts_with("alien://")) { + TGrid::Connect("alien://"); + } + std::unique_ptr parentFile{TFile::Open(parentFilename.c_str())}; if (parentFile.get() == nullptr) { LOGP(fatal, "Couldn't open derived file \"{}\"!", parentFilename); From e00fdebb99859c127906a7aea1eac61d6b15607c Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 7 Nov 2024 22:53:19 +0100 Subject: [PATCH 0434/2205] TPC: Fix invalid template keyword with argument list (clang19 complains, remove since not really needed) --- GPU/TPCFastTransformation/Spline1DSpec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/TPCFastTransformation/Spline1DSpec.h b/GPU/TPCFastTransformation/Spline1DSpec.h index e37ee67581c63..f8af1980d81ae 100644 --- a/GPU/TPCFastTransformation/Spline1DSpec.h +++ b/GPU/TPCFastTransformation/Spline1DSpec.h @@ -448,7 +448,7 @@ class Spline1DSpec GPUgeneric() const T Sr[/*mYdim*/], GPUgeneric() const T Dr[/*mYdim*/], DataT u, GPUgeneric() T S[/*mYdim*/]) const { - TBase::template interpolateU(YdimT, knotL, Sl, Dl, Sr, Dr, u, S); + TBase::interpolateU(YdimT, knotL, Sl, Dl, Sr, Dr, u, S); } using TBase::getNumberOfKnots; From 2ab8d92ee0da7c549814e79d3027177052758221 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:51:34 +0100 Subject: [PATCH 0435/2205] DPL: account for aod-parent-access-level == 0 In the case of self contained derived data, it is ok not to look in the parents for missing metadata. --- .../src/AODJAlienReaderHelpers.cxx | 23 +++++++++---------- Framework/AnalysisSupport/src/Plugin.cxx | 9 +++++++- Framework/Core/src/Plugin.cxx | 5 +++- Framework/Core/src/WorkflowHelpers.cxx | 1 - 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx index 90d88cb43626e..9c19de85739ce 100644 --- a/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx +++ b/Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx @@ -118,19 +118,23 @@ static inline auto extractOriginalsTuple(framework::pack, ProcessingConte return std::make_tuple(extractTypedOriginal(pc)...); } -AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const& config) +AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const& ctx) { // aod-parent-base-path-replacement is now a workflow option, so it needs to be // retrieved from the ConfigContext. This is because we do not allow workflow options // to change over start-stop-start because they can affect the topology generation. std::string parentFileReplacement; - if (config.options().isSet("aod-parent-base-path-replacement")) { - parentFileReplacement = config.options().get("aod-parent-base-path-replacement"); + if (ctx.options().isSet("aod-parent-base-path-replacement")) { + parentFileReplacement = ctx.options().get("aod-parent-base-path-replacement"); } - auto callback = AlgorithmSpec{adaptStateful([parentFileReplacement](ConfigParamRegistry const& options, - DeviceSpec const& spec, - Monitoring& monitoring, - DataProcessingStats& stats) { + int parentAccessLevel = 0; + if (ctx.options().isSet("aod-parent-access-level")) { + parentAccessLevel = ctx.options().get("aod-parent-access-level"); + } + auto callback = AlgorithmSpec{adaptStateful([parentFileReplacement, parentAccessLevel](ConfigParamRegistry const& options, + DeviceSpec const& spec, + Monitoring& monitoring, + DataProcessingStats& stats) { // FIXME: not actually needed, since data processing stats can specify that we should // send the initial value. stats.updateStats({static_cast(ProcessingStatsId::ARROW_BYTES_CREATED), DataProcessingStats::Op::Set, 0}); @@ -148,11 +152,6 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const auto maxRate = options.get("aod-max-io-rate"); - int parentAccessLevel = 0; - if (options.isSet("aod-parent-access-level")) { - parentAccessLevel = options.get("aod-parent-access-level"); - } - // create a DataInputDirector auto didir = std::make_shared(filename, &monitoring, parentAccessLevel, parentFileReplacement); if (options.isSet("aod-reader-json")) { diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index e2a9a98ab90d3..bba3499286e08 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -150,13 +150,20 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { return results; } - // Lets try in parent files + if (!registry.isSet("aod-parent-access-level") || registry.get("aod-parent-access-level") == 0) { + LOGP(info, "No metadata found in file \"{}\" and parent level 0 prevents further lookup.", filename); + results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}}); + return results; + } + + // Lets try in parent file. auto parentFiles = (TMap*)currentFile->Get("parentFiles"); if (!parentFiles) { LOGP(info, "No metadata found in file \"{}\"", filename); results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}}); return results; } + LOGP(info, "No metadata found in file \"{}\", checking in its parents.", filename); for (auto* p : *parentFiles) { std::string parentFilename = ((TPair*)p)->Value()->GetName(); // Do the replacement. Notice this will require changing aod-parent-base-path-replacement to be diff --git a/Framework/Core/src/Plugin.cxx b/Framework/Core/src/Plugin.cxx index 91c74bafff5ad..726b12ff68365 100644 --- a/Framework/Core/src/Plugin.cxx +++ b/Framework/Core/src/Plugin.cxx @@ -141,7 +141,7 @@ struct DiscoverAODOptionsInCommandLine : o2::framework::ConfigDiscoveryPlugin { bool injectOption = true; for (size_t i = 0; i < argc; i++) { std::string_view arg = argv[i]; - if (!arg.starts_with("--aod-writer-") && arg != "--aod-parent-base-path-replacement") { + if (!arg.starts_with("--aod-writer-") && !arg.starts_with("--aod-parent-")) { continue; } std::string key = arg.data() + 2; @@ -156,6 +156,9 @@ struct DiscoverAODOptionsInCommandLine : o2::framework::ConfigDiscoveryPlugin { if (key == "aod-parent-base-path-replacement") { results.push_back(ConfigParamSpec{"aod-parent-base-path-replacement", VariantType::String, value, {R"(Replace base path of parent files. Syntax: FROM;TO. E.g. "alien:///path/in/alien;/local/path". Enclose in "" on the command line.)"}}); } + if (key == "aod-parent-access-level") { + results.push_back(ConfigParamSpec{"aod-parent-access-level", VariantType::String, value, {"Allow parent file access up to specified level. Default: no (0)"}}); + } } if (injectOption) { results.push_back(ConfigParamSpec{"aod-writer-compression", VariantType::Int, 505, {"AOD Compression options"}}); diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 56e9930e3b655..da9a135dc5eb8 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -216,7 +216,6 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext .options = {ConfigParamSpec{"aod-file-private", VariantType::String, ctx.options().get("aod-file"), {"AOD file"}}, ConfigParamSpec{"aod-max-io-rate", VariantType::Float, 0.f, {"Maximum I/O rate in MB/s"}}, ConfigParamSpec{"aod-reader-json", VariantType::String, {"json configuration file"}}, - ConfigParamSpec{"aod-parent-access-level", VariantType::String, {"Allow parent file access up to specified level. Default: no (0)"}}, ConfigParamSpec{"time-limit", VariantType::Int64, 0ll, {"Maximum run time limit in seconds"}}, ConfigParamSpec{"orbit-offset-enumeration", VariantType::Int64, 0ll, {"initial value for the orbit"}}, ConfigParamSpec{"orbit-multiplier-enumeration", VariantType::Int64, 0ll, {"multiplier to get the orbit from the counter"}}, From 56ccb8b3156a3ff671fe98e91fde2ba815b03b64 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 8 Nov 2024 13:55:05 +0100 Subject: [PATCH 0436/2205] GPU: Add overrideNHbfPerTF option --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/Workflow/src/GPUWorkflowSpec.cxx | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 224e7c720c334..b4831c2088dc2 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -526,6 +526,7 @@ BeginSubConfig(GPUSettingsO2, global, configStandalone, "O2", 0, "O2 workflow se AddOption(solenoidBzNominalGPU, float, -1e6f, "", 0, "Field strength of solenoid Bz in kGaus") AddOption(constBz, bool, false, "", 0, "force constant Bz for tests") AddOption(continuousMaxTimeBin, int32_t, 0, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for default of 23ms") +AddOption(overrideNHbfPerTF, int32_t, 0, "", 0, "Overrides the number of HBF per TF if != 0") AddOption(deviceType, std::string, "CPU", "", 0, "Device type, CPU | CUDA | HIP | OCL1 | OCL2") AddOption(forceDeviceType, bool, true, "", 0, "force device type, otherwise allows fall-back to CPU") AddOption(synchronousProcessing, bool, false, "", 0, "Apply performance shortcuts for synchronous processing, disable unneeded steps") diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index 4549d895c26b9..b7bd7b608aaf5 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -156,7 +156,7 @@ void GPURecoWorkflowSpec::init(InitContext& ic) mAutoSolenoidBz = mConfParam->solenoidBzNominalGPU == -1e6f; mAutoContinuousMaxTimeBin = mConfig->configGRP.continuousMaxTimeBin == -1; if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.continuousMaxTimeBin = (256 * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.continuousMaxTimeBin = ((mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : 256) * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; } if (mConfig->configProcessing.deviceNum == -2) { int32_t myId = ic.services().get().inputTimesliceId; @@ -583,7 +583,7 @@ void GPURecoWorkflowSpec::run(ProcessingContext& pc) mTFSettings->tfStartOrbit = tinfo.firstTForbit; mTFSettings->hasTfStartOrbit = 1; mTFSettings->hasNHBFPerTF = 1; - mTFSettings->nHBFPerTF = GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); + mTFSettings->nHBFPerTF = mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); mTFSettings->hasRunStartOrbit = 0; if (mVerbosity) { LOG(info) << "TF firstTForbit " << mTFSettings->tfStartOrbit << " nHBF " << mTFSettings->nHBFPerTF << " runStartOrbit " << mTFSettings->runStartOrbit << " simStartOrbit " << mTFSettings->simStartOrbit; @@ -1016,7 +1016,7 @@ void GPURecoWorkflowSpec::doCalibUpdates(o2::framework::ProcessingContext& pc, c mConfig->configGRP.continuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; newCalibValues.newContinuousMaxTimeBin = true; newCalibValues.continuousMaxTimeBin = mConfig->configGRP.continuousMaxTimeBin; - LOG(info) << "Updating max time bin " << newCalibValues.continuousMaxTimeBin; + LOG(info) << "Updating max time bin " << newCalibValues.continuousMaxTimeBin << " (" << mTFSettings->nHBFPerTF << " orbits)"; } if (!mPropagatorInstanceCreated) { From ac19d82daecd0dd89ee35eb63328a30c102959e3 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 8 Nov 2024 14:53:33 +0100 Subject: [PATCH 0437/2205] GPU: Rename some continuousMaxTimeBin to avoid confusion, improve defaults, and cleanup --- Detectors/TPC/qc/src/Tracking.cxx | 2 +- .../src/TPCTrackingDigitsPreCheck.cxx | 2 +- .../reconstruction/test/testGPUCATracking.cxx | 2 +- .../TPC/workflow/src/EntropyEncoderSpec.cxx | 2 +- GPU/GPUTracking/Base/GPUParam.cxx | 4 ++-- GPU/GPUTracking/DataTypes/GPUSettings.h | 2 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 4 ++-- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- .../GPUO2InterfaceConfigurableParam.cxx | 8 ++++---- .../Interface/GPUO2InterfaceUtils.cxx | 20 ++++++++++--------- .../Standalone/Benchmark/standalone.cxx | 16 +++++++-------- GPU/Workflow/src/GPUWorkflowSpec.cxx | 8 ++++---- GPU/Workflow/src/O2GPUDPLDisplay.cxx | 6 +++--- 13 files changed, 40 insertions(+), 38 deletions(-) diff --git a/Detectors/TPC/qc/src/Tracking.cxx b/Detectors/TPC/qc/src/Tracking.cxx index a3ae6320fe9e0..c2bdf2a5c54bf 100644 --- a/Detectors/TPC/qc/src/Tracking.cxx +++ b/Detectors/TPC/qc/src/Tracking.cxx @@ -51,7 +51,7 @@ void Tracking::initialize(outputModes outputMode, bool postprocessOnly) const auto grp = o2::parameters::GRPObject::loadFrom(); if (grp) { mQAConfig->configGRP.solenoidBzNominalGPU = GPUO2InterfaceUtils::getNominalGPUBz(*grp); - mQAConfig->configGRP.continuousMaxTimeBin = grp->isDetContinuousReadOut(o2::detectors::DetID::TPC) ? -1 : 0; + mQAConfig->configGRP.grpContinuousMaxTimeBin = grp->isDetContinuousReadOut(o2::detectors::DetID::TPC) ? -1 : 0; } else { throw std::runtime_error("Failed to initialize run parameters from GRP"); } diff --git a/Detectors/TPC/reconstruction/src/TPCTrackingDigitsPreCheck.cxx b/Detectors/TPC/reconstruction/src/TPCTrackingDigitsPreCheck.cxx index b2a11811c5661..738e6cff20df4 100644 --- a/Detectors/TPC/reconstruction/src/TPCTrackingDigitsPreCheck.cxx +++ b/Detectors/TPC/reconstruction/src/TPCTrackingDigitsPreCheck.cxx @@ -53,7 +53,7 @@ TPCTrackingDigitsPreCheck::precheckModifiedData TPCTrackingDigitsPreCheck::runPr std::unique_ptr retVal = std::make_unique(); retVal->tpcDigitsMap = *ptrs->tpcPackedDigits; const float zsThreshold = config->configReconstruction.tpc.zsThreshold; - const int maxContTimeBin = config->configGRP.continuousMaxTimeBin; + const int maxContTimeBin = config->configGRP.grpContinuousMaxTimeBin; static bool filterOutOfTF = getenv("TPC_WORKFLOW_FILTER_DIGITS_OUTSIDE_OF_TF") && atoi(getenv("TPC_WORKFLOW_FILTER_DIGITS_OUTSIDE_OF_TF")); bool updateDigits = (zsThreshold > 0 || filterOutOfTF) && ptrs->tpcZS == nullptr; const auto& d = ptrs->tpcPackedDigits; diff --git a/Detectors/TPC/reconstruction/test/testGPUCATracking.cxx b/Detectors/TPC/reconstruction/test/testGPUCATracking.cxx index 33537dc373451..6c0ea8b265585 100644 --- a/Detectors/TPC/reconstruction/test/testGPUCATracking.cxx +++ b/Detectors/TPC/reconstruction/test/testGPUCATracking.cxx @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(CATracking_test1) config.configProcessing.eventDisplay = nullptr; //Ptr to event display backend, for running standalone OpenGL event display config.configGRP.solenoidBzNominalGPU = solenoidBz; - config.configGRP.continuousMaxTimeBin = continuous ? GPUSettings::TPC_MAX_TF_TIME_BIN : 0; //Number of timebins in timeframe if continuous, 0 otherwise + config.configGRP.grpContinuousMaxTimeBin = continuous ? GPUSettings::TPC_MAX_TF_TIME_BIN : 0; // Number of timebins in timeframe if continuous, 0 otherwise config.configReconstruction.tpc.nWays = 3; //Should always be 3! config.configReconstruction.tpc.nWaysOuter = true; //Will create outer param for TRD diff --git a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx index 35b76715cbc28..8cca67f65f275 100644 --- a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx +++ b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx @@ -92,7 +92,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) LOG(fatal) << "configKeyValue tpcTriggeredMode does not match GRP isDetContinuousReadOut(TPC) setting"; } - mConfig->configGRP.continuousMaxTimeBin = (GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF() * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = (GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF() * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; mConfig->configGRP.solenoidBzNominalGPU = GPUO2InterfaceUtils::getNominalGPUBz(*GRPGeomHelper::instance().getGRPMagField()); mParam->UpdateSettings(&mConfig->configGRP); diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index 8e2daf1a61490..42d4f61f77116 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -130,8 +130,8 @@ void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessi UpdateBzOnly(g->solenoidBzNominalGPU); par.assumeConstantBz = g->constBz; par.toyMCEventsFlag = g->homemadeEvents; - par.continuousTracking = g->continuousMaxTimeBin != 0; - continuousMaxTimeBin = g->continuousMaxTimeBin == -1 ? GPUSettings::TPC_MAX_TF_TIME_BIN : g->continuousMaxTimeBin; + par.continuousTracking = g->grpContinuousMaxTimeBin != 0; + continuousMaxTimeBin = g->grpContinuousMaxTimeBin == -1 ? GPUSettings::TPC_MAX_TF_TIME_BIN : g->grpContinuousMaxTimeBin; } par.earlyTpcTransform = rec.tpc.forceEarlyTransform == -1 ? (!par.continuousTracking) : rec.tpc.forceEarlyTransform; qptB5Scaler = CAMath::Abs(bzkG) > 0.1f ? CAMath::Abs(bzkG) / 5.006680f : 1.f; // Repeat here, since passing in g is optional diff --git a/GPU/GPUTracking/DataTypes/GPUSettings.h b/GPU/GPUTracking/DataTypes/GPUSettings.h index 69f3ff67cf257..738457ec99d7b 100644 --- a/GPU/GPUTracking/DataTypes/GPUSettings.h +++ b/GPU/GPUTracking/DataTypes/GPUSettings.h @@ -57,7 +57,7 @@ struct GPUSettingsGRP { float solenoidBzNominalGPU = -5.00668f; // solenoid field strength int32_t constBz = 0; // for test-MC events with constant Bz int32_t homemadeEvents = 0; // Toy-MC events - int32_t continuousMaxTimeBin = 0; // 0 for triggered events, -1 for default TF length + int32_t grpContinuousMaxTimeBin = -2; // 0 for triggered events, -1 for automatic setting, -2 invalid default int32_t needsClusterer = 0; // Set to true if the data requires the clusterizer int32_t doCompClusterDecode = 0; // Set to true if the data contains compressed TPC clusters }; diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index b4831c2088dc2..0b2da89b79ad5 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -478,7 +478,7 @@ AddOption(eventsDir, const char*, "pp", "events", 'e', "Directory with events to AddOption(noEvents, bool, false, "", 0, "Run without data (e.g. for field visualization)") AddOption(eventDisplay, int32_t, 0, "display", 'd', "Show standalone event display", def(1)) AddOption(eventGenerator, bool, false, "", 0, "Run event generator") -AddOption(cont, bool, false, "", 0, "Process continuous timeframe data") +AddOption(cont, bool, false, "", 0, "Process continuous timeframe data, even if input is triggered") AddOption(outputcontrolmem, uint64_t, 0, "outputMemory", 0, "Use predefined output buffer of this size", min(0ul), message("Using %s bytes as output memory")) AddOption(inputcontrolmem, uint64_t, 0, "inputMemory", 0, "Use predefined input buffer of this size", min(0ul), message("Using %s bytes as input memory")) AddOption(cpuAffinity, int32_t, -1, "", 0, "Pin CPU affinity to this CPU core", min(-1)) @@ -525,7 +525,7 @@ EndConfig() BeginSubConfig(GPUSettingsO2, global, configStandalone, "O2", 0, "O2 workflow settings", global) AddOption(solenoidBzNominalGPU, float, -1e6f, "", 0, "Field strength of solenoid Bz in kGaus") AddOption(constBz, bool, false, "", 0, "force constant Bz for tests") -AddOption(continuousMaxTimeBin, int32_t, 0, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for default of 23ms") +AddOption(setMaxTimeBin, int32_t, -2, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for automatic continuous mode, -2 for automatic continuous / triggered") AddOption(overrideNHbfPerTF, int32_t, 0, "", 0, "Overrides the number of HBF per TF if != 0") AddOption(deviceType, std::string, "CPU", "", 0, "Device type, CPU | CUDA | HIP | OCL1 | OCL2") AddOption(forceDeviceType, bool, true, "", 0, "force device type, otherwise allows fall-back to CPU") diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 319e57d99fd0e..8c2599604387b 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -639,7 +639,7 @@ int32_t GPUChainTracking::DoQueuedUpdates(int32_t stream, bool updateSlave) grp->solenoidBzNominalGPU = mNewCalibValues->solenoidField; } if (mNewCalibValues->newContinuousMaxTimeBin) { - grp->continuousMaxTimeBin = mNewCalibValues->continuousMaxTimeBin; + grp->grpContinuousMaxTimeBin = mNewCalibValues->continuousMaxTimeBin; } } } diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx index c3aaec8d9f9a6..86ae8e3457019 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfigurableParam.cxx @@ -103,11 +103,11 @@ GPUSettingsO2 GPUO2InterfaceConfiguration::ReadConfigurableParam(GPUO2InterfaceC obj.configReconstruction = rec; obj.configDisplay = display; obj.configQA = QA; - if (obj.configGRP.continuousMaxTimeBin == 0 || obj.configGRP.continuousMaxTimeBin == -1) { - if (global.continuousMaxTimeBin) { - obj.configGRP.continuousMaxTimeBin = global.continuousMaxTimeBin; + if (obj.configGRP.grpContinuousMaxTimeBin < 0) { + if (global.setMaxTimeBin != -2) { + obj.configGRP.grpContinuousMaxTimeBin = global.setMaxTimeBin; } else { - obj.configGRP.continuousMaxTimeBin = global.tpcTriggeredMode ? 0 : -1; + obj.configGRP.grpContinuousMaxTimeBin = global.tpcTriggeredMode ? 0 : -1; } } if (global.solenoidBzNominalGPU > -1e6f) { diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index 15a5980a47696..c765909fd879f 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -83,30 +83,32 @@ std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, ui { std::unique_ptr retVal = std::make_unique(); std::unique_ptr tmpConfig; + std::unique_ptr tmpSettingsO2; if (!pConfiguration) { tmpConfig = std::make_unique(); pConfiguration = &tmpConfig; - (*pConfiguration)->configGRP.continuousMaxTimeBin = -1; + (*pConfiguration)->configGRP.grpContinuousMaxTimeBin = -1; } else if (!*pConfiguration) { *pConfiguration = std::make_unique(); - (*pConfiguration)->configGRP.continuousMaxTimeBin = -1; + (*pConfiguration)->configGRP.grpContinuousMaxTimeBin = -1; } (*pConfiguration)->configGRP.solenoidBzNominalGPU = solenoidBz; if (pO2Settings && *pO2Settings) { **pO2Settings = (*pConfiguration)->ReadConfigurableParam(); - } else if (pO2Settings) { - *pO2Settings = std::make_unique((*pConfiguration)->ReadConfigurableParam()); } else { - (*pConfiguration)->ReadConfigurableParam(); + if (!pO2Settings) { + pO2Settings = &tmpSettingsO2; + } + *pO2Settings = std::make_unique((*pConfiguration)->ReadConfigurableParam()); } if (nHbfPerTf == 0) { - nHbfPerTf = 256; + nHbfPerTf = (*pO2Settings)->overrideNHbfPerTF ? (*pO2Settings)->overrideNHbfPerTF : 256; } if (autoMaxTimeBin) { - *autoMaxTimeBin = (*pConfiguration)->configGRP.continuousMaxTimeBin == -1; + *autoMaxTimeBin = (*pConfiguration)->configGRP.grpContinuousMaxTimeBin == -1; } - if ((*pConfiguration)->configGRP.continuousMaxTimeBin == -1) { - (*pConfiguration)->configGRP.continuousMaxTimeBin = (nHbfPerTf * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + if ((*pConfiguration)->configGRP.grpContinuousMaxTimeBin == -1) { + (*pConfiguration)->configGRP.grpContinuousMaxTimeBin = (nHbfPerTf * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; } retVal->SetDefaults(&(*pConfiguration)->configGRP, &(*pConfiguration)->configReconstruction, &(*pConfiguration)->configProcessing, nullptr); return retVal; diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index 3626c33dfbb2c..09069ba1d104d 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -302,7 +302,7 @@ int32_t SetupReconstruction() printf("Error reading event config file\n"); return 1; } - printf("Read event settings from dir %s (solenoidBz: %f, home-made events %d, constBz %d, maxTimeBin %d)\n", filename, rec->GetGRPSettings().solenoidBzNominalGPU, (int32_t)rec->GetGRPSettings().homemadeEvents, (int32_t)rec->GetGRPSettings().constBz, rec->GetGRPSettings().continuousMaxTimeBin); + printf("Read event settings from dir %s (solenoidBz: %f, home-made events %d, constBz %d, maxTimeBin %d)\n", filename, rec->GetGRPSettings().solenoidBzNominalGPU, (int32_t)rec->GetGRPSettings().homemadeEvents, (int32_t)rec->GetGRPSettings().constBz, rec->GetGRPSettings().grpContinuousMaxTimeBin); if (configStandalone.testSyncAsync) { recAsync->ReadSettings(filename); } @@ -331,7 +331,7 @@ int32_t SetupReconstruction() grp.constBz = true; } if (configStandalone.TF.nMerge || configStandalone.TF.bunchSim) { - if (grp.continuousMaxTimeBin) { + if (grp.grpContinuousMaxTimeBin) { printf("ERROR: requested to overlay continuous data - not supported\n"); return 1; } @@ -340,11 +340,11 @@ int32_t SetupReconstruction() configStandalone.cont = true; } if (chainTracking->GetTPCTransformHelper()) { - grp.continuousMaxTimeBin = configStandalone.TF.timeFrameLen * ((double)GPUReconstructionTimeframe::TPCZ / (double)GPUReconstructionTimeframe::DRIFT_TIME) / chainTracking->GetTPCTransformHelper()->getCorrMap()->getVDrift(); + grp.grpContinuousMaxTimeBin = configStandalone.TF.timeFrameLen * ((double)GPUReconstructionTimeframe::TPCZ / (double)GPUReconstructionTimeframe::DRIFT_TIME) / chainTracking->GetTPCTransformHelper()->getCorrMap()->getVDrift(); } } - if (configStandalone.cont && grp.continuousMaxTimeBin == 0) { - grp.continuousMaxTimeBin = -1; + if (configStandalone.cont && grp.grpContinuousMaxTimeBin == 0) { + grp.grpContinuousMaxTimeBin = -1; } if (rec->GetDeviceType() == GPUReconstruction::DeviceType::CPU) { printf("Standalone Test Framework for CA Tracker - Using CPU\n"); @@ -904,11 +904,11 @@ int32_t main(int argc, char** argv) if (configStandalone.overrideMaxTimebin && (chainTracking->mIOPtrs.clustersNative || chainTracking->mIOPtrs.tpcPackedDigits || chainTracking->mIOPtrs.tpcZS)) { GPUSettingsGRP grp = rec->GetGRPSettings(); - if (grp.continuousMaxTimeBin == 0) { + if (grp.grpContinuousMaxTimeBin == 0) { printf("Cannot override max time bin for non-continuous data!\n"); } else { - grp.continuousMaxTimeBin = chainTracking->mIOPtrs.tpcZS ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcZS) : chainTracking->mIOPtrs.tpcPackedDigits ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcPackedDigits) : GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.clustersNative); - printf("Max time bin set to %d\n", (int32_t)grp.continuousMaxTimeBin); + grp.grpContinuousMaxTimeBin = chainTracking->mIOPtrs.tpcZS ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcZS) : chainTracking->mIOPtrs.tpcPackedDigits ? GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.tpcPackedDigits) : GPUReconstructionConvert::GetMaxTimeBin(*chainTracking->mIOPtrs.clustersNative); + printf("Max time bin set to %d\n", grp.grpContinuousMaxTimeBin); rec->UpdateSettings(&grp); if (recAsync) { recAsync->UpdateSettings(&grp); diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index b7bd7b608aaf5..fcf27074ca717 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -154,9 +154,9 @@ void GPURecoWorkflowSpec::init(InitContext& ic) } mAutoSolenoidBz = mConfParam->solenoidBzNominalGPU == -1e6f; - mAutoContinuousMaxTimeBin = mConfig->configGRP.continuousMaxTimeBin == -1; + mAutoContinuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin < 0; if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.continuousMaxTimeBin = ((mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : 256) * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = ((mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : 256) * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; } if (mConfig->configProcessing.deviceNum == -2) { int32_t myId = ic.services().get().inputTimesliceId; @@ -1013,9 +1013,9 @@ void GPURecoWorkflowSpec::doCalibUpdates(o2::framework::ProcessingContext& pc, c LOG(info) << "Updating solenoid field " << newCalibValues.solenoidField; } if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.continuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; newCalibValues.newContinuousMaxTimeBin = true; - newCalibValues.continuousMaxTimeBin = mConfig->configGRP.continuousMaxTimeBin; + newCalibValues.continuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin; LOG(info) << "Updating max time bin " << newCalibValues.continuousMaxTimeBin << " (" << mTFSettings->nHBFPerTF << " orbits)"; } diff --git a/GPU/Workflow/src/O2GPUDPLDisplay.cxx b/GPU/Workflow/src/O2GPUDPLDisplay.cxx index bb46bd440d399..6946d65915503 100644 --- a/GPU/Workflow/src/O2GPUDPLDisplay.cxx +++ b/GPU/Workflow/src/O2GPUDPLDisplay.cxx @@ -90,7 +90,7 @@ void O2GPUDPLDisplaySpec::init(InitContext& ic) mTFSettings->hasSimStartOrbit = 1; auto& hbfu = o2::raw::HBFUtils::Instance(); mTFSettings->simStartOrbit = hbfu.getFirstIRofTF(o2::InteractionRecord(0, hbfu.orbitFirstSampled)).orbit; - mAutoContinuousMaxTimeBin = mConfig->configGRP.continuousMaxTimeBin == -1; + mAutoContinuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin < -1; mDisplay.reset(new GPUO2InterfaceDisplay(mConfig.get())); } @@ -108,14 +108,14 @@ void O2GPUDPLDisplaySpec::run(ProcessingContext& pc) mTFSettings->tfStartOrbit = pc.services().get().firstTForbit; mTFSettings->hasTfStartOrbit = 1; mTFSettings->hasNHBFPerTF = 1; - mTFSettings->nHBFPerTF = GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); + mTFSettings->nHBFPerTF = mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF(); mTFSettings->hasRunStartOrbit = 0; if (mGRPGeomUpdated) { mGRPGeomUpdated = false; mConfig->configGRP.solenoidBzNominalGPU = GPUO2InterfaceUtils::getNominalGPUBz(*GRPGeomHelper::instance().getGRPMagField()); if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.continuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; } mDisplay->UpdateGRP(&mConfig->configGRP); if (mGeometryCreated == 0) { From c4f9811d15d072b8c9a6aba226f57b775c21263e Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 8 Nov 2024 15:07:49 +0100 Subject: [PATCH 0438/2205] GPU: Add GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf and remove copy&paste --- Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx | 2 +- GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx | 7 ++++++- GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h | 1 + GPU/Workflow/src/GPUWorkflowSpec.cxx | 4 ++-- GPU/Workflow/src/O2GPUDPLDisplay.cxx | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx index 8cca67f65f275..b81cb9a802a4a 100644 --- a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx +++ b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx @@ -92,7 +92,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) LOG(fatal) << "configKeyValue tpcTriggeredMode does not match GRP isDetContinuousReadOut(TPC) setting"; } - mConfig->configGRP.grpContinuousMaxTimeBin = (GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF() * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(GRPGeomHelper::instance().getGRPECS()->getNHBFPerTF()); mConfig->configGRP.solenoidBzNominalGPU = GPUO2InterfaceUtils::getNominalGPUBz(*GRPGeomHelper::instance().getGRPMagField()); mParam->UpdateSettings(&mConfig->configGRP); diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx index c765909fd879f..fa5705e903d1a 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.cxx @@ -108,7 +108,7 @@ std::unique_ptr GPUO2InterfaceUtils::getFullParam(float solenoidBz, ui *autoMaxTimeBin = (*pConfiguration)->configGRP.grpContinuousMaxTimeBin == -1; } if ((*pConfiguration)->configGRP.grpContinuousMaxTimeBin == -1) { - (*pConfiguration)->configGRP.grpContinuousMaxTimeBin = (nHbfPerTf * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + (*pConfiguration)->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(nHbfPerTf); } retVal->SetDefaults(&(*pConfiguration)->configGRP, &(*pConfiguration)->configReconstruction, &(*pConfiguration)->configProcessing, nullptr); return retVal; @@ -135,3 +135,8 @@ void GPUO2InterfaceUtils::paramUseExternalOccupancyMap(GPUParam* param, uint32_t } } } + +uint32_t GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(uint32_t nHbf) +{ + return (nHbf * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; +} diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h index 7b96326387f59..0b5d2b5aa3f7a 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceUtils.h @@ -58,6 +58,7 @@ class GPUO2InterfaceUtils static std::unique_ptr getFullParam(float solenoidBz, uint32_t nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); static std::shared_ptr getFullParamShared(float solenoidBz, uint32_t nHbfPerTf = 0, std::unique_ptr* pConfiguration = nullptr, std::unique_ptr* pO2Settings = nullptr, bool* autoMaxTimeBin = nullptr); // Return owning pointer static void paramUseExternalOccupancyMap(GPUParam* param, uint32_t nHbfPerTf, const uint32_t* occupancymap, int32_t occupancyMapSize); + static uint32_t getTpcMaxTimeBinFromNHbf(uint32_t nHbf); class GPUReconstructionZSDecoder { diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index fcf27074ca717..0360a352b0a90 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -156,7 +156,7 @@ void GPURecoWorkflowSpec::init(InitContext& ic) mAutoSolenoidBz = mConfParam->solenoidBzNominalGPU == -1e6f; mAutoContinuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin < 0; if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.grpContinuousMaxTimeBin = ((mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : 256) * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(mConfParam->overrideNHbfPerTF ? mConfParam->overrideNHbfPerTF : 256); } if (mConfig->configProcessing.deviceNum == -2) { int32_t myId = ic.services().get().inputTimesliceId; @@ -1013,7 +1013,7 @@ void GPURecoWorkflowSpec::doCalibUpdates(o2::framework::ProcessingContext& pc, c LOG(info) << "Updating solenoid field " << newCalibValues.solenoidField; } if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.grpContinuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(mTFSettings->nHBFPerTF); newCalibValues.newContinuousMaxTimeBin = true; newCalibValues.continuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin; LOG(info) << "Updating max time bin " << newCalibValues.continuousMaxTimeBin << " (" << mTFSettings->nHBFPerTF << " orbits)"; diff --git a/GPU/Workflow/src/O2GPUDPLDisplay.cxx b/GPU/Workflow/src/O2GPUDPLDisplay.cxx index 6946d65915503..8513541bcae43 100644 --- a/GPU/Workflow/src/O2GPUDPLDisplay.cxx +++ b/GPU/Workflow/src/O2GPUDPLDisplay.cxx @@ -115,7 +115,7 @@ void O2GPUDPLDisplaySpec::run(ProcessingContext& pc) mGRPGeomUpdated = false; mConfig->configGRP.solenoidBzNominalGPU = GPUO2InterfaceUtils::getNominalGPUBz(*GRPGeomHelper::instance().getGRPMagField()); if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.grpContinuousMaxTimeBin = (mTFSettings->nHBFPerTF * o2::constants::lhc::LHCMaxBunches + 2 * o2::tpc::constants::LHCBCPERTIMEBIN - 2) / o2::tpc::constants::LHCBCPERTIMEBIN; + mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(mTFSettings->nHBFPerTF); } mDisplay->UpdateGRP(&mConfig->configGRP); if (mGeometryCreated == 0) { From 5190c05d7125ad6e9e6dc886d9bf9dd52bfb96ea Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sat, 9 Nov 2024 10:35:11 +0100 Subject: [PATCH 0439/2205] DPL: introduce FragmentToBatch --- .../Core/include/Framework/DataAllocator.h | 14 +++++ .../Core/include/Framework/TableTreeHelpers.h | 17 ++++++ Framework/Core/src/DataAllocator.cxx | 60 +++++++++++++++++++ Framework/Core/src/TableTreeHelpers.cxx | 30 +++++++++- 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/DataAllocator.h b/Framework/Core/include/Framework/DataAllocator.h index 9c563b06910b5..eb63b5469bb29 100644 --- a/Framework/Core/include/Framework/DataAllocator.h +++ b/Framework/Core/include/Framework/DataAllocator.h @@ -242,6 +242,15 @@ class DataAllocator return t2t; } + template + requires(requires { static_cast(std::declval>()); }) + decltype(auto) make(const Output& spec, Args... args) + { + auto f2b = std::move(LifetimeHolder(new std::decay_t(args...))); + adopt(spec, f2b); + return f2b; + } + template requires is_messageable::value && (!is_specialization_v) decltype(auto) make(const Output& spec) @@ -284,6 +293,11 @@ class DataAllocator void adopt(const Output& spec, LifetimeHolder&); + /// Adopt a Source2Batch in the framework and serialise / send + /// it as an Arrow Dataset to all consumers of @a spec once done + void + adopt(const Output& spec, LifetimeHolder&); + /// Adopt an Arrow table and send it to all consumers of @a spec void adopt(const Output& spec, std::shared_ptr); diff --git a/Framework/Core/include/Framework/TableTreeHelpers.h b/Framework/Core/include/Framework/TableTreeHelpers.h index ccc7035ba3435..9dc7038b83fe1 100644 --- a/Framework/Core/include/Framework/TableTreeHelpers.h +++ b/Framework/Core/include/Framework/TableTreeHelpers.h @@ -11,11 +11,14 @@ #ifndef O2_FRAMEWORK_TABLETREEHELPERS_H_ #define O2_FRAMEWORK_TABLETREEHELPERS_H_ +#include #include "TFile.h" #include "TTreeReader.h" #include "TTreeReaderValue.h" #include "TTreeReaderArray.h" #include "TableBuilder.h" +#include +#include // ============================================================================= namespace o2::framework @@ -140,6 +143,20 @@ class TreeToTable void addReader(TBranch* branch, std::string const& name, bool VLA); }; +class FragmentToBatch +{ + public: + FragmentToBatch(arrow::MemoryPool* pool = arrow::default_memory_pool()); + void setLabel(const char* label); + void fill(std::shared_ptr, std::shared_ptr dataSetSchema, std::shared_ptr); + std::shared_ptr finalize(); + + private: + arrow::MemoryPool* mArrowMemoryPool = nullptr; + std::string mTableLabel; + std::shared_ptr mRecordBatch; +}; + // ----------------------------------------------------------------------------- } // namespace o2::framework diff --git a/Framework/Core/src/DataAllocator.cxx b/Framework/Core/src/DataAllocator.cxx index bae40f2b47947..c310892c4c490 100644 --- a/Framework/Core/src/DataAllocator.cxx +++ b/Framework/Core/src/DataAllocator.cxx @@ -211,6 +211,34 @@ void doWriteTable(std::shared_ptr b, arrow::Table* table) } } +void doWriteBatch(std::shared_ptr b, arrow::RecordBatch* batch) +{ + auto mock = std::make_shared(); + int64_t expectedSize = 0; + auto mockWriter = arrow::ipc::MakeStreamWriter(mock.get(), batch->schema()); + arrow::Status outStatus = mockWriter.ValueOrDie()->WriteRecordBatch(*batch); + + expectedSize = mock->Tell().ValueOrDie(); + auto reserve = b->Reserve(expectedSize); + if (reserve.ok() == false) { + throw std::runtime_error("Unable to reserve memory for table"); + } + + auto stream = std::make_shared(b); + // This is a copy maybe we can finally get rid of it by having using the + // dataset API? + auto outBatch = arrow::ipc::MakeStreamWriter(stream.get(), batch->schema()); + if (outBatch.ok() == false) { + throw ::std::runtime_error("Unable to create batch writer"); + } + + outStatus = outBatch.ValueOrDie()->WriteRecordBatch(*batch); + + if (outStatus.ok() == false) { + throw std::runtime_error("Unable to Write batch"); + } +} + void DataAllocator::adopt(const Output& spec, LifetimeHolder& tb) { auto& timingInfo = mRegistry.get(); @@ -273,6 +301,38 @@ void DataAllocator::adopt(const Output& spec, LifetimeHolder& t2t) context.addBuffer(std::move(header), buffer, std::move(finalizer), routeIndex); } +void DataAllocator::adopt(const Output& spec, LifetimeHolder& f2b) +{ + auto& timingInfo = mRegistry.get(); + RouteIndex routeIndex = matchDataHeader(spec, timingInfo.timeslice); + + auto header = headerMessageFromOutput(spec, routeIndex, o2::header::gSerializationMethodArrow, 0); + auto& context = mRegistry.get(); + + auto creator = [transport = context.proxy().getOutputTransport(routeIndex)](size_t s) -> std::unique_ptr { + return transport->CreateMessage(s); + }; + auto buffer = std::make_shared(creator); + + f2b.callback = [buffer = buffer, transport = context.proxy().getOutputTransport(routeIndex)](FragmentToBatch& source) { + // Serialization happens in here, so that we can + // get rid of the intermediate tree 2 table object, saving memory. + auto batch = source.finalize(); + doWriteBatch(buffer, batch.get()); + // deletion happens in the caller + }; + + /// To finalise this we write the table to the buffer. + /// FIXME: most likely not a great idea. We should probably write to the buffer + /// directly in the TableBuilder, incrementally. + auto finalizer = [](std::shared_ptr b) -> void { + // This is empty because we already serialised the object when + // the LifetimeHolder goes out of scope. + }; + + context.addBuffer(std::move(header), buffer, std::move(finalizer), routeIndex); +} + void DataAllocator::adopt(const Output& spec, std::shared_ptr ptr) { auto& timingInfo = mRegistry.get(); diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index 23aa934c2ca8b..c20febaac517d 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -13,9 +13,13 @@ #include "Framework/Endian.h" #include "arrow/type_traits.h" +#include +#include +#include #include #include +#include #include namespace TableTreeHelpers { @@ -407,7 +411,7 @@ std::shared_ptr TableToTree::process() for (auto& reader : mColumnReaders) { int idealBasketSize = 1024 + reader->fieldSize() * reader->columnEntries(); // minimal additional size needed, otherwise we get 2 baskets - int basketSize = std::max(32000, idealBasketSize); // keep a minimum value + int basketSize = std::max(32000, idealBasketSize); // keep a minimum value // std::cout << "Setting baskets size for " << reader->branchName() << " to " << basketSize << " = 1024 + " // << reader->fieldSize() << " * " << reader->columnEntries() << ". mRows was " << mRows << std::endl; mTree->SetBasketSize(reader->branchName(), basketSize); @@ -555,4 +559,28 @@ std::shared_ptr TreeToTable::finalize() return mTable; } +FragmentToBatch::FragmentToBatch(arrow::MemoryPool* pool) + : mArrowMemoryPool{pool} +{ +} + +void FragmentToBatch::setLabel(const char* label) +{ + mTableLabel = label; +} + +void FragmentToBatch::fill(std::shared_ptr fragment, std::shared_ptr schema, std::shared_ptr format) +{ + auto options = std::make_shared(); + options->dataset_schema = schema; + auto scanner = format->ScanBatchesAsync(options, fragment); + auto batch = (*scanner)(); + mRecordBatch = *batch.result(); +} + +std::shared_ptr FragmentToBatch::finalize() +{ + return mRecordBatch; +} + } // namespace o2::framework From dc77cb3b925e51c004b38b2f98e9003ddace8790 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Sat, 9 Nov 2024 17:51:49 +0100 Subject: [PATCH 0440/2205] SVStudy: Add mc mother pdg code --- .../study/include/GlobalTrackingStudy/V0Ext.h | 10 ++-- .../study/src/SVStudy.cxx | 50 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/V0Ext.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/V0Ext.h index 99b35247081e6..79221b893882d 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/V0Ext.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/V0Ext.h @@ -17,9 +17,7 @@ #include "ReconstructionDataFormats/V0.h" #include "SimulationDataFormat/MCCompLabel.h" -namespace o2 -{ -namespace dataformats +namespace o2::dataformats { struct ProngInfoExt { @@ -40,10 +38,10 @@ struct V0Ext { V0Index v0ID; std::array prInfo{}; const ProngInfoExt& getPrInfo(int i) const { return prInfo[i]; } - ClassDefNV(V0Ext, 1); + int mcPID = -1; + ClassDefNV(V0Ext, 2); }; -} // namespace dataformats -} // namespace o2 +} // namespace o2::dataformats #endif diff --git a/Detectors/GlobalTrackingWorkflow/study/src/SVStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/SVStudy.cxx index 8ce1c1cec3e01..17b33c86e61ad 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/SVStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/SVStudy.cxx @@ -22,6 +22,7 @@ #include "DetectorsBase/GeometryManager.h" #include "SimulationDataFormat/MCEventLabel.h" #include "SimulationDataFormat/MCUtils.h" +#include "SimulationDataFormat/MCTrack.h" #include "CommonDataFormat/BunchFilling.h" #include "CommonUtils/NameConf.h" #include "DataFormatsFT0/RecPoints.h" @@ -86,7 +87,7 @@ class SVStudySpec : public Task float mBz = 0; GTrackID::mask_t mTracksSrc{}; o2::vertexing::DCAFitterN<2> mFitterV0; - o2::steer::MCKinematicsReader mcReader; // reader of MC information + std::unique_ptr mcReader; // reader of MC information }; void SVStudySpec::init(InitContext& ic) @@ -96,6 +97,9 @@ void SVStudySpec::init(InitContext& ic) mRefit = ic.options().get("refit"); mSelK0 = ic.options().get("sel-k0"); mMaxEta = ic.options().get("max-eta"); + if (mUseMC) { + mcReader = std::make_unique("collisioncontext.root"); + } } void SVStudySpec::run(ProcessingContext& pc) @@ -161,23 +165,24 @@ o2::dataformats::V0Ext SVStudySpec::processV0(int iv, o2::globaltracking::RecoCo v0ext.v0 = v0sel; } v0ext.v0ID = v0id; - o2::MCCompLabel lb; + o2::MCCompLabel lb[2]; + const o2::MCTrack* mcTrks[2]; for (int ip = 0; ip < 2; ip++) { auto& prInfo = v0ext.prInfo[ip]; auto gid = v0ext.v0ID.getProngID(ip); auto gidset = recoData.getSingleDetectorRefs(gid); - lb = recoData.getTrackMCLabel(gid); - if (lb.isValid()) { - prInfo.corrGlo = !lb.isFake(); + lb[ip] = recoData.getTrackMCLabel(gid); + if (lb[ip].isValid()) { + prInfo.corrGlo = !lb[ip].isFake(); } // get TPC tracks, if any if (gidset[GTrackID::TPC].isSourceSet()) { const auto& tpcTr = recoData.getTPCTrack(gidset[GTrackID::TPC]); prInfo.trackTPC = tpcTr; prInfo.nClTPC = tpcTr.getNClusters(); - lb = recoData.getTrackMCLabel(gidset[GTrackID::TPC]); - if (lb.isValid()) { - prInfo.corrTPC = !lb.isFake(); + lb[ip] = recoData.getTrackMCLabel(gidset[GTrackID::TPC]); + if (lb[ip].isValid()) { + prInfo.corrTPC = !lb[ip].isFake(); } } // get ITS tracks, if any @@ -186,9 +191,9 @@ o2::dataformats::V0Ext SVStudySpec::processV0(int iv, o2::globaltracking::RecoCo if (gidset[GTrackID::ITS].isSourceSet()) { const auto& itsTr = recoData.getITSTrack(gidset[GTrackID::ITS]); prInfo.nClITS = itsTr.getNClusters(); - lb = recoData.getTrackMCLabel(gidset[GTrackID::ITS]); - if (lb.isValid()) { - prInfo.corrITS = !lb.isFake(); + lb[ip] = recoData.getTrackMCLabel(gidset[GTrackID::ITS]); + if (lb[ip].isValid()) { + prInfo.corrITS = !lb[ip].isFake(); } for (int il = 0; il < 7; il++) { if (itsTr.hasHitOnLayer(il)) { @@ -198,9 +203,9 @@ o2::dataformats::V0Ext SVStudySpec::processV0(int iv, o2::globaltracking::RecoCo } else { const auto& itsTrf = recoData.getITSABRefs()[gidset[GTrackID::ITSAB]]; prInfo.nClITS = itsTrf.getNClusters(); - lb = recoData.getTrackMCLabel(gidset[GTrackID::ITSAB]); - if (lb.isValid()) { - prInfo.corrITS = !lb.isFake(); + lb[ip] = recoData.getTrackMCLabel(gidset[GTrackID::ITSAB]); + if (lb[ip].isValid()) { + prInfo.corrITS = !lb[ip].isFake(); } for (int il = 0; il < 7; il++) { if (itsTrf.hasHitOnLayer(il)) { @@ -211,13 +216,24 @@ o2::dataformats::V0Ext SVStudySpec::processV0(int iv, o2::globaltracking::RecoCo } if (gidset[GTrackID::ITSTPC].isSourceSet()) { auto mtc = recoData.getTPCITSTrack(gidset[GTrackID::ITSTPC]); - lb = recoData.getTrackMCLabel(gidset[GTrackID::ITSTPC]); + lb[ip] = recoData.getTrackMCLabel(gidset[GTrackID::ITSTPC]); prInfo.chi2ITSTPC = mtc.getChi2Match(); - if (lb.isValid()) { - prInfo.corrITSTPC = !lb.isFake(); + if (lb[ip].isValid()) { + prInfo.corrITSTPC = !lb[ip].isFake(); } } } + if (mUseMC && lb[ip].isValid()) { // temp store of mctrks + mcTrks[ip] = mcReader->getTrack(lb[ip]); + } + } + if (mUseMC && (mcTrks[0] != nullptr) && (mcTrks[1] != nullptr)) { + // check majority vote on mother particle otherwise leave pdg -1 + if (lb[0].getSourceID() == lb[1].getSourceID() && lb[0].getEventID() == lb[1].getEventID() && + mcTrks[0]->getMotherTrackId() == mcTrks[1]->getMotherTrackId() && mcTrks[0]->getMotherTrackId() >= 0) { + const auto mother = mcReader->getTrack(lb[0].getSourceID(), lb[0].getEventID(), mcTrks[0]->getMotherTrackId()); + v0ext.mcPID = mother->GetPdgCode(); + } } return v0ext; } From d0c4891828e5e868dd879d37f670acede41f9217 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:47:11 +0100 Subject: [PATCH 0441/2205] DPL: enable the plugin for any parent option If we read metadata from parents, we might be affecting the workflow generation, therefore we must consider all the parent affecting options as workflow ones. --- Framework/Core/src/Plugin.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/src/Plugin.cxx b/Framework/Core/src/Plugin.cxx index 726b12ff68365..0d225b81c0581 100644 --- a/Framework/Core/src/Plugin.cxx +++ b/Framework/Core/src/Plugin.cxx @@ -57,7 +57,7 @@ auto lookForCommandLineAODOptions = [](ConfigParamRegistry& registry, int argc, O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLineCapability", "AOD options found in arguments. Populating from them."); return true; } - if (arg.starts_with("--aod-parent-base-path-replacement")) { + if (arg.starts_with("--aod-parent-")) { O2_SIGNPOST_EVENT_EMIT(capabilities, sid, "DiscoverAODOptionsInCommandLineCapability", "AOD options found in arguments. Populating from them."); return true; } From adc8cad268949741f71df3e43ab6cfd801a2a562 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 8 Nov 2024 15:06:19 +0100 Subject: [PATCH 0442/2205] Digicontext: Several improvements Work needed for restructuring O2DPG MC workflows towards the use of a globally pre-generated collision context. * fixes for picking up vertices from collision contexts * possibility to generate vertices in CollContextTool from CCDB entry * smaller cleanup relates to https://its.cern.ch/jira/browse/O2-3622 --- .../SimConfig/include/SimConfig/SimConfig.h | 5 ++ Common/SimConfig/src/SimConfig.cxx | 30 +++++++----- .../simulation/src/DigitizationContext.cxx | 2 + Steer/src/CollisionContextTool.cxx | 48 +++++++++++++------ run/O2PrimaryServerDevice.h | 5 +- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/Common/SimConfig/include/SimConfig/SimConfig.h b/Common/SimConfig/include/SimConfig/SimConfig.h index da2f978ddf319..d70fca2400399 100644 --- a/Common/SimConfig/include/SimConfig/SimConfig.h +++ b/Common/SimConfig/include/SimConfig/SimConfig.h @@ -83,6 +83,7 @@ struct SimConfigData { bool mNoGeant = false; // if Geant transport should be turned off (when one is only interested in the generated events) bool mIsUpgrade = false; // true if the simulation is for Run 5 std::string mFromCollisionContext = ""; // string denoting a collision context file; If given, this file will be used to determine number of events + // bool mForwardKine = false; // true if tracks and event headers are to be published on a FairMQ channel (for reading by other consumers) bool mWriteToDisc = true; // whether we write simulation products (kine, hits) to disc VertexMode mVertexMode = VertexMode::kDiamondParam; // by default we should use die InteractionDiamond parameter @@ -177,6 +178,10 @@ class SimConfig bool writeToDisc() const { return mConfigData.mWriteToDisc; } VertexMode getVertexMode() const { return mConfigData.mVertexMode; } + // returns the pair of collision context filename as well as event prefix encoded + // in the mFromCollisionContext string. Returns empty string if information is not available or set. + std::pair getCollContextFilenameAndEventPrefix() const; + private: SimConfigData mConfigData; //! diff --git a/Common/SimConfig/src/SimConfig.cxx b/Common/SimConfig/src/SimConfig.cxx index 9a10b26547ce6..be21c38c5efc8 100644 --- a/Common/SimConfig/src/SimConfig.cxx +++ b/Common/SimConfig/src/SimConfig.cxx @@ -76,7 +76,7 @@ void SimConfig::initOptions(boost::program_options::options_description& options "noGeant", bpo::bool_switch(), "prohibits any Geant transport/physics (by using tight cuts)")( "forwardKine", bpo::bool_switch(), "forward kinematics on a FairMQ channel")( "noDiscOutput", bpo::bool_switch(), "switch off writing sim results to disc (useful in combination with forwardKine)"); - options.add_options()("fromCollContext", bpo::value()->default_value(""), "Use a pregenerated collision context to infer number of events to simulate, how to embedd them, the vertex position etc. Takes precedence of other options such as \"--nEvents\"."); + options.add_options()("fromCollContext", bpo::value()->default_value(""), "Use a pregenerated collision context to infer number of events to simulate, how to embedd them, the vertex position etc. Takes precedence of other options such as \"--nEvents\". The format is COLLISIONCONTEXTFILE.root[:SIGNALNAME] where SIGNALNAME is the event part in the context which is relevant."); } void SimConfig::determineActiveModules(std::vector const& inputargs, std::vector const& skippedModules, std::vector& activeModules, bool isUpgrade) @@ -270,6 +270,21 @@ void SimConfig::determineReadoutDetectors(std::vector const& active } } +std::pair SimConfig::getCollContextFilenameAndEventPrefix() const +{ + // we decompose the argument to fetch + // (a) collision contextfilename + // (b) sim prefix to use from the context + auto pos = mConfigData.mFromCollisionContext.find(':'); + std::string collcontextfile{mConfigData.mFromCollisionContext}; + std::string simprefix{mConfigData.mOutputPrefix}; + if (pos != std::string::npos) { + collcontextfile = mConfigData.mFromCollisionContext.substr(0, pos); + simprefix = mConfigData.mFromCollisionContext.substr(pos + 1); + } + return std::make_pair(collcontextfile, simprefix); +} + bool SimConfig::resetFromParsedMap(boost::program_options::variables_map const& vm) { using o2::detectors::DetID; @@ -333,17 +348,8 @@ bool SimConfig::resetFromParsedMap(boost::program_options::variables_map const& mConfigData.mFilterNoHitEvents = true; } mConfigData.mFromCollisionContext = vm["fromCollContext"].as(); - // we decompose the argument to fetch - // (a) collision contextfilename - // (b) sim prefix to use from the context - auto pos = mConfigData.mFromCollisionContext.find(':'); - std::string collcontextfile{mConfigData.mFromCollisionContext}; - std::string simprefix{mConfigData.mOutputPrefix}; - if (pos != std::string::npos) { - collcontextfile = mConfigData.mFromCollisionContext.substr(0, pos); - simprefix = mConfigData.mFromCollisionContext.substr(pos + 1); - } - adjustFromCollContext(collcontextfile, simprefix); + auto collcontext_simprefix = getCollContextFilenameAndEventPrefix(); + adjustFromCollContext(collcontext_simprefix.first, collcontext_simprefix.second); // analyse vertex options if (!parseVertexModeString(vm["vertexMode"].as(), mConfigData.mVertexMode)) { diff --git a/DataFormats/simulation/src/DigitizationContext.cxx b/DataFormats/simulation/src/DigitizationContext.cxx index ba1fda53e179b..3fb6b757aeea3 100644 --- a/DataFormats/simulation/src/DigitizationContext.cxx +++ b/DataFormats/simulation/src/DigitizationContext.cxx @@ -578,5 +578,7 @@ DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid, } catch (std::exception) { LOG(warn) << "No such timeframe id in collision context. Returing empty object"; } + // fix number of collisions + r.setNCollisions(r.mEventRecords.size()); return r; } diff --git a/Steer/src/CollisionContextTool.cxx b/Steer/src/CollisionContextTool.cxx index af2f607b88774..3d1dcec29976e 100644 --- a/Steer/src/CollisionContextTool.cxx +++ b/Steer/src/CollisionContextTool.cxx @@ -27,6 +27,7 @@ #include "CommonUtils/ConfigurableParam.h" #include #include "DataFormatsParameters/GRPLHCIFData.h" +#include "SimConfig/SimConfig.h" // // Created by Sandro Wenzel on 13.07.21. @@ -52,11 +53,12 @@ struct Options { bool useexistingkinematics = false; bool noEmptyTF = false; // prevent empty timeframes; the first interaction will be shifted backwards to fall within the range given by Options.orbits int maxCollsPerTF = -1; // the maximal number of hadronic collisions per TF (can be used to constrain number of collisions per timeframe to some maximal value) - bool genVertices = false; // whether to assign vertices to collisions std::string configKeyValues = ""; // string to init config key values long timestamp = -1; // timestamp for CCDB queries std::string individualTFextraction = ""; // triggers extraction of individuel timeframe components when non-null // format is path prefix + std::string vertexModeString{"kNoVertex"}; // Vertex Mode; vertices will be assigned to collisions of mode != kNoVertex + o2::conf::VertexMode vertexMode = o2::conf::VertexMode::kNoVertex; }; enum class InteractionLockMode { @@ -203,7 +205,9 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) "first-orbit", bpo::value(&optvalues.firstFractionalOrbit)->default_value(0), "First (fractional) orbit in the run (HBFUtils.firstOrbit + BC from decimal)")( "maxCollsPerTF", bpo::value(&optvalues.maxCollsPerTF)->default_value(-1), "Maximal number of MC collisions to put into one timeframe. By default no constraint.")( "noEmptyTF", bpo::bool_switch(&optvalues.noEmptyTF), "Enforce to have at least one collision")( - "configKeyValues", bpo::value(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")("with-vertices", "Assign vertices to collisions.")("timestamp", bpo::value(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring")( + "configKeyValues", bpo::value(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")( + "with-vertices", bpo::value(&optvalues.vertexModeString)->default_value("kNoVertex"), "Assign vertices to collisions. Argument is the vertex mode. Defaults to no vertexing applied")( + "timestamp", bpo::value(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring")( "extract-per-timeframe", bpo::value(&optvalues.individualTFextraction)->default_value(""), "Extract individual timeframe contexts. Format required: time_frame_prefix[:comma_separated_list_of_signals_to_offset]"); @@ -225,9 +229,8 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) if (vm.count("use-existing-kine")) { optvalues.useexistingkinematics = true; } - if (vm.count("with-vertices")) { - optvalues.genVertices = true; - } + + o2::conf::SimConfig::parseVertexModeString(optvalues.vertexModeString, optvalues.vertexMode); // fix the first orbit and bunch crossing // auto orbitbcpair = parseOrbitAndBC(optvalues.firstIRString); @@ -277,10 +280,9 @@ int main(int argc, char* argv[]) LOG(info) << "Fetch bcPattern information from CCDB"; // fetch the GRP Object auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); - ccdb.setTimestamp(options.timestamp); ccdb.setCaching(false); ccdb.setLocalObjectValidityChecking(true); - auto grpLHC = ccdb.get("GLO/Config/GRPLHCIF"); + auto grpLHC = ccdb.getForTimeStamp("GLO/Config/GRPLHCIF", options.timestamp); LOG(info) << "Fetched injection scheme " << grpLHC->getInjectionScheme() << " from CCDB"; sampler.setBunchFilling(grpLHC->getBunchFilling()); } else { @@ -449,14 +451,32 @@ int main(int argc, char* argv[]) auto numTimeFrames = digicontext.finalizeTimeframeStructure(orbitstart, options.orbitsPerTF); - if (options.genVertices) { - // TODO: offer option taking meanVertex directly from CCDB ! "GLO/Calib/MeanVertex" - // sample interaction vertices + if (options.vertexMode != o2::conf::VertexMode::kNoVertex) { + switch (options.vertexMode) { + case o2::conf::VertexMode::kCCDB: { + // fetch mean vertex from CCDB + auto meanv = o2::ccdb::BasicCCDBManager::instance().getForTimeStamp("GLO/Calib/MeanVertex", options.timestamp); + if (meanv) { + LOG(info) << "Applying vertexing using CCDB mean vertex " << *meanv; + digicontext.sampleInteractionVertices(*meanv); + } else { + LOG(fatal) << "No vertex available"; + } + break; + } - // init this vertex from CCDB or InteractionDiamond parameter - const auto& dparam = o2::eventgen::InteractionDiamondParam::Instance(); - o2::dataformats::MeanVertexObject meanv(dparam.position[0], dparam.position[1], dparam.position[2], dparam.width[0], dparam.width[1], dparam.width[2], dparam.slopeX, dparam.slopeY); - digicontext.sampleInteractionVertices(meanv); + case o2::conf::VertexMode::kDiamondParam: { + // init this vertex from CCDB or InteractionDiamond parameter + const auto& dparam = o2::eventgen::InteractionDiamondParam::Instance(); + o2::dataformats::MeanVertexObject meanv(dparam.position[0], dparam.position[1], dparam.position[2], dparam.width[0], dparam.width[1], dparam.width[2], dparam.slopeX, dparam.slopeY); + LOG(info) << "Applying vertexing using DiamondParam mean vertex " << meanv; + digicontext.sampleInteractionVertices(meanv); + break; + } + default: { + LOG(error) << "Unknown vertex mode ... Not generating vertices"; + } + } } // we fill QED contributions to the context diff --git a/run/O2PrimaryServerDevice.h b/run/O2PrimaryServerDevice.h index 202e6e8652cc7..53b86d1f23591 100644 --- a/run/O2PrimaryServerDevice.h +++ b/run/O2PrimaryServerDevice.h @@ -138,7 +138,8 @@ class O2PrimaryServerDevice final : public fair::mq::Device mPrimGen->SetEvent(&mEventHeader); // A good moment to couple to collision context - auto collContextFileName = mSimConfig.getConfigData().mFromCollisionContext; + auto collContextFileName_PrefixPair = mSimConfig.getCollContextFilenameAndEventPrefix(); + auto collContextFileName = collContextFileName_PrefixPair.first; if (collContextFileName.size() > 0) { LOG(info) << "Simulation has collission context"; mCollissionContext = o2::steer::DigitizationContext::loadFromFile(collContextFileName); @@ -147,7 +148,7 @@ class O2PrimaryServerDevice final : public fair::mq::Device LOG(info) << "We found " << vertices.size() << " vertices included "; // initialize the eventID to collID mapping - const auto source = mCollissionContext->findSimPrefix(mSimConfig.getOutPrefix()); + const auto source = mCollissionContext->findSimPrefix(collContextFileName_PrefixPair.second); if (source == -1) { LOG(fatal) << "Wrong simulation prefix"; } From 37a1f623d270548827cad7b896e2d1a418733084 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Fri, 13 Sep 2024 12:23:01 +0200 Subject: [PATCH 0443/2205] Fix typo and add explanation comments --- Detectors/MUON/MID/Calibration/macros/build_rejectlist.C | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C index 0782a08a3822d..685b28fd543d6 100644 --- a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C +++ b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C @@ -109,6 +109,12 @@ std::vector findObjectsTSInPeriod(long start, long end, const o2::ccdb::Cc /// @return Pair with first and last time std::pair findTSRange(TCanvas* qcQuality, bool selectBad = true) { + // Gets the plot with the quality flags + // The flag values are: + // Good: 3.5 + // Medium: 2.5 + // Bad: 1.5 + // Null: 0.5 auto* gr = static_cast(qcQuality->GetListOfPrimitives()->FindObject("Graph")); double xp, yp; std::pair range{std::numeric_limits::max(), 0}; @@ -276,7 +282,7 @@ std::vector build_rejectlist(long timestamp, const char* qc return build_rejectlist(timestamp, qcdbApi, ccdbApi, outCCDBApi); } -/// @brief Builds the reject list iin a time range +/// @brief Builds the reject list in a time range /// @param start Start time for query /// @param end End time for query /// @param qcdbUrl QCDB URL From 404b41442fab332901e2cf624e2bc8c883046010 Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Mon, 30 Sep 2024 15:45:26 +0200 Subject: [PATCH 0444/2205] Add possibility to specify a manual reject list for MID --- .../MUON/MID/Calibration/macros/README.md | 47 ++++ .../MID/Calibration/macros/build_rejectlist.C | 208 ++++++++++++++---- 2 files changed, 212 insertions(+), 43 deletions(-) diff --git a/Detectors/MUON/MID/Calibration/macros/README.md b/Detectors/MUON/MID/Calibration/macros/README.md index 7009e99086419..83e88f18ecf48 100644 --- a/Detectors/MUON/MID/Calibration/macros/README.md +++ b/Detectors/MUON/MID/Calibration/macros/README.md @@ -60,6 +60,53 @@ root -l .x build_rejectlist.C+(1716436103391,1721272208000,"localhost:8083") ``` +### Add custom bad channels + +The macro `build_rejectlist.C` scans the QCDB and the CCDB in search of issues. +However, the QCDB flag is based on local boards with empty signals. +It can happen that a local board is problematic, but not completely dead and, therefore, it is not correctly spotted by the macro. +It is therefore important to have a way to add the issues by hand. +This can be done with a json file in the form: + +```json +{ + "startRun": 557251, + "endRun": 557926, + "rejectList": [ + { + "deId": 4, + "columnId": 2, + "patterns": [ + "0x0", + "0xFFFF", + "0x0", + "0x0", + "0x0" + ] + }, + { + "deId": 13, + "columnId": 2, + "patterns": [ + "0x0", + "0xFFFF", + "0x0", + "0x0", + "0x0" + ] + } + ] +} +``` + +The path to the file is then given to the macro with: + +```shell +.x build_rejectlist.C+(1726299038000,1727386238000,"http://localhost:8083","http://alice-ccdb.cern.ch","http://localhost:8080","rejectlist.json") +``` + +The macro will then merge the manual reject list from the file with the reject list that it finds by scanning the QCDB and CCDB. + ## Running the local CCDB The local CCDB server can be easily built through alibuild. diff --git a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C index 685b28fd543d6..7a395d2c099da 100644 --- a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C +++ b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C @@ -21,6 +21,8 @@ #include #include #include +#include "rapidjson/document.h" +#include "rapidjson/istreamwrapper.h" #include "TCanvas.h" #include "TH1.h" #include "TGraph.h" @@ -29,15 +31,25 @@ #include "DataFormatsParameters/GRPECSObject.h" #include "DetectorsCommonDataFormats/DetID.h" #include "DataFormatsMID/ColumnData.h" +#include "MIDBase/ColumnDataHandler.h" #include "MIDGlobalMapping/ExtendedMappingInfo.h" #include "MIDGlobalMapping/GlobalMapper.h" #include "MIDFiltering/ChannelMasksHandler.h" + +// ... #if !defined(__CLING__) || defined(__ROOTCLING__) #include "CCDB/BasicCCDBManager.h" #endif static const std::string sPathQCQuality = "qc/MID/MO/MIDQuality/Trends/global/MIDQuality/MIDQuality"; +/// @brief Reject list object +struct RejectListStruct { + long start = 0; /// Start validity + long end = 0; /// End validity + std::vector rejectList{}; /// Bad channels +}; + /// @brief Get timestamp in milliseconds /// @param timestamp Input timestamp (in s or ms) /// @return Timestamp in ms @@ -174,25 +186,38 @@ std::vector getRejectList(std::vector return badChannels; } +/// @brief Gets the run duration with a safety marging +/// @param ccdbApi CCDB api +/// @param marging margin in milliseconds +/// @return Pair with the timestamps of start-margin and end+margin for the run +std::pair getRunDuration(const o2::ccdb::CcdbApi& ccdbApi, int runNumber, int64_t margin = 120000) +{ + auto runRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, runNumber); + runRange.first -= margin; // Subtract margin + runRange.second += margin; // Add margin + return runRange; +} + /// @brief Builds the reject list for the selected timestamp /// @param timestamp Timestamp for query /// @param qcdbApi QCDB api /// @param ccdbApi CCDB api /// @param outCCDBApi api of the CCDB where the reject list will be uploaded /// @return Reject list -std::vector build_rejectlist(long timestamp, const o2::ccdb::CcdbApi& qcdbApi, const o2::ccdb::CcdbApi& ccdbApi, const o2::ccdb::CcdbApi& outCCDBApi) +RejectListStruct build_rejectlist(long timestamp, const o2::ccdb::CcdbApi& qcdbApi, const o2::ccdb::CcdbApi& ccdbApi) { std::map metadata; + RejectListStruct rl; auto* qcQuality = qcdbApi.retrieveFromTFileAny(sPathQCQuality, metadata, getTSMS(timestamp)); if (!qcQuality) { std::cerr << "Cannot find QC quality for " << tsToString(timestamp) << std::endl; - return {}; + return rl; } // Find the first and last timestamp where the quality was bad (if any) auto badTSRange = findTSRange(qcQuality); if (badTSRange.second == 0) { std::cout << "All good" << std::endl; - return {}; + return rl; } // Search for the last timestamp for which the run quality was good auto goodTSRange = findTSRange(qcQuality, false); @@ -202,18 +227,15 @@ std::vector build_rejectlist(long timestamp, const o2::ccdb if (!grpecs.isDetReadOut(o2::detectors::DetID::MID)) { std::cout << "Error: we are probably reading a parallel run" << std::endl; grpecs.print(); - return {}; + return rl; } if (grpecs.getRunType() != o2::parameters::GRPECS::PHYSICS) { std::cout << "This is not a physics run: skip" << std::endl; grpecs.print(); - return {}; + return rl; } - auto runRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, grpecs.getRun()); - long margin = 120000; // Add a two minutes safety margin - runRange.first -= margin; // Subtract margin - runRange.second += margin; // Add margin + auto runRange = getRunDuration(ccdbApi, grpecs.getRun()); // Search for hits histogram in the period where the QC quality was bad auto tsVector = findObjectsTSInPeriod(badTSRange.first, badTSRange.second, qcdbApi, "qc/MID/MO/QcTaskMIDDigits/Hits"); @@ -227,15 +249,15 @@ std::vector build_rejectlist(long timestamp, const o2::ccdb auto infos = gm.buildStripsInfo(); auto badChannels = findBadChannels(occupancy, infos); auto badChannelsCCDB = *ccdbApi.retrieveFromTFileAny>("MID/Calib/BadChannels", metadata, getTSMS(timestamp)); - auto rejectList = getRejectList(badChannels, badChannelsCCDB); - if (rejectList.empty()) { + rl.rejectList = getRejectList(badChannels, badChannelsCCDB); + if (rl.rejectList.empty()) { std::cout << "Warning: reject list was empty. It probably means that an entire board is already masked in calibration for run " << grpecs.getRun() << std::endl; - return {}; + return rl; } // Print some useful information std::cout << "Reject list:" << std::endl; - for (auto& col : rejectList) { + for (auto& col : rl.rejectList) { std::cout << col << std::endl; } std::cout << "Run number: " << grpecs.getRun() << std::endl; @@ -245,41 +267,120 @@ std::vector build_rejectlist(long timestamp, const o2::ccdb std::cout << "Bad: " << timeRangeToString(badTSRange.first, badTSRange.second) << std::endl; // Set the start of the reject list to the last timestamp in which the occupancy was ok - auto startRL = goodTSRange.second; + rl.start = goodTSRange.second; if (goodTSRange.first == 0) { // If the quality was bad for the full run, set the start of the reject list to the SOR std::cout << "CAVEAT: no good TS found. Will use SOT instead" << std::endl; - startRL = runRange.first; + rl.start = runRange.first; } // Set the end of the reject list to the end of run - auto endRL = runRange.second; - // Ask if you want to upload the object to the CCDB - std::cout << "Upload reject list with validity: " << startRL << " - " << endRL << " to " << outCCDBApi.getURL() << "? [y/n]" << std::endl; - std::string answer; - std::cin >> answer; - if (answer == "y") { - std::cout << "Storing RejectList valid from " << startRL << " to " << endRL << std::endl; - outCCDBApi.storeAsTFileAny(&rejectList, "MID/Calib/RejectList", metadata, startRL, endRL); + rl.end = runRange.second; + return rl; +} + +/// @brief Loads the reject list from a json file +/// @param ccdbApi CCDB api +/// @param filename json filename +/// @return Reject list structure +RejectListStruct load_from_json(const o2::ccdb::CcdbApi& ccdbApi, const char* filename = "rejectlist.json") +{ + // Open the JSON file + std::cout << "Reading reject list from file " << filename << std::endl; + RejectListStruct rl; + std::ifstream inFile(filename); + if (!inFile.is_open()) { + std::cerr << "Could not open the file!" << std::endl; + return rl; } - return rejectList; + + // Create an IStreamWrapper for file input stream + rapidjson::IStreamWrapper isw(inFile); + + rapidjson::Document doc; + if (doc.ParseStream(isw).HasParseError()) { + std::cerr << "Problem parsing " << filename << std::endl; + return rl; + } + auto startRange = getRunDuration(ccdbApi, doc["startRun"].GetInt()); + auto endRange = getRunDuration(ccdbApi, doc["endRun"].GetInt()); + rl.start = startRange.first; + rl.end = endRange.second; + std::cout << "Manual RL validity: " << timeRangeToString(rl.start, rl.end) << std::endl; + auto rlArray = doc["rejectList"].GetArray(); + for (auto& ar : rlArray) { + o2::mid::ColumnData col; + col.deId = ar["deId"].GetInt(); + col.columnId = ar["columnId"].GetInt(); + auto patterns = ar["patterns"].GetArray(); + for (size_t iar = 0; iar < 5; ++iar) { + col.patterns[iar] = std::strtol(patterns[iar].GetString(), NULL, 16); + } + rl.rejectList.emplace_back(col); + std::cout << col << std::endl; + } + return rl; } -/// @brief Builds the reject list for the selected timestamp -/// @param timestamp Timestamp for query -/// @param qcdbUrl QCDB URL -/// @param ccdbUrl CCDB URL -/// @param outCCDBUrl URL of the CCDB where the reject list will be uploaded -/// @return Reject list -std::vector build_rejectlist(long timestamp, const char* qcdbUrl = "http://ali-qcdb-gpn.cern.ch:8083", const char* ccdbUrl = "http://alice-ccdb.cern.ch", const char* outCCDBUrl = "http://localhost:8080") +/// @brief Merges the manual and automatic reject lists +/// @param manualRL Manual reject list from json file +/// @param rls Reject list from QCDB and CCDB +/// @return Merged reject list +std::vector merge_rejectlists(const RejectListStruct& manualRL, const std::vector& rls) { - // Get the QC quality object for the selected timestamp - o2::ccdb::CcdbApi qcdbApi; - qcdbApi.init(qcdbUrl); - o2::ccdb::CcdbApi ccdbApi; - ccdbApi.init(ccdbUrl); - o2::ccdb::CcdbApi outCCDBApi; - outCCDBApi.init(outCCDBUrl); - return build_rejectlist(timestamp, qcdbApi, ccdbApi, outCCDBApi); + std::vector merged; + if (rls.empty()) { + merged.emplace_back(manualRL); + return merged; + } + o2::mid::ColumnDataHandler ch; + RejectListStruct tmpRL; + long lastEnd = manualRL.start; + for (auto& rl : rls) { + std::cout << "Checking rl with validity: " << timeRangeToString(rl.start, rl.end) << std::endl; + if (rl.start >= manualRL.start && rl.end <= manualRL.end) { + // The period is included in the validity of the manual reject list + if (rl.start > lastEnd) { + // Fill holes between periods + tmpRL = manualRL; + tmpRL.start = lastEnd; + tmpRL.end = rl.start; + merged.emplace_back(tmpRL); + std::cout << "Adding manual RL with validity: " << timeRangeToString(tmpRL.start, tmpRL.end) << std::endl; + } + lastEnd = rl.end; + + // merge + ch.clear(); + ch.merge(rl.rejectList); + ch.merge(manualRL.rejectList); + tmpRL = rl; + tmpRL.rejectList = ch.getMerged(); + std::sort(tmpRL.rejectList.begin(), tmpRL.rejectList.end(), [](const o2::mid::ColumnData& col1, const o2::mid::ColumnData& col2) { return o2::mid::getColumnDataUniqueId(col1.deId, col1.columnId) < o2::mid::getColumnDataUniqueId(col2.deId, col2.columnId); }); + merged.emplace_back(tmpRL); + std::cout << "Merging RL with validity: " << timeRangeToString(tmpRL.start, tmpRL.end) << std::endl; + // std::cout << "Before: " << std::endl; + // for (auto& col : rl.rejectList) { + // std::cout << col << std::endl; + // } + // std::cout << "After: " << std::endl; + // for (auto& col : tmpRL.rejectList) { + // std::cout << col << std::endl; + // } + } else { + if (rl.start > manualRL.end && lastEnd < manualRL.end) { + // Close manual period + tmpRL = manualRL; + tmpRL.start = lastEnd; + merged.emplace_back(tmpRL); + std::cout << "Adding manual RL with validity: " << timeRangeToString(tmpRL.start, tmpRL.end) << std::endl; + lastEnd = manualRL.end; + } + // Add current reject list as it is + merged.emplace_back(rl); + std::cout << "Adding RL with validity: " << timeRangeToString(rl.start, rl.end) << std::endl; + } + } + return merged; } /// @brief Builds the reject list in a time range @@ -288,17 +389,38 @@ std::vector build_rejectlist(long timestamp, const char* qc /// @param qcdbUrl QCDB URL /// @param ccdbUrl CCDB URL /// @param outCCDBUrl URL of the CCDB where the reject lists will be uploaded -void build_rejectlist(long start, long end, const char* qcdbUrl = "http://ali-qcdb-gpn.cern.ch:8083", const char* ccdbUrl = "http://alice-ccdb.cern.ch", const char* outCCDBUrl = "http://localhost:8080") +void build_rejectlist(long start, long end, const char* qcdbUrl = "http://ali-qcdb-gpn.cern.ch:8083", const char* ccdbUrl = "http://alice-ccdb.cern.ch", const char* outCCDBUrl = "http://localhost:8080", const char* json_rejectlist = "") { // Query the MID QC quality objects o2::ccdb::CcdbApi qcdbApi; qcdbApi.init(qcdbUrl); o2::ccdb::CcdbApi ccdbApi; ccdbApi.init(ccdbUrl); - o2::ccdb::CcdbApi outCCDBApi; - outCCDBApi.init(outCCDBUrl); + std::vector rls; auto objectsTS = findObjectsTSInPeriod(start, end, qcdbApi, sPathQCQuality.c_str()); for (auto ts : objectsTS) { - build_rejectlist(ts, qcdbApi, ccdbApi, outCCDBApi); + auto rl = build_rejectlist(ts, qcdbApi, ccdbApi); + if (rl.start != rl.end) { + rls.emplace_back(rl); + } + } + + if (!std::string(json_rejectlist).empty()) { + auto rlManual = load_from_json(ccdbApi, json_rejectlist); + rls = merge_rejectlists(rlManual, rls); + } + + o2::ccdb::CcdbApi outCCDBApi; + outCCDBApi.init(outCCDBUrl); + std::map metadata; + for (auto& rl : rls) { + // Ask if you want to upload the object to the CCDB + std::cout << "Upload reject list with validity: " << rl.start << " - " << rl.end << " to " << outCCDBApi.getURL() << "? [y/n]" << std::endl; + std::string answer; + std::cin >> answer; + if (answer == "y") { + std::cout << "Storing RejectList valid from " << rl.start << " to " << rl.end << std::endl; + outCCDBApi.storeAsTFileAny(&rl.rejectList, "MID/Calib/RejectList", metadata, rl.start, rl.end); + } } } \ No newline at end of file From 549537982cb2191c29d0ddacabaa6c241cf723cc Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 12 Nov 2024 15:18:22 +0100 Subject: [PATCH 0445/2205] Fix acknowledgment of -h option by HBFUtilsInitializer --- Detectors/Raw/src/HBFUtilsInitializer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/Raw/src/HBFUtilsInitializer.cxx b/Detectors/Raw/src/HBFUtilsInitializer.cxx index 1f89d9725b397..e3cc9a8eef414 100644 --- a/Detectors/Raw/src/HBFUtilsInitializer.cxx +++ b/Detectors/Raw/src/HBFUtilsInitializer.cxx @@ -78,7 +78,7 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext hbfuInput = optStr; } else if (opt == HBFOpt::ROOT) { rootFileInput = optStr; - } else { + } else if (!helpasked) { LOGP(fatal, "uknown hbfutils-config option {}", optStr); } } From 25896b2f94bea8256d347686f1dc0143ab276826 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 13 Nov 2024 16:33:19 +0100 Subject: [PATCH 0446/2205] TrackStudy stores TPC lowest cluster position --- .../GlobalTrackingStudy/TrackInfoExt.h | 12 ++++- .../study/src/TrackingStudy.cxx | 50 +++++++++---------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h index b988eddfa861f..ea79d5d4a2c92 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h @@ -30,6 +30,8 @@ struct TrackInfoExt { DCA dcaTPC{}; VtxTrackIndex gid; MatchInfoTOF infoTOF; + std::array innerTPCPos{}; // innermost cluster position at assigned time + std::array innerTPCPos0{}; // innermost cluster position at nominal time0 float ttime = 0; float ttimeE = 0; float xmin = 0; @@ -44,7 +46,15 @@ struct TrackInfoExt { uint8_t rowMinTPC = 0; uint8_t rowMaxTPC = 0; uint8_t rowCountTPC = 0; - ClassDefNV(TrackInfoExt, 2); + + float getTPCInX() const { return innerTPCPos[0]; } + float getTPCInY() const { return innerTPCPos[1]; } + float getTPCInZ() const { return innerTPCPos[2]; } + float getTPCInX0() const { return innerTPCPos0[0]; } + float getTPCInY0() const { return innerTPCPos0[1]; } + float getTPCInZ0() const { return innerTPCPos0[2]; } + + ClassDefNV(TrackInfoExt, 3); }; } // namespace dataformats diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx index 1e605e308f4ab..5a67bd344f271 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx @@ -248,26 +248,30 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) auto vdrit = mTPCVDriftHelper.getVDriftObject().getVDrift(); bool tpcTrackOK = recoData.isTrackSourceLoaded(GTrackID::TPC); - auto getTPCClInfo = [&recoData](const o2::tpc::TrackTPC& trc) { + auto fillTPCClInfo = [&recoData, this](const o2::tpc::TrackTPC& trc, o2::dataformats::TrackInfoExt& trExt, float timestampTB = -1e9) { const auto clRefs = recoData.getTPCTracksClusterRefs(); - std::array clinfo = {}; if (recoData.inputsTPCclusters) { uint8_t clSect = 0, clRow = 0, clRowP = -1; uint32_t clIdx = 0; for (int ic = 0; ic < trc.getNClusterReferences(); ic++) { trc.getClusterReference(clRefs, ic, clSect, clRow, clIdx); if (clRow != clRowP) { - clinfo[2]++; + trExt.rowCountTPC++; clRowP = clRow; } } - const auto clRefs = recoData.getTPCTracksClusterRefs(); trc.getClusterReference(clRefs, trc.getNClusterReferences() - 1, clSect, clRow, clIdx); - clinfo[0] = clRow; + trExt.rowMinTPC = clRow; + const auto& clus = recoData.inputsTPCclusters->clusterIndex.clusters[clSect][clRow][clIdx]; + this->mTPCCorrMapsLoader.Transform(clSect, clRow, clus.getPad(), clus.getTime(), trExt.innerTPCPos0[0], trExt.innerTPCPos0[1], trExt.innerTPCPos0[2], trc.getTime0()); // nominal time of the track + if (timestampTB > -1e8) { + this->mTPCCorrMapsLoader.Transform(clSect, clRow, clus.getPad(), clus.getTime(), trExt.innerTPCPos[0], trExt.innerTPCPos[1], trExt.innerTPCPos[2], timestampTB); // time assigned from the global track track + } else { + trExt.innerTPCPos = trExt.innerTPCPos0; + } trc.getClusterReference(clRefs, 0, clSect, clRow, clIdx); - clinfo[1] = clRow; + trExt.rowMaxTPC = clRow; } - return clinfo; }; for (int iv = 0; iv < nv; iv++) { @@ -276,7 +280,6 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) if (iv != nv - 1) { auto& pve = pveVec[iv]; static_cast(pve) = pvvec[iv]; - // find best matching FT0 signal float bestTimeDiff = 1000, bestTime = -999; int bestFTID = -1; @@ -319,7 +322,6 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) GTrackID tpcTrID; const o2::tpc::TrackTPC* tpcTr = nullptr; int nclTPC = 0; - std::array tpcClInfo{}; if (dm[DetID::TPC] && tpcTrackOK) { tpcTrID = recoData.getTPCContributorGID(vid); tpcTr = &recoData.getTPCTrack(tpcTrID); @@ -327,7 +329,6 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) if (nclTPC < mMinTPCClusters) { continue; } - tpcClInfo = getTPCClInfo(*tpcTr); } bool ambig = vid.isAmbiguous(); auto trc = recoData.getTrackParam(vid); @@ -364,11 +365,19 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) continue; } { - o2::dataformats::DCA dcaTPC; - dcaTPC.set(-999.f, -999.f); + auto& trcExt = trcExtVec.emplace_back(); + recoData.getTrackTime(vid, trcExt.ttime, trcExt.ttimeE); + trcExt.track = trc; + trcExt.dca = dca; + trcExt.gid = vid; + trcExt.xmin = xmin; + trcExt.dcaTPC.set(-999.f, -999.f); + if (tpcTr) { + float tsuse = trcExt.ttime / (8 * o2::constants::lhc::LHCBunchSpacingMUS); if (is == GTrackID::TPC) { - dcaTPC = dca; + trcExt.dcaTPC = dca; + tsuse = -1e9; } else { o2::track::TrackParCov tmpTPC(*tpcTr); if (iv < nv - 1 && is == GTrackID::TPC && tpcTr && !tpcTr->hasBothSidesClusters()) { // for unconstrained TPC tracks correct track Z @@ -378,18 +387,12 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) } tmpTPC.setZ(tmpTPC.getZ() + corz); } - if (!prop->propagateToDCA(iv == nv - 1 ? vtxDummy : pvvec[iv], tmpTPC, prop->getNominalBz(), 2., o2::base::PropagatorF::MatCorrType::USEMatCorrLUT, &dcaTPC)) { - dcaTPC.set(-999.f, -999.f); + if (!prop->propagateToDCA(iv == nv - 1 ? vtxDummy : pvvec[iv], tmpTPC, prop->getNominalBz(), 2., o2::base::PropagatorF::MatCorrType::USEMatCorrLUT, &trcExt.dcaTPC)) { + trcExt.dcaTPC.set(-999.f, -999.f); } } + fillTPCClInfo(*tpcTr, trcExt, tsuse); } - auto& trcExt = trcExtVec.emplace_back(); - recoData.getTrackTime(vid, trcExt.ttime, trcExt.ttimeE); - trcExt.track = trc; - trcExt.dca = dca; - trcExt.dcaTPC = dcaTPC; - trcExt.gid = vid; - trcExt.xmin = xmin; auto gidRefs = recoData.getSingleDetectorRefs(vid); if (gidRefs[GTrackID::ITS].isIndexSet()) { const auto& itsTr = recoData.getITSTrack(gidRefs[GTrackID::ITS]); @@ -412,9 +415,6 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) if (gidRefs[GTrackID::TPC].isIndexSet()) { trcExt.q2ptTPC = recoData.getTrackParam(gidRefs[GTrackID::TPC]).getQ2Pt(); trcExt.nClTPC = nclTPC; - trcExt.rowMinTPC = tpcClInfo[0]; - trcExt.rowMaxTPC = tpcClInfo[1]; - trcExt.rowCountTPC = tpcClInfo[2]; } if (gidRefs[GTrackID::ITSTPC].isIndexSet()) { const auto& trTPCITS = recoData.getTPCITSTrack(gidRefs[GTrackID::ITSTPC]); From 4b9ede8b97d5941c353cd4769deb68409e0163be Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 13 Nov 2024 17:11:15 +0100 Subject: [PATCH 0447/2205] Protect LT-int.calculation in TRD refit from bad TPC correction --- .../TRD/workflow/src/TRDGlobalTrackingSpec.cxx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx index 3773f07ccd1ab..424657ac19426 100644 --- a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx @@ -615,7 +615,6 @@ bool TRDGlobalTracking::refitITSTPCTRDTrack(TrackTRD& trk, float timeTRD, o2::gl LOG(debug) << "TRD refit outwards failed"; return false; } - // refit ITS-TPC-TRD track inwards to innermost ITS cluster // here we also calculate the LT integral for matching to TOF float chi2In = 0.f; @@ -629,6 +628,12 @@ bool TRDGlobalTracking::refitITSTPCTRDTrack(TrackTRD& trk, float timeTRD, o2::gl LOG(debug) << "TPC refit inwards failed"; return false; } + // if for some reason the track was overshoot over the inner field cage, bring it back w/o material correction and LTintegral update + if (trk.getX() < o2::constants::geom::XTPCInnerRef && + !propagator->PropagateToXBxByBz(trk, o2::constants::geom::XTPCInnerRef, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) { + LOG(debug) << "BACK-Propagationto inner boundary failed"; + return false; + } auto posEnd = trk.getXYZGlo(); auto lInt = propagator->estimateLTIncrement(trk, posStart, posEnd); trk.getLTIntegralOut().addStep(lInt, trk.getP2Inv()); @@ -718,7 +723,12 @@ bool TRDGlobalTracking::refitTPCTRDTrack(TrackTRD& trk, float timeTRD, o2::globa if (pileUpOn) { // account pileup time uncertainty in Z errors trk.updateCov(timeZErr, o2::track::CovLabels::kSigZ2); } - + // if for some reason the track was overshoot over the inner field cage, bring it back w/o material correction and LTintegral update + if (trk.getX() < o2::constants::geom::XTPCInnerRef && + !propagator->PropagateToXBxByBz(trk, o2::constants::geom::XTPCInnerRef, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) { + LOG(debug) << "BACK-Propagationto inner boundary failed"; + return false; + } auto posEnd = trk.getXYZGlo(); auto lInt = propagator->estimateLTIncrement(trk, posStart, posEnd); trk.getLTIntegralOut().addStep(lInt, trk.getP2Inv()); From 1fbc2d01eb44dacd021cdc61584f45c732133e7c Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:41:19 +0100 Subject: [PATCH 0448/2205] DPL: move writers to plugin This will allow us at some point to remove the dependency on TTree in the framework, hopefully saving memory and allowing us to more easily customize the writing backend. --- Framework/AnalysisSupport/CMakeLists.txt | 1 + .../AnalysisSupport/src/AODWriterHelpers.cxx | 414 +++++++++++++++ .../AnalysisSupport/src/AODWriterHelpers.h | 28 + Framework/AnalysisSupport/src/Plugin.cxx | 17 + .../Core/include/Framework/AnalysisContext.h | 58 +++ .../Framework}/AnalysisSupportHelpers.h | 40 +- .../Core/include/Framework/ConfigContext.h | 15 +- .../include/Framework/runDataProcessing.h | 4 +- Framework/Core/src/AnalysisSupportHelpers.cxx | 484 ++++-------------- Framework/Core/src/ArrowSupport.cxx | 10 +- Framework/Core/src/ConfigContext.cxx | 3 + Framework/Core/src/WorkflowHelpers.cxx | 149 +----- Framework/Core/src/WorkflowHelpers.h | 4 +- Framework/Core/test/Mocking.h | 5 +- .../Core/test/benchmark_WorkflowHelpers.cxx | 3 +- Framework/Core/test/test_OverrideLabels.cxx | 3 +- .../TestWorkflows/src/o2TestHistograms.cxx | 5 +- 17 files changed, 690 insertions(+), 553 deletions(-) create mode 100644 Framework/AnalysisSupport/src/AODWriterHelpers.cxx create mode 100644 Framework/AnalysisSupport/src/AODWriterHelpers.h create mode 100644 Framework/Core/include/Framework/AnalysisContext.h rename Framework/Core/{src => include/Framework}/AnalysisSupportHelpers.h (71%) diff --git a/Framework/AnalysisSupport/CMakeLists.txt b/Framework/AnalysisSupport/CMakeLists.txt index eb5706817704b..5fb1282469711 100644 --- a/Framework/AnalysisSupport/CMakeLists.txt +++ b/Framework/AnalysisSupport/CMakeLists.txt @@ -20,6 +20,7 @@ o2_add_library(FrameworkAnalysisSupport SOURCES src/Plugin.cxx src/DataInputDirector.cxx src/AODJAlienReaderHelpers.cxx + src/AODWriterHelpers.cxx PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/src PUBLIC_LINK_LIBRARIES O2::Framework ${EXTRA_TARGETS} ROOT::TreePlayer) diff --git a/Framework/AnalysisSupport/src/AODWriterHelpers.cxx b/Framework/AnalysisSupport/src/AODWriterHelpers.cxx new file mode 100644 index 0000000000000..fa10d4661f537 --- /dev/null +++ b/Framework/AnalysisSupport/src/AODWriterHelpers.cxx @@ -0,0 +1,414 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/AnalysisContext.h" +#include "Framework/ConfigContext.h" +#include "Framework/ControlService.h" +#include "AODWriterHelpers.h" +#include "Framework/OutputObjHeader.h" +#include "Framework/EndOfStreamContext.h" +#include "Framework/ProcessingContext.h" +#include "Framework/InitContext.h" +#include "Framework/CallbackService.h" +#include "Framework/AnalysisSupportHelpers.h" +#include "Framework/TableConsumer.h" +#include "Framework/DataOutputDirector.h" +#include "Framework/TableTreeHelpers.h" + +#include +#include +#include +#include +#include +#include + +namespace o2::framework::writers +{ + +struct InputObjectRoute { + std::string name; + uint32_t uniqueId; + std::string directory; + uint32_t taskHash; + OutputObjHandlingPolicy policy; + OutputObjSourceType sourceType; +}; + +struct InputObject { + TClass* kind = nullptr; + void* obj = nullptr; + std::string name; + int count = -1; +}; + +const static std::unordered_map ROOTfileNames = {{OutputObjHandlingPolicy::AnalysisObject, "AnalysisResults.root"}, + {OutputObjHandlingPolicy::QAObject, "QAResults.root"}}; + +AlgorithmSpec AODWriterHelpers::getOutputTTreeWriter(ConfigContext const& ctx) +{ + auto& ac = ctx.services().get(); + auto dod = AnalysisSupportHelpers::getDataOutputDirector(ctx); + int compressionLevel = 505; + if (ctx.options().hasOption("aod-writer-compression")) { + compressionLevel = ctx.options().get("aod-writer-compression"); + } + return AlgorithmSpec{[dod, outputInputs = ac.outputsInputsAOD, compressionLevel](InitContext& ic) -> std::function { + LOGP(debug, "======== getGlobalAODSink::Init =========="); + + // find out if any table needs to be saved + bool hasOutputsToWrite = false; + for (auto& outobj : outputInputs) { + auto ds = dod->getDataOutputDescriptors(outobj); + if (ds.size() > 0) { + hasOutputsToWrite = true; + break; + } + } + + // if nothing needs to be saved then return a trivial functor + // this happens when nothing needs to be saved but there are dangling outputs + if (!hasOutputsToWrite) { + return [](ProcessingContext&) mutable -> void { + static bool once = false; + if (!once) { + LOG(info) << "No AODs to be saved."; + once = true; + } + }; + } + + // end of data functor is called at the end of the data stream + auto endofdatacb = [dod](EndOfStreamContext& context) { + dod->closeDataFiles(); + context.services().get().readyToQuit(QuitRequest::Me); + }; + + auto& callbacks = ic.services().get(); + callbacks.set(endofdatacb); + + // prepare map(startTime, tfNumber) + std::map tfNumbers; + std::map tfFilenames; + + std::vector aodMetaDataKeys; + std::vector aodMetaDataVals; + + // this functor is called once per time frame + return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals, compressionLevel](ProcessingContext& pc) mutable -> void { + LOGP(debug, "======== getGlobalAODSink::processing =========="); + LOGP(debug, " processing data set with {} entries", pc.inputs().size()); + + // return immediately if pc.inputs() is empty. This should never happen! + if (pc.inputs().size() == 0) { + LOGP(info, "No inputs available!"); + return; + } + + // update tfNumbers + uint64_t startTime = 0; + uint64_t tfNumber = 0; + auto ref = pc.inputs().get("tfn"); + if (ref.spec && ref.payload) { + startTime = DataRefUtils::getHeader(ref)->startTime; + tfNumber = pc.inputs().get("tfn"); + tfNumbers.insert(std::pair(startTime, tfNumber)); + } + // update tfFilenames + std::string aodInputFile; + auto ref2 = pc.inputs().get("tff"); + if (ref2.spec && ref2.payload) { + startTime = DataRefUtils::getHeader(ref2)->startTime; + aodInputFile = pc.inputs().get("tff"); + tfFilenames.insert(std::pair(startTime, aodInputFile)); + } + + // close all output files if one has reached size limit + dod->checkFileSizes(); + + // loop over the DataRefs which are contained in pc.inputs() + for (const auto& ref : pc.inputs()) { + if (!ref.spec) { + LOGP(debug, "Invalid input will be skipped!"); + continue; + } + + // get metadata + if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataKeys"))) { + aodMetaDataKeys = pc.inputs().get>(ref.spec->binding); + } + if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataVals"))) { + aodMetaDataVals = pc.inputs().get>(ref.spec->binding); + } + + // skip non-AOD refs + if (!DataSpecUtils::partialMatch(*ref.spec, writableAODOrigins)) { + continue; + } + startTime = DataRefUtils::getHeader(ref)->startTime; + + // does this need to be saved? + auto dh = DataRefUtils::getHeader(ref); + auto tableName = dh->dataDescription.as(); + auto ds = dod->getDataOutputDescriptors(*dh); + if (ds.empty()) { + continue; + } + + // get TF number from startTime + auto it = tfNumbers.find(startTime); + if (it != tfNumbers.end()) { + tfNumber = (it->second / dod->getNumberTimeFramesToMerge()) * dod->getNumberTimeFramesToMerge(); + } else { + LOGP(fatal, "No time frame number found for output with start time {}", startTime); + throw std::runtime_error("Processing is stopped!"); + } + // get aod input file from startTime + auto it2 = tfFilenames.find(startTime); + if (it2 != tfFilenames.end()) { + aodInputFile = it2->second; + } + + // get the TableConsumer and corresponding arrow table + auto msg = pc.inputs().get(ref.spec->binding); + if (msg.header == nullptr) { + LOGP(error, "No header for message {}:{}", ref.spec->binding, DataSpecUtils::describe(*ref.spec)); + continue; + } + auto s = pc.inputs().get(ref.spec->binding); + auto table = s->asArrowTable(); + if (!table->Validate().ok()) { + LOGP(warning, "The table \"{}\" is not valid and will not be saved!", tableName); + continue; + } + if (table->schema()->fields().empty()) { + LOGP(debug, "The table \"{}\" is empty but will be saved anyway!", tableName); + } + + // loop over all DataOutputDescriptors + // a table can be saved in multiple ways + // e.g. different selections of columns to different files + for (auto d : ds) { + auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile, compressionLevel); + auto treename = fileAndFolder.folderName + "/" + d->treename; + TableToTree ta2tr(table, + fileAndFolder.file, + treename.c_str()); + + // update metadata + if (fileAndFolder.file->FindObjectAny("metaData")) { + LOGF(debug, "Metadata: target file %s already has metadata, preserving it", fileAndFolder.file->GetName()); + } else if (!aodMetaDataKeys.empty() && !aodMetaDataVals.empty()) { + TMap aodMetaDataMap; + for (uint32_t imd = 0; imd < aodMetaDataKeys.size(); imd++) { + aodMetaDataMap.Add(new TObjString(aodMetaDataKeys[imd]), new TObjString(aodMetaDataVals[imd])); + } + fileAndFolder.file->WriteObject(&aodMetaDataMap, "metaData", "Overwrite"); + } + + if (!d->colnames.empty()) { + for (auto& cn : d->colnames) { + auto idx = table->schema()->GetFieldIndex(cn); + auto col = table->column(idx); + auto field = table->schema()->field(idx); + if (idx != -1) { + ta2tr.addBranch(col, field); + } + } + } else { + ta2tr.addAllBranches(); + } + ta2tr.process(); + } + } + }; + } + + }; +} + +AlgorithmSpec AODWriterHelpers::getOutputObjHistWriter(ConfigContext const& ctx) +{ + auto& ac = ctx.services().get(); + auto tskmap = ac.outTskMap; + auto objmap = ac.outObjHistMap; + + return AlgorithmSpec{[objmap, tskmap](InitContext& ic) -> std::function { + auto& callbacks = ic.services().get(); + auto inputObjects = std::make_shared>>(); + + static TFile* f[OutputObjHandlingPolicy::numPolicies]; + for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { + f[i] = nullptr; + } + + static std::string currentDirectory = ""; + static std::string currentFile = ""; + + auto endofdatacb = [inputObjects](EndOfStreamContext& context) { + LOG(debug) << "Writing merged objects and histograms to file"; + if (inputObjects->empty()) { + LOG(error) << "Output object map is empty!"; + context.services().get().readyToQuit(QuitRequest::Me); + return; + } + for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { + if (f[i] != nullptr) { + f[i]->Close(); + } + } + LOG(debug) << "All outputs merged in their respective target files"; + context.services().get().readyToQuit(QuitRequest::Me); + }; + + callbacks.set(endofdatacb); + return [inputObjects, objmap, tskmap](ProcessingContext& pc) mutable -> void { + auto const& ref = pc.inputs().get("x"); + if (!ref.header) { + LOG(error) << "Header not found"; + return; + } + if (!ref.payload) { + LOG(error) << "Payload not found"; + return; + } + auto datah = o2::header::get(ref.header); + if (!datah) { + LOG(error) << "No data header in stack"; + return; + } + + auto objh = o2::header::get(ref.header); + if (!objh) { + LOG(error) << "No output object header in stack"; + return; + } + + InputObject obj; + FairInputTBuffer tm(const_cast(ref.payload), static_cast(datah->payloadSize)); + tm.InitMap(); + obj.kind = tm.ReadClass(); + tm.SetBufferOffset(0); + tm.ResetMap(); + if (obj.kind == nullptr) { + LOG(error) << "Cannot read class info from buffer."; + return; + } + + auto policy = objh->mPolicy; + auto sourceType = objh->mSourceType; + auto hash = objh->mTaskHash; + + obj.obj = tm.ReadObjectAny(obj.kind); + auto* named = static_cast(obj.obj); + obj.name = named->GetName(); + auto hpos = std::find_if(tskmap.begin(), tskmap.end(), [&](auto&& x) { return x.id == hash; }); + if (hpos == tskmap.end()) { + LOG(error) << "No task found for hash " << hash; + return; + } + auto taskname = hpos->name; + auto opos = std::find_if(objmap.begin(), objmap.end(), [&](auto&& x) { return x.id == hash; }); + if (opos == objmap.end()) { + LOG(error) << "No object list found for task " << taskname << " (hash=" << hash << ")"; + return; + } + auto objects = opos->bindings; + if (std::find(objects.begin(), objects.end(), obj.name) == objects.end()) { + LOG(error) << "No object " << obj.name << " in map for task " << taskname; + return; + } + auto nameHash = runtime_hash(obj.name.c_str()); + InputObjectRoute key{obj.name, nameHash, taskname, hash, policy, sourceType}; + auto existing = std::find_if(inputObjects->begin(), inputObjects->end(), [&](auto&& x) { return (x.first.uniqueId == nameHash) && (x.first.taskHash == hash); }); + // If it's the first one, we just add it to the list. + if (existing == inputObjects->end()) { + obj.count = objh->mPipelineSize; + inputObjects->push_back(std::make_pair(key, obj)); + existing = inputObjects->end() - 1; + } else { + obj.count = existing->second.count; + // Otherwise, we merge it with the existing one. + auto merger = existing->second.kind->GetMerge(); + if (!merger) { + LOG(error) << "Already one unmergeable object found for " << obj.name; + return; + } + TList coll; + coll.Add(static_cast(obj.obj)); + merger(existing->second.obj, &coll, nullptr); + } + // We expect as many objects as the pipeline size, for + // a given object name and task hash. + existing->second.count -= 1; + + if (existing->second.count != 0) { + return; + } + // Write the object here. + auto route = existing->first; + auto entry = existing->second; + auto file = ROOTfileNames.find(route.policy); + if (file == ROOTfileNames.end()) { + return; + } + auto filename = file->second; + if (f[route.policy] == nullptr) { + f[route.policy] = TFile::Open(filename.c_str(), "RECREATE"); + } + auto nextDirectory = route.directory; + if ((nextDirectory != currentDirectory) || (filename != currentFile)) { + if (!f[route.policy]->FindKey(nextDirectory.c_str())) { + f[route.policy]->mkdir(nextDirectory.c_str()); + } + currentDirectory = nextDirectory; + currentFile = filename; + } + + // translate the list-structure created by the registry into a directory structure within the file + std::function writeListToFile; + writeListToFile = [&](TList* list, TDirectory* parentDir) { + TIter next(list); + TObject* object = nullptr; + while ((object = next())) { + if (object->InheritsFrom(TList::Class())) { + writeListToFile(static_cast(object), parentDir->mkdir(object->GetName(), object->GetName(), true)); + } else { + parentDir->WriteObjectAny(object, object->Class(), object->GetName()); + auto* written = list->Remove(object); + delete written; + } + } + }; + + TDirectory* currentDir = f[route.policy]->GetDirectory(currentDirectory.c_str()); + if (route.sourceType == OutputObjSourceType::HistogramRegistrySource) { + auto* outputList = static_cast(entry.obj); + outputList->SetOwner(false); + + // if registry should live in dedicated folder a TNamed object is appended to the list + if (outputList->Last() && outputList->Last()->IsA() == TNamed::Class()) { + delete outputList->Last(); + outputList->RemoveLast(); + currentDir = currentDir->mkdir(outputList->GetName(), outputList->GetName(), true); + } + + writeListToFile(outputList, currentDir); + outputList->SetOwner(); + delete outputList; + entry.obj = nullptr; + } else { + currentDir->WriteObjectAny(entry.obj, entry.kind, entry.name.c_str()); + delete (TObject*)entry.obj; + entry.obj = nullptr; + } + }; + }}; +} +} // namespace o2::framework::writers diff --git a/Framework/AnalysisSupport/src/AODWriterHelpers.h b/Framework/AnalysisSupport/src/AODWriterHelpers.h new file mode 100644 index 0000000000000..7ae59a5cf3b01 --- /dev/null +++ b/Framework/AnalysisSupport/src/AODWriterHelpers.h @@ -0,0 +1,28 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_FRAMEWORK_AODROOTWRITERHELPERS_H_ +#define O2_FRAMEWORK_AODROOTWRITERHELPERS_H_ + +#include "Framework/AlgorithmSpec.h" +#include + +namespace o2::framework::writers +{ + +struct AODWriterHelpers { + static AlgorithmSpec getOutputObjHistWriter(ConfigContext const& context); + static AlgorithmSpec getOutputTTreeWriter(ConfigContext const& context); +}; + +} // namespace o2::framework::writers + +#endif // O2_FRAMEWORK_AODROOTWRITERHELPERS_H_ diff --git a/Framework/AnalysisSupport/src/Plugin.cxx b/Framework/AnalysisSupport/src/Plugin.cxx index bba3499286e08..52435375d7e9e 100644 --- a/Framework/AnalysisSupport/src/Plugin.cxx +++ b/Framework/AnalysisSupport/src/Plugin.cxx @@ -16,6 +16,7 @@ #include "Framework/Capability.h" #include "Framework/Signpost.h" #include "AODJAlienReaderHelpers.h" +#include "AODWriterHelpers.h" #include #include #include @@ -33,6 +34,20 @@ struct ROOTFileReader : o2::framework::AlgorithmPlugin { } }; +struct ROOTObjWriter : o2::framework::AlgorithmPlugin { + o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const& config) override + { + return o2::framework::writers::AODWriterHelpers::getOutputObjHistWriter(config); + } +}; + +struct ROOTTTreeWriter : o2::framework::AlgorithmPlugin { + o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const& config) override + { + return o2::framework::writers::AODWriterHelpers::getOutputTTreeWriter(config); + } +}; + using namespace o2::framework; struct RunSummary : o2::framework::ServicePlugin { o2::framework::ServiceSpec* create() final @@ -211,6 +226,8 @@ struct DiscoverMetadataInAOD : o2::framework::ConfigDiscoveryPlugin { DEFINE_DPL_PLUGINS_BEGIN DEFINE_DPL_PLUGIN_INSTANCE(ROOTFileReader, CustomAlgorithm); +DEFINE_DPL_PLUGIN_INSTANCE(ROOTObjWriter, CustomAlgorithm); +DEFINE_DPL_PLUGIN_INSTANCE(ROOTTTreeWriter, CustomAlgorithm); DEFINE_DPL_PLUGIN_INSTANCE(RunSummary, CustomService); DEFINE_DPL_PLUGIN_INSTANCE(DiscoverMetadataInAOD, ConfigDiscovery); DEFINE_DPL_PLUGINS_END diff --git a/Framework/Core/include/Framework/AnalysisContext.h b/Framework/Core/include/Framework/AnalysisContext.h new file mode 100644 index 0000000000000..0f62f952d0aaa --- /dev/null +++ b/Framework/Core/include/Framework/AnalysisContext.h @@ -0,0 +1,58 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_ANALYSISCONTEXT_H_ +#define O2_FRAMEWORK_ANALYSISCONTEXT_H_ + +#include +#include "Framework/InputSpec.h" +#include "Framework/OutputSpec.h" + +namespace o2::framework +{ +class DataOutputDirector; + +struct OutputTaskInfo { + uint32_t id; + std::string name; +}; + +struct OutputObjectInfo { + uint32_t id; + std::vector bindings; +}; + +// +struct AnalysisContext { + std::vector requestedAODs; + std::vector providedAODs; + std::vector requestedDYNs; + std::vector providedDYNs; + std::vector requestedIDXs; + std::vector providedOutputObjHist; + std::vector spawnerInputs; + + // Needed to created the hist writer + std::vector outTskMap; + std::vector outObjHistMap; + + // Needed to create the output director + std::vector outputsInputs; + std::vector isDangling; + + // Needed to create the aod writer + std::vector outputsInputsAOD; +}; +} // namespace o2::framework + +extern template class std::vector; +extern template class std::vector; + +#endif // O2_FRAMEWORK_ANALYSISCONTEXT_H_ diff --git a/Framework/Core/src/AnalysisSupportHelpers.h b/Framework/Core/include/Framework/AnalysisSupportHelpers.h similarity index 71% rename from Framework/Core/src/AnalysisSupportHelpers.h rename to Framework/Core/include/Framework/AnalysisSupportHelpers.h index ba5bcedb4bc67..4ae601dc9e4a2 100644 --- a/Framework/Core/src/AnalysisSupportHelpers.h +++ b/Framework/Core/include/Framework/AnalysisSupportHelpers.h @@ -14,6 +14,7 @@ #include "Framework/OutputSpec.h" #include "Framework/InputSpec.h" #include "Framework/DataProcessorSpec.h" +#include "Framework/AnalysisContext.h" #include "Headers/DataHeader.h" #include @@ -24,36 +25,7 @@ static constexpr std::array extendedAODOrigins{header::Da static constexpr std::array writableAODOrigins{header::DataOrigin{"AOD"}, header::DataOrigin{"AOD1"}, header::DataOrigin{"AOD2"}, header::DataOrigin{"DYN"}}; class DataOutputDirector; - -struct OutputTaskInfo { - uint32_t id; - std::string name; -}; - -struct OutputObjectInfo { - uint32_t id; - std::vector bindings; -}; -} // namespace o2::framework - -extern template class std::vector; -extern template class std::vector; - -namespace o2::framework -{ -// -struct AnalysisContext { - std::vector requestedAODs; - std::vector providedAODs; - std::vector requestedDYNs; - std::vector providedDYNs; - std::vector requestedIDXs; - std::vector providedOutputObjHist; - std::vector spawnerInputs; - - std::vector outTskMap; - std::vector outObjHistMap; -}; +class ConfigContext; // Helper class to be moved in the AnalysisSupport plugin at some point struct AnalysisSupportHelpers { @@ -74,11 +46,11 @@ struct AnalysisSupportHelpers { /// Match all inputs of kind ATSK and write them to a ROOT file, /// one root file per originating task. - static DataProcessorSpec getOutputObjHistSink(std::vector const& objmap, - std::vector const& tskmap); + static DataProcessorSpec getOutputObjHistSink(ConfigContext const&); /// writes inputs of kind AOD to file - static DataProcessorSpec getGlobalAODSink(std::shared_ptr dod, - std::vector const& outputInputs, int compression); + static DataProcessorSpec getGlobalAODSink(ConfigContext const&); + /// Get the data director + static std::shared_ptr getDataOutputDirector(ConfigContext const& ctx); }; }; // namespace o2::framework diff --git a/Framework/Core/include/Framework/ConfigContext.h b/Framework/Core/include/Framework/ConfigContext.h index 5790699fe68bb..87259f0519915 100644 --- a/Framework/Core/include/Framework/ConfigContext.h +++ b/Framework/Core/include/Framework/ConfigContext.h @@ -8,11 +8,11 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef FRAMEWORK_CONFIG_CONTEXT_H -#define FRAMEWORK_CONFIG_CONTEXT_H +#ifndef O2_FRAMEWORK_CONFIG_CONTEXT_H_ +#define O2_FRAMEWORK_CONFIG_CONTEXT_H_ #include "Framework/ConfigParamRegistry.h" -#include "Framework/ServiceRegistry.h" +#include "Framework/ServiceRegistryRef.h" namespace o2::framework { @@ -23,9 +23,10 @@ namespace o2::framework class ConfigContext { public: - ConfigContext(ConfigParamRegistry& options, int argc, char** argv) : mOptions{options}, mArgc{argc}, mArgv{argv} {} + ConfigContext(ConfigParamRegistry& options, ServiceRegistryRef services, int argc, char** argv); [[nodiscard]] ConfigParamRegistry& options() const { return mOptions; } + [[nodiscard]] ServiceRegistryRef services() const { return mServices; } [[nodiscard]] bool helpOnCommandLine() const; @@ -34,11 +35,13 @@ class ConfigContext private: ConfigParamRegistry& mOptions; + + ServiceRegistryRef mServices; // additionaly keep information about the original command line int mArgc = 0; char** mArgv = nullptr; }; -} // namespace o2 +} // namespace o2::framework -#endif +#endif // O2_FRAMEWORK_CONFIG_CONTEXT_H_ diff --git a/Framework/Core/include/Framework/runDataProcessing.h b/Framework/Core/include/Framework/runDataProcessing.h index eee4c4b6583d3..8293bf0cf7039 100644 --- a/Framework/Core/include/Framework/runDataProcessing.h +++ b/Framework/Core/include/Framework/runDataProcessing.h @@ -30,6 +30,7 @@ #include "Framework/CheckTypes.h" #include "Framework/StructToTuple.h" #include "Framework/ConfigParamDiscovery.h" +#include "ServiceRegistryRef.h" #include namespace o2::framework @@ -198,7 +199,8 @@ int mainNoCatch(int argc, char** argv) workflowOptions.push_back(extra); } - ConfigContext configContext(workflowOptionsRegistry, argc, argv); + ServiceRegistry configRegistry; + ConfigContext configContext(workflowOptionsRegistry, ServiceRegistryRef{configRegistry}, argc, argv); o2::framework::WorkflowSpec specs = defineDataProcessing(configContext); overrideCloning(configContext, specs); overridePipeline(configContext, specs); diff --git a/Framework/Core/src/AnalysisSupportHelpers.cxx b/Framework/Core/src/AnalysisSupportHelpers.cxx index e949f27a6eed6..eb17566fd6d31 100644 --- a/Framework/Core/src/AnalysisSupportHelpers.cxx +++ b/Framework/Core/src/AnalysisSupportHelpers.cxx @@ -9,18 +9,16 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "AnalysisSupportHelpers.h" +#include "Framework/AnalysisSupportHelpers.h" #include "Framework/DataOutputDirector.h" #include "Framework/OutputObjHeader.h" #include "Framework/ControlService.h" #include "Framework/EndOfStreamContext.h" #include "Framework/DeviceSpec.h" #include "Framework/TableTreeHelpers.h" - -#include "TFile.h" -#include "TTree.h" -#include "TMap.h" -#include "TObjString.h" +#include "Framework/PluginManager.h" +#include "Framework/ConfigContext.h" +#include "WorkflowHelpers.h" template class std::vector; template class std::vector; @@ -28,21 +26,105 @@ template class std::vector; namespace o2::framework { -struct InputObjectRoute { - std::string name; - uint32_t uniqueId; - std::string directory; - uint32_t taskHash; - OutputObjHandlingPolicy policy; - OutputObjSourceType sourceType; -}; +std::shared_ptr AnalysisSupportHelpers::getDataOutputDirector(ConfigContext const& ctx) +{ + auto const& options = ctx.options(); + auto const& OutputsInputs = ctx.services().get().outputsInputs; + auto const& isDangling = ctx.services().get().isDangling; + + std::shared_ptr dod = std::make_shared(); + + // analyze options and take actions accordingly + // default values + std::string rdn, resdir("./"); + std::string fnb, fnbase("AnalysisResults_trees"); + float mfs, maxfilesize(-1.); + std::string fmo, filemode("RECREATE"); + int ntfm, ntfmerge = 1; + + // values from json + if (options.isSet("aod-writer-json")) { + auto fnjson = options.get("aod-writer-json"); + if (!fnjson.empty()) { + std::tie(rdn, fnb, fmo, mfs, ntfm) = dod->readJson(fnjson); + if (!rdn.empty()) { + resdir = rdn; + } + if (!fnb.empty()) { + fnbase = fnb; + } + if (!fmo.empty()) { + filemode = fmo; + } + if (mfs > 0.) { + maxfilesize = mfs; + } + if (ntfm > 0) { + ntfmerge = ntfm; + } + } + } + + // values from command line options, information from json is overwritten + if (options.isSet("aod-writer-resdir")) { + rdn = options.get("aod-writer-resdir"); + if (!rdn.empty()) { + resdir = rdn; + } + } + if (options.isSet("aod-writer-resfile")) { + fnb = options.get("aod-writer-resfile"); + if (!fnb.empty()) { + fnbase = fnb; + } + } + if (options.isSet("aod-writer-resmode")) { + fmo = options.get("aod-writer-resmode"); + if (!fmo.empty()) { + filemode = fmo; + } + } + if (options.isSet("aod-writer-maxfilesize")) { + mfs = options.get("aod-writer-maxfilesize"); + if (mfs > 0) { + maxfilesize = mfs; + } + } + if (options.isSet("aod-writer-ntfmerge")) { + ntfm = options.get("aod-writer-ntfmerge"); + if (ntfm > 0) { + ntfmerge = ntfm; + } + } + // parse the keepString + if (options.isSet("aod-writer-keep")) { + auto keepString = options.get("aod-writer-keep"); + if (!keepString.empty()) { + dod->reset(); + std::string d("dangling"); + if (d.find(keepString) == 0) { + // use the dangling outputs + std::vector danglingOutputs; + for (auto ii = 0u; ii < OutputsInputs.size(); ii++) { + if (DataSpecUtils::partialMatch(OutputsInputs[ii], writableAODOrigins) && isDangling[ii]) { + danglingOutputs.emplace_back(OutputsInputs[ii]); + } + } + dod->readSpecs(danglingOutputs); + } else { + // use the keep string + dod->readString(keepString); + } + } + } + dod->setResultDir(resdir); + dod->setFilenameBase(fnbase); + dod->setFileMode(filemode); + dod->setMaximumFileSize(maxfilesize); + dod->setNumberTimeFramesToMerge(ntfmerge); -struct InputObject { - TClass* kind = nullptr; - void* obj = nullptr; - std::string name; - int count = -1; -}; + return dod; +} void AnalysisSupportHelpers::addMissingOutputsToReader(std::vector const& providedOutputs, std::vector const& requestedInputs, @@ -125,191 +207,16 @@ void AnalysisSupportHelpers::addMissingOutputsToBuilder(std::vector c } } -const static std::unordered_map ROOTfileNames = {{OutputObjHandlingPolicy::AnalysisObject, "AnalysisResults.root"}, - {OutputObjHandlingPolicy::QAObject, "QAResults.root"}}; - // ============================================================================= -DataProcessorSpec AnalysisSupportHelpers::getOutputObjHistSink(std::vector const& objmap, std::vector const& tskmap) +DataProcessorSpec AnalysisSupportHelpers::getOutputObjHistSink(ConfigContext const& ctx) { - auto writerFunction = [objmap, tskmap](InitContext& ic) -> std::function { - auto& callbacks = ic.services().get(); - auto inputObjects = std::make_shared>>(); - - static TFile* f[OutputObjHandlingPolicy::numPolicies]; - for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { - f[i] = nullptr; - } - - static std::string currentDirectory = ""; - static std::string currentFile = ""; - - auto endofdatacb = [inputObjects](EndOfStreamContext& context) { - LOG(debug) << "Writing merged objects and histograms to file"; - if (inputObjects->empty()) { - LOG(error) << "Output object map is empty!"; - context.services().get().readyToQuit(QuitRequest::Me); - return; - } - for (auto i = 0u; i < OutputObjHandlingPolicy::numPolicies; ++i) { - if (f[i] != nullptr) { - f[i]->Close(); - } - } - LOG(debug) << "All outputs merged in their respective target files"; - context.services().get().readyToQuit(QuitRequest::Me); - }; - - callbacks.set(endofdatacb); - return [inputObjects, objmap, tskmap](ProcessingContext& pc) mutable -> void { - auto const& ref = pc.inputs().get("x"); - if (!ref.header) { - LOG(error) << "Header not found"; - return; - } - if (!ref.payload) { - LOG(error) << "Payload not found"; - return; - } - auto datah = o2::header::get(ref.header); - if (!datah) { - LOG(error) << "No data header in stack"; - return; - } - - auto objh = o2::header::get(ref.header); - if (!objh) { - LOG(error) << "No output object header in stack"; - return; - } - - InputObject obj; - FairInputTBuffer tm(const_cast(ref.payload), static_cast(datah->payloadSize)); - tm.InitMap(); - obj.kind = tm.ReadClass(); - tm.SetBufferOffset(0); - tm.ResetMap(); - if (obj.kind == nullptr) { - LOG(error) << "Cannot read class info from buffer."; - return; - } - - auto policy = objh->mPolicy; - auto sourceType = objh->mSourceType; - auto hash = objh->mTaskHash; - - obj.obj = tm.ReadObjectAny(obj.kind); - auto* named = static_cast(obj.obj); - obj.name = named->GetName(); - auto hpos = std::find_if(tskmap.begin(), tskmap.end(), [&](auto&& x) { return x.id == hash; }); - if (hpos == tskmap.end()) { - LOG(error) << "No task found for hash " << hash; - return; - } - auto taskname = hpos->name; - auto opos = std::find_if(objmap.begin(), objmap.end(), [&](auto&& x) { return x.id == hash; }); - if (opos == objmap.end()) { - LOG(error) << "No object list found for task " << taskname << " (hash=" << hash << ")"; - return; - } - auto objects = opos->bindings; - if (std::find(objects.begin(), objects.end(), obj.name) == objects.end()) { - LOG(error) << "No object " << obj.name << " in map for task " << taskname; - return; - } - auto nameHash = runtime_hash(obj.name.c_str()); - InputObjectRoute key{obj.name, nameHash, taskname, hash, policy, sourceType}; - auto existing = std::find_if(inputObjects->begin(), inputObjects->end(), [&](auto&& x) { return (x.first.uniqueId == nameHash) && (x.first.taskHash == hash); }); - // If it's the first one, we just add it to the list. - if (existing == inputObjects->end()) { - obj.count = objh->mPipelineSize; - inputObjects->push_back(std::make_pair(key, obj)); - existing = inputObjects->end() - 1; - } else { - obj.count = existing->second.count; - // Otherwise, we merge it with the existing one. - auto merger = existing->second.kind->GetMerge(); - if (!merger) { - LOG(error) << "Already one unmergeable object found for " << obj.name; - return; - } - TList coll; - coll.Add(static_cast(obj.obj)); - merger(existing->second.obj, &coll, nullptr); - } - // We expect as many objects as the pipeline size, for - // a given object name and task hash. - existing->second.count -= 1; - - if (existing->second.count != 0) { - return; - } - // Write the object here. - auto route = existing->first; - auto entry = existing->second; - auto file = ROOTfileNames.find(route.policy); - if (file == ROOTfileNames.end()) { - return; - } - auto filename = file->second; - if (f[route.policy] == nullptr) { - f[route.policy] = TFile::Open(filename.c_str(), "RECREATE"); - } - auto nextDirectory = route.directory; - if ((nextDirectory != currentDirectory) || (filename != currentFile)) { - if (!f[route.policy]->FindKey(nextDirectory.c_str())) { - f[route.policy]->mkdir(nextDirectory.c_str()); - } - currentDirectory = nextDirectory; - currentFile = filename; - } - - // translate the list-structure created by the registry into a directory structure within the file - std::function writeListToFile; - writeListToFile = [&](TList* list, TDirectory* parentDir) { - TIter next(list); - TObject* object = nullptr; - while ((object = next())) { - if (object->InheritsFrom(TList::Class())) { - writeListToFile(static_cast(object), parentDir->mkdir(object->GetName(), object->GetName(), true)); - } else { - parentDir->WriteObjectAny(object, object->Class(), object->GetName()); - auto* written = list->Remove(object); - delete written; - } - } - }; - - TDirectory* currentDir = f[route.policy]->GetDirectory(currentDirectory.c_str()); - if (route.sourceType == OutputObjSourceType::HistogramRegistrySource) { - auto* outputList = static_cast(entry.obj); - outputList->SetOwner(false); - - // if registry should live in dedicated folder a TNamed object is appended to the list - if (outputList->Last() && outputList->Last()->IsA() == TNamed::Class()) { - delete outputList->Last(); - outputList->RemoveLast(); - currentDir = currentDir->mkdir(outputList->GetName(), outputList->GetName(), true); - } - - writeListToFile(outputList, currentDir); - outputList->SetOwner(); - delete outputList; - entry.obj = nullptr; - } else { - currentDir->WriteObjectAny(entry.obj, entry.kind, entry.name.c_str()); - delete (TObject*)entry.obj; - entry.obj = nullptr; - } - }; - }; - - char const* name = "internal-dpl-aod-global-analysis-file-sink"; // Lifetime is sporadic because we do not ask each analysis task to send its // results every timeframe. DataProcessorSpec spec{ - .name = name, + .name = "internal-dpl-aod-global-analysis-file-sink", .inputs = {InputSpec("x", DataSpecUtils::dataDescriptorMatcherFrom(header::DataOrigin{"ATSK"}), Lifetime::Sporadic)}, - .algorithm = {writerFunction}, + .outputs = {}, + .algorithm = PluginManager::loadAlgorithmFromPlugin("O2FrameworkAnalysisSupport", "ROOTObjWriter", ctx), }; return spec; @@ -317,188 +224,17 @@ DataProcessorSpec AnalysisSupportHelpers::getOutputObjHistSink(std::vector dod, - std::vector const& outputInputs, int compressionLevel) + AnalysisSupportHelpers::getGlobalAODSink(ConfigContext const& ctx) { - - auto writerFunction = [dod, outputInputs, compressionLevel](InitContext& ic) -> std::function { - LOGP(debug, "======== getGlobalAODSink::Init =========="); - - // find out if any table needs to be saved - bool hasOutputsToWrite = false; - for (auto& outobj : outputInputs) { - auto ds = dod->getDataOutputDescriptors(outobj); - if (ds.size() > 0) { - hasOutputsToWrite = true; - break; - } - } - - // if nothing needs to be saved then return a trivial functor - // this happens when nothing needs to be saved but there are dangling outputs - if (!hasOutputsToWrite) { - return [](ProcessingContext&) mutable -> void { - static bool once = false; - if (!once) { - LOG(info) << "No AODs to be saved."; - once = true; - } - }; - } - - // end of data functor is called at the end of the data stream - auto endofdatacb = [dod](EndOfStreamContext& context) { - dod->closeDataFiles(); - context.services().get().readyToQuit(QuitRequest::Me); - }; - - auto& callbacks = ic.services().get(); - callbacks.set(endofdatacb); - - // prepare map(startTime, tfNumber) - std::map tfNumbers; - std::map tfFilenames; - - std::vector aodMetaDataKeys; - std::vector aodMetaDataVals; - - // this functor is called once per time frame - return [dod, tfNumbers, tfFilenames, aodMetaDataKeys, aodMetaDataVals, compressionLevel](ProcessingContext& pc) mutable -> void { - LOGP(debug, "======== getGlobalAODSink::processing =========="); - LOGP(debug, " processing data set with {} entries", pc.inputs().size()); - - // return immediately if pc.inputs() is empty. This should never happen! - if (pc.inputs().size() == 0) { - LOGP(info, "No inputs available!"); - return; - } - - // update tfNumbers - uint64_t startTime = 0; - uint64_t tfNumber = 0; - auto ref = pc.inputs().get("tfn"); - if (ref.spec && ref.payload) { - startTime = DataRefUtils::getHeader(ref)->startTime; - tfNumber = pc.inputs().get("tfn"); - tfNumbers.insert(std::pair(startTime, tfNumber)); - } - // update tfFilenames - std::string aodInputFile; - auto ref2 = pc.inputs().get("tff"); - if (ref2.spec && ref2.payload) { - startTime = DataRefUtils::getHeader(ref2)->startTime; - aodInputFile = pc.inputs().get("tff"); - tfFilenames.insert(std::pair(startTime, aodInputFile)); - } - - // close all output files if one has reached size limit - dod->checkFileSizes(); - - // loop over the DataRefs which are contained in pc.inputs() - for (const auto& ref : pc.inputs()) { - if (!ref.spec) { - LOGP(debug, "Invalid input will be skipped!"); - continue; - } - - // get metadata - if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataKeys"))) { - aodMetaDataKeys = pc.inputs().get>(ref.spec->binding); - } - if (DataSpecUtils::partialMatch(*ref.spec, header::DataDescription("AODMetadataVals"))) { - aodMetaDataVals = pc.inputs().get>(ref.spec->binding); - } - - // skip non-AOD refs - if (!DataSpecUtils::partialMatch(*ref.spec, writableAODOrigins)) { - continue; - } - startTime = DataRefUtils::getHeader(ref)->startTime; - - // does this need to be saved? - auto dh = DataRefUtils::getHeader(ref); - auto tableName = dh->dataDescription.as(); - auto ds = dod->getDataOutputDescriptors(*dh); - if (ds.empty()) { - continue; - } - - // get TF number from startTime - auto it = tfNumbers.find(startTime); - if (it != tfNumbers.end()) { - tfNumber = (it->second / dod->getNumberTimeFramesToMerge()) * dod->getNumberTimeFramesToMerge(); - } else { - LOGP(fatal, "No time frame number found for output with start time {}", startTime); - throw std::runtime_error("Processing is stopped!"); - } - // get aod input file from startTime - auto it2 = tfFilenames.find(startTime); - if (it2 != tfFilenames.end()) { - aodInputFile = it2->second; - } - - // get the TableConsumer and corresponding arrow table - auto msg = pc.inputs().get(ref.spec->binding); - if (msg.header == nullptr) { - LOGP(error, "No header for message {}:{}", ref.spec->binding, DataSpecUtils::describe(*ref.spec)); - continue; - } - auto s = pc.inputs().get(ref.spec->binding); - auto table = s->asArrowTable(); - if (!table->Validate().ok()) { - LOGP(warning, "The table \"{}\" is not valid and will not be saved!", tableName); - continue; - } - if (table->schema()->fields().empty()) { - LOGP(debug, "The table \"{}\" is empty but will be saved anyway!", tableName); - } - - // loop over all DataOutputDescriptors - // a table can be saved in multiple ways - // e.g. different selections of columns to different files - for (auto d : ds) { - auto fileAndFolder = dod->getFileFolder(d, tfNumber, aodInputFile, compressionLevel); - auto treename = fileAndFolder.folderName + "/" + d->treename; - TableToTree ta2tr(table, - fileAndFolder.file, - treename.c_str()); - - // update metadata - if (fileAndFolder.file->FindObjectAny("metaData")) { - LOGF(debug, "Metadata: target file %s already has metadata, preserving it", fileAndFolder.file->GetName()); - } else if (!aodMetaDataKeys.empty() && !aodMetaDataVals.empty()) { - TMap aodMetaDataMap; - for (uint32_t imd = 0; imd < aodMetaDataKeys.size(); imd++) { - aodMetaDataMap.Add(new TObjString(aodMetaDataKeys[imd]), new TObjString(aodMetaDataVals[imd])); - } - fileAndFolder.file->WriteObject(&aodMetaDataMap, "metaData", "Overwrite"); - } - - if (!d->colnames.empty()) { - for (auto& cn : d->colnames) { - auto idx = table->schema()->GetFieldIndex(cn); - auto col = table->column(idx); - auto field = table->schema()->field(idx); - if (idx != -1) { - ta2tr.addBranch(col, field); - } - } - } else { - ta2tr.addAllBranches(); - } - ta2tr.process(); - } - } - }; - }; // end of writerFunction + auto& ac = ctx.services().get(); // the command line options relevant for the writer are global // see runDataProcessing.h DataProcessorSpec spec{ .name = "internal-dpl-aod-writer", - .inputs = outputInputs, + .inputs = ac.outputsInputsAOD, .outputs = {}, - .algorithm = AlgorithmSpec{writerFunction}, + .algorithm = PluginManager::loadAlgorithmFromPlugin("O2FrameworkAnalysisSupport", "ROOTTTreeWriter", ctx), }; return spec; diff --git a/Framework/Core/src/ArrowSupport.cxx b/Framework/Core/src/ArrowSupport.cxx index 1a656e4d60080..230d708b47dc7 100644 --- a/Framework/Core/src/ArrowSupport.cxx +++ b/Framework/Core/src/ArrowSupport.cxx @@ -30,7 +30,7 @@ #include "Framework/ServiceMetricsInfo.h" #include "WorkflowHelpers.h" #include "Framework/WorkflowSpecNode.h" -#include "AnalysisSupportHelpers.h" +#include "Framework/AnalysisSupportHelpers.h" #include "CommonMessageBackendsHelpers.h" #include @@ -516,7 +516,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() auto [outputsInputs, isDangling] = WorkflowHelpers::analyzeOutputs(workflow); // create DataOutputDescriptor - std::shared_ptr dod = WorkflowHelpers::getDataOutputDirector(ctx.options(), outputsInputs, isDangling); + std::shared_ptr dod = AnalysisSupportHelpers::getDataOutputDirector(ctx); // select outputs of type AOD which need to be saved // ATTENTION: if there are dangling outputs the getGlobalAODSink @@ -537,11 +537,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // add TFNumber and TFFilename as input to the writer outputsInputsAOD.emplace_back("tfn", "TFN", "TFNumber"); outputsInputsAOD.emplace_back("tff", "TFF", "TFFilename"); - int compression = 505; - if (ctx.options().hasOption("aod-writer-compression")) { - compression = ctx.options().get("aod-writer-compression"); - } - workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD, compression)); + workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(ctx)); } // Move the dummy sink at the end, if needed for (size_t i = 0; i < workflow.size(); ++i) { diff --git a/Framework/Core/src/ConfigContext.cxx b/Framework/Core/src/ConfigContext.cxx index 726332e1d0ae3..9b121b1884998 100644 --- a/Framework/Core/src/ConfigContext.cxx +++ b/Framework/Core/src/ConfigContext.cxx @@ -14,6 +14,9 @@ namespace o2::framework { +ConfigContext::ConfigContext(ConfigParamRegistry& options, ServiceRegistryRef services, int argc, char** argv) + : mOptions{options}, mServices{services}, mArgc{argc}, mArgv{argv} {} + bool ConfigContext::helpOnCommandLine() const { bool helpasked = false; diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index da9a135dc5eb8..3782c48e81c56 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. #include "WorkflowHelpers.h" -#include "AnalysisSupportHelpers.h" +#include "Framework/AnalysisSupportHelpers.h" #include "Framework/AlgorithmSpec.h" #include "Framework/AODReaderHelpers.h" #include "Framework/ConfigParamSpec.h" @@ -153,7 +153,7 @@ int defaultConditionQueryRateMultiplier() return getenv("DPL_CONDITION_QUERY_RATE_MULTIPLIER") ? std::stoi(getenv("DPL_CONDITION_QUERY_RATE_MULTIPLIER")) : 1; } -void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext const& ctx) +void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext& ctx) { auto fakeCallback = AlgorithmSpec{[](InitContext& ic) { LOG(info) << "This is not a real device, merely a placeholder for external inputs"; @@ -241,7 +241,9 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext aodReader.options.emplace_back(ConfigParamSpec{"channel-config", VariantType::String, rateLimitingChannelConfigInput, {"how many timeframes can be in flight at the same time"}}); } - AnalysisContext ac; + ctx.services().registerService(ServiceRegistryHelpers::handleForService(new AnalysisContext)); + auto& ac = ctx.services().get(); + std::vector requestedCCDBs; std::vector providedCCDBs; @@ -573,7 +575,7 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // This is to inject a file sink so that any dangling ATSK object is written // to a ROOT file. if (ac.providedOutputObjHist.empty() == false) { - auto rootSink = AnalysisSupportHelpers::getOutputObjHistSink(ac.outObjHistMap, ac.outTskMap); + auto rootSink = AnalysisSupportHelpers::getOutputObjHistSink(ctx); extraSpecs.push_back(rootSink); } @@ -581,41 +583,38 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext extraSpecs.clear(); /// Analyze all ouputs - auto [outputsInputs, isDangling] = analyzeOutputs(workflow); + auto [outputsInputsTmp, isDanglingTmp] = analyzeOutputs(workflow); + ac.isDangling = isDanglingTmp; + ac.outputsInputs = outputsInputsTmp; // create DataOutputDescriptor - std::shared_ptr dod = getDataOutputDirector(ctx.options(), outputsInputs, isDangling); + std::shared_ptr dod = AnalysisSupportHelpers::getDataOutputDirector(ctx); // select outputs of type AOD which need to be saved // ATTENTION: if there are dangling outputs the getGlobalAODSink // has to be created in any case! - std::vector outputsInputsAOD; - for (auto ii = 0u; ii < outputsInputs.size(); ii++) { - if (DataSpecUtils::partialMatch(outputsInputs[ii], extendedAODOrigins)) { - auto ds = dod->getDataOutputDescriptors(outputsInputs[ii]); - if (ds.size() > 0 || isDangling[ii]) { - outputsInputsAOD.emplace_back(outputsInputs[ii]); + for (auto ii = 0u; ii < ac.outputsInputs.size(); ii++) { + if (DataSpecUtils::partialMatch(ac.outputsInputs[ii], extendedAODOrigins)) { + auto ds = dod->getDataOutputDescriptors(ac.outputsInputs[ii]); + if (ds.size() > 0 || ac.isDangling[ii]) { + ac.outputsInputsAOD.emplace_back(ac.outputsInputs[ii]); } } } // file sink for any AOD output - if (outputsInputsAOD.size() > 0) { + if (ac.outputsInputsAOD.size() > 0) { // add TFNumber and TFFilename as input to the writer - outputsInputsAOD.emplace_back(InputSpec{"tfn", "TFN", "TFNumber"}); - outputsInputsAOD.emplace_back(InputSpec{"tff", "TFF", "TFFilename"}); - int compressionLevel = 505; - if (ctx.options().hasOption("aod-writer-compression")) { - compressionLevel = ctx.options().get("aod-writer-compression"); - } - auto fileSink = AnalysisSupportHelpers::getGlobalAODSink(dod, outputsInputsAOD, compressionLevel); + ac.outputsInputsAOD.emplace_back(InputSpec{"tfn", "TFN", "TFNumber"}); + ac.outputsInputsAOD.emplace_back(InputSpec{"tff", "TFF", "TFFilename"}); + auto fileSink = AnalysisSupportHelpers::getGlobalAODSink(ctx); extraSpecs.push_back(fileSink); - auto it = std::find_if(outputsInputs.begin(), outputsInputs.end(), [](InputSpec& spec) -> bool { + auto it = std::find_if(ac.outputsInputs.begin(), ac.outputsInputs.end(), [](InputSpec& spec) -> bool { return DataSpecUtils::partialMatch(spec, o2::header::DataOrigin("TFN")); }); - size_t ii = std::distance(outputsInputs.begin(), it); - isDangling[ii] = false; + size_t ii = std::distance(ac.outputsInputs.begin(), it); + ac.isDangling[ii] = false; } workflow.insert(workflow.end(), extraSpecs.begin(), extraSpecs.end()); @@ -623,20 +622,20 @@ void WorkflowHelpers::injectServiceDevices(WorkflowSpec& workflow, ConfigContext // Select dangling outputs which are not of type AOD std::vector redirectedOutputsInputs; - for (auto ii = 0u; ii < outputsInputs.size(); ii++) { + for (auto ii = 0u; ii < ac.outputsInputs.size(); ii++) { if (ctx.options().get("forwarding-policy") == "none") { continue; } // We forward to the output proxy all the inputs only if they are dangling // or if the forwarding policy is "proxy". - if (!isDangling[ii] && (ctx.options().get("forwarding-policy") != "all")) { + if (!ac.isDangling[ii] && (ctx.options().get("forwarding-policy") != "all")) { continue; } // AODs are skipped in any case. - if (DataSpecUtils::partialMatch(outputsInputs[ii], extendedAODOrigins)) { + if (DataSpecUtils::partialMatch(ac.outputsInputs[ii], extendedAODOrigins)) { continue; } - redirectedOutputsInputs.emplace_back(outputsInputs[ii]); + redirectedOutputsInputs.emplace_back(ac.outputsInputs[ii]); } std::vector unmatched; @@ -985,102 +984,6 @@ struct DataMatcherId { size_t id; }; -std::shared_ptr WorkflowHelpers::getDataOutputDirector(ConfigParamRegistry const& options, std::vector const& OutputsInputs, std::vector const& isDangling) -{ - std::shared_ptr dod = std::make_shared(); - - // analyze options and take actions accordingly - // default values - std::string rdn, resdir("./"); - std::string fnb, fnbase("AnalysisResults_trees"); - float mfs, maxfilesize(-1.); - std::string fmo, filemode("RECREATE"); - int ntfm, ntfmerge = 1; - - // values from json - if (options.isSet("aod-writer-json")) { - auto fnjson = options.get("aod-writer-json"); - if (!fnjson.empty()) { - std::tie(rdn, fnb, fmo, mfs, ntfm) = dod->readJson(fnjson); - if (!rdn.empty()) { - resdir = rdn; - } - if (!fnb.empty()) { - fnbase = fnb; - } - if (!fmo.empty()) { - filemode = fmo; - } - if (mfs > 0.) { - maxfilesize = mfs; - } - if (ntfm > 0) { - ntfmerge = ntfm; - } - } - } - - // values from command line options, information from json is overwritten - if (options.isSet("aod-writer-resdir")) { - rdn = options.get("aod-writer-resdir"); - if (!rdn.empty()) { - resdir = rdn; - } - } - if (options.isSet("aod-writer-resfile")) { - fnb = options.get("aod-writer-resfile"); - if (!fnb.empty()) { - fnbase = fnb; - } - } - if (options.isSet("aod-writer-resmode")) { - fmo = options.get("aod-writer-resmode"); - if (!fmo.empty()) { - filemode = fmo; - } - } - if (options.isSet("aod-writer-maxfilesize")) { - mfs = options.get("aod-writer-maxfilesize"); - if (mfs > 0) { - maxfilesize = mfs; - } - } - if (options.isSet("aod-writer-ntfmerge")) { - ntfm = options.get("aod-writer-ntfmerge"); - if (ntfm > 0) { - ntfmerge = ntfm; - } - } - // parse the keepString - if (options.isSet("aod-writer-keep")) { - auto keepString = options.get("aod-writer-keep"); - if (!keepString.empty()) { - dod->reset(); - std::string d("dangling"); - if (d.find(keepString) == 0) { - // use the dangling outputs - std::vector danglingOutputs; - for (auto ii = 0u; ii < OutputsInputs.size(); ii++) { - if (DataSpecUtils::partialMatch(OutputsInputs[ii], writableAODOrigins) && isDangling[ii]) { - danglingOutputs.emplace_back(OutputsInputs[ii]); - } - } - dod->readSpecs(danglingOutputs); - } else { - // use the keep string - dod->readString(keepString); - } - } - } - dod->setResultDir(resdir); - dod->setFilenameBase(fnbase); - dod->setFileMode(filemode); - dod->setMaximumFileSize(maxfilesize); - dod->setNumberTimeFramesToMerge(ntfmerge); - - return dod; -} - std::tuple, std::vector> WorkflowHelpers::analyzeOutputs(WorkflowSpec const& workflow) { // compute total number of input/output diff --git a/Framework/Core/src/WorkflowHelpers.h b/Framework/Core/src/WorkflowHelpers.h index b20249b99edc8..b2a4d4cab55df 100644 --- a/Framework/Core/src/WorkflowHelpers.h +++ b/Framework/Core/src/WorkflowHelpers.h @@ -180,7 +180,7 @@ struct WorkflowHelpers { // dangling inputs are satisfied. // @a workflow the workflow to decorate // @a ctx the context for the configuration phase - static void injectServiceDevices(WorkflowSpec& workflow, ConfigContext const& ctx); + static void injectServiceDevices(WorkflowSpec& workflow, ConfigContext& ctx); // Final adjustments to @a workflow after service devices have been injected. static void adjustTopology(WorkflowSpec& workflow, ConfigContext const& ctx); @@ -204,8 +204,6 @@ struct WorkflowHelpers { const std::vector& edges, const std::vector& index); - static std::shared_ptr getDataOutputDirector(ConfigParamRegistry const& options, std::vector const& OutputsInputs, std::vector const& outputTypes); - /// Given @a workflow it gathers all the OutputSpec and in addition provides /// the information whether and output is dangling and/or of type AOD /// An Output is dangling if it does not have a corresponding InputSpec. diff --git a/Framework/Core/test/Mocking.h b/Framework/Core/test/Mocking.h index b3e48ad3b2d0f..a42a1b30a662f 100644 --- a/Framework/Core/test/Mocking.h +++ b/Framework/Core/test/Mocking.h @@ -34,7 +34,10 @@ std::unique_ptr makeEmptyConfigContext() store->preload(); store->activate(); static ConfigParamRegistry registry(std::move(store)); - auto context = std::make_unique(registry, 0, nullptr); + static std::unique_ptr services; + // We need to reset it because we will inject services into it. + services = std::make_unique(); + auto context = std::make_unique(registry, ServiceRegistryRef{*services}, 0, nullptr); return context; } diff --git a/Framework/Core/test/benchmark_WorkflowHelpers.cxx b/Framework/Core/test/benchmark_WorkflowHelpers.cxx index f1c070d8a0f4e..09a9ae0cca923 100644 --- a/Framework/Core/test/benchmark_WorkflowHelpers.cxx +++ b/Framework/Core/test/benchmark_WorkflowHelpers.cxx @@ -30,7 +30,8 @@ std::unique_ptr makeEmptyConfigContext() store->preload(); store->activate(); static ConfigParamRegistry registry(std::move(store)); - auto context = std::make_unique(registry, 0, nullptr); + static ServiceRegistry services; + auto context = std::make_unique(registry, ServiceRegistryRef{services}, 0, nullptr); return context; } diff --git a/Framework/Core/test/test_OverrideLabels.cxx b/Framework/Core/test/test_OverrideLabels.cxx index 573bd13be797a..c5134c0c169c0 100644 --- a/Framework/Core/test/test_OverrideLabels.cxx +++ b/Framework/Core/test/test_OverrideLabels.cxx @@ -31,7 +31,8 @@ std::unique_ptr mockupLabels(std::string labelArg) store->preload(); store->activate(); registry = ConfigParamRegistry(std::move(store)); - auto context = std::make_unique(registry, 0, nullptr); + static ServiceRegistry services; + auto context = std::make_unique(registry, ServiceRegistryRef{services}, 0, nullptr); return context; } diff --git a/Framework/TestWorkflows/src/o2TestHistograms.cxx b/Framework/TestWorkflows/src/o2TestHistograms.cxx index 9986f52a1d940..efac16f6da4f0 100644 --- a/Framework/TestWorkflows/src/o2TestHistograms.cxx +++ b/Framework/TestWorkflows/src/o2TestHistograms.cxx @@ -17,6 +17,7 @@ #include "Framework/AnalysisTask.h" #include #include +#include using namespace o2; using namespace o2::framework; @@ -43,7 +44,7 @@ struct EtaAndClsHistogramsSimple { { LOGP(info, "Invoking the simple one"); for (auto& track : tracks) { - etaClsH->Fill(track.eta(), track.pt(), 0); + etaClsH->Fill(track.eta(), track.pt()); skimEx(track.pt(), track.eta()); } } @@ -57,7 +58,7 @@ struct EtaAndClsHistogramsIUSimple { { LOGP(info, "Invoking the simple one"); for (auto& track : tracks) { - etaClsH->Fill(track.eta(), track.pt(), 0); + etaClsH->Fill(track.eta(), track.pt()); skimEx(track.pt(), track.eta()); } } From dcb767f01f2fb1a526042375dcd4ab325c96743d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 13 Nov 2024 09:33:17 +0100 Subject: [PATCH 0449/2205] GPU TPC: Reject clusters with too small radius during refit instead of giving them IFC mask errors --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 0b2da89b79ad5..106a222862f49 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -131,6 +131,7 @@ AddOptionRTC(cfNoiseSuppressionEpsilonRelative, uint8_t, 76, "", 0, "Cluster Fin AddOptionRTC(nWays, uint8_t, 3, "", 0, "Do N fit passes in final fit of merger") AddOptionRTC(nWaysOuter, int8_t, 0, "", 0, "Store outer param") AddOptionRTC(trackFitRejectMode, int8_t, 5, "", 0, "0: no limit on rejection or missed hits, >0: break after n rejected hits, <0: reject at max -n hits") +AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 0, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(globalTracking, int8_t, 1, "", 0, "Enable Global Tracking (prolong tracks to adjacent sectors to find short segments)") diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx index 13244dcb4b621..0b1c282f3b2f0 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx @@ -68,7 +68,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ GPUTPCGMPropagator prop; gputpcgmmergertypes::InterpolationErrors interpolation; prop.SetMaterialTPC(); - prop.SetPolynomialField(&merger->Param().polynomialField); + prop.SetPolynomialField(¶m.polynomialField); prop.SetMaxSinPhi(maxSinPhi); prop.SetToyMCEventsFlag(param.par.toyMCEventsFlag); if ((clusters[0].slice < 18) == (clusters[N - 1].slice < 18)) { @@ -157,7 +157,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ uint8_t clusterState = clusters[ihit].state; const float clAlpha = param.Alpha(clusters[ihit].slice); float xx, yy, zz; - if (merger->Param().par.earlyTpcTransform) { + if (param.par.earlyTpcTransform) { const float zOffset = (clusters[ihit].slice < 18) == (clusters[0].slice < 18) ? mTZOffset : -mTZOffset; xx = clustersXYZ[ihit].x; yy = clustersXYZ[ihit].y; @@ -177,6 +177,14 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ continue; } + if (param.rec.tpc.rejectIFCLowRadiusCluster) { + const float r2 = xx * xx + yy * yy; + const float rmax = (83.5f + param.rec.tpc.sysClusErrorMinDist); + if (r2 < rmax * rmax) { + MarkClusters(clusters, ihitMergeFirst, ihit, wayDirection, GPUTPCGMMergedTrackHit::flagRejectErr); + } + } + const auto& cluster = clusters[ihit]; bool changeDirection = (cluster.leg - lastLeg) & 1; @@ -212,7 +220,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ continue; } } else if (allowModification && lastRow != 255 && CAMath::Abs(cluster.row - lastRow) > 1) { - bool dodEdx = merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled && merger->Param().rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg; + bool dodEdx = param.par.dodEdx && param.dodEdxDownscaled && param.rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg; dodEdx = AttachClustersPropagate(merger, cluster.slice, lastRow, cluster.row, iTrk, cluster.leg == clusters[maxN - 1].leg, prop, inFlyDirection, GPUCA_MAX_SIN_PHI, dodEdx); if (dodEdx) { dEdx.fillSubThreshold(lastRow - 1, param); @@ -323,7 +331,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ } #endif GPUCA_DEBUG_STREAMER_CHECK(GPUTPCGMPropagator::DebugStreamerVals debugVals;); - if (merger->Param().rec.tpc.rejectEdgeClustersInTrackFit && uncorrectedY > -1e6f && merger->Param().rejectEdgeClusterByY(uncorrectedY, cluster.row, CAMath::Sqrt(mC[0]))) { // uncorrectedY > -1e6f implies allowModification + if (param.rec.tpc.rejectEdgeClustersInTrackFit && uncorrectedY > -1e6f && param.rejectEdgeClusterByY(uncorrectedY, cluster.row, CAMath::Sqrt(mC[0]))) { // uncorrectedY > -1e6f implies allowModification retVal = GPUTPCGMPropagator::updateErrorEdgeCluster; } else { const float time = merger->GetConstantMem()->ioPtrs.clustersNative ? merger->GetConstantMem()->ioPtrs.clustersNative->clustersLinear[cluster.num].getTime() : -1.f; @@ -358,11 +366,11 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ ihitStart = ihit; float dy = mP[0] - prop.Model().Y(); float dz = mP[1] - prop.Model().Z(); - if (CAMath::Abs(mP[4]) * merger->Param().qptB5Scaler > 10 && --resetT0 <= 0 && CAMath::Abs(mP[2]) < 0.15f && dy * dy + dz * dz > 1) { + if (CAMath::Abs(mP[4]) * param.qptB5Scaler > 10 && --resetT0 <= 0 && CAMath::Abs(mP[2]) < 0.15f && dy * dy + dz * dz > 1) { CADEBUG(printf("Reinit linearization\n")); prop.SetTrack(this, prop.GetAlpha()); } - if (merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { + if (param.par.dodEdx && param.dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { float qtot = 0, qmax = 0, pad = 0, relTime = 0; const int32_t clusterCount = (ihit - ihitMergeFirst) * wayDirection + 1; for (int32_t iTmp = ihitMergeFirst; iTmp != ihit + wayDirection; iTmp += wayDirection) { @@ -404,16 +412,16 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ o2::utils::DebugStreamer::instance()->getStreamer("debug_accept_track", "UPDATE") << o2::utils::DebugStreamer::instance()->getUniqueTreeName("debug_accept_track").data() << "iTrk=" << iTrk << "outerParam=" << *outerParam << "track=" << this << "ihitStart=" << ihitStart << "\n"; }) - if (!(N + NTolerated >= GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(mP[4] * merger->Param().qptB5Scaler) && 2 * NTolerated <= CAMath::Max(10, N) && CheckNumericalQuality(covYYUpd))) { + if (!(N + NTolerated >= GPUCA_TRACKLET_SELECTOR_MIN_HITS_B5(mP[4] * param.qptB5Scaler) && 2 * NTolerated <= CAMath::Max(10, N) && CheckNumericalQuality(covYYUpd))) { return false; // TODO: NTolerated should never become that large, check what is going wrong! } - if (merger->Param().rec.tpc.minNClustersFinalTrack != -1 && N + NTolerated < merger->Param().rec.tpc.minNClustersFinalTrack) { + if (param.rec.tpc.minNClustersFinalTrack != -1 && N + NTolerated < param.rec.tpc.minNClustersFinalTrack) { return false; } // TODO: we have looping tracks here with 0 accepted clusters in the primary leg. In that case we should refit the track using only the primary leg. - if (merger->Param().par.dodEdx && merger->Param().dodEdxDownscaled) { + if (param.par.dodEdx && param.dodEdxDownscaled) { dEdx.computedEdx(merger->OutputTracksdEdx()[iTrk], param); } Alpha = prop.GetAlpha(); From 197384977d7a71e8c2e87e36ee58d977055c048e Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 14:11:45 +0100 Subject: [PATCH 0450/2205] Add empty streaming operator, so that std::cout << SMatrixGPU() does not fail --- Common/MathUtils/include/MathUtils/SMatrixGPU.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index 60965a4fa2776..2bfdcf54752b2 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -29,6 +29,7 @@ #include "GPUCommonMath.h" #include "GPUCommonAlgorithm.h" #include "GPUCommonLogger.h" +#include "GPUCommonTypeTraits.h" namespace o2::math_utils::detail { @@ -468,6 +469,9 @@ class SMatrixGPU GPUd() const T& operator()(unsigned int i, unsigned int j) const; GPUd() T& operator()(unsigned int i, unsigned int j); + template + GPUd() friend X& operator<<(Y& y, const SMatrixGPU&); + class SMatrixRowGPU { public: @@ -512,6 +516,13 @@ class SMatrixGPU R mRep; }; +template + requires(sizeof(typename X::traits_type::pos_type) != 0) // do not provide a template to fair::Logger, etc... (pos_type is a member type of all std::ostream classes) +GPUd() X& operator<<(Y& y, const SMatrixGPU&) +{ + return y; +} + template GPUdi() SMatrixGPU::SMatrixGPU(SMatrixIdentity) { From 80e298b8712abbac3c55d5cdf0c57a92fc8083f1 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 14:12:30 +0100 Subject: [PATCH 0451/2205] GPU: Fix includes of certain headers (fix order, avoid ROOT in GPU code) --- GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx | 5 ++--- GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx | 1 + GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx | 3 +-- GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h | 2 +- GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx | 2 +- GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx index a632bf361498c..002bb1ed9e9d7 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxContainer.cxx @@ -12,14 +12,13 @@ /// \file CalibdEdxContainer.cxx /// \author Matthias Kleiner -#include "CalibdEdxContainer.h" - -#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) +#if !defined(GPUCA_STANDALONE) #include "TFile.h" #include "TPCBase/CalDet.h" #include "Framework/Logger.h" #include "clusterFinderDefs.h" #endif +#include "CalibdEdxContainer.h" using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx index 548bbafae686d..533763e14c6d7 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "Rtypes.h" #include "CalibdEdxTrackTopologyPol.h" #include diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx index 4c6e750355397..3b0e718026536 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.cxx @@ -14,11 +14,10 @@ /// /// \author Matthias Kleiner -#include "CalibdEdxTrackTopologySpline.h" - #if !defined(GPUCA_STANDALONE) #include "TFile.h" #endif +#include "CalibdEdxTrackTopologySpline.h" using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h index 563872fb90d4d..d9d4b9e35592d 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h @@ -19,12 +19,12 @@ #include "FlatObject.h" #include "Spline.h" +#include "GPUCommonRtypes.h" #ifdef GPUCA_HAVE_O2HEADERS #include "DataFormatsTPC/Defs.h" #endif #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation -#include "Rtypes.h" // for ClassDefNV #include #endif diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx index db6df3f9f1ede..7005fbb3bab25 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx @@ -12,11 +12,11 @@ /// \file GPUO2InterfaceQA.cxx /// \author David Rohr +#include "TGraphAsymmErrors.h" #include "GPUParam.h" #include "GPUQA.h" #include "GPUO2InterfaceConfiguration.h" #include "GPUO2InterfaceQA.h" -#include "TGraphAsymmErrors.h" using namespace o2::gpu; using namespace o2::tpc; diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx index 6baea86f05d36..f7e3bca47a0fc 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefitKernel.cxx @@ -12,9 +12,9 @@ /// \file GPUTrackingRefitKernel.cxx /// \author David Rohr +#include "GPUROOTDump.h" #include "GPUTrackingRefitKernel.h" #include "GPUTrackingRefit.h" -#include "GPUROOTDump.h" using namespace GPUCA_NAMESPACE::gpu; From 4ee9785a941eb11f5ea8f5cb86fa42ce31050b88 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 14:36:09 +0100 Subject: [PATCH 0452/2205] FST: Force correct number of orbits to gpu-reco --- prodtests/full_system_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/prodtests/full_system_test.sh b/prodtests/full_system_test.sh index f8b6d66ce87e4..8d6a0ca3cf1f9 100755 --- a/prodtests/full_system_test.sh +++ b/prodtests/full_system_test.sh @@ -227,6 +227,7 @@ if [[ ${RANS_OPT:-} =~ (--ans-version +)(compat) ]] ; then # for decoding we use either just produced or externally provided common local file export ARGS_EXTRA_PROCESS_o2_ctf_reader_workflow+="--ctf-dict $CTFDICTFILE" fi +export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_global.overrideNHbfPerTF=$NHBPERTF;" for STAGE in $STAGES; do logfile=reco_${STAGE}.log From ddfe6d025cc4a9f42ef3ffd0eba95a09059ae4f6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 14:36:55 +0100 Subject: [PATCH 0453/2205] Calibration aggregator-workflow.sh: Update default lanes/threads for TPC IDC calib --- prodtests/full-system-test/aggregator-workflow.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prodtests/full-system-test/aggregator-workflow.sh b/prodtests/full-system-test/aggregator-workflow.sh index 4c20e901a2978..23336cafffab8 100755 --- a/prodtests/full-system-test/aggregator-workflow.sh +++ b/prodtests/full-system-test/aggregator-workflow.sh @@ -295,8 +295,8 @@ fi # TPC IDCs and SAC crus="0-359" # to be used with $AGGREGATOR_TASKS == TPC_IDCBOTH_SAC or ALL -lanesFactorize=${O2_TPC_IDC_FACTORIZE_NLANES:-10} -threadFactorize=${O2_TPC_IDC_FACTORIZE_NTHREADS:-8} +lanesFactorize=${O2_TPC_IDC_FACTORIZE_NLANES:-12} +threadFactorize=${O2_TPC_IDC_FACTORIZE_NTHREADS:-16} nTFs=$((1000 * 128 / ${NHBPERTF})) nTFs_SAC=$((1000 * 128 / ${NHBPERTF})) nBuffer=$((100 * 128 / ${NHBPERTF})) From b8b824ce09d785013f8c216393e2f5267f2aec59 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 18:06:24 +0100 Subject: [PATCH 0454/2205] GPU Display: Fix race condition --- GPU/GPUTracking/display/render/GPUDisplayDraw.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx index ab7ebf6811766..746c41938e2e1 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -27,6 +27,7 @@ #include "GPUTPCGMPropagator.h" #include "GPUTPCMCInfo.h" #include "GPUParam.inc" +#include "GPUCommonMath.h" #include @@ -66,8 +67,12 @@ inline void GPUDisplay::insertVertexList(int32_t iSlice, size_t first, size_t la inline void GPUDisplay::drawPointLinestrip(int32_t iSlice, int32_t cid, int32_t id, int32_t id_limit) { mVertexBuffer[iSlice].emplace_back(mGlobalPos[cid].x, mGlobalPos[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPos[cid].z); - if (mGlobalPos[cid].w < id_limit) { - mGlobalPos[cid].w = id; + float curVal; + while ((curVal = mGlobalPos[cid].w) < id_limit) { + if (GPUCommonMath::AtomicCAS(&mGlobalPos[cid].w, curVal, (float)id)) { + break; + } + curVal = mGlobalPos[cid].w; } } From 98746db30c03bcbbaac83d2fe7b8977f4957e279 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 13 Nov 2024 09:30:47 +0100 Subject: [PATCH 0455/2205] GPU: Split NDPiecewisePolynomials in header and inc file, get rid of ROOT in the header --- .../DataTypes/CalibdEdxTrackTopologyPol.cxx | 1 + .../NDPiecewisePolynomials.h | 351 +++--------------- .../NDPiecewisePolynomials.inc | 276 ++++++++++++++ .../test/testMultivarPolynomials.cxx | 2 +- 4 files changed, 330 insertions(+), 300 deletions(-) create mode 100644 GPU/TPCFastTransformation/NDPiecewisePolynomials.inc diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx index 533763e14c6d7..47a6e4cff72df 100644 --- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx +++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.cxx @@ -21,6 +21,7 @@ using namespace o2::tpc; #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation +#include "NDPiecewisePolynomials.inc" void CalibdEdxTrackTopologyPol::dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName) const { for (uint32_t i = 0; i < FFits; i++) { diff --git a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h index 6de2bc7afbae8..9498645b76220 100644 --- a/GPU/TPCFastTransformation/NDPiecewisePolynomials.h +++ b/GPU/TPCFastTransformation/NDPiecewisePolynomials.h @@ -20,17 +20,12 @@ #include "MultivariatePolynomialHelper.h" #include "GPUCommonMath.h" -#if !defined(GPUCA_GPUCODE) +#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) #include -#if !defined(GPUCA_STANDALONE) -#include "TLinearFitter.h" -#ifndef GPUCA_ALIROOT_LIB -#include "CommonUtils/TreeStreamRedirector.h" -#endif -#include -#endif #endif +class TFile; + namespace GPUCA_NAMESPACE::gpu { @@ -81,23 +76,20 @@ template class NDPiecewisePolynomials : public FlatObject { public: -#ifndef GPUCA_GPUCODE +#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// constructor /// \param min minimum coordinates of the grid /// \param max maximum coordinates of the grid (note: the resulting polynomials can NOT be evaluated at the maximum coordinates: only at min <= X < max) /// \param n number of vertices: defines number of fits per dimension: nFits = n - 1. n should be at least 2 to perform one fit NDPiecewisePolynomials(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]) { init(min, max, n); } -#endif -#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// constructor construct and object by initializing it from an object stored in a Root file /// \param fileName name of the file /// \param name name of the object NDPiecewisePolynomials(const char* fileName, const char* name) { - TFile f(fileName, "READ"); - loadFromFile(f, name); + loadFromFile(fileName, name); }; -#endif +#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// default constructor NDPiecewisePolynomials() CON_DEFAULT; @@ -115,7 +107,7 @@ class NDPiecewisePolynomials : public FlatObject /// move flat buffer to new location /// \param newBufferPtr new buffer location void moveBufferTo(char* newBufferPtr); -#endif +#endif // !defined(GPUCA_GPUCODE) /// destroy the object (release internal flat buffer) void destroy(); @@ -168,17 +160,16 @@ class NDPiecewisePolynomials : public FlatObject /// \return returns the parameters of the coefficients GPUd() const float* getParams() const { return mParams; } -#if !defined(GPUCA_GPUCODE) - /// Setting directly the parameters of the polynomials - void setParams(const float params[/* getNParameters() */]) { std::copy(params, params + getNParameters(), mParams); } - /// initalize the members /// \param min minimum coordinates of the grid /// \param max maximum coordinates of the grid (note: the resulting polynomials can NOT be evaluated at the maximum coordinates: only at min <= X < max) /// \param n number of vertices: defines number of fits per dimension: nFits = n - 1. n should be at least 2 to perform one fit void init(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]); -#ifndef GPUCA_STANDALONE +#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) + /// Setting directly the parameters of the polynomials + void setParams(const float params[/* getNParameters() */]) { std::copy(params, params + getNParameters(), mParams); } + /// perform the polynomial fits on the grid /// \param func function which returns for every input x on the defined grid the true value /// \param nAuxiliaryPoints number of points which will be used for the fits (should be at least 2) @@ -194,6 +185,8 @@ class NDPiecewisePolynomials : public FlatObject /// \param name name of the object in the file void loadFromFile(TFile& inpf, const char* name); + void loadFromFile(const char* fileName, const char* name); + /// write parameters to file /// \param outf output file /// \param name name of the output object @@ -211,7 +204,6 @@ class NDPiecewisePolynomials : public FlatObject /// \return returns total number of polynomial fits uint32_t getNPolynomials() const; -#endif /// converts the class to a container which can be written to a root file NDPiecewisePolynomialContainer getContainer() const { return NDPiecewisePolynomialContainer{Dim, Degree, getNParameters(), mParams, InteractionOnly, mMin, mMax, mN}; } @@ -219,10 +211,10 @@ class NDPiecewisePolynomials : public FlatObject /// set the parameters from NDPiecewisePolynomialContainer /// \param container container for the parameters void setFromContainer(const NDPiecewisePolynomialContainer& container); +#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) /// \return returns the total number of stored parameters uint32_t getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); } -#endif /// \return returns number of dimensions of the polynomials GPUd() static constexpr uint32_t getDim() { return Dim; } @@ -292,15 +284,15 @@ class NDPiecewisePolynomials : public FlatObject /// \param ix index /// \param dim dimension double getVertexPosition(const uint32_t ix, const int32_t dim) const { return ix / static_cast(mInvSpacing[dim]) + mMin[dim]; } -#endif +#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) #if !defined(GPUCA_GPUCODE) /// \return returns the size of the parameters std::size_t sizeOfParameters() const { return getNParameters() * sizeof(DataTParams); } +#endif // #if !defined(GPUCA_GPUCODE) // construct the object (flatbuffer) void construct(); -#endif #ifndef GPUCA_ALIROOT_LIB ClassDefNV(NDPiecewisePolynomials, 1); @@ -313,20 +305,6 @@ class NDPiecewisePolynomials : public FlatObject #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) template -void NDPiecewisePolynomials::loadFromFile(TFile& inpf, const char* name) -{ - NDPiecewisePolynomialContainer* gridTmp = nullptr; - inpf.GetObject(name, gridTmp); - if (gridTmp) { - setFromContainer(*gridTmp); - delete gridTmp; - } else { -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "couldnt load object {} from input file", name); -#endif - } -} -template void NDPiecewisePolynomials::setFromContainer(const NDPiecewisePolynomialContainer& container) { if (Dim != container.mDim) { @@ -350,12 +328,6 @@ void NDPiecewisePolynomials::setFromContainer(cons init(container.mMin.data(), container.mMax.data(), container.mN.data()); setParams(container.mParams.data()); } -template -void NDPiecewisePolynomials::writeToFile(TFile& outf, const char* name) const -{ - const NDPiecewisePolynomialContainer cont = getContainer(); - outf.WriteObject(&cont, name); -} template void NDPiecewisePolynomials::setDefault() @@ -368,7 +340,29 @@ void NDPiecewisePolynomials::setDefault() std::copy(params.begin(), params.end(), &mParams[i * nParamsPerPol]); } } -#endif + +template +uint32_t NDPiecewisePolynomials::getNPolynomials() const +{ + uint32_t nP = getNPolynomials(0); + for (uint32_t i = 1; i < Dim; ++i) { + nP *= getNPolynomials(i); + } + return nP; +} + +template +void NDPiecewisePolynomials::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const +{ + for (uint32_t i = 0; i < Dim; ++i) { + if (pos[i] == int32_t(iMax[i])) { + ++pos[i + 1]; + std::fill_n(pos, i + 1, 0); + } + } +} + +#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) #ifndef GPUCA_GPUCODE template @@ -405,7 +399,19 @@ void NDPiecewisePolynomials::construct() FlatObject::finishConstruction(flatbufferSize); mParams = reinterpret_cast(mFlatBufferPtr); } -#endif + +template +void NDPiecewisePolynomials::init(const float min[], const float max[], const uint32_t n[]) +{ + for (uint32_t i = 0; i < Dim; ++i) { + mMin[i] = min[i]; + mMax[i] = max[i]; + mN[i] = n[i]; + mInvSpacing[i] = (mN[i] - 1) / (mMax[i] - mMin[i]); + } + construct(); +} +#endif // !GPUCA_GPUCODE template void NDPiecewisePolynomials::destroy() @@ -472,259 +478,6 @@ GPUdi() void NDPiecewisePolynomials::clamp(float x } } -#ifndef GPUCA_GPUCODE -template -void NDPiecewisePolynomials::init(const float min[], const float max[], const uint32_t n[]) -{ - for (uint32_t i = 0; i < Dim; ++i) { - mMin[i] = min[i]; - mMax[i] = max[i]; - mN[i] = n[i]; - mInvSpacing[i] = (mN[i] - 1) / (mMax[i] - mMin[i]); - } - construct(); -} -#endif - -#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) -template -uint32_t NDPiecewisePolynomials::getNPolynomials() const -{ - uint32_t nP = getNPolynomials(0); - for (uint32_t i = 1; i < Dim; ++i) { - nP *= getNPolynomials(i); - } - return nP; -} - -template -void NDPiecewisePolynomials::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const -{ - for (uint32_t i = 0; i < Dim; ++i) { - if (pos[i] == int32_t(iMax[i])) { - ++pos[i + 1]; - std::fill_n(pos, i + 1, 0); - } - } -} - -template -void NDPiecewisePolynomials::performFits(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */]) -{ - const int32_t nTotalFits = getNPolynomials(); -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); -#endif - - MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); - TLinearFitter fitter = pol.getTLinearFitter(); - - uint32_t nPoints = 1; - for (uint32_t i = 0; i < Dim; ++i) { - nPoints *= nAuxiliaryPoints[i]; - } - - std::vector xCords; - std::vector response; - xCords.reserve(Dim * nPoints); - response.reserve(nPoints); - - uint32_t nPolynomials[Dim]{0}; - for (uint32_t i = 0; i < Dim; ++i) { - nPolynomials[i] = getNPolynomials(i); - } - - int32_t pos[Dim + 1]{0}; - uint32_t counter = 0; - const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; - - for (;;) { - const bool debug = !(++counter % printDebugForNFits); - if (debug) { -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); -#endif - } - - checkPos(nPolynomials, pos); - - if (pos[Dim] == 1) { - break; - } - - xCords.clear(); - response.clear(); - fitInnerGrid(func, nAuxiliaryPoints, pos, fitter, xCords, response); - ++pos[0]; - } -} - -template -void NDPiecewisePolynomials::performFits(const std::vector& x, const std::vector& y) -{ - const int32_t nTotalFits = getNPolynomials(); -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); -#endif - - // approximate number of points - uint32_t nPoints = 2 * y.size() / nTotalFits; - - // polynomial index -> indices to datapoints - std::unordered_map> dataPointsIndices; - for (int32_t i = 0; i < nTotalFits; ++i) { - dataPointsIndices[i].reserve(nPoints); - } - - // check for each data point which polynomial to use - for (size_t i = 0; i < y.size(); ++i) { - std::array index; - float xVal[Dim]; - std::copy(x.begin() + i * Dim, x.begin() + i * Dim + Dim, xVal); - setIndex(xVal, index.data()); - - std::array indexClamped{index}; - clamp(xVal, indexClamped.data()); - - // check if data points are in the grid - if (index == indexClamped) { - // index of the polyniomial - const uint32_t idx = getDataIndex(index.data()) / MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); - - // store index to data point - dataPointsIndices[idx].emplace_back(i); - } - } - - // for fitting - MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); - TLinearFitter fitter = pol.getTLinearFitter(); - - uint32_t counter = 0; - const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; - - // temp storage for x and y values for fitting - std::vector xCords; - std::vector response; - - for (int32_t i = 0; i < nTotalFits; ++i) { - const bool debug = !(++counter % printDebugForNFits); - if (debug) { -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); -#endif - } - - // store values for fitting - if (dataPointsIndices[i].empty()) { -#ifndef GPUCA_ALIROOT_LIB - LOGP(info, "No data points to fit"); -#endif - continue; - } - - const auto nP = dataPointsIndices[i].size(); - xCords.reserve(Dim * nP); - response.reserve(nP); - xCords.clear(); - response.clear(); - - // add datapoints to fit - for (size_t j = 0; j < nP; ++j) { - const size_t idxOrig = dataPointsIndices[i][j]; - - // insert x values at the end of xCords - const int32_t idxXStart = idxOrig * Dim; - xCords.insert(xCords.end(), x.begin() + idxXStart, x.begin() + idxXStart + Dim); - response.emplace_back(y[idxOrig]); - } - - // perform the fit on the points TODO make errors configurable - std::vector error; - const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); - - // store parameters - std::copy(params.begin(), params.end(), &mParams[i * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly)]); - } -} - -template -void NDPiecewisePolynomials::fitInnerGrid(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */], const int32_t currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response) -{ - int32_t pos[Dim + 1]{0}; - - // add points which will be used for the fit - for (;;) { - checkPos(nAuxiliaryPoints, pos); - - if (pos[Dim] == 1) { - break; - } - - for (uint32_t iDim = 0; iDim < Dim; ++iDim) { - const double stepWidth = getStepWidth(iDim, nAuxiliaryPoints[iDim]); - const double vertexPos = getVertexPosition(currentIndex[iDim], iDim); - const double realPosTmp = vertexPos + pos[iDim] * stepWidth; - xCords.emplace_back(realPosTmp); - } - - // get response for last added points - const double responseTmp = func(&xCords[xCords.size() - Dim]); - response.emplace_back(responseTmp); - ++pos[0]; - } - - // perform the fit on the points TODO make errors configurable - std::vector error; - const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); - - // store parameters - const uint32_t index = getDataIndex(currentIndex); - std::copy(params.begin(), params.end(), &mParams[index]); -} - -#ifndef GPUCA_ALIROOT_LIB -template -void NDPiecewisePolynomials::dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName, const char* treeName, const bool recreateFile) const -{ - o2::utils::TreeStreamRedirector pcstream(outName, recreateFile ? "RECREATE" : "UPDATE"); - - double factor[Dim]{}; - for (uint32_t iDim = 0; iDim < Dim; ++iDim) { - factor[iDim] = (mMax[iDim] - mMin[iDim]) / (nSamplingPoints[iDim] - 1); - } - - std::vector x(Dim); - std::vector ix(Dim); - int32_t pos[Dim + 1]{0}; - - for (;;) { - checkPos(nSamplingPoints, pos); - - if (pos[Dim] == 1) { - break; - } - - for (uint32_t iDim = 0; iDim < Dim; ++iDim) { - ix[iDim] = pos[iDim]; - x[iDim] = mMin[iDim] + pos[iDim] * factor[iDim]; - } - - float value = eval(x.data()); - pcstream << treeName - << "ix=" << ix - << "x=" << x - << "value=" << value - << "\n"; - - ++pos[0]; - } - pcstream.Close(); -} -#endif - -#endif - } // namespace GPUCA_NAMESPACE::gpu #endif diff --git a/GPU/TPCFastTransformation/NDPiecewisePolynomials.inc b/GPU/TPCFastTransformation/NDPiecewisePolynomials.inc new file mode 100644 index 0000000000000..d7bb9d702e96f --- /dev/null +++ b/GPU/TPCFastTransformation/NDPiecewisePolynomials.inc @@ -0,0 +1,276 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file NDPiecewisePolynomials.inc +/// \author Matthias Kleiner + +#ifndef ALICEO2_TPC_NDPIECEWISEPOLYNOMIALS_INC +#define ALICEO2_TPC_NDPIECEWISEPOLYNOMIALS_INC + +#include +#include +#include "CommonUtils/TreeStreamRedirector.h" +#include "NDPiecewisePolynomials.h" + +namespace GPUCA_NAMESPACE::gpu +{ + +#ifndef GPUCA_ALIROOT_LIB +template +void NDPiecewisePolynomials::dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName, const char* treeName, const bool recreateFile) const +{ + o2::utils::TreeStreamRedirector pcstream(outName, recreateFile ? "RECREATE" : "UPDATE"); + + double factor[Dim]{}; + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { + factor[iDim] = (mMax[iDim] - mMin[iDim]) / (nSamplingPoints[iDim] - 1); + } + + std::vector x(Dim); + std::vector ix(Dim); + int32_t pos[Dim + 1]{0}; + + for (;;) { + checkPos(nSamplingPoints, pos); + + if (pos[Dim] == 1) { + break; + } + + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { + ix[iDim] = pos[iDim]; + x[iDim] = mMin[iDim] + pos[iDim] * factor[iDim]; + } + + float value = eval(x.data()); + pcstream << treeName + << "ix=" << ix + << "x=" << x + << "value=" << value + << "\n"; + + ++pos[0]; + } + pcstream.Close(); +} +#endif // GPUCA_ALIROOT_LIB + +#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) + +template +void NDPiecewisePolynomials::loadFromFile(TFile& inpf, const char* name) +{ + NDPiecewisePolynomialContainer* gridTmp = nullptr; + inpf.GetObject(name, gridTmp); + if (gridTmp) { + setFromContainer(*gridTmp); + delete gridTmp; + } else { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "couldnt load object {} from input file", name); +#endif + } +} + +template +void NDPiecewisePolynomials::loadFromFile(const char* fileName, const char* name) +{ + TFile f(fileName, "READ"); + loadFromFile(f, name); +} + +template +void NDPiecewisePolynomials::writeToFile(TFile& outf, const char* name) const +{ + const NDPiecewisePolynomialContainer cont = getContainer(); + outf.WriteObject(&cont, name); +} + +template +void NDPiecewisePolynomials::performFits(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */]) +{ + const int32_t nTotalFits = getNPolynomials(); +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); +#endif + + MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); + TLinearFitter fitter = pol.getTLinearFitter(); + + uint32_t nPoints = 1; + for (uint32_t i = 0; i < Dim; ++i) { + nPoints *= nAuxiliaryPoints[i]; + } + + std::vector xCords; + std::vector response; + xCords.reserve(Dim * nPoints); + response.reserve(nPoints); + + uint32_t nPolynomials[Dim]{0}; + for (uint32_t i = 0; i < Dim; ++i) { + nPolynomials[i] = getNPolynomials(i); + } + + int32_t pos[Dim + 1]{0}; + uint32_t counter = 0; + const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; + + for (;;) { + const bool debug = !(++counter % printDebugForNFits); + if (debug) { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); +#endif + } + + checkPos(nPolynomials, pos); + + if (pos[Dim] == 1) { + break; + } + + xCords.clear(); + response.clear(); + fitInnerGrid(func, nAuxiliaryPoints, pos, fitter, xCords, response); + ++pos[0]; + } +} + +template +void NDPiecewisePolynomials::performFits(const std::vector& x, const std::vector& y) +{ + const int32_t nTotalFits = getNPolynomials(); +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Perform fitting of {}D-Polynomials of degree {} for a total of {} fits.", Dim, Degree, nTotalFits); +#endif + + // approximate number of points + uint32_t nPoints = 2 * y.size() / nTotalFits; + + // polynomial index -> indices to datapoints + std::unordered_map> dataPointsIndices; + for (int32_t i = 0; i < nTotalFits; ++i) { + dataPointsIndices[i].reserve(nPoints); + } + + // check for each data point which polynomial to use + for (size_t i = 0; i < y.size(); ++i) { + std::array index; + float xVal[Dim]; + std::copy(x.begin() + i * Dim, x.begin() + i * Dim + Dim, xVal); + setIndex(xVal, index.data()); + + std::array indexClamped{index}; + clamp(xVal, indexClamped.data()); + + // check if data points are in the grid + if (index == indexClamped) { + // index of the polyniomial + const uint32_t idx = getDataIndex(index.data()) / MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); + + // store index to data point + dataPointsIndices[idx].emplace_back(i); + } + } + + // for fitting + MultivariatePolynomialHelper<0, 0, false> pol(Dim, Degree, InteractionOnly); + TLinearFitter fitter = pol.getTLinearFitter(); + + uint32_t counter = 0; + const int32_t printDebugForNFits = int32_t(nTotalFits / 20) + 1; + + // temp storage for x and y values for fitting + std::vector xCords; + std::vector response; + + for (int32_t i = 0; i < nTotalFits; ++i) { + const bool debug = !(++counter % printDebugForNFits); + if (debug) { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "Performing fit {} out of {}", counter, nTotalFits); +#endif + } + + // store values for fitting + if (dataPointsIndices[i].empty()) { +#ifndef GPUCA_ALIROOT_LIB + LOGP(info, "No data points to fit"); +#endif + continue; + } + + const auto nP = dataPointsIndices[i].size(); + xCords.reserve(Dim * nP); + response.reserve(nP); + xCords.clear(); + response.clear(); + + // add datapoints to fit + for (size_t j = 0; j < nP; ++j) { + const size_t idxOrig = dataPointsIndices[i][j]; + + // insert x values at the end of xCords + const int32_t idxXStart = idxOrig * Dim; + xCords.insert(xCords.end(), x.begin() + idxXStart, x.begin() + idxXStart + Dim); + response.emplace_back(y[idxOrig]); + } + + // perform the fit on the points TODO make errors configurable + std::vector error; + const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); + + // store parameters + std::copy(params.begin(), params.end(), &mParams[i * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly)]); + } +} + +template +void NDPiecewisePolynomials::fitInnerGrid(const std::function& func, const uint32_t nAuxiliaryPoints[/* Dim */], const int32_t currentIndex[/* Dim */], TLinearFitter& fitter, std::vector& xCords, std::vector& response) +{ + int32_t pos[Dim + 1]{0}; + + // add points which will be used for the fit + for (;;) { + checkPos(nAuxiliaryPoints, pos); + + if (pos[Dim] == 1) { + break; + } + + for (uint32_t iDim = 0; iDim < Dim; ++iDim) { + const double stepWidth = getStepWidth(iDim, nAuxiliaryPoints[iDim]); + const double vertexPos = getVertexPosition(currentIndex[iDim], iDim); + const double realPosTmp = vertexPos + pos[iDim] * stepWidth; + xCords.emplace_back(realPosTmp); + } + + // get response for last added points + const double responseTmp = func(&xCords[xCords.size() - Dim]); + response.emplace_back(responseTmp); + ++pos[0]; + } + + // perform the fit on the points TODO make errors configurable + std::vector error; + const auto params = MultivariatePolynomialHelper<0, 0, false>::fit(fitter, xCords, response, error, true); + + // store parameters + const uint32_t index = getDataIndex(currentIndex); + std::copy(params.begin(), params.end(), &mParams[index]); +} + +} // namespace GPUCA_NAMESPACE::gpu + +#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) + +#endif // ALICEO2_TPC_NDPIECEWISEPOLYNOMIALS_INC diff --git a/GPU/TPCFastTransformation/test/testMultivarPolynomials.cxx b/GPU/TPCFastTransformation/test/testMultivarPolynomials.cxx index c3373cdad63f0..a9c39e8528354 100644 --- a/GPU/TPCFastTransformation/test/testMultivarPolynomials.cxx +++ b/GPU/TPCFastTransformation/test/testMultivarPolynomials.cxx @@ -18,7 +18,7 @@ #include #include "MultivariatePolynomial.h" -#include "NDPiecewisePolynomials.h" +#include "NDPiecewisePolynomials.inc" #include namespace o2::gpu From a1cae4e860986de751bcd2fa221bc69a563a5bcc Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 11 Nov 2024 14:12:16 +0100 Subject: [PATCH 0456/2205] GPU: Some protection so we get a compiler warning when headers are included in wrong order --- GPU/Common/GPUCommonRtypes.h | 4 ++-- GPU/Common/GPUROOTSMatrixFwd.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/Common/GPUCommonRtypes.h b/GPU/Common/GPUCommonRtypes.h index 5ae2ddbb83b26..7aaf5a36befe2 100644 --- a/GPU/Common/GPUCommonRtypes.h +++ b/GPU/Common/GPUCommonRtypes.h @@ -20,14 +20,14 @@ #if defined(GPUCA_STANDALONE) || (defined(GPUCA_O2_LIB) && !defined(GPUCA_O2_INTERFACE)) || defined(GPUCA_GPUCODE) // clang-format off #if !defined(ROOT_Rtypes) && !defined(__CLING__) #define GPUCOMMONRTYPES_H_ACTIVE + struct MUST_NOT_USE_Rtypes_h {}; + typedef MUST_NOT_USE_Rtypes_h TClass; #define ClassDef(name,id) #define ClassDefNV(name, id) #define ClassDefOverride(name, id) #define ClassImp(name) #define templateClassImp(name) #ifndef GPUCA_GPUCODE_DEVICE -// typedef uint64_t ULong64_t; -// typedef uint32_t UInt_t; #include #endif #endif diff --git a/GPU/Common/GPUROOTSMatrixFwd.h b/GPU/Common/GPUROOTSMatrixFwd.h index a3b5abc55d3bc..44b2254949df2 100644 --- a/GPU/Common/GPUROOTSMatrixFwd.h +++ b/GPU/Common/GPUROOTSMatrixFwd.h @@ -52,7 +52,7 @@ template class MatRepStdGPU; } // namespace detail -#if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE) +#if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE) && !defined(GPUCOMMONRTYPES_H_ACTIVE) template using SVector = ROOT::Math::SVector; template From bdb39f613566718201c36f0c5310e1eb05d771fb Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 13 Nov 2024 19:37:19 +0100 Subject: [PATCH 0457/2205] GPU: Workaround for OpenCL --- Common/MathUtils/include/MathUtils/SMatrixGPU.h | 2 ++ GPU/GPUTracking/dEdx/GPUdEdx.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Common/MathUtils/include/MathUtils/SMatrixGPU.h b/Common/MathUtils/include/MathUtils/SMatrixGPU.h index 2bfdcf54752b2..5ecdcd75a9906 100644 --- a/Common/MathUtils/include/MathUtils/SMatrixGPU.h +++ b/Common/MathUtils/include/MathUtils/SMatrixGPU.h @@ -516,12 +516,14 @@ class SMatrixGPU R mRep; }; +#ifndef __OPENCL__ // TODO: current C++ for OpenCL 2021 is at C++17, so no concepts. But we don't need this trick for OpenCL anyway, so we can just hide it. template requires(sizeof(typename X::traits_type::pos_type) != 0) // do not provide a template to fair::Logger, etc... (pos_type is a member type of all std::ostream classes) GPUd() X& operator<<(Y& y, const SMatrixGPU&) { return y; } +#endif template GPUdi() SMatrixGPU::SMatrixGPU(SMatrixIdentity) diff --git a/GPU/GPUTracking/dEdx/GPUdEdx.h b/GPU/GPUTracking/dEdx/GPUdEdx.h index 9a1784e2be49a..516d1fced0a20 100644 --- a/GPU/GPUTracking/dEdx/GPUdEdx.h +++ b/GPU/GPUTracking/dEdx/GPUdEdx.h @@ -212,7 +212,7 @@ GPUdi() void GPUdEdx::fillSubThreshold(int32_t padRow, const GPUParam& GPUrestri mNSubThresh++; } -#endif // !GPUCA_HAVE_O2HEADERS || __OPENCL1__ +#endif // !GPUCA_HAVE_O2HEADERS || GPUCA_OPENCL1 } // namespace gpu } // namespace GPUCA_NAMESPACE From 8aeaa54fc122d373dda19448180ce92681981bac Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 13 Nov 2024 20:05:36 +0100 Subject: [PATCH 0458/2205] GPU: Simplify __OPENCL__ macros using __OPENCL1__ --- GPU/Common/GPUCommonConstants.h | 2 +- GPU/Common/GPUCommonDef.h | 4 ++-- GPU/Common/GPUCommonMath.h | 10 +++++----- GPU/Common/GPUCommonTypeTraits.h | 2 +- GPU/GPUTracking/Base/GPUParam.inc | 4 ++-- .../Base/opencl-common/GPUReconstructionOCL.cl | 5 +++++ GPU/GPUTracking/Base/opencl2/CMakeLists.txt | 2 -- GPU/GPUTracking/DataTypes/GPUDataTypes.h | 2 +- GPU/GPUTracking/DataTypes/GPUO2DataTypes.h | 4 ++-- GPU/GPUTracking/DataTypes/GPUSettings.h | 2 +- .../DataTypes/GPUTPCGMPolynomialField.h | 4 ++-- GPU/GPUTracking/DataTypes/GPUTPCGeometry.h | 10 +++++----- .../Definitions/GPUDefConstantsAndSettings.h | 2 +- .../SliceTracker/GPUTPCGlobalTracking.cxx | 4 ++-- .../SliceTracker/GPUTPCGlobalTracking.h | 2 +- GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h | 2 +- GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx | 2 +- GPU/GPUTracking/SliceTracker/GPUTPCTracker.h | 2 +- .../SliceTracker/GPUTPCTrackletConstructor.cxx | 16 ++++++++-------- .../SliceTracker/GPUTPCTrackletConstructor.h | 2 +- 20 files changed, 43 insertions(+), 40 deletions(-) diff --git a/GPU/Common/GPUCommonConstants.h b/GPU/Common/GPUCommonConstants.h index 5744c078dc197..883f64b7bdd12 100644 --- a/GPU/Common/GPUCommonConstants.h +++ b/GPU/Common/GPUCommonConstants.h @@ -17,7 +17,7 @@ #include "GPUCommonDef.h" -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) namespace GPUCA_NAMESPACE::gpu::gpu_common_constants { static CONSTEXPR const float kCLight = 0.000299792458f; diff --git a/GPU/Common/GPUCommonDef.h b/GPU/Common/GPUCommonDef.h index a8bf772d7aacc..ac3d7279fbaf4 100644 --- a/GPU/Common/GPUCommonDef.h +++ b/GPU/Common/GPUCommonDef.h @@ -30,7 +30,7 @@ //Some GPU configuration settings, must be included first #include "GPUCommonDefSettings.h" -#if (!defined(__OPENCL__) || defined(__OPENCLCPP__)) && (!(defined(__CINT__) || defined(__ROOTCINT__)) || defined(__CLING__)) && defined(__cplusplus) && __cplusplus >= 201103L +#if !defined(__OPENCL1__) && (!(defined(__CINT__) || defined(__ROOTCINT__)) || defined(__CLING__)) && defined(__cplusplus) && __cplusplus >= 201103L #define GPUCA_NOCOMPAT // C++11 + No old ROOT5 + No old OpenCL #ifndef __OPENCL__ #define GPUCA_NOCOMPAT_ALLOPENCL // + No OpenCL at all @@ -82,7 +82,7 @@ #define GPUCA_NAMESPACE o2 #endif -#if (defined(__CUDACC__) && defined(GPUCA_CUDA_NO_CONSTANT_MEMORY)) || (defined(__HIPCC__) && defined(GPUCA_HIP_NO_CONSTANT_MEMORY)) || (defined(__OPENCL__) && !defined(__OPENCLCPP__) && defined(GPUCA_OPENCL_NO_CONSTANT_MEMORY)) || (defined(__OPENCLCPP__) && defined(GPUCA_OPENCLCPP_NO_CONSTANT_MEMORY)) +#if (defined(__CUDACC__) && defined(GPUCA_CUDA_NO_CONSTANT_MEMORY)) || (defined(__HIPCC__) && defined(GPUCA_HIP_NO_CONSTANT_MEMORY)) || (defined(__OPENCL1__) && defined(GPUCA_OPENCL_NO_CONSTANT_MEMORY)) || (defined(__OPENCLCPP__) && defined(GPUCA_OPENCLCPP_NO_CONSTANT_MEMORY)) #define GPUCA_NO_CONSTANT_MEMORY #elif defined(__CUDACC__) || defined(__HIPCC__) #define GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM diff --git a/GPU/Common/GPUCommonMath.h b/GPU/Common/GPUCommonMath.h index 8b129ff29a987..bc842d00c6568 100644 --- a/GPU/Common/GPUCommonMath.h +++ b/GPU/Common/GPUCommonMath.h @@ -31,7 +31,7 @@ #include #endif -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) namespace GPUCA_NAMESPACE { namespace gpu @@ -220,7 +220,7 @@ GPUdi() uint32_t GPUCommonMath::Float2UIntReint(const float& x) { #if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__)) return __float_as_uint(x); -#elif defined(GPUCA_GPUCODE_DEVICE) && (defined(__OPENCL__) || defined(__OPENCLCPP__)) +#elif defined(GPUCA_GPUCODE_DEVICE) && defined(__OPENCL__) return as_uint(x); #else return reinterpret_cast(x); @@ -289,7 +289,7 @@ GPUhdi() void GPUCommonMath::SinCosd(double x, double& s, double& c) GPUdi() uint32_t GPUCommonMath::Clz(uint32_t x) { -#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && (!defined(__OPENCL__) || defined(__OPENCLCPP__)) +#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && !defined(__OPENCL1__) return x == 0 ? 32 : CHOICE(__builtin_clz(x), __clz(x), __builtin_clz(x)); // use builtin if available #else for (int32_t i = 31; i >= 0; i--) { @@ -303,7 +303,7 @@ GPUdi() uint32_t GPUCommonMath::Clz(uint32_t x) GPUdi() uint32_t GPUCommonMath::Popcount(uint32_t x) { -#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && (!defined(__OPENCL__) /*|| defined(__OPENCLCPP__)*/) // TODO: remove OPENCLCPP workaround when reported SPIR-V bug is fixed +#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && (!defined(__OPENCL__) /* !defined(__OPENCL1__)*/) // TODO: exclude only OPENCLC (not CPP) when reported SPIR-V bug is fixed // use builtin if available return CHOICE(__builtin_popcount(x), __popc(x), __builtin_popcount(x)); #else @@ -563,7 +563,7 @@ GPUdii() void GPUCommonMath::AtomicMinInternal(GPUglobalref() GPUgeneric() GPUAt #undef CHOICE -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) } } #endif diff --git a/GPU/Common/GPUCommonTypeTraits.h b/GPU/Common/GPUCommonTypeTraits.h index 2ae524f8d1c76..88fcc9b838a65 100644 --- a/GPU/Common/GPUCommonTypeTraits.h +++ b/GPU/Common/GPUCommonTypeTraits.h @@ -21,7 +21,7 @@ #ifndef GPUCA_GPUCODE_COMPILEKERNELS #include #endif -#elif !defined(__OPENCL__) || defined(__OPENCLCPP__) +#elif !defined(__OPENCL1__) // We just reimplement some type traits in std for the GPU namespace std { diff --git a/GPU/GPUTracking/Base/GPUParam.inc b/GPU/GPUTracking/Base/GPUParam.inc index c7c526471d505..41ed3c8f203cb 100644 --- a/GPU/GPUTracking/Base/GPUParam.inc +++ b/GPU/GPUTracking/Base/GPUParam.inc @@ -17,7 +17,7 @@ #include "GPUParam.h" #include "GPUTPCGMMergedTrackHit.h" -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) #include "GPUTPCClusterOccupancyMap.h" #endif @@ -228,7 +228,7 @@ GPUdi() void MEM_LG(GPUParam)::UpdateClusterError2ByState(int16_t clusterState, MEM_CLASS_PRE() GPUdi() float MEM_LG(GPUParam)::GetUnscaledMult(float time) const { -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) if (!occupancyMap) { return 0.f; } diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl index 42a640579e9e3..672c4b63eb476 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cl @@ -14,6 +14,11 @@ // clang-format off #define __OPENCL__ +#if defined(__cplusplus) && __cplusplus >= 201703L + #define __OPENCLCPP__ +#else + #define __OPENCL1__ +#endif #define GPUCA_GPUTYPE_OPENCL #ifdef __OPENCLCPP__ diff --git a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt index ec2a4446142c8..0a4168b130766 100644 --- a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt +++ b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt @@ -32,8 +32,6 @@ set(OCL_DEFINECL "-D$ GPUdii() void GPUTPCGlobalTrackingCopyNumbers::Thread<0>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & smem, processorType& GPUrestrict() tracker, int32_t n) diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h index 075957ff4c8c8..9d732a582b1c4 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCGlobalTracking.h @@ -25,7 +25,7 @@ namespace gpu MEM_CLASS_PRE() class GPUTPCTracker; -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) class GPUTPCGlobalTracking : public GPUKernelTemplate { public: diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h index 8892225f119cd..3ab5b0a331f31 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceOutput.h @@ -44,7 +44,7 @@ class GPUTPCSliceOutput } GPUhd() uint32_t NLocalTracks() const { return mNLocalTracks; } GPUhd() uint32_t NTrackClusters() const { return mNTrackClusters; } -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) GPUhd() const GPUTPCTrack* GetFirstTrack() const { return (const GPUTPCTrack*)((const char*)this + sizeof(*this)); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx index 552d61a88fc39..7428a4ccbd0ed 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx @@ -22,7 +22,7 @@ #include "GPUO2DataTypes.h" #include "GPUTPCTrackParam.h" #include "GPUParam.inc" -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) #include "GPUTPCConvertImpl.h" #endif diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h index f19b4f0a6c0a7..da8d3d1fb28d4 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.h @@ -94,7 +94,7 @@ class GPUTPCTracker : public GPUProcessor StructGPUParameters gpuParameters; // GPU parameters }; -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) GPUhdi() GPUglobalref() const GPUTPCClusterData* ClusterData() const { return mData.ClusterData(); diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx index 9d6ed630dee8c..ba17b88436845 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx @@ -21,7 +21,7 @@ #include "GPUTPCTracker.h" #include "GPUTPCTracklet.h" #include "GPUTPCTrackletConstructor.h" -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) #include "GPUTPCGlobalTracking.h" #include "CorrectionMapsHelper.h" #ifdef GPUCA_HAVE_O2HEADERS @@ -140,14 +140,14 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, float z = z0 + hh.y * stepZ; if (iRow != r.mStartRow || !tracker.Param().par.continuousTracking) { tParam.ConstrainZ(z, tracker.ISlice(), z0, r.mLastZ); -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) tracker.GetConstantMem()->calibObjects.fastTransformHelper->TransformXYZ(tracker.ISlice(), iRow, x, y, z); #endif } if (iRow == r.mStartRow) { if (tracker.Param().par.continuousTracking) { float refZ = ((z > 0) ? tracker.Param().rec.tpc.defaultZOffsetOverR : -tracker.Param().rec.tpc.defaultZOffsetOverR) * x; -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) float zTmp = refZ; tracker.GetConstantMem()->calibObjects.fastTransformHelper->TransformXYZ(tracker.ISlice(), iRow, x, y, zTmp); z += zTmp - refZ; // Add zCorrection (=zTmp - refZ) to z, such that zOffset is set such, that transformed (z - zOffset) becomes refZ @@ -266,7 +266,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, r.mNMissed++; float x = row.X(); -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) { float tmpY, tmpZ; if (!tParam.GetPropagatedYZ(tracker.Param().bzCLight, x, tmpY, tmpZ)) { @@ -299,7 +299,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, GPUglobalref() const cahit2* hits = tracker.HitData(row); GPUglobalref() const calink* firsthit = tracker.FirstHitInBin(row); #endif //! GPUCA_TEXTURE_FETCH_CONSTRUCTOR -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) tracker.GetConstantMem()->calibObjects.fastTransformHelper->InverseTransformYZtoNominalYZ(tracker.ISlice(), iRow, yUncorrected, zUncorrected, yUncorrected, zUncorrected); #endif @@ -391,7 +391,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/, } } while (false); (void)found; -#if defined(GPUCA_HAVE_O2HEADERS) && (!defined(__OPENCL__) || defined(__OPENCLCPP__)) +#if defined(GPUCA_HAVE_O2HEADERS) && !defined(__OPENCL1__) if (!found && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer) { uint32_t pad = CAMath::Float2UIntRn(tracker.Param().tpcGeometry.LinearY2Pad(tracker.ISlice(), iRow, yUncorrected)); if (pad < tracker.Param().tpcGeometry.NPads(iRow) && tracker.GetConstantMem()->calibObjects.dEdxCalibContainer->isDead(tracker.ISlice(), iRow, pad)) { @@ -461,7 +461,7 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::DoTracklet(GPUconstantref() MEM_GLO iRow = r.mEndRow; iRowEnd = -1; float x = tracker.Row(r.mEndRow).X(); -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) { float tmpY, tmpZ; if (tParam.GetPropagatedYZ(tracker.Param().bzCLight, x, tmpY, tmpZ)) { @@ -584,7 +584,7 @@ GPUd() int32_t GPUTPCTrackletConstructor::FetchTracklet(GPUconstantref() MEM_GLO #endif // GPUCA_GPUCODE -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) template <> GPUd() int32_t GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCGlobalTracking::GPUSharedMemory& sMem, MEM_LG(GPUTPCTrackParam) & GPUrestrict() tParam, int32_t row, int32_t increment, int32_t iTracklet, calink* rowHits) { diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h index 06dd941ca5cf7..effee4fa757b8 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.h @@ -100,7 +100,7 @@ class GPUTPCTrackletConstructor GPUd() static int32_t FetchTracklet(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() MEM_LOCAL(GPUSharedMemory) & sMem); #endif // GPUCA_GPUCODE -#if !defined(__OPENCL__) || defined(__OPENCLCPP__) +#if !defined(__OPENCL1__) template GPUd() static int32_t GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & tracker, GPUsharedref() T& sMem, GPUTPCTrackParam& tParam, int32_t startrow, int32_t increment, int32_t iTracklet, calink* rowHits); #endif From 1901f380fba4079c162be24d82c2aa592172c084 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 13 Nov 2024 09:35:07 +0100 Subject: [PATCH 0459/2205] GPU Display: make connecting A and C side segments of a track optional --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 3 +- GPU/GPUTracking/display/GPUDisplay.cxx | 1 + GPU/GPUTracking/display/GPUDisplay.h | 1 + .../display/frontend/GPUDisplayKeys.cxx | 7 ++-- .../display/helpers/GPUDisplayHelpers.cxx | 7 ++++ .../display/render/GPUDisplayDraw.cxx | 33 +++++++++++-------- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 106a222862f49..c4e0dadb87659 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -346,7 +346,8 @@ AddOption(drawTracksAndFilter, bool, false, "", 0, "Use AND filter instead of OR AddOption(propagateLoopers, bool, false, "", 0, "Enabale propagation of loopers") AddOption(clustersOnly, bool, false, "", 0, "Visualize clusters only") AddOption(clustersOnNominalRow, bool, false, "", 0, "Show clusters at nominal x of pad row for early-transformed data") -AddOption(separateGlobalTracks, bool, false, "", 0, "Separate global tracks") +AddOption(separateGlobalTracks, bool, false, "", 0, "Draw track segments propagated to adjacent sectors separately") +AddOption(splitCETracks, int8_t, -1, "", 0, "Split CE tracks when they cross the central electrode (-1 = for triggered data)") AddOption(markClusters, int32_t, 0, "", 0, "Mark clusters") AddOption(markFakeClusters, int32_t, 0, "", 0, "Mark fake clusters") AddOption(markAdjacentClusters, int32_t, 0, "", 0, "Mark adjacent clusters") diff --git a/GPU/GPUTracking/display/GPUDisplay.cxx b/GPU/GPUTracking/display/GPUDisplay.cxx index 74d89fbf6de81..56e59d664491a 100644 --- a/GPU/GPUTracking/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/display/GPUDisplay.cxx @@ -611,6 +611,7 @@ void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) bool showTimer = false; bool doScreenshot = (mRequestScreenshot || mAnimateScreenshot) && animateTime < 0; + updateOptions(); if (animateTime < 0 && (mUpdateEventData || mResetScene || mUpdateVertexLists) && mIOPtrs) { disableUnsupportedOptions(); } diff --git a/GPU/GPUTracking/display/GPUDisplay.h b/GPU/GPUTracking/display/GPUDisplay.h index 38dacae60c51a..ab6fe540d01bf 100644 --- a/GPU/GPUTracking/display/GPUDisplay.h +++ b/GPU/GPUTracking/display/GPUDisplay.h @@ -150,6 +150,7 @@ class GPUDisplay : public GPUDisplayInterface void DrawGLScene_drawCommands(); int32_t InitDisplay_internal(); int32_t getNumThreads(); + void updateOptions(); void disableUnsupportedOptions(); int32_t buildTrackFilter(); const GPUTPCTracker& sliceTracker(int32_t iSlice); diff --git a/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx b/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx index 1842c276a580c..8dccdc60c0d93 100644 --- a/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/display/frontend/GPUDisplayKeys.cxx @@ -35,7 +35,7 @@ const char* HelpText[] = { "[L] / [K] Draw single collisions (next / previous)", "[C] Colorcode clusters of different collisions", "[v] Hide rejected clusters from tracks", - "[j] Show global tracks as additional segments of final tracks", + "[j] Show tracks segments propagated to adjacent sector in different color / splt CE tracks", "[u] Cycle through track filter", "[E] / [G] Extrapolate tracks / loopers", "[t] / [T] Take Screenshot / Record Animation to pictures", @@ -164,8 +164,11 @@ void GPUDisplay::HandleKey(uint8_t key) mPrintInfoText &= 3; SetInfo("Info text display - console: %s, onscreen %s", (mPrintInfoText & 2) ? "enabled" : "disabled", (mPrintInfoText & 1) ? "enabled" : "disabled"); } else if (key == 'j') { + if (mCfgH.separateGlobalTracks) { + mCfgH.splitCETracks ^= 1; + } mCfgH.separateGlobalTracks ^= 1; - SetInfo("Seperated display of global tracks %s", mCfgH.separateGlobalTracks ? "enabled" : "disabled"); + SetInfo("Seperated display of tracks propagated to adjacent sectors %s / of CE tracks %s", mCfgH.separateGlobalTracks ? "enabled" : "disabled", mCfgH.splitCETracks ? "enabled" : "disabled"); } else if (key == 'c') { if (mCfgH.markClusters == 0) { mCfgH.markClusters = 1; diff --git a/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx index cd73cc0b9b34f..d782898380281 100644 --- a/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx +++ b/GPU/GPUTracking/display/helpers/GPUDisplayHelpers.cxx @@ -36,6 +36,13 @@ int32_t GPUDisplay::getNumThreads() } } +void GPUDisplay::updateOptions() +{ + if (mCfgH.splitCETracks == -1 && mParam) { + mCfgH.splitCETracks = mParam->continuousMaxTimeBin != 0; + } +} + void GPUDisplay::disableUnsupportedOptions() { if (!mIOPtrs->mergedTrackHitAttachment) { diff --git a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx index 746c41938e2e1..ffebc373b253f 100644 --- a/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx +++ b/GPU/GPUTracking/display/render/GPUDisplayDraw.cxx @@ -45,7 +45,6 @@ using namespace GPUCA_NAMESPACE::gpu; #define GET_CID(slice, i) (mParam->par.earlyTpcTransform ? mIOPtrs->clusterData[slice][i].id : (mIOPtrs->clustersNative->clusterOffset[slice][0] + i)) -#define SEPERATE_GLOBAL_TRACKS_LIMIT (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT) const GPUTRDGeometry* GPUDisplay::trdGeometry() { return (GPUTRDGeometry*)mCalib->trdGeometry; } const GPUTPCTracker& GPUDisplay::sliceTracker(int32_t iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } @@ -421,6 +420,8 @@ void GPUDisplay::DrawFinal(int32_t iSlice, int32_t /*iCol*/, GPUTPCGMPropagator* } // Print TPC part of track + int32_t separateGlobalTracksLimit = (mCfgH.separateGlobalTracks ? tGLOBALTRACK : TRACK_TYPE_ID_LIMIT); + uint32_t lastSide = -1; for (int32_t k = 0; k < nClusters; k++) { if constexpr (std::is_same_v) { if (mCfgH.hideRejectedClusters && (mIOPtrs->mergedTrackHits[track->FirstClusterRef() + k].state & GPUTPCGMMergedTrackHit::flagReject)) { @@ -435,9 +436,15 @@ void GPUDisplay::DrawFinal(int32_t iSlice, int32_t /*iCol*/, GPUTPCGMPropagator* } int32_t w = mGlobalPos[cid].w; if (drawing) { - drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); + if (mCfgH.splitCETracks && lastSide != (mGlobalPos[cid].z < 0)) { + insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); + drawing = false; + lastCluster = -1; + } else { + drawPointLinestrip(iSlice, cid, tFINALTRACK, separateGlobalTracksLimit); + } } - if (w == SEPERATE_GLOBAL_TRACKS_LIMIT) { + if (w == separateGlobalTracksLimit) { if (drawing) { insertVertexList(vBuf[0], startCountInner, mVertexBuffer[iSlice].size()); } @@ -445,21 +452,21 @@ void GPUDisplay::DrawFinal(int32_t iSlice, int32_t /*iCol*/, GPUTPCGMPropagator* } else { if (!drawing) { startCountInner = mVertexBuffer[iSlice].size(); - } - if (!drawing) { - drawPointLinestrip(iSlice, cid, tFINALTRACK, SEPERATE_GLOBAL_TRACKS_LIMIT); - } - if (!drawing && lastCluster != -1) { - if constexpr (std::is_same_v) { - cid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster].num; - } else { - cid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; + if (lastCluster != -1 && (!mCfgH.splitCETracks || lastSide == (mGlobalPos[cid].z < 0))) { + int32_t lastcid; + if constexpr (std::is_same_v) { + lastcid = mIOPtrs->mergedTrackHits[track->FirstClusterRef() + lastCluster].num; + } else { + lastcid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear; + } + drawPointLinestrip(iSlice, lastcid, tFINALTRACK, separateGlobalTracksLimit); } - drawPointLinestrip(iSlice, cid, 7, SEPERATE_GLOBAL_TRACKS_LIMIT); + drawPointLinestrip(iSlice, cid, tFINALTRACK, separateGlobalTracksLimit); } drawing = true; } lastCluster = k; + lastSide = mGlobalPos[cid].z < 0; } // Print ITS part of track From 1a86fd1e30ecd77d8dc58c7d5bd2612f6c0efaeb Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:57:13 +0100 Subject: [PATCH 0460/2205] DPL: Cleanup unneeded headers --- Framework/Core/src/CommonDataProcessors.cxx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Framework/Core/src/CommonDataProcessors.cxx b/Framework/Core/src/CommonDataProcessors.cxx index d893e16513f40..737e1b7e635c8 100644 --- a/Framework/Core/src/CommonDataProcessors.cxx +++ b/Framework/Core/src/CommonDataProcessors.cxx @@ -17,39 +17,26 @@ #include "Framework/DataProcessingHeader.h" #include "Framework/DataDescriptorQueryBuilder.h" #include "Framework/DataDescriptorMatcher.h" -#include "Framework/DataOutputDirector.h" #include "Framework/DataProcessorSpec.h" #include "Framework/DataProcessingStats.h" #include "Framework/DataSpecUtils.h" -#include "Framework/TableBuilder.h" -#include "Framework/EndOfStreamContext.h" #include "Framework/InitContext.h" #include "Framework/InputSpec.h" -#include "Framework/Logger.h" -#include "Framework/OutputSpec.h" #include "Framework/RawDeviceService.h" #include "Framework/TimesliceIndex.h" #include "Framework/Variant.h" -#include "../../../Algorithm/include/Algorithm/HeaderStack.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/StringHelpers.h" #include "Framework/ChannelSpec.h" -#include "Framework/ChannelSpecHelpers.h" #include "Framework/ExternalFairMQDeviceProxy.h" #include "Framework/RuntimeError.h" #include "Framework/RateLimiter.h" #include "Framework/PluginManager.h" -#include "Framework/DeviceSpec.h" -#include "WorkflowHelpers.h" #include #include -#include #include #include #include #include -#include using namespace o2::framework::data_matcher; From e26063964797762f2719dfeadb97c62b335fd9e8 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Thu, 14 Nov 2024 12:23:03 +0100 Subject: [PATCH 0461/2205] ITSGPU: disable linter for false positive in CUB calls Reported `0`s are detected as to be used as `nullptr`. This is wrong. See also the signature here: https://rocm.docs.amd.com/projects/hipCUB/en/docs-5.7.0/.doxygen/docBin/html/classhipcub_1_1DeviceScan.html --- .../ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index e31e3f378298b..73dcf3bcb4894 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -842,14 +842,14 @@ void countCellsHandler( cellsLUTsHost, // d_in cellsLUTsHost, // d_out nTracklets + 1, // num_items - 0)); + 0)); // NOLINT: this is the offset of the sum, not a pointer discardResult(cudaMalloc(&d_temp_storage, temp_storage_bytes)); gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage temp_storage_bytes, // temp_storage_bytes cellsLUTsHost, // d_in cellsLUTsHost, // d_out nTracklets + 1, // num_items - 0)); + 0)); // NOLINT: this is the offset of the sum, not a pointer // gpu::printBufferLayerOnThread<<<1, 1>>>(layer, cellsLUTsHost, nTracklets + 1); gpuCheckError(cudaFree(d_temp_storage)); } @@ -934,14 +934,14 @@ void countCellNeighboursHandler(CellSeed** cellsLayersDevice, neighboursIndexTable, // d_in neighboursIndexTable, // d_out nCells + 1, // num_items - 0)); + 0)); // NOLINT: this is the offset of the sum, not a pointer discardResult(cudaMalloc(&d_temp_storage_2, temp_storage_bytes_2)); gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage_2, // d_temp_storage temp_storage_bytes_2, // temp_storage_bytes neighboursIndexTable, // d_in neighboursIndexTable, // d_out nCells + 1, // num_items - 0)); + 0)); // NOLINT: this is the offset of the sum, not a pointer gpuCheckError(cudaFree(d_temp_storage)); gpuCheckError(cudaFree(d_temp_storage_2)); gpuCheckError(cudaPeekAtLastError()); @@ -1032,4 +1032,4 @@ void trackSeedHandler(CellSeed* trackSeeds, gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); } -} // namespace o2::its \ No newline at end of file +} // namespace o2::its From 3486413113c892d7293ec5dcddac58db5301acc0 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:17:55 +0100 Subject: [PATCH 0462/2205] DPL: Use AnalysisContext also in the case of amended topologies --- Framework/Core/src/ArrowSupport.cxx | 44 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/Framework/Core/src/ArrowSupport.cxx b/Framework/Core/src/ArrowSupport.cxx index 230d708b47dc7..e6f8fb90c7af9 100644 --- a/Framework/Core/src/ArrowSupport.cxx +++ b/Framework/Core/src/ArrowSupport.cxx @@ -420,16 +420,18 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() auto builder = std::find_if(workflow.begin(), workflow.end(), [](DataProcessorSpec const& spec) { return spec.name == "internal-dpl-aod-index-builder"; }); auto reader = std::find_if(workflow.begin(), workflow.end(), [](DataProcessorSpec const& spec) { return spec.name == "internal-dpl-aod-reader"; }); auto writer = std::find_if(workflow.begin(), workflow.end(), [](DataProcessorSpec const& spec) { return spec.name == "internal-dpl-aod-writer"; }); - std::vector requestedAODs; - std::vector requestedDYNs; - std::vector providedDYNs; + auto &ac = ctx.services().get(); + ac.requestedAODs.clear(); + ac.requestedDYNs.clear(); + ac.providedDYNs.clear(); + auto inputSpecLessThan = [](InputSpec const& lhs, InputSpec const& rhs) { return DataSpecUtils::describe(lhs) < DataSpecUtils::describe(rhs); }; auto outputSpecLessThan = [](OutputSpec const& lhs, OutputSpec const& rhs) { return DataSpecUtils::describe(lhs) < DataSpecUtils::describe(rhs); }; if (builder != workflow.end()) { // collect currently requested IDXs - std::vector requestedIDXs; + ac.requestedIDXs.clear(); for (auto& d : workflow) { if (d.name == builder->name) { continue; @@ -437,7 +439,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() for (auto& i : d.inputs) { if (DataSpecUtils::partialMatch(i, header::DataOrigin{"IDX"})) { auto copy = i; - DataSpecUtils::updateInputList(requestedIDXs, std::move(copy)); + DataSpecUtils::updateInputList(ac.requestedIDXs, std::move(copy)); } } } @@ -446,8 +448,8 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() builder->outputs.clear(); // replace AlgorithmSpec // FIXME: it should be made more generic, so it does not need replacement... - builder->algorithm = readers::AODReaderHelpers::indexBuilderCallback(requestedIDXs); - AnalysisSupportHelpers::addMissingOutputsToBuilder(requestedIDXs, requestedAODs, requestedDYNs, *builder); + builder->algorithm = readers::AODReaderHelpers::indexBuilderCallback(ac.requestedIDXs); + AnalysisSupportHelpers::addMissingOutputsToBuilder(ac.requestedIDXs, ac.requestedAODs, ac.requestedDYNs, *builder); } if (spawner != workflow.end()) { @@ -459,20 +461,20 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() for (auto const& i : d.inputs) { if (DataSpecUtils::partialMatch(i, header::DataOrigin{"DYN"})) { auto copy = i; - DataSpecUtils::updateInputList(requestedDYNs, std::move(copy)); + DataSpecUtils::updateInputList(ac.requestedDYNs, std::move(copy)); } } for (auto const& o : d.outputs) { if (DataSpecUtils::partialMatch(o, header::DataOrigin{"DYN"})) { - providedDYNs.emplace_back(o); + ac.providedDYNs.emplace_back(o); } } } - std::sort(requestedDYNs.begin(), requestedDYNs.end(), inputSpecLessThan); - std::sort(providedDYNs.begin(), providedDYNs.end(), outputSpecLessThan); + std::sort(ac.requestedDYNs.begin(), ac.requestedDYNs.end(), inputSpecLessThan); + std::sort(ac.providedDYNs.begin(), ac.providedDYNs.end(), outputSpecLessThan); std::vector spawnerInputs; - for (auto& input : requestedDYNs) { - if (std::none_of(providedDYNs.begin(), providedDYNs.end(), [&input](auto const& x) { return DataSpecUtils::match(input, x); })) { + for (auto& input : ac.requestedDYNs) { + if (std::none_of(ac.providedDYNs.begin(), ac.providedDYNs.end(), [&input](auto const& x) { return DataSpecUtils::match(input, x); })) { spawnerInputs.emplace_back(input); } } @@ -482,7 +484,7 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // replace AlgorithmSpec // FIXME: it should be made more generic, so it does not need replacement... spawner->algorithm = readers::AODReaderHelpers::aodSpawnerCallback(spawnerInputs); - AnalysisSupportHelpers::addMissingOutputsToSpawner({}, spawnerInputs, requestedAODs, *spawner); + AnalysisSupportHelpers::addMissingOutputsToSpawner({}, spawnerInputs, ac.requestedAODs, *spawner); } if (writer != workflow.end()) { @@ -496,14 +498,14 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() for (auto const& i : d.inputs) { if (DataSpecUtils::partialMatch(i, AODOrigins)) { auto copy = i; - DataSpecUtils::updateInputList(requestedAODs, std::move(copy)); + DataSpecUtils::updateInputList(ac.requestedAODs, std::move(copy)); } } } // remove unmatched outputs auto o_end = std::remove_if(reader->outputs.begin(), reader->outputs.end(), [&](OutputSpec const& o) { - return !DataSpecUtils::partialMatch(o, o2::header::DataDescription{"TFNumber"}) && !DataSpecUtils::partialMatch(o, o2::header::DataDescription{"TFFilename"}) && std::none_of(requestedAODs.begin(), requestedAODs.end(), [&](InputSpec const& i) { return DataSpecUtils::match(i, o); }); + return !DataSpecUtils::partialMatch(o, o2::header::DataDescription{"TFNumber"}) && !DataSpecUtils::partialMatch(o, o2::header::DataDescription{"TFFilename"}) && std::none_of(ac.requestedAODs.begin(), ac.requestedAODs.end(), [&](InputSpec const& i) { return DataSpecUtils::match(i, o); }); }); reader->outputs.erase(o_end, reader->outputs.end()); if (reader->outputs.empty()) { @@ -521,22 +523,22 @@ o2::framework::ServiceSpec ArrowSupport::arrowBackendSpec() // select outputs of type AOD which need to be saved // ATTENTION: if there are dangling outputs the getGlobalAODSink // has to be created in any case! - std::vector outputsInputsAOD; + ac.outputsInputsAOD.clear(); for (auto ii = 0u; ii < outputsInputs.size(); ii++) { if (DataSpecUtils::partialMatch(outputsInputs[ii], extendedAODOrigins)) { auto ds = dod->getDataOutputDescriptors(outputsInputs[ii]); if (!ds.empty() || isDangling[ii]) { - outputsInputsAOD.emplace_back(outputsInputs[ii]); + ac.outputsInputsAOD.emplace_back(outputsInputs[ii]); } } } // file sink for any AOD output - if (!outputsInputsAOD.empty()) { + if (!ac.outputsInputsAOD.empty()) { // add TFNumber and TFFilename as input to the writer - outputsInputsAOD.emplace_back("tfn", "TFN", "TFNumber"); - outputsInputsAOD.emplace_back("tff", "TFF", "TFFilename"); + ac.outputsInputsAOD.emplace_back("tfn", "TFN", "TFNumber"); + ac.outputsInputsAOD.emplace_back("tff", "TFF", "TFFilename"); workflow.push_back(AnalysisSupportHelpers::getGlobalAODSink(ctx)); } // Move the dummy sink at the end, if needed From 66df649cb46568a62fde730fcf3fede0a6e2f27c Mon Sep 17 00:00:00 2001 From: Sean Murray Date: Thu, 14 Nov 2024 16:16:25 +0100 Subject: [PATCH 0463/2205] TRD add less than operator to Tracklet64 to permit std::merge usage --- DataFormats/Detectors/TRD/src/Tracklet64.cxx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/DataFormats/Detectors/TRD/src/Tracklet64.cxx b/DataFormats/Detectors/TRD/src/Tracklet64.cxx index 9245165709979..d7b63cae45354 100644 --- a/DataFormats/Detectors/TRD/src/Tracklet64.cxx +++ b/DataFormats/Detectors/TRD/src/Tracklet64.cxx @@ -40,6 +40,16 @@ std::ostream& operator<<(std::ostream& stream, const Tracklet64& trg) trg.printStream(stream); return stream; } + +bool operator<(const Tracklet64& lhs, const Tracklet64& rhs) +{ + return (lhs.getDetector() < rhs.getDetector()) || + (lhs.getDetector() == rhs.getDetector() && lhs.getROB() < rhs.getROB()) || + (lhs.getDetector() == rhs.getDetector() && lhs.getROB() == rhs.getROB() && lhs.getMCM() < rhs.getMCM()) || + (lhs.getDetector() == rhs.getDetector() && lhs.getROB() == rhs.getROB() && lhs.getMCM() == rhs.getMCM() && lhs.getPadRow() < rhs.getPadRow()) || + (lhs.getDetector() == rhs.getDetector() && lhs.getROB() == rhs.getROB() && lhs.getMCM() == rhs.getMCM() && lhs.getPadRow() == rhs.getPadRow() && lhs.getPadCol() < rhs.getPadCol()); +} + #endif // GPUCA_GPUCODE_DEVICE } // namespace trd From 6b8ca303d7107dc76fcd6492dd3f8da612ae4a69 Mon Sep 17 00:00:00 2001 From: Sawan Date: Thu, 14 Nov 2024 10:06:03 +0530 Subject: [PATCH 0464/2205] added particle a2(1320) in the O2Database for the study of glueball --- .../simulation/include/SimulationDataFormat/O2DatabasePDG.h | 4 ++++ Steer/src/O2MCApplication.cxx | 3 +++ 2 files changed, 7 insertions(+) diff --git a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h index 3487f7a0e5aef..229a1a7a8a535 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h +++ b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h @@ -500,6 +500,10 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db) } // glueball hunting + ionCode = 115; + if (!db->GetParticle(ionCode)) { + db->AddParticle("a2_1320", "a2_1320", 1.3182, kFALSE, 0.1078, 0, "Resonance", ionCode); + } ionCode = 10221; if (!db->GetParticle(ionCode)) { db->AddParticle("f0_1370", "f0_1370", 1.37, kFALSE, 0.200, 0, "Resonance", ionCode); diff --git a/Steer/src/O2MCApplication.cxx b/Steer/src/O2MCApplication.cxx index 240e56aba28c4..96cc2f2e969db 100644 --- a/Steer/src/O2MCApplication.cxx +++ b/Steer/src/O2MCApplication.cxx @@ -388,6 +388,8 @@ void addSpecialParticles() // Their life times are not known, so we set them to 1e-24 // f0(1370) (PDG: width = 200-500 MeV) Spin/Parity might not be correct TVirtualMC::GetMC()->DefineParticle(10221, "f0_1370", kPTNeutron, 1.37, 0.0, 1e-24, "Hadron", 0.2, 1, 1, 1, 0, 0, 1, 0, 0, kTRUE); + // a2(1320) (PDG: width = 107.8 MeV) (Spin/Parity might not be correct) + TVirtualMC::GetMC()->DefineParticle(115, "a2_1320", kPTNeutron, 1.3182, 0.0, 1e-24, "Hadron", 0.1078, 1, 1, 1, 1, 0, 1, 0, 0, kTRUE); // f0(1500) (PDG: width = 112 MeV) Spin/Parity might not be correct TVirtualMC::GetMC()->DefineParticle(9030221, "f0_1500", kPTNeutron, 1.506, 0.0, 1e-24, "Hadron", 0.112, 0, 1, 1, 0, 0, 1, 0, 0, kTRUE); // f0(1710) (PDG: width = 139 MeV) Spin/Parity might not be correct @@ -1242,6 +1244,7 @@ void addSpecialParticles() TVirtualMC::GetMC()->SetDecayMode(335, bratio, mode); // f2(1525) TVirtualMC::GetMC()->SetDecayMode(10331, bratio, mode); // f0(1710) TVirtualMC::GetMC()->SetDecayMode(10221, bratio, mode); // f0(1370) + TVirtualMC::GetMC()->SetDecayMode(115, bratio, mode); // a2(1320) // Define the 3-body phase space decay for the resonances: f1(1285), f1(1420) for (Int_t kz = 0; kz < 6; kz++) { From 9fa6915dea9e5f948743b41d96b630a25e1db577 Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 15 Nov 2024 13:16:02 +0100 Subject: [PATCH 0465/2205] Orbit-early treatment in CollisionContext tool Developments to allow treatment/inclusion of additional orbits before each timeframe start: - A new option `--earlyOrbits x` will prepend x orbits with collisions before the firstOrbit asked - It will also do the same in each individual timeframe collision context extracted from the global context - Collisions falling within the 'earlyOrbit' range are always kept and not filtered out based on a maximal count filter Some cleanup. Some restructuring/simplification of DigitizationContext: - less internal state - timeframe boundary indices are generalized from (start, end) --> (start, end, previous) where previous is the index from which on this timeframe can still be influenced with an earlyOrbit criterion --- .../DigitizationContext.h | 20 +-- .../simulation/src/DigitizationContext.cxx | 151 +++++++++++++++--- Steer/src/CollisionContextTool.cxx | 46 ++++-- 3 files changed, 174 insertions(+), 43 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h index 4149b32683060..4bd5dfa2ab76c 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h +++ b/DataFormats/simulation/include/SimulationDataFormat/DigitizationContext.h @@ -115,8 +115,8 @@ class DigitizationContext /// retrieves collision context for a single timeframe-id (which may be needed by simulation) /// (Only copies collision context without QED information. This can be added to the result with the fillQED method - /// in a second step. As a pre-condition, one should have called finalizeTimeframeStructure) - DigitizationContext extractSingleTimeframe(int timeframeid, std::vector const& sources_to_offset); + /// in a second step. Takes as input a timeframe indices collection) + DigitizationContext extractSingleTimeframe(int timeframeid, std::vector> const& timeframeindices, std::vector const& sources_to_offset); /// function reading the hits from a chain (previously initialized with initSimChains /// The hits pointer will be initialized (what to we do about ownership??) @@ -130,12 +130,12 @@ class DigitizationContext /// returns the GRP object associated to this context o2::parameters::GRPObject const& getGRP() const; - // apply collision number cuts and potential relabeling of eventID - void applyMaxCollisionFilter(long startOrbit, long orbitsPerTF, int maxColl); + // apply collision number cuts and potential relabeling of eventID, (keeps collisions which fall into the orbitsEarly range for the next timeframe) + // needs a timeframe index structure (determined by calcTimeframeIndices), which is adjusted during the process to reflect the filtering + void applyMaxCollisionFilter(std::vector>& timeframeindices, long startOrbit, long orbitsPerTF, int maxColl, double orbitsEarly = 0.); - /// finalize timeframe structure (fixes the indices in mTimeFrameStartIndex) - // returns the number of timeframes - int finalizeTimeframeStructure(long startOrbit, long orbitsPerTF); + /// get timeframe structure --> index markers where timeframe starts/ends/is_influenced_by + std::vector> calcTimeframeIndices(long startOrbit, long orbitsPerTF, double orbitsEarly = 0.) const; // Sample and fix interaction vertices (according to some distribution). Makes sure that same event ids // have to have same vertex, as well as event ids associated to same collision. @@ -176,17 +176,13 @@ class DigitizationContext // for each collision we record the constituents (which shall not exceed mMaxPartNumber) std::vector> mEventParts; - // for each collision we may record/fix the interaction vertex (to be used in event generation) + // for each collisionstd::vector> &timeframeindice we may record/fix the interaction vertex (to be used in event generation) std::vector> mInteractionVertices; // the collision records **with** QED interleaved; std::vector mEventRecordsWithQED; std::vector> mEventPartsWithQED; - // timeframe structure - std::vector> mTimeFrameStartIndex; // for each timeframe, the pair of start-index and end-index into mEventParts, mEventRecords - std::vector> mTimeFrameStartIndexQED; // for each timeframe, the pair of start-index and end-index into mEventParts, mEventRecords (QED version) - o2::BunchFilling mBCFilling; // pattern of active BCs std::vector mSimPrefixes; // identifiers to the hit sim products; the key corresponds to the source ID of event record diff --git a/DataFormats/simulation/src/DigitizationContext.cxx b/DataFormats/simulation/src/DigitizationContext.cxx index 3fb6b757aeea3..bbb9b384f65fa 100644 --- a/DataFormats/simulation/src/DigitizationContext.cxx +++ b/DataFormats/simulation/src/DigitizationContext.cxx @@ -380,9 +380,67 @@ std::vector> getTimeFrameBoundaries(std::vector(left, right - 1)); return result; } + +// a common helper for timeframe structure - includes indices for orbits-early (orbits from last timeframe still affecting current one) +std::vector> getTimeFrameBoundaries(std::vector const& irecords, + long startOrbit, + long orbitsPerTF, + float orbitsEarly) +{ + // we could actually use the other method first ... then do another pass to fix the early-index ... or impact index + auto true_indices = getTimeFrameBoundaries(irecords, startOrbit, orbitsPerTF); + + std::vector> indices_with_early{}; + for (int ti = 0; ti < true_indices.size(); ++ti) { + // for each timeframe we copy the true indices + auto& tf_range = true_indices[ti]; + + // init new index without fixing the early index yet + indices_with_early.push_back(std::make_tuple(tf_range.first, tf_range.second, -1)); + + // from the second timeframe on we can determine the index in the previous timeframe + // which matches our criterion + if (orbitsEarly > 0. && ti > 0) { + auto& prev_tf_range = true_indices[ti - 1]; + // in this range search the smallest index which precedes + // timeframe ti by not more than "orbitsEarly" orbits + // (could probably use binary search, in case optimization becomes necessary) + int earlyOrbitIndex = prev_tf_range.second; + + // this is the orbit of the ti-th timeframe start + auto orbit_timeframe_start = startOrbit + ti * orbitsPerTF; + + auto orbit_timeframe_early_fractional = orbit_timeframe_start - orbitsEarly; + auto orbit_timeframe_early_integral = (uint32_t)(orbit_timeframe_early_fractional); + + auto bc_early = (uint32_t)((orbit_timeframe_early_fractional - orbit_timeframe_early_integral) * o2::constants::lhc::LHCMaxBunches); + + // this is the interaction record of the ti-th timeframe start + o2::InteractionRecord timeframe_start_record(0, orbit_timeframe_early_integral); + // this is the interaction record in some previous timeframe after which interactions could still + // influence the ti-th timeframe according to orbitsEarly + o2::InteractionRecord timeframe_early_record(bc_early, orbit_timeframe_early_integral); + + auto differenceInBCNS_max = timeframe_start_record.differenceInBCNS(timeframe_early_record); + + for (int j = prev_tf_range.second; j >= prev_tf_range.first; --j) { + // determine difference in timing in NS; compare that with the limit given by orbitsEarly + auto timediff_NS = timeframe_start_record.differenceInBCNS(irecords[j]); + if (timediff_NS < differenceInBCNS_max) { + earlyOrbitIndex = j; + } else { + break; + } + } + std::get<2>(indices_with_early.back()) = earlyOrbitIndex; + } + } + return indices_with_early; +} + } // namespace -void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPerTF, int maxColl) +void DigitizationContext::applyMaxCollisionFilter(std::vector>& timeframeindices, long startOrbit, long orbitsPerTF, int maxColl, double orbitsEarly) { // the idea is to go through each timeframe and throw away collisions beyond a certain count // then the indices should be condensed @@ -390,9 +448,6 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe std::vector> newparts; std::vector newrecords; - // get a timeframe boundary indexing - auto timeframeindices = getTimeFrameBoundaries(mEventRecords, startOrbit, orbitsPerTF); - std::unordered_map currMaxId; // the max id encountered for a source std::unordered_map> reIndexMap; // for each source, a map of old to new index for the event parts @@ -400,12 +455,51 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe maxColl = mEventRecords.size(); } + // the actual first actual timeframe + int first_timeframe = orbitsEarly > 0. ? 1 : 0; + + // mapping of old to new indices + std::unordered_map indices_old_to_new; + // now we can go through the structure timeframe by timeframe - for (auto timeframe : timeframeindices) { - auto firstindex = timeframe.first; - auto lastindex = timeframe.second; + for (int tf_id = first_timeframe; tf_id < timeframeindices.size(); ++tf_id) { + auto& tf_indices = timeframeindices[tf_id]; + + auto firstindex = std::get<0>(tf_indices); // .first; + auto lastindex = std::get<1>(tf_indices); // .second; + auto previndex = std::get<2>(tf_indices); + + LOG(info) << "timeframe indices " << previndex << " : " << firstindex << " : " << lastindex; + + int collCount = 0; // counting collisions within timeframe // copy to new structure - for (int index = firstindex; index <= std::min(lastindex, firstindex + maxColl - 1); ++index) { + for (int index = previndex >= 0 ? previndex : firstindex; index <= lastindex; ++index) { + if (collCount >= maxColl) { + continue; + } + + // look if this index was already done? + // avoid duplicate entries in transformed records + if (indices_old_to_new.find(index) != indices_old_to_new.end()) { + continue; + } + + // we put these events under a certain condition + bool keep = index < firstindex || collCount < maxColl; + + if (!keep) { + continue; + } + + if (index >= firstindex) { + collCount++; + } + + // we must also make sure that we don't duplicate the records + // moreover some records are merely put as precoll of tf2 ---> so they shouldn't be part of tf1 in the final + // extraction, ouch ! + // maybe we should combine the filter and individual tf extraction in one step !! + indices_old_to_new[index] = newrecords.size(); newrecords.push_back(mEventRecords[index]); newparts.push_back(mEventParts[index]); @@ -427,6 +521,19 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe currMaxId[source] += 1; } } + } // ends one timeframe + + // correct the timeframe indices + if (indices_old_to_new.find(firstindex) != indices_old_to_new.end()) { + std::get<0>(tf_indices) = indices_old_to_new[firstindex]; // start + } + if (indices_old_to_new.find(lastindex) != indices_old_to_new.end()) { + std::get<1>(tf_indices) = indices_old_to_new[lastindex]; // end; + } else { + std::get<1>(tf_indices) = newrecords.size(); // end; + } + if (indices_old_to_new.find(previndex) != indices_old_to_new.end()) { + std::get<2>(tf_indices) = indices_old_to_new[previndex]; // previous or "early" index } } // reassignment @@ -434,15 +541,15 @@ void DigitizationContext::applyMaxCollisionFilter(long startOrbit, long orbitsPe mEventParts = newparts; } -int DigitizationContext::finalizeTimeframeStructure(long startOrbit, long orbitsPerTF) +std::vector> DigitizationContext::calcTimeframeIndices(long startOrbit, long orbitsPerTF, double orbitsEarly) const { - mTimeFrameStartIndex = getTimeFrameBoundaries(mEventRecords, startOrbit, orbitsPerTF); - LOG(info) << "Fixed " << mTimeFrameStartIndex.size() << " timeframes "; - for (auto p : mTimeFrameStartIndex) { - LOG(info) << p.first << " " << p.second; + auto timeframeindices = getTimeFrameBoundaries(mEventRecords, startOrbit, orbitsPerTF, orbitsEarly); + LOG(info) << "Fixed " << timeframeindices.size() << " timeframes "; + for (auto p : timeframeindices) { + LOG(info) << std::get<0>(p) << " " << std::get<1>(p) << " " << std::get<2>(p); } - return mTimeFrameStartIndex.size(); + return timeframeindices; } std::unordered_map DigitizationContext::getCollisionIndicesForSource(int source) const @@ -529,21 +636,25 @@ void DigitizationContext::sampleInteractionVertices(o2::dataformats::MeanVertexO } } -DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid, std::vector const& sources_to_offset) +DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid, std::vector> const& timeframeindices, std::vector const& sources_to_offset) { DigitizationContext r; // make a return object - if (mTimeFrameStartIndex.size() == 0) { - LOG(error) << "No timeframe structure determined; Returning empty object. Please call ::finalizeTimeframeStructure before calling this function"; + if (timeframeindices.size() == 0) { + LOG(error) << "Timeframe index structure empty; Returning empty object."; return r; } r.mSimPrefixes = mSimPrefixes; r.mMuBC = mMuBC; try { - auto startend = mTimeFrameStartIndex.at(timeframeid); + auto tf_ranges = timeframeindices.at(timeframeid); - auto startindex = startend.first; - auto endindex = startend.second; + auto startindex = std::get<0>(tf_ranges); + auto endindex = std::get<1>(tf_ranges); + auto earlyindex = std::get<2>(tf_ranges); + if (earlyindex >= 0) { + startindex = earlyindex; + } std::copy(mEventRecords.begin() + startindex, mEventRecords.begin() + endindex, std::back_inserter(r.mEventRecords)); std::copy(mEventParts.begin() + startindex, mEventParts.begin() + endindex, std::back_inserter(r.mEventParts)); if (mInteractionVertices.size() > endindex) { diff --git a/Steer/src/CollisionContextTool.cxx b/Steer/src/CollisionContextTool.cxx index 3d1dcec29976e..9cb4d401f3851 100644 --- a/Steer/src/CollisionContextTool.cxx +++ b/Steer/src/CollisionContextTool.cxx @@ -40,12 +40,12 @@ struct Options { std::vector interactionRates; std::string qedInteraction; // specification for QED contribution std::string outfilename; // - double timeframelengthinMS; // timeframe length in milliseconds int orbits; // number of orbits to generate (can be a multiple of orbitsPerTF --> determine fraction or multiple of timeframes) long seed; // bool printContext = false; std::string bcpatternfile; int tfid = 0; // tfid -> used to calculate start orbit for collisions + double orbitsEarly = 0.; // how many orbits from a prev timeframe should still be kept in the current timeframe double firstFractionalOrbit; // capture orbit and bunch crossing via decimal number uint32_t firstOrbit = 0; // first orbit in run (orbit offset) uint32_t firstBC = 0; // first bunch crossing (relative to firstOrbit) of the first interaction; @@ -191,7 +191,7 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) options.add_options()( "interactions,i", bpo::value>(&optvalues.interactionRates)->multitoken(), "name,IRate|LockSpecifier")( - "QEDinteraction", bpo::value(&optvalues.qedInteraction)->default_value(""), "Interaction specifyer for QED contribution (name,IRATE,maxeventnumber)")( + "QEDinteraction", bpo::value(&optvalues.qedInteraction)->default_value(""), "Interaction specifier for QED contribution (name,IRATE,maxeventnumber)")( "outfile,o", bpo::value(&optvalues.outfilename)->default_value("collisioncontext.root"), "Outfile of collision context")( "orbits", bpo::value(&optvalues.orbits)->default_value(-1), "Number of orbits to generate maximally (if given, can be used to determine the number of timeframes). " @@ -200,6 +200,7 @@ bool parseOptions(int argc, char* argv[], Options& optvalues) "show-context", "Print generated collision context to terminal.")( "bcPatternFile", bpo::value(&optvalues.bcpatternfile)->default_value(""), "Interacting BC pattern file (e.g. from CreateBCPattern.C); Use \"ccdb\" when fetching from CCDB.")( "orbitsPerTF", bpo::value(&optvalues.orbitsPerTF)->default_value(256), "Orbits per timeframes")( + "orbitsEarly", bpo::value(&optvalues.orbitsEarly)->default_value(0.), "Number of orbits with extra collisions prefixed to each timeframe")( "use-existing-kine", "Read existing kinematics to adjust event counts")( "timeframeID", bpo::value(&optvalues.tfid)->default_value(0), "Timeframe id of the first timeframe int this context. Allows to generate contexts for different start orbits")( "first-orbit", bpo::value(&optvalues.firstFractionalOrbit)->default_value(0), "First (fractional) orbit in the run (HBFUtils.firstOrbit + BC from decimal)")( @@ -273,7 +274,6 @@ int main(int argc, char* argv[]) // now we generate the collision structure (interaction type by interaction type) bool usetimeframelength = options.orbits > 0; - o2::InteractionTimeRecord limitInteraction(0, options.orbits); auto setBCFillingHelper = [&options](auto& sampler, auto& bcPatternString) { if (bcPatternString == "ccdb") { @@ -290,7 +290,14 @@ int main(int argc, char* argv[]) } }; + // this is the starting orbit from which on we construct interactions (it is possibly shifted by one tf to the left + // in order to generate eventual "earlyOrbits" auto orbitstart = options.firstOrbit + options.tfid * options.orbitsPerTF; + auto orbits_total = options.orbits; + if (options.orbitsEarly > 0.) { + orbitstart -= options.orbitsPerTF; + orbits_total += options.orbitsPerTF; + } for (int id = 0; id < ispecs.size(); ++id) { auto mode = ispecs[id].syncmode; @@ -306,10 +313,10 @@ int main(int argc, char* argv[]) sampler.setFirstIR(o2::InteractionRecord(options.firstBC, orbitstart)); sampler.init(); record = sampler.generateCollisionTime(); - } while (options.noEmptyTF && usetimeframelength && record.orbit >= orbitstart + options.orbits); + } while (options.noEmptyTF && usetimeframelength && record.orbit >= orbitstart + orbits_total); int count = 0; do { - if (usetimeframelength && record.orbit >= orbitstart + options.orbits) { + if (usetimeframelength && record.orbit >= orbitstart + orbits_total) { break; } std::vector parts; @@ -320,7 +327,7 @@ int main(int argc, char* argv[]) collisions.insert(iter, insertvalue); record = sampler.generateCollisionTime(); count++; - } while ((ispecs[id].mcnumberasked > 0 && count < ispecs[id].mcnumberasked)); + } while ((ispecs[id].mcnumberasked > 0 && count < ispecs[id].mcnumberasked)); // TODO: this loop should probably be replaced by a condition with usetimeframelength and number of orbits // we support randomization etc on non-injected/embedded interactions // and we can apply them here @@ -446,10 +453,25 @@ int main(int argc, char* argv[]) } digicontext.setSimPrefixes(prefixes); + // <---- at this moment we have a dense collision context (not representing the final output we want) + LOG(info) << "<<------ DENSE CONTEXT ---------"; + if (options.printContext) { + digicontext.printCollisionSummary(options.qedInteraction.size() > 0); + } + LOG(info) << "-------- DENSE CONTEXT ------->>"; + + auto timeframeindices = digicontext.calcTimeframeIndices(orbitstart, options.orbitsPerTF, options.orbitsEarly); // apply max collision per timeframe filters + reindexing of event id (linearisation and compactification) - digicontext.applyMaxCollisionFilter(orbitstart, options.orbitsPerTF, options.maxCollsPerTF); + digicontext.applyMaxCollisionFilter(timeframeindices, orbitstart, options.orbitsPerTF, options.maxCollsPerTF, options.orbitsEarly); + + // <---- at this moment we have a dense collision context (not representing the final output we want) + LOG(info) << "<<------ FILTERED CONTEXT ---------"; + if (options.printContext) { + digicontext.printCollisionSummary(options.qedInteraction.size() > 0); + } + LOG(info) << "-------- FILTERED CONTEXT ------->>"; - auto numTimeFrames = digicontext.finalizeTimeframeStructure(orbitstart, options.orbitsPerTF); + auto numTimeFrames = timeframeindices.size(); // digicontext.finalizeTimeframeStructure(orbitstart, options.orbitsPerTF, options.orbitsEarly); if (options.vertexMode != o2::conf::VertexMode::kNoVertex) { switch (options.vertexMode) { @@ -539,9 +561,11 @@ int main(int argc, char* argv[]) sources_to_offset.push_back(digicontext.findSimPrefix(tokens[i])); } + auto first_timeframe = options.orbitsEarly > 0. ? 1 : 0; // now we are ready to loop over all timeframes - for (int tf_id = 0; tf_id < numTimeFrames; ++tf_id) { - auto copy = digicontext.extractSingleTimeframe(tf_id, sources_to_offset); + int tf_output_counter = 1; + for (int tf_id = first_timeframe; tf_id < numTimeFrames; ++tf_id) { + auto copy = digicontext.extractSingleTimeframe(tf_id, timeframeindices, sources_to_offset); // each individual case gets QED interactions injected // This should probably be done inside the extraction itself @@ -551,7 +575,7 @@ int main(int argc, char* argv[]) } std::stringstream str; - str << path_prefix << (tf_id + 1) << "/collisioncontext.root"; + str << path_prefix << tf_output_counter++ << "/collisioncontext.root"; copy.saveToFile(str.str()); LOG(info) << "----"; copy.printCollisionSummary(options.qedInteraction.size() > 0); From 19fd6971870ff54dda967314c18248cbb25d58d1 Mon Sep 17 00:00:00 2001 From: Matthias Kleiner Date: Thu, 14 Nov 2024 11:36:20 +0100 Subject: [PATCH 0466/2205] TPC: add check for empty data when receiving IDCs --- .../TPCFourierTransformAggregatorSpec.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h index adc43ee6d0258..956e9c899cebc 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/TPCFourierTransformAggregatorSpec.h @@ -74,7 +74,12 @@ class TPCFourierTransformAggregatorSpec : public o2::framework::Task return; } - mCCDBBuffer[lane] = pc.inputs().get>("tsccdb"); + const auto tsTmp = pc.inputs().get>("tsccdb"); + if (tsTmp.front() == 0) { + LOGP(warning, "Received dummy data with empty timestamp"); + return; + } + mCCDBBuffer[lane] = tsTmp; if (mProcessedTimeStamp > mCCDBBuffer[lane].front()) { LOGP(warning, "Already received data from a later time stamp {} then the currently received time stamp {}! (This might not be an issue)", mProcessedTimeStamp, mCCDBBuffer[lane].front()); } else { @@ -289,6 +294,7 @@ class TPCFourierTransformAggregatorSpec : public o2::framework::Task if (eos) { // in case of eos write out everything lastValidIdx = times.empty() ? -1 : times.size() - 1; + LOGP(info, "End of stream detected: Creating IDC scalers with {} IDC objects", lastValidIdx); } // create IDC scaler in case index is valid @@ -342,7 +348,13 @@ class TPCFourierTransformAggregatorSpec : public o2::framework::Task const float deltaTime = times[i + 1].first - time.second; // if delta time is too large add dummy values if (deltaTime > (timesDuration / checkGapp)) { - const int nDummyValues = deltaTime / idcIntegrationTime + 0.5; + int nDummyValues = deltaTime / idcIntegrationTime + 0.5; + // restrict dummy values + const int nMaxDummyValues = checkGapp * timesDuration / idcIntegrationTime; + if (nDummyValues > nMaxDummyValues) { + nDummyValues = nMaxDummyValues; + } + // add dummy to A if (idc.idc1[0].size() > 0) { float meanA = std::reduce(idc.idc1[0].begin(), idc.idc1[0].end()) / static_cast(idc.idc1[0].size()); From 13bdce12f4f9ed2fd21f14714d052ef9c538b188 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Fri, 15 Nov 2024 15:40:29 +0100 Subject: [PATCH 0467/2205] HBFUtils: Optional throw on failed parsing of opt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also fixed the use of ’--hbfutils-config none’. --- Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h | 2 +- Detectors/Raw/src/HBFUtilsInitializer.cxx | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h b/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h index 895eff097e7a0..3d44f9f0bb4bb 100644 --- a/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h +++ b/Detectors/Raw/include/DetectorsRaw/HBFUtilsInitializer.h @@ -64,7 +64,7 @@ struct HBFUtilsInitializer { static o2::dataformats::IRFrame IRFrameSel; // IRFrame selected for the current TF HBFUtilsInitializer(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& wf); - static HBFOpt getOptType(const std::string& optString); + static HBFOpt getOptType(const std::string& optString, bool throwOnFailure = true); static std::vector readTFIDInfoVector(const std::string& fname); static void readIRFramesVector(const std::string& fname); static void assignDataHeaderFromTFIDInfo(const std::vector& tfinfoVec, o2::header::DataHeader& dh, o2::framework::DataProcessingHeader& dph); diff --git a/Detectors/Raw/src/HBFUtilsInitializer.cxx b/Detectors/Raw/src/HBFUtilsInitializer.cxx index e3cc9a8eef414..1b0dbdbf3fe30 100644 --- a/Detectors/Raw/src/HBFUtilsInitializer.cxx +++ b/Detectors/Raw/src/HBFUtilsInitializer.cxx @@ -65,7 +65,7 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext upstream = true; continue; } - HBFOpt opt = getOptType(optStr); + HBFOpt opt = getOptType(optStr, !helpasked); // do not throw on unknown opt if help-opt was given nopts++; if ((opt == HBFOpt::INI || opt == HBFOpt::JSON) && !helpasked) { o2::conf::ConfigurableParam::updateFromFile(optStr, "HBFUtils", true); // update only those values which were not touched yet (provenance == kCODE) @@ -78,8 +78,6 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext hbfuInput = optStr; } else if (opt == HBFOpt::ROOT) { rootFileInput = optStr; - } else if (!helpasked) { - LOGP(fatal, "uknown hbfutils-config option {}", optStr); } } if (!nopts && !helpasked) { @@ -125,7 +123,7 @@ HBFUtilsInitializer::HBFUtilsInitializer(const o2f::ConfigContext& configcontext } //_________________________________________________________ -HBFUtilsInitializer::HBFOpt HBFUtilsInitializer::getOptType(const std::string& optString) +HBFUtilsInitializer::HBFOpt HBFUtilsInitializer::getOptType(const std::string& optString, bool throwOnFailure) { // return type of the file provided via HBFConfOpt HBFOpt opt = HBFOpt::NONE; @@ -138,7 +136,7 @@ HBFUtilsInitializer::HBFOpt HBFUtilsInitializer::getOptType(const std::string& o opt = HBFOpt::ROOT; } else if (optString == HBFUSrc) { opt = HBFOpt::HBFUTILS; - } else if (optString != "none") { + } else if (optString != "none" && throwOnFailure) { throw std::runtime_error(fmt::format("invalid option {} for {}", optString, HBFConfOpt)); } } From adcd323449830b18aa797c136c1e46c43281b70b Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 15 Nov 2024 18:37:36 +0100 Subject: [PATCH 0468/2205] Limit TFs extraxted from CTF file with --max-tf-per-file CTF-reader N --- Detectors/CTF/README.md | 5 +++++ Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h | 1 + Detectors/CTF/workflow/src/CTFReaderSpec.cxx | 2 +- Detectors/CTF/workflow/src/ctf-reader-workflow.cxx | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Detectors/CTF/README.md b/Detectors/CTF/README.md index 48fa78c896a86..e1e65060db523 100644 --- a/Detectors/CTF/README.md +++ b/Detectors/CTF/README.md @@ -100,6 +100,11 @@ comma-separated list of detectors to skip ``` max CTFs to process (<= 0 : infinite) +``` +--max-tf-per-file arg (=-1) +``` +max TFs to process from every CTF file (<= 0 : infinite) + ``` --loop arg (=0) ``` diff --git a/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h b/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h index 501541f25cf27..997572e0371b2 100644 --- a/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h +++ b/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h @@ -40,6 +40,7 @@ struct CTFReaderInp { int64_t delay_us = 0; int maxLoops = 0; int maxTFs = -1; + int maxTFsPerFile = -1; unsigned int subspec = 0; unsigned int decSSpecEMC = 0; int tfRateLimit = -999; diff --git a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx index 681547f9a814c..9b16e65c3a2b7 100644 --- a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx +++ b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx @@ -360,7 +360,7 @@ bool CTFReaderSpec::processTF(ProcessingContext& pc) void CTFReaderSpec::checkTreeEntries() { // check if the tree has entries left, if needed, close current tree/file - if (++mCurrTreeEntry >= mCTFTree->GetEntries()) { // this file is done, check if there are other files + if (++mCurrTreeEntry >= mCTFTree->GetEntries() || (mInput.maxTFsPerFile > 0 && mCurrTreeEntry >= mInput.maxTFsPerFile)) { // this file is done, check if there are other files mCTFTree.reset(); mCTFFile->Close(); mCTFFile.reset(); diff --git a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx index ef3a0f8d3c2c4..a12c9c10f9dd8 100644 --- a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx +++ b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx @@ -55,6 +55,7 @@ void customize(std::vector& workflowOptions) options.push_back(ConfigParamSpec{"onlyDet", VariantType::String, std::string{DetID::ALL}, {"comma-separated list of detectors to accept. Overrides skipDet"}}); options.push_back(ConfigParamSpec{"skipDet", VariantType::String, std::string{DetID::NONE}, {"comma-separate list of detectors to skip"}}); options.push_back(ConfigParamSpec{"max-tf", VariantType::Int, -1, {"max CTFs to process (<= 0 : infinite)"}}); + options.push_back(ConfigParamSpec{"max-tf-per-file", VariantType::Int, -1, {"max TFs to process per ctf file (<= 0 : infinite)"}}); options.push_back(ConfigParamSpec{"loop", VariantType::Int, 0, {"loop N times (infinite for N<0)"}}); options.push_back(ConfigParamSpec{"delay", VariantType::Float, 0.f, {"delay in seconds between consecutive TFs sending"}}); options.push_back(ConfigParamSpec{"copy-cmd", VariantType::String, "alien_cp ?src file://?dst", {"copy command for remote files or no-copy to avoid copying"}}); // Use "XrdSecPROTOCOL=sss,unix xrdcp -N root://eosaliceo2.cern.ch/?src ?dst" for direct EOS access @@ -119,6 +120,9 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) int n = configcontext.options().get("max-tf"); ctfInput.maxTFs = n > 0 ? n : 0x7fffffff; + n = configcontext.options().get("max-tf-per-file"); + ctfInput.maxTFsPerFile = n > 0 ? n : 0x7fffffff; + ctfInput.maxFileCache = std::max(1, configcontext.options().get("max-cached-files")); ctfInput.copyCmd = configcontext.options().get("copy-cmd"); From fd4a6d226b440c61e9cd7a9419e268c6b7854c14 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Thu, 14 Nov 2024 18:37:33 +0100 Subject: [PATCH 0469/2205] GPU: Fix debug message --- .../Base/opencl-common/GPUReconstructionOCL.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx index 0e1c94eced7e3..de32f03340c03 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx @@ -115,16 +115,17 @@ int32_t GPUReconstructionOCL::InitDevice_Runtime() clGetPlatformInfo(mInternals->platforms[i_platform], CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, nullptr); clGetPlatformInfo(mInternals->platforms[i_platform], CL_PLATFORM_NAME, sizeof(platform_name), platform_name, nullptr); clGetPlatformInfo(mInternals->platforms[i_platform], CL_PLATFORM_VENDOR, sizeof(platform_vendor), platform_vendor, nullptr); - if (mProcessingSettings.debugLevel >= 2) { - GPUInfo("Available Platform %d: (%s %s) %s %s", i_platform, platform_profile, platform_version, platform_vendor, platform_name); - } + const char* platformUsageInfo = ""; if (!found && CheckPlatform(i_platform)) { found = true; mInternals->platform = mInternals->platforms[i_platform]; if (mProcessingSettings.debugLevel >= 2) { - GPUInfo(" Using this platform"); + platformUsageInfo = " !!! Using this platform !!!"; } } + if (mProcessingSettings.debugLevel >= 2) { + GPUInfo("Available Platform %d: (%s %s) %s %s%s", i_platform, platform_profile, platform_version, platform_vendor, platform_name, platformUsageInfo); + } } } From cb97e7a4792e70df9e2b32ad9bbaeb013bccb880 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Fri, 15 Nov 2024 23:46:53 +0100 Subject: [PATCH 0470/2205] GPU: Clarify file name --- .../Base/GPUReconstructionIncludesDeviceAll.template.h | 4 ---- ...nels.template.h => GPUReconstructionKernelList.template.h} | 0 GPU/GPUTracking/CMakeLists.txt | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) rename GPU/GPUTracking/Base/{GPUReconstructionKernels.template.h => GPUReconstructionKernelList.template.h} (100%) diff --git a/GPU/GPUTracking/Base/GPUReconstructionIncludesDeviceAll.template.h b/GPU/GPUTracking/Base/GPUReconstructionIncludesDeviceAll.template.h index 8a23a6792dcd1..4822332a1839c 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionIncludesDeviceAll.template.h +++ b/GPU/GPUTracking/Base/GPUReconstructionIncludesDeviceAll.template.h @@ -25,10 +25,6 @@ namespace gpu } // namespace GPUCA_NAMESPACE using namespace GPUCA_NAMESPACE::gpu; -#if !defined(GPUCA_OPENCL1) && (!defined(GPUCA_ALIROOT_LIB) || !defined(GPUCA_GPUCODE)) -#define GPUCA_KRNL_NOOCL1 -#endif - // clang-format off $>,APPEND,">,PREPEND,#include ">, > diff --git a/GPU/GPUTracking/Base/GPUReconstructionKernels.template.h b/GPU/GPUTracking/Base/GPUReconstructionKernelList.template.h similarity index 100% rename from GPU/GPUTracking/Base/GPUReconstructionKernels.template.h rename to GPU/GPUTracking/Base/GPUReconstructionKernelList.template.h diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index f97e966287d41..937346fe478c3 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -265,7 +265,7 @@ endif() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include_gpu_onthefly) file(GENERATE OUTPUT include_gpu_onthefly/GPUReconstructionKernelList.h - INPUT Base/GPUReconstructionKernels.template.h + INPUT Base/GPUReconstructionKernelList.template.h ) file(GENERATE OUTPUT include_gpu_onthefly/GPUReconstructionKernelIncludes.h From 4c0671a33e1f518ae11dd21f2f7dd27548afa18a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 00:13:52 +0100 Subject: [PATCH 0471/2205] GPU OpenCL: subgroup functions not defined for int8 --- GPU/Common/GPUCommonAlgorithm.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/GPU/Common/GPUCommonAlgorithm.h b/GPU/Common/GPUCommonAlgorithm.h index f86bd42fe82f6..e5a963b4c2020 100644 --- a/GPU/Common/GPUCommonAlgorithm.h +++ b/GPU/Common/GPUCommonAlgorithm.h @@ -338,8 +338,29 @@ GPUdi() void GPUCommonAlgorithm::swap(T& a, T& b) // Nothing to do, work_group functions available #pragma OPENCL EXTENSION cl_khr_subgroups : enable -#define warp_scan_inclusive_add(v) sub_group_scan_inclusive_add(v) -#define warp_broadcast(v, i) sub_group_broadcast(v, i) +template +GPUdi() T work_group_scan_inclusive_add_FUNC(T v) +{ + return sub_group_scan_inclusive_add(v); +} +template <> // FIXME: It seems OpenCL does not support 8 and 16 bit subgroup operations +GPUdi() uint8_t work_group_scan_inclusive_add_FUNC(uint8_t v) +{ + return sub_group_scan_inclusive_add((uint32_t)v); +} +template +GPUdi() T work_group_broadcast_FUNC(T v, int32_t i) +{ + return sub_group_broadcast(v, i); +} +template <> +GPUdi() uint8_t work_group_broadcast_FUNC(uint8_t v, int32_t i) +{ + return sub_group_broadcast((uint32_t)v, i); +} + +#define warp_scan_inclusive_add(v) work_group_scan_inclusive_add_FUNC(v) +#define warp_broadcast(v, i) work_group_broadcast_FUNC(v, i) #elif (defined(__CUDACC__) || defined(__HIPCC__)) // CUDA and HIP work the same way using cub, need just different header From 483005418c1ec8e91d98525bc1edfcb21ddc1db6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 00:43:14 +0100 Subject: [PATCH 0472/2205] GPU OpenCL: Fix RTC source generation --- GPU/GPUTracking/Base/opencl2/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt index 0a4168b130766..73062ad82f728 100644 --- a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt +++ b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt @@ -53,7 +53,7 @@ if(OPENCL2_ENABLED_SPIRV) # BUILD OpenCL2 intermediate code for SPIR-V target MAIN_DEPENDENCY ${CL_SRC} IMPLICIT_DEPENDS CXX ${CL_SRC} COMMAND_EXPAND_LISTS - COMMENT "Compiling OpenCL2 CL source file ${CL_SRC} to SPIRV") + COMMENT "Compiling OpenCL2 CL source file ${CL_SRC} to SPIRV ${CL_BIN}.spirv") create_binary_resource(${CL_BIN}.spirv ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionOCLCode.spirv.o) set(SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionOCLCode.spirv.o) @@ -64,12 +64,14 @@ if(OPENCL2_ENABLED) # BUILD OpenCL2 source code for runtime compilation target add_custom_command( OUTPUT ${CL_BIN}.src COMMAND ${LLVM_CLANG} - ${OCL_DEFINECL} -cl-no-stdinc + ${OCL_FLAGS} + ${OCL_DEFINECL} + -cl-no-stdinc -E ${CL_SRC} > ${CL_BIN}.src MAIN_DEPENDENCY ${CL_SRC} IMPLICIT_DEPENDS CXX ${CL_SRC} COMMAND_EXPAND_LISTS - COMMENT "Preparing OpenCL2 CL source file for run time compilation") + COMMENT "Preparing OpenCL2 CL source file for run time compilation ${CL_BIN}.src") create_binary_resource(${CL_BIN}.src ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionOCLCode.src.o) set(SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionOCLCode.src.o) From 76ee600e62e7df99ce76f37979c689536236e546 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 01:11:49 +0100 Subject: [PATCH 0473/2205] GPU OpenCL: OpenCL >=2 should use generic address space for pointer kernel arguments, otherwise clang fails to derive the address space if used in a variadic template --- GPU/GPUTracking/Definitions/GPUDef.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Definitions/GPUDef.h b/GPU/GPUTracking/Definitions/GPUDef.h index abc6bb04291d3..38784b1ded80e 100644 --- a/GPU/GPUTracking/Definitions/GPUDef.h +++ b/GPU/GPUTracking/Definitions/GPUDef.h @@ -25,7 +25,11 @@ // Macros for masking ptrs in OpenCL kernel calls as uint64_t (The API only allows us to pass buffer objects) #ifdef __OPENCL__ #define GPUPtr1(a, b) uint64_t b - #define GPUPtr2(a, b) ((__global a) (a) b) + #ifdef __OPENCLCPP__ + #define GPUPtr2(a, b) ((__generic a) (a) b) + #else + #define GPUPtr2(a, b) ((__global a) (a) b) + #endif #else #define GPUPtr1(a, b) a b #define GPUPtr2(a, b) b From 37adc60e71e6b470a1a948ea98c4ef9040d3a388 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 01:41:51 +0100 Subject: [PATCH 0474/2205] GPU OpenCL: Workaround for some clang name mangling issues --- GPU/GPUTracking/Refit/GPUTrackingRefit.cxx | 4 ++-- GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx index 25be5b3647d57..8220b743dde0e 100644 --- a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx +++ b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx @@ -78,7 +78,7 @@ struct refitTrackTypes { } // anonymous namespace template <> -GPUd() void GPUTrackingRefit::initProp(GPUTPCGMPropagator& prop) +GPUd() void GPUTrackingRefit::initProp(GPUTPCGMPropagator& prop) // FIXME: GPUgeneric() needed to make the clang spirv output link correctly { prop.SetMaterialTPC(); prop.SetMaxSinPhi(GPUCA_MAX_SIN_PHI); @@ -91,7 +91,7 @@ GPUd() void GPUTrackingRefit::initProp(GPUTPCGMPropagator& p } template <> -GPUd() void GPUTrackingRefit::initProp(const Propagator*& prop) +GPUd() void GPUTrackingRefit::initProp(const Propagator*& prop) // FIXME: GPUgeneric() needed to make the clang spirv output link correctly { prop = mPpropagator; } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx index ba17b88436845..05e75232297a3 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTrackletConstructor.cxx @@ -585,8 +585,8 @@ GPUd() int32_t GPUTPCTrackletConstructor::FetchTracklet(GPUconstantref() MEM_GLO #endif // GPUCA_GPUCODE #if !defined(__OPENCL1__) -template <> -GPUd() int32_t GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCGlobalTracking::GPUSharedMemory& sMem, MEM_LG(GPUTPCTrackParam) & GPUrestrict() tParam, int32_t row, int32_t increment, int32_t iTracklet, calink* rowHits) +template <> // FIXME: GPUgeneric() needed to make the clang spirv output link correctly +GPUd() int32_t GPUTPCTrackletConstructor::GPUTPCTrackletConstructorGlobalTracking(GPUconstantref() MEM_GLOBAL(GPUTPCTracker) & GPUrestrict() tracker, GPUsharedref() GPUTPCGlobalTracking::GPUSharedMemory& sMem, MEM_LG(GPUTPCTrackParam) & GPUrestrict() tParam, int32_t row, int32_t increment, int32_t iTracklet, calink* rowHits) { GPUTPCThreadMemory rMem; rMem.mISH = iTracklet; From bcec346566f77dd3b386dc399dcb8e4a8ff6a7ff Mon Sep 17 00:00:00 2001 From: swenzel Date: Fri, 15 Nov 2024 18:47:16 +0100 Subject: [PATCH 0475/2205] CollisionContextTool: different QED printing No longer print all QED interactions (may be too long). Rather, give a short summary of QED stats. --- .../simulation/src/DigitizationContext.cxx | 21 +++++++++++++++++++ Steer/src/CollisionContextTool.cxx | 8 +++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/DataFormats/simulation/src/DigitizationContext.cxx b/DataFormats/simulation/src/DigitizationContext.cxx index bbb9b384f65fa..f3c993c9508b7 100644 --- a/DataFormats/simulation/src/DigitizationContext.cxx +++ b/DataFormats/simulation/src/DigitizationContext.cxx @@ -49,6 +49,27 @@ void DigitizationContext::printCollisionSummary(bool withQED, int truncateOutput } } else { std::cout << "Number of Collisions " << mEventRecords.size() << "\n"; + if (mEventPartsWithQED.size() > 0) { + auto num_qed_events = mEventPartsWithQED.size() - mEventRecords.size(); + if (num_qed_events > 0) { + std::cout << "Number of QED events (but not shown) " << num_qed_events << "\n"; + // find first and last QED collision so that we can give the range in orbits where these + // things are included + auto firstQEDcoll_iter = std::find_if(mEventPartsWithQED.begin(), mEventPartsWithQED.end(), + [](const std::vector& vec) { + return std::find_if(vec.begin(), vec.end(), [](EventPart const& p) { return p.sourceID == 99; }) != vec.end(); + }); + + auto lastColl_iter = std::find_if(mEventPartsWithQED.rbegin(), mEventPartsWithQED.rend(), + [](const std::vector& vec) { + return std::find_if(vec.begin(), vec.end(), [](EventPart const& p) { return p.sourceID == 99; }) != vec.end(); + }); + + auto firstindex = std::distance(mEventPartsWithQED.begin(), firstQEDcoll_iter); + auto lastindex = std::distance(mEventPartsWithQED.begin(), lastColl_iter.base()) - 1; + std::cout << "QED from: " << mEventRecordsWithQED[firstindex] << " ---> " << mEventRecordsWithQED[lastindex] << "\n"; + } + } for (int i = 0; i < mEventRecords.size(); ++i) { if (truncateOutputTo >= 0 && i > truncateOutputTo) { std::cout << "--- Output truncated to " << truncateOutputTo << " ---\n"; diff --git a/Steer/src/CollisionContextTool.cxx b/Steer/src/CollisionContextTool.cxx index 9cb4d401f3851..6dffdc921d651 100644 --- a/Steer/src/CollisionContextTool.cxx +++ b/Steer/src/CollisionContextTool.cxx @@ -456,7 +456,7 @@ int main(int argc, char* argv[]) // <---- at this moment we have a dense collision context (not representing the final output we want) LOG(info) << "<<------ DENSE CONTEXT ---------"; if (options.printContext) { - digicontext.printCollisionSummary(options.qedInteraction.size() > 0); + digicontext.printCollisionSummary(); } LOG(info) << "-------- DENSE CONTEXT ------->>"; @@ -467,7 +467,7 @@ int main(int argc, char* argv[]) // <---- at this moment we have a dense collision context (not representing the final output we want) LOG(info) << "<<------ FILTERED CONTEXT ---------"; if (options.printContext) { - digicontext.printCollisionSummary(options.qedInteraction.size() > 0); + digicontext.printCollisionSummary(); } LOG(info) << "-------- FILTERED CONTEXT ------->>"; @@ -510,7 +510,7 @@ int main(int argc, char* argv[]) } if (options.printContext) { - digicontext.printCollisionSummary(options.qedInteraction.size() > 0); + digicontext.printCollisionSummary(); } digicontext.saveToFile(options.outfilename); @@ -578,7 +578,7 @@ int main(int argc, char* argv[]) str << path_prefix << tf_output_counter++ << "/collisioncontext.root"; copy.saveToFile(str.str()); LOG(info) << "----"; - copy.printCollisionSummary(options.qedInteraction.size() > 0); + copy.printCollisionSummary(); } } } From 62d02b2450704f6face21018879086d551055b89 Mon Sep 17 00:00:00 2001 From: Gabriele Cimador Date: Wed, 6 Nov 2024 09:48:35 +0100 Subject: [PATCH 0476/2205] GPU: TPC Decoding: added variadic templates to decompressTrack() and decompressHits() in GPU code --- .../GPUTPCDecompressionKernels.cxx | 19 +++++++++++++------ .../GPUTPCDecompressionKernels.h | 9 +++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index 417b109cc80d3..afecb4859f1e3 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -31,11 +31,13 @@ GPUdii() void GPUTPCDecompressionKernels::Thread +GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args) { float zOffset = 0; uint32_t slice = cmprClusters.sliceA[trackIndex]; @@ -96,7 +98,7 @@ GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cm time = cmprClusters.timeA[trackIndex]; pad = cmprClusters.padA[trackIndex]; } - const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, decompressor); + const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, args...); float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); if (clusterIndex == 0) { @@ -111,7 +113,7 @@ GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cm clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; } -GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) +GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) { uint32_t tmpBufferIndex = computeLinearTmpBufferIndex(slice, row, decompressor.mMaxNativeClustersPerBuffer); uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); @@ -161,7 +163,8 @@ GPUdii() void GPUTPCDecompressionKernels::Thread +GPUdii() void GPUTPCDecompressionKernels::decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) { uint32_t time = 0; uint16_t pad = 0; @@ -177,10 +180,14 @@ GPUdii() void GPUTPCDecompressionKernels::decompressHits(const o2::tpc::Compress time = cmprClusters.timeDiffU[k]; pad = cmprClusters.padDiffU[k]; } - *(clusterNativeBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); + decompressHitsStore(cmprClusters, k, time, pad, args...); } } +GPUdii() void GPUTPCDecompressionKernels::decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& clusterNativeBuffer){ + *(clusterNativeBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); +} + template GPUdi() void GPUTPCDecompressionKernels::decompressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, uint32_t size) { diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h index 941e745da40d9..ddd9a5629768c 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h @@ -45,9 +45,14 @@ class GPUTPCDecompressionKernels : public GPUKernelTemplate template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, Args... args); - GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t clusterOffset, GPUTPCDecompression& decompressor); + + template + GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args); GPUdi() static o2::tpc::ClusterNative decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor); - GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, o2::tpc::ClusterNative* clusterNativeBuffer); + + template + GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args); + GPUdi() static void decompressHitsStore(const o2::tpc::CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, o2::tpc::ClusterNative*& clusterNativeBuffer); GPUd() static uint32_t computeLinearTmpBufferIndex(uint32_t slice, uint32_t row, uint32_t maxClustersPerBuffer) { From 804d27efa6c98d648e43c9f92aac3a9abbd6e52a Mon Sep 17 00:00:00 2001 From: Gabriele Cimador Date: Fri, 8 Nov 2024 14:47:15 +0100 Subject: [PATCH 0477/2205] GPU: TPC Decoding: add new class TPCClusterDecompressionCore to avoid code duplication for old and new decoding --- GPU/GPUTracking/CMakeLists.txt | 1 + .../DataCompression/GPUTPCDecompression.h | 2 +- .../GPUTPCDecompressionKernels.cxx | 121 +----------- .../GPUTPCDecompressionKernels.h | 4 +- .../TPCClusterDecompressionCore.inc | 185 ++++++++++++++++++ .../TPCClusterDecompressor.cxx | 6 +- .../Global/GPUChainTrackingCompression.cxx | 51 ++++- 7 files changed, 245 insertions(+), 125 deletions(-) create mode 100644 GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index 937346fe478c3..282f8b8f25031 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -122,6 +122,7 @@ set(HDRS_INSTALL DataCompression/GPUTPCClusterRejection.h DataCompression/GPUTPCCompressionKernels.inc DataCompression/TPCClusterDecompressor.inc + DataCompression/TPCClusterDecompressionCore.inc DataTypes/GPUdEdxInfo.h DataTypes/GPUHostDataTypes.h DataTypes/GPUO2DataTypes.h diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h index 49c73e6743d20..038fbd905db4f 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h @@ -43,7 +43,7 @@ class GPUTPCDecompression : public GPUProcessor friend class GPUTPCDecompressionKernels; friend class GPUTPCDecompressionUtilKernels; friend class GPUChainTracking; - + friend class TPCClusterDecompressionCore; public: #ifndef GPUCA_GPUCODE void InitializeProcessor(); diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index afecb4859f1e3..2c88ea0079a26 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -17,6 +17,7 @@ #include "GPUConstantMem.h" #include "GPUTPCCompressionTrackModel.h" #include "GPUCommonAlgorithm.h" +#include "TPCClusterDecompressionCore.inc" using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; @@ -32,101 +33,10 @@ GPUdii() void GPUTPCDecompressionKernels::Thread -GPUdii() void GPUTPCDecompressionKernels::decompressTrack(CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args) -{ - float zOffset = 0; - uint32_t slice = cmprClusters.sliceA[trackIndex]; - uint32_t row = cmprClusters.rowA[trackIndex]; - GPUTPCCompressionTrackModel track; - uint32_t clusterIndex; - for (clusterIndex = 0; clusterIndex < cmprClusters.nTrackClusters[trackIndex]; clusterIndex++) { - uint32_t pad = 0, time = 0; - if (clusterIndex != 0) { - uint8_t tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; - bool changeLeg = (tmpSlice >= GPUCA_NSLICES); - if (changeLeg) { - tmpSlice -= GPUCA_NSLICES; - } - if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { - slice += tmpSlice; - if (slice >= GPUCA_NSLICES) { - slice -= GPUCA_NSLICES; - } - row += cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; - if (row >= GPUCA_ROW_COUNT) { - row -= GPUCA_ROW_COUNT; - } - } else { - slice = tmpSlice; - row = cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; - } - if (changeLeg && track.Mirror()) { - break; - } - if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { - break; - } - uint32_t timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; - } - time = timeTmp + ClusterNative::packTime(CAMath::Max(0.f, param.tpcGeometry.LinearZ2Time(slice, track.Z() + zOffset))); - float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); - pad = cmprClusters.padResA[clusterOffset - trackIndex - 1] + ClusterNative::packPad(tmpPad); - time = time & 0xFFFFFF; - pad = (uint16_t)pad; - if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { - if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 - pad = 0; - } else { - pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; - } - } - if (param.continuousMaxTimeBin > 0 && time >= maxTime) { - if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) - time = 0; - } else { - time = maxTime; - } - } - } else { - time = cmprClusters.timeA[trackIndex]; - pad = cmprClusters.padA[trackIndex]; - } - const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, args...); - float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); - float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); - if (clusterIndex == 0) { - zOffset = z; - track.Init(param.tpcGeometry.Row2X(row), y, z - zOffset, param.SliceParam[slice].Alpha, cmprClusters.qPtA[trackIndex], param); - } - if (clusterIndex + 1 < cmprClusters.nTrackClusters[trackIndex] && track.Filter(y, z - zOffset, row)) { - break; - } - clusterOffset++; - } - clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; -} - -GPUdii() ClusterNative GPUTPCDecompressionKernels::decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) -{ - uint32_t tmpBufferIndex = computeLinearTmpBufferIndex(slice, row, decompressor.mMaxNativeClustersPerBuffer); - uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); - const ClusterNative c(time, cmprClusters.flagsA[clusterOffset], pad, cmprClusters.sigmaTimeA[clusterOffset], cmprClusters.sigmaPadA[clusterOffset], cmprClusters.qMaxA[clusterOffset], cmprClusters.qTotA[clusterOffset]); - if (currentClusterIndex < decompressor.mMaxNativeClustersPerBuffer) { - decompressor.mTmpNativeClusters[tmpBufferIndex + currentClusterIndex] = c; - } else { - decompressor.raiseError(GPUErrors::ERROR_DECOMPRESSION_ATTACHED_CLUSTER_OVERFLOW, slice * 1000 + row, currentClusterIndex, decompressor.mMaxNativeClustersPerBuffer); - CAMath::AtomicExch(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), decompressor.mMaxNativeClustersPerBuffer); - } - return c; -} - template <> GPUdii() void GPUTPCDecompressionKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors, int32_t sliceStart, int32_t nSlices) { @@ -146,7 +56,7 @@ GPUdii() void GPUTPCDecompressionKernels::Thread= decompressor.mInputGPU.nSliceRows) ? 0 : decompressor.mInputGPU.nSliceRowClusters[linearIndex]); - decompressHits(cmprClusters, offsets[linearIndex], end, clout); + TPCClusterDecompressionCore::decompressHits(cmprClusters, offsets[linearIndex], end, clout); if (processors.param.rec.tpc.clustersShiftTimebins != 0.f) { for (uint32_t k = 0; k < outputAccess->nClusters[iSlice][iRow]; k++) { auto& cl = buffer[k]; @@ -163,31 +73,6 @@ GPUdii() void GPUTPCDecompressionKernels::Thread -GPUdii() void GPUTPCDecompressionKernels::decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) -{ - uint32_t time = 0; - uint16_t pad = 0; - for (uint32_t k = start; k < end; k++) { - if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { - uint32_t timeTmp = cmprClusters.timeDiffU[k]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; - } - time += timeTmp; - pad += cmprClusters.padDiffU[k]; - } else { - time = cmprClusters.timeDiffU[k]; - pad = cmprClusters.padDiffU[k]; - } - decompressHitsStore(cmprClusters, k, time, pad, args...); - } -} - -GPUdii() void GPUTPCDecompressionKernels::decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& clusterNativeBuffer){ - *(clusterNativeBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); -} - template GPUdi() void GPUTPCDecompressionKernels::decompressorMemcpyBasic(T* GPUrestrict() dst, const T* GPUrestrict() src, uint32_t size) { diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h index ddd9a5629768c..cfa3589dd21f7 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h @@ -46,13 +46,13 @@ class GPUTPCDecompressionKernels : public GPUKernelTemplate template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, Args... args); - template + /*template GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args); GPUdi() static o2::tpc::ClusterNative decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor); template GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args); - GPUdi() static void decompressHitsStore(const o2::tpc::CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, o2::tpc::ClusterNative*& clusterNativeBuffer); + GPUdi() static void decompressHitsStore(const o2::tpc::CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, o2::tpc::ClusterNative*& clusterNativeBuffer);*/ GPUd() static uint32_t computeLinearTmpBufferIndex(uint32_t slice, uint32_t row, uint32_t maxClustersPerBuffer) { diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc new file mode 100644 index 0000000000000..1aee6677edcfc --- /dev/null +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc @@ -0,0 +1,185 @@ +// Copyright 2024-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file TPCCLusterDecompressionCore.inc +/// \author Gabriele Cimador + +#ifndef TPCCLUSTERDECOMPRESSOR_INC +#define TPCCLUSTERDECOMPRESSOR_INC + +#include "GPUTPCDecompression.h" +#include "GPUConstantMem.h" +#include "GPUTPCCompressionTrackModel.h" +#include "GPUCommonAlgorithm.h" +#include "GPUO2DataTypes.h" + +using namespace o2::tpc; + +namespace GPUCA_NAMESPACE::gpu +{ + +class TPCClusterDecompressionCore{ + public: + +#ifndef GPUCA_GPUCODE +GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::function func) +{ + const auto cluster = ClusterNative(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); + func(cluster, offset); + return cluster; +} + +GPUhi() static const auto& decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector& clusterVector) +{ + clusterVector.emplace_back(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); + return clusterVector.back(); +} + +GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) +{ + std::vector& clusterVector = clusters[slice][row]; + auto& lock = locks[slice][row]; + while (lock.test_and_set(std::memory_order_acquire)) { + } + ClusterNative retVal = decompressTrackStore(clustersCompressed, offset, slice, row, pad, time, clusterVector); + lock.clear(std::memory_order_release); + return retVal; +} +#endif + +GPUdii() static ClusterNative decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) +{ + uint32_t tmpBufferIndex = slice * (GPUCA_ROW_COUNT * decompressor.mMaxNativeClustersPerBuffer) + row * decompressor.mMaxNativeClustersPerBuffer; + uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); + const ClusterNative c(time, cmprClusters.flagsA[clusterOffset], pad, cmprClusters.sigmaTimeA[clusterOffset], cmprClusters.sigmaPadA[clusterOffset], cmprClusters.qMaxA[clusterOffset], cmprClusters.qTotA[clusterOffset]); + if (currentClusterIndex < decompressor.mMaxNativeClustersPerBuffer) { + decompressor.mTmpNativeClusters[tmpBufferIndex + currentClusterIndex] = c; + } else { + decompressor.raiseError(GPUErrors::ERROR_DECOMPRESSION_ATTACHED_CLUSTER_OVERFLOW, slice * 1000 + row, currentClusterIndex, decompressor.mMaxNativeClustersPerBuffer); + CAMath::AtomicExch(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), decompressor.mMaxNativeClustersPerBuffer); + } + return c; +} + +template +GPUhdi() static void decompressTrack(const CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args) +{ + float zOffset = 0; + uint32_t slice = cmprClusters.sliceA[trackIndex]; + uint32_t row = cmprClusters.rowA[trackIndex]; + GPUTPCCompressionTrackModel track; + uint32_t clusterIndex; + for (clusterIndex = 0; clusterIndex < cmprClusters.nTrackClusters[trackIndex]; clusterIndex++) { + uint32_t pad = 0, time = 0; + if (clusterIndex != 0) { + uint8_t tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; + bool changeLeg = (tmpSlice >= GPUCA_NSLICES); + if (changeLeg) { + tmpSlice -= GPUCA_NSLICES; + } + if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { + slice += tmpSlice; + if (slice >= GPUCA_NSLICES) { + slice -= GPUCA_NSLICES; + } + row += cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; + if (row >= GPUCA_ROW_COUNT) { + row -= GPUCA_ROW_COUNT; + } + } else { + slice = tmpSlice; + row = cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; + } + if (changeLeg && track.Mirror()) { + break; + } + if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { + break; + } + uint32_t timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; + if (timeTmp & 800000) { + timeTmp |= 0xFF000000; + } + time = timeTmp + ClusterNative::packTime(CAMath::Max(0.f, param.tpcGeometry.LinearZ2Time(slice, track.Z() + zOffset))); + float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); + pad = cmprClusters.padResA[clusterOffset - trackIndex - 1] + ClusterNative::packPad(tmpPad); + time = time & 0xFFFFFF; + pad = (uint16_t)pad; + if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { + if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 + pad = 0; + } else { + pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; + } + } + if (param.continuousMaxTimeBin > 0 && time >= maxTime) { + if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) + time = 0; + } else { + time = maxTime; + } + } + } else { + time = cmprClusters.timeA[trackIndex]; + pad = cmprClusters.padA[trackIndex]; + } + const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, args...); + float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); + float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); + if (clusterIndex == 0) { + zOffset = z; + track.Init(param.tpcGeometry.Row2X(row), y, z - zOffset, param.SliceParam[slice].Alpha, cmprClusters.qPtA[trackIndex], param); + } + if (clusterIndex + 1 < cmprClusters.nTrackClusters[trackIndex] && track.Filter(y, z - zOffset, row)) { + break; + } + clusterOffset++; + } + clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; +} + +GPUhdi() static const auto& decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& clusterBuffer) +{ + return ((*(clusterBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]))); +} + +GPUhdi() static auto decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, std::function func) +{ + const auto cluster = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); + func(cluster, k); + return cluster; +} + +template +GPUdii() static void decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) +{ + uint32_t time = 0; + uint16_t pad = 0; + for (uint32_t k = start; k < end; k++) { + if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { + uint32_t timeTmp = cmprClusters.timeDiffU[k]; + if (timeTmp & 800000) { + timeTmp |= 0xFF000000; + } + time += timeTmp; + pad += cmprClusters.padDiffU[k]; + } else { + time = cmprClusters.timeDiffU[k]; + pad = cmprClusters.padDiffU[k]; + } + decompressHitsStore(cmprClusters, k, time, pad, args...); + } +} + +}; +} + +#endif \ No newline at end of file diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx index 503f09c22af5c..4a38c2e0d57e5 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.cxx @@ -20,7 +20,7 @@ #include #include #include -#include "TPCClusterDecompressor.inc" +#include "TPCClusterDecompressionCore.inc" using namespace GPUCA_NAMESPACE::gpu; using namespace o2::tpc; @@ -62,7 +62,7 @@ int32_t TPCClusterDecompressor::decompress(const CompressedClusters* clustersCom offset += clustersCompressed->nTrackClusters[lasti++]; } lasti++; - decompressTrack(clustersCompressed, param, maxTime, i, offset, clusters, locks); + TPCClusterDecompressionCore::decompressTrack(*clustersCompressed, param, maxTime, i, offset, clusters, locks); } size_t nTotalClusters = clustersCompressed->nAttachedClusters + clustersCompressed->nUnattachedClusters; ClusterNative* clusterBuffer = allocator(nTotalClusters); @@ -91,7 +91,7 @@ int32_t TPCClusterDecompressor::decompress(const CompressedClusters* clustersCom } ClusterNative* clout = buffer + clusters[i][j].size(); uint32_t end = offsets[i][j] + ((i * GPUCA_ROW_COUNT + j >= clustersCompressed->nSliceRows) ? 0 : clustersCompressed->nSliceRowClusters[i * GPUCA_ROW_COUNT + j]); - decompressHits(clustersCompressed, offsets[i][j], end, clout); + TPCClusterDecompressionCore::decompressHits(*clustersCompressed, offsets[i][j], end, clout); if (param.rec.tpc.clustersShiftTimebins != 0.f) { for (uint32_t k = 0; k < clustersNative.nClusters[i][j]; k++) { auto& cl = buffer[k]; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index c0679c090c20c..b2203ec8de999 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -205,6 +205,12 @@ int32_t GPUChainTracking::RunTPCCompression() int32_t GPUChainTracking::RunTPCDecompression() { + ClusterNativeAccess* original = new ClusterNativeAccess; + original->clustersLinear = new ClusterNative[mIOPtrs.clustersNative->nClustersTotal]; + memcpy((void*)original->clustersLinear, mIOPtrs.clustersNative->clustersLinear, mIOPtrs.clustersNative->nClustersTotal * sizeof(mIOPtrs.clustersNative->clustersLinear[0])); + memcpy((void*)original->nClusters, mIOPtrs.clustersNative->nClusters, NSLICES * GPUCA_ROW_COUNT * sizeof(mIOPtrs.clustersNative->nClusters[0][0])); + original->setOffsetPtrs(); + #ifdef GPUCA_HAVE_O2HEADERS if (GetProcessingSettings().tpcUseOldCPUDecoding) { const auto& threadContext = GetThreadContext(); @@ -374,7 +380,7 @@ int32_t GPUChainTracking::RunTPCDecompression() } SynchronizeGPU(); - if (GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4) { + if (1 || GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4) { runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; if (doGPU) { @@ -387,6 +393,49 @@ int32_t GPUChainTracking::RunTPCDecompression() } } } + + const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; + unsigned int decodingErrors = 0; + std::vector tmpClusters; + if (param().rec.tpc.rejectionStrategy == GPUSettings::RejectionNone) { + for (unsigned int i = 0; i < NSLICES; i++) { + for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { + if (original->nClusters[i][j] != decoded->nClusters[i][j]) { + GPUError("Number of clusters mismatch slice %u row %u: expected %d v.s. decoded %d", i, j, original->nClusters[i][j], decoded->nClusters[i][j]); + decodingErrors++; + continue; + } + tmpClusters.resize(original->nClusters[i][j]); + for (unsigned int k = 0; k < original->nClusters[i][j]; k++) { + tmpClusters[k] = original->clusters[i][j][k]; + if (param().rec.tpc.compressionTypeMask & GPUSettings::CompressionTruncate) { + GPUTPCCompression::truncateSignificantBitsChargeMax(tmpClusters[k].qMax, param()); + GPUTPCCompression::truncateSignificantBitsCharge(tmpClusters[k].qTot, param()); + GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaPadPacked, param()); + GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaTimePacked, param()); + } + } + std::sort(tmpClusters.begin(), tmpClusters.end()); + for (unsigned int k = 0; k < original->nClusters[i][j]; k++) { + const o2::tpc::ClusterNative& c1 = tmpClusters[k]; + const o2::tpc::ClusterNative& c2 = decoded->clusters[i][j][k]; + if (!(c1 == c2)) { + if (decodingErrors++ < 100) { + GPUWarning("Cluster mismatch: slice %2u row %3u hit %5u: %6d %3d %4d %3d %3d %4d %4d", i, j, k, (int)c1.getTimePacked(), (int)c1.getFlags(), (int)c1.padPacked, (int)c1.sigmaTimePacked, (int)c1.sigmaPadPacked, (int)c1.qMax, (int)c1.qTot); + GPUWarning("%45s %6d %3d %4d %3d %3d %4d %4d", "", (int)c2.getTimePacked(), (int)c2.getFlags(), (int)c2.padPacked, (int)c2.sigmaTimePacked, (int)c2.sigmaPadPacked, (int)c2.qMax, (int)c2.qTot); + } + } + } + } + } +if (decodingErrors) { + GPUWarning("Errors during cluster decoding %u\n", decodingErrors); + } else { + GPUInfo("Cluster decoding verification on GPU: PASSED"); + } +} + delete[] original->clustersLinear; + delete original; mRec->PopNonPersistentMemory(RecoStep::TPCDecompression, qStr2Tag("TPCDCMPR")); } #endif From 5695338ef4a7c5c2d2f80f0848b096de229e1bf6 Mon Sep 17 00:00:00 2001 From: Gabriele Cimador Date: Mon, 11 Nov 2024 16:17:54 +0100 Subject: [PATCH 0478/2205] GPU: TPC Decoding: integrated new decoding class stucture into TPC/.../EntropyEncoderSpec.cxx --- .../TPC/workflow/src/EntropyEncoderSpec.cxx | 6 +-- .../TPCClusterDecompressionCore.inc | 4 +- .../Global/GPUChainTrackingCompression.cxx | 51 +------------------ 3 files changed, 6 insertions(+), 55 deletions(-) diff --git a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx index b81cb9a802a4a..294a93709e863 100644 --- a/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx +++ b/Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx @@ -25,7 +25,7 @@ #include "GPUO2InterfaceUtils.h" #include "GPUParam.h" #include "DataFormatsTPC/ClusterNative.h" -#include "TPCClusterDecompressor.inc" +#include "TPCClusterDecompressionCore.inc" #include "GPUTPCCompressionKernels.inc" #include "TPCCalibration/VDriftHelper.h" #include "DetectorsBase/GRPGeomHelper.h" @@ -183,7 +183,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) offset += clusters.nTrackClusters[lasti++]; } lasti++; - o2::gpu::TPCClusterDecompressor::decompressTrack(&clusters, *mParam, maxTime, i, offset, checker); + o2::gpu::TPCClusterDecompressionCore::decompressTrack(clusters, *mParam, maxTime, i, offset, checker); const float tMin = o2::tpc::ClusterNative::unpackTime(tMinP), tMax = o2::tpc::ClusterNative::unpackTime(tMaxP); const auto chkVal = firstIR + (tMin * constants::LHCBCPERTIMEBIN); const auto chkExt = totalT > tMax - tMin ? ((totalT - (tMax - tMin)) * constants::LHCBCPERTIMEBIN + 1) : 0; @@ -255,7 +255,7 @@ void EntropyEncoderSpec::run(ProcessingContext& pc) } }; unsigned int end = offsets[i][j] + clusters.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; - o2::gpu::TPCClusterDecompressor::decompressHits(&clusters, offsets[i][j], end, checker); + o2::gpu::TPCClusterDecompressionCore::decompressHits(clusters, offsets[i][j], end, checker); } tmpBuffer[0].first.reserve(clustersFiltered.nUnattachedClusters); tmpBuffer[0].second.reserve(clustersFiltered.nUnattachedClusters); diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc index 1aee6677edcfc..5a2fc1e85c71d 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc @@ -55,7 +55,7 @@ GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompr } #endif -GPUdii() static ClusterNative decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) +GPUdi() static ClusterNative decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) { uint32_t tmpBufferIndex = slice * (GPUCA_ROW_COUNT * decompressor.mMaxNativeClustersPerBuffer) + row * decompressor.mMaxNativeClustersPerBuffer; uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); @@ -159,7 +159,7 @@ GPUhdi() static auto decompressHitsStore(const CompressedClusters& cmprClusters, } template -GPUdii() static void decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) +GPUdi() static void decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) { uint32_t time = 0; uint16_t pad = 0; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index b2203ec8de999..c0679c090c20c 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -205,12 +205,6 @@ int32_t GPUChainTracking::RunTPCCompression() int32_t GPUChainTracking::RunTPCDecompression() { - ClusterNativeAccess* original = new ClusterNativeAccess; - original->clustersLinear = new ClusterNative[mIOPtrs.clustersNative->nClustersTotal]; - memcpy((void*)original->clustersLinear, mIOPtrs.clustersNative->clustersLinear, mIOPtrs.clustersNative->nClustersTotal * sizeof(mIOPtrs.clustersNative->clustersLinear[0])); - memcpy((void*)original->nClusters, mIOPtrs.clustersNative->nClusters, NSLICES * GPUCA_ROW_COUNT * sizeof(mIOPtrs.clustersNative->nClusters[0][0])); - original->setOffsetPtrs(); - #ifdef GPUCA_HAVE_O2HEADERS if (GetProcessingSettings().tpcUseOldCPUDecoding) { const auto& threadContext = GetThreadContext(); @@ -380,7 +374,7 @@ int32_t GPUChainTracking::RunTPCDecompression() } SynchronizeGPU(); - if (1 || GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4) { + if (GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4) { runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; if (doGPU) { @@ -393,49 +387,6 @@ int32_t GPUChainTracking::RunTPCDecompression() } } } - - const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; - unsigned int decodingErrors = 0; - std::vector tmpClusters; - if (param().rec.tpc.rejectionStrategy == GPUSettings::RejectionNone) { - for (unsigned int i = 0; i < NSLICES; i++) { - for (unsigned int j = 0; j < GPUCA_ROW_COUNT; j++) { - if (original->nClusters[i][j] != decoded->nClusters[i][j]) { - GPUError("Number of clusters mismatch slice %u row %u: expected %d v.s. decoded %d", i, j, original->nClusters[i][j], decoded->nClusters[i][j]); - decodingErrors++; - continue; - } - tmpClusters.resize(original->nClusters[i][j]); - for (unsigned int k = 0; k < original->nClusters[i][j]; k++) { - tmpClusters[k] = original->clusters[i][j][k]; - if (param().rec.tpc.compressionTypeMask & GPUSettings::CompressionTruncate) { - GPUTPCCompression::truncateSignificantBitsChargeMax(tmpClusters[k].qMax, param()); - GPUTPCCompression::truncateSignificantBitsCharge(tmpClusters[k].qTot, param()); - GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaPadPacked, param()); - GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaTimePacked, param()); - } - } - std::sort(tmpClusters.begin(), tmpClusters.end()); - for (unsigned int k = 0; k < original->nClusters[i][j]; k++) { - const o2::tpc::ClusterNative& c1 = tmpClusters[k]; - const o2::tpc::ClusterNative& c2 = decoded->clusters[i][j][k]; - if (!(c1 == c2)) { - if (decodingErrors++ < 100) { - GPUWarning("Cluster mismatch: slice %2u row %3u hit %5u: %6d %3d %4d %3d %3d %4d %4d", i, j, k, (int)c1.getTimePacked(), (int)c1.getFlags(), (int)c1.padPacked, (int)c1.sigmaTimePacked, (int)c1.sigmaPadPacked, (int)c1.qMax, (int)c1.qTot); - GPUWarning("%45s %6d %3d %4d %3d %3d %4d %4d", "", (int)c2.getTimePacked(), (int)c2.getFlags(), (int)c2.padPacked, (int)c2.sigmaTimePacked, (int)c2.sigmaPadPacked, (int)c2.qMax, (int)c2.qTot); - } - } - } - } - } -if (decodingErrors) { - GPUWarning("Errors during cluster decoding %u\n", decodingErrors); - } else { - GPUInfo("Cluster decoding verification on GPU: PASSED"); - } -} - delete[] original->clustersLinear; - delete original; mRec->PopNonPersistentMemory(RecoStep::TPCDecompression, qStr2Tag("TPCDCMPR")); } #endif From 9b43d33e91c5263fb50c47cccc53b2becbc5d851 Mon Sep 17 00:00:00 2001 From: Gabriele Cimador Date: Thu, 14 Nov 2024 16:37:43 +0100 Subject: [PATCH 0479/2205] Removed TPCCluterDecompressor.inc --- GPU/GPUTracking/CMakeLists.txt | 1 - .../DataCompression/GPUTPCDecompression.h | 1 + .../GPUTPCDecompressionKernels.h | 8 - .../TPCClusterDecompressionCore.inc | 267 +++++++++--------- .../DataCompression/TPCClusterDecompressor.h | 5 - .../TPCClusterDecompressor.inc | 164 ----------- 6 files changed, 137 insertions(+), 309 deletions(-) delete mode 100644 GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index 282f8b8f25031..6400fbc65dc61 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -121,7 +121,6 @@ set(HDRS_INSTALL Base/GPUReconstructionKernels.h DataCompression/GPUTPCClusterRejection.h DataCompression/GPUTPCCompressionKernels.inc - DataCompression/TPCClusterDecompressor.inc DataCompression/TPCClusterDecompressionCore.inc DataTypes/GPUdEdxInfo.h DataTypes/GPUHostDataTypes.h diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h index 038fbd905db4f..d9871613d8401 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h @@ -44,6 +44,7 @@ class GPUTPCDecompression : public GPUProcessor friend class GPUTPCDecompressionUtilKernels; friend class GPUChainTracking; friend class TPCClusterDecompressionCore; + public: #ifndef GPUCA_GPUCODE void InitializeProcessor(); diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h index cfa3589dd21f7..622e1fd984fa7 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h @@ -45,14 +45,6 @@ class GPUTPCDecompressionKernels : public GPUKernelTemplate template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors, Args... args); - - /*template - GPUd() static void decompressTrack(o2::tpc::CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args); - GPUdi() static o2::tpc::ClusterNative decompressTrackStore(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor); - - template - GPUdi() static void decompressHits(const o2::tpc::CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args); - GPUdi() static void decompressHitsStore(const o2::tpc::CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, o2::tpc::ClusterNative*& clusterNativeBuffer);*/ GPUd() static uint32_t computeLinearTmpBufferIndex(uint32_t slice, uint32_t row, uint32_t maxClustersPerBuffer) { diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc index 5a2fc1e85c71d..73352182328d5 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressionCore.inc @@ -21,165 +21,170 @@ #include "GPUCommonAlgorithm.h" #include "GPUO2DataTypes.h" +#ifndef GPUCA_GPUCODE +#include +#endif + using namespace o2::tpc; namespace GPUCA_NAMESPACE::gpu { -class TPCClusterDecompressionCore{ - public: - -#ifndef GPUCA_GPUCODE -GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::function func) +class TPCClusterDecompressionCore { - const auto cluster = ClusterNative(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); - func(cluster, offset); - return cluster; -} + public: +#ifndef GPUCA_GPUCODE + GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::function func) + { + const auto cluster = ClusterNative(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); + func(cluster, offset); + return cluster; + } -GPUhi() static const auto& decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector& clusterVector) -{ - clusterVector.emplace_back(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); - return clusterVector.back(); -} + GPUhi() static const auto& decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector& clusterVector) + { + clusterVector.emplace_back(time, clustersCompressed.flagsA[offset], pad, clustersCompressed.sigmaTimeA[offset], clustersCompressed.sigmaPadA[offset], clustersCompressed.qMaxA[offset], clustersCompressed.qTotA[offset]); + return clusterVector.back(); + } -GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) -{ - std::vector& clusterVector = clusters[slice][row]; - auto& lock = locks[slice][row]; - while (lock.test_and_set(std::memory_order_acquire)) { + GPUhi() static auto decompressTrackStore(const CompressedClusters& clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) + { + std::vector& clusterVector = clusters[slice][row]; + auto& lock = locks[slice][row]; + while (lock.test_and_set(std::memory_order_acquire)) { + } + ClusterNative retVal = decompressTrackStore(clustersCompressed, offset, slice, row, pad, time, clusterVector); + lock.clear(std::memory_order_release); + return retVal; } - ClusterNative retVal = decompressTrackStore(clustersCompressed, offset, slice, row, pad, time, clusterVector); - lock.clear(std::memory_order_release); - return retVal; -} #endif -GPUdi() static ClusterNative decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) -{ - uint32_t tmpBufferIndex = slice * (GPUCA_ROW_COUNT * decompressor.mMaxNativeClustersPerBuffer) + row * decompressor.mMaxNativeClustersPerBuffer; - uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); - const ClusterNative c(time, cmprClusters.flagsA[clusterOffset], pad, cmprClusters.sigmaTimeA[clusterOffset], cmprClusters.sigmaPadA[clusterOffset], cmprClusters.qMaxA[clusterOffset], cmprClusters.qTotA[clusterOffset]); - if (currentClusterIndex < decompressor.mMaxNativeClustersPerBuffer) { - decompressor.mTmpNativeClusters[tmpBufferIndex + currentClusterIndex] = c; - } else { - decompressor.raiseError(GPUErrors::ERROR_DECOMPRESSION_ATTACHED_CLUSTER_OVERFLOW, slice * 1000 + row, currentClusterIndex, decompressor.mMaxNativeClustersPerBuffer); - CAMath::AtomicExch(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), decompressor.mMaxNativeClustersPerBuffer); + GPUdi() static ClusterNative decompressTrackStore(const CompressedClusters& cmprClusters, const uint32_t clusterOffset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, GPUTPCDecompression& decompressor) + { + uint32_t tmpBufferIndex = slice * (GPUCA_ROW_COUNT * decompressor.mMaxNativeClustersPerBuffer) + row * decompressor.mMaxNativeClustersPerBuffer; + uint32_t currentClusterIndex = CAMath::AtomicAdd(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), 1u); + const ClusterNative c(time, cmprClusters.flagsA[clusterOffset], pad, cmprClusters.sigmaTimeA[clusterOffset], cmprClusters.sigmaPadA[clusterOffset], cmprClusters.qMaxA[clusterOffset], cmprClusters.qTotA[clusterOffset]); + if (currentClusterIndex < decompressor.mMaxNativeClustersPerBuffer) { + decompressor.mTmpNativeClusters[tmpBufferIndex + currentClusterIndex] = c; + } else { + decompressor.raiseError(GPUErrors::ERROR_DECOMPRESSION_ATTACHED_CLUSTER_OVERFLOW, slice * 1000 + row, currentClusterIndex, decompressor.mMaxNativeClustersPerBuffer); + CAMath::AtomicExch(decompressor.mNativeClustersIndex + (slice * GPUCA_ROW_COUNT + row), decompressor.mMaxNativeClustersPerBuffer); + } + return c; } - return c; -} -template -GPUhdi() static void decompressTrack(const CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t trackIndex, uint32_t& clusterOffset, Args&... args) -{ - float zOffset = 0; - uint32_t slice = cmprClusters.sliceA[trackIndex]; - uint32_t row = cmprClusters.rowA[trackIndex]; - GPUTPCCompressionTrackModel track; - uint32_t clusterIndex; - for (clusterIndex = 0; clusterIndex < cmprClusters.nTrackClusters[trackIndex]; clusterIndex++) { - uint32_t pad = 0, time = 0; - if (clusterIndex != 0) { - uint8_t tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; - bool changeLeg = (tmpSlice >= GPUCA_NSLICES); - if (changeLeg) { - tmpSlice -= GPUCA_NSLICES; - } - if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { - slice += tmpSlice; - if (slice >= GPUCA_NSLICES) { - slice -= GPUCA_NSLICES; + template + GPUdi() static void decompressTrack(const CompressedClusters& cmprClusters, const GPUParam& param, const uint32_t maxTime, const uint32_t& trackIndex, uint32_t& clusterOffset, Args&... args) + { + float zOffset = 0; + uint32_t slice = cmprClusters.sliceA[trackIndex]; + uint32_t row = cmprClusters.rowA[trackIndex]; + GPUTPCCompressionTrackModel track; + uint32_t clusterIndex; + for (clusterIndex = 0; clusterIndex < cmprClusters.nTrackClusters[trackIndex]; clusterIndex++) { + uint32_t pad = 0, time = 0; + if (clusterIndex != 0) { + uint8_t tmpSlice = cmprClusters.sliceLegDiffA[clusterOffset - trackIndex - 1]; + bool changeLeg = (tmpSlice >= GPUCA_NSLICES); + if (changeLeg) { + tmpSlice -= GPUCA_NSLICES; + } + if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { + slice += tmpSlice; + if (slice >= GPUCA_NSLICES) { + slice -= GPUCA_NSLICES; + } + row += cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; + if (row >= GPUCA_ROW_COUNT) { + row -= GPUCA_ROW_COUNT; + } + } else { + slice = tmpSlice; + row = cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; + } + if (changeLeg && track.Mirror()) { + break; + } + if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { + break; + } + uint32_t timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; + if (timeTmp & 800000) { + timeTmp |= 0xFF000000; + } + time = timeTmp + ClusterNative::packTime(CAMath::Max(0.f, param.tpcGeometry.LinearZ2Time(slice, track.Z() + zOffset))); + float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); + pad = cmprClusters.padResA[clusterOffset - trackIndex - 1] + ClusterNative::packPad(tmpPad); + time = time & 0xFFFFFF; + pad = (uint16_t)pad; + if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { + if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 + pad = 0; + } else { + pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; + } } - row += cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; - if (row >= GPUCA_ROW_COUNT) { - row -= GPUCA_ROW_COUNT; + if (param.continuousMaxTimeBin > 0 && time >= maxTime) { + if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) + time = 0; + } else { + time = maxTime; + } } } else { - slice = tmpSlice; - row = cmprClusters.rowDiffA[clusterOffset - trackIndex - 1]; + time = cmprClusters.timeA[trackIndex]; + pad = cmprClusters.padA[trackIndex]; } - if (changeLeg && track.Mirror()) { - break; + const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, args...); + float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); + float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); + if (clusterIndex == 0) { + zOffset = z; + track.Init(param.tpcGeometry.Row2X(row), y, z - zOffset, param.SliceParam[slice].Alpha, cmprClusters.qPtA[trackIndex], param); } - if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { + if (clusterIndex + 1 < cmprClusters.nTrackClusters[trackIndex] && track.Filter(y, z - zOffset, row)) { break; } - uint32_t timeTmp = cmprClusters.timeResA[clusterOffset - trackIndex - 1]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; - } - time = timeTmp + ClusterNative::packTime(CAMath::Max(0.f, param.tpcGeometry.LinearZ2Time(slice, track.Z() + zOffset))); - float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); - pad = cmprClusters.padResA[clusterOffset - trackIndex - 1] + ClusterNative::packPad(tmpPad); - time = time & 0xFFFFFF; - pad = (uint16_t)pad; - if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { - if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 - pad = 0; - } else { - pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; - } - } - if (param.continuousMaxTimeBin > 0 && time >= maxTime) { - if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) - time = 0; - } else { - time = maxTime; - } - } - } else { - time = cmprClusters.timeA[trackIndex]; - pad = cmprClusters.padA[trackIndex]; + clusterOffset++; } - const auto cluster = decompressTrackStore(cmprClusters, clusterOffset, slice, row, pad, time, args...); - float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); - float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); - if (clusterIndex == 0) { - zOffset = z; - track.Init(param.tpcGeometry.Row2X(row), y, z - zOffset, param.SliceParam[slice].Alpha, cmprClusters.qPtA[trackIndex], param); - } - if (clusterIndex + 1 < cmprClusters.nTrackClusters[trackIndex] && track.Filter(y, z - zOffset, row)) { - break; - } - clusterOffset++; + clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; } - clusterOffset += cmprClusters.nTrackClusters[trackIndex] - clusterIndex; -} -GPUhdi() static const auto& decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& clusterBuffer) -{ - return ((*(clusterBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]))); -} + GPUdi() static const auto& decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& clusterBuffer) + { + return ((*(clusterBuffer++) = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]))); + } -GPUhdi() static auto decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, std::function func) -{ - const auto cluster = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); - func(cluster, k); - return cluster; -} +#ifndef GPUCA_GPUCODE + GPUhi() static auto decompressHitsStore(const CompressedClusters& cmprClusters, uint32_t k, uint32_t time, uint16_t pad, std::function func) + { + const auto cluster = ClusterNative(time, cmprClusters.flagsU[k], pad, cmprClusters.sigmaTimeU[k], cmprClusters.sigmaPadU[k], cmprClusters.qMaxU[k], cmprClusters.qTotU[k]); + func(cluster, k); + return cluster; + } +#endif -template -GPUdi() static void decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) -{ - uint32_t time = 0; - uint16_t pad = 0; - for (uint32_t k = start; k < end; k++) { - if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { - uint32_t timeTmp = cmprClusters.timeDiffU[k]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; + template + GPUdi() static void decompressHits(const CompressedClusters& cmprClusters, const uint32_t start, const uint32_t end, Args&... args) + { + uint32_t time = 0; + uint16_t pad = 0; + for (uint32_t k = start; k < end; k++) { + if (cmprClusters.nComppressionModes & GPUSettings::CompressionDifferences) { + uint32_t timeTmp = cmprClusters.timeDiffU[k]; + if (timeTmp & 800000) { + timeTmp |= 0xFF000000; + } + time += timeTmp; + pad += cmprClusters.padDiffU[k]; + } else { + time = cmprClusters.timeDiffU[k]; + pad = cmprClusters.padDiffU[k]; } - time += timeTmp; - pad += cmprClusters.padDiffU[k]; - } else { - time = cmprClusters.timeDiffU[k]; - pad = cmprClusters.padDiffU[k]; + decompressHitsStore(cmprClusters, k, time, pad, args...); } - decompressHitsStore(cmprClusters, k, time, pad, args...); } -} - }; -} +} // namespace GPUCA_NAMESPACE::gpu #endif \ No newline at end of file diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h index fc96f5fc72e28..d8e404b8a2ab7 100644 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h +++ b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.h @@ -35,11 +35,6 @@ class TPCClusterDecompressor static constexpr uint32_t NSLICES = GPUCA_NSLICES; static int32_t decompress(const o2::tpc::CompressedClustersFlat* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); static int32_t decompress(const o2::tpc::CompressedClusters* clustersCompressed, o2::tpc::ClusterNativeAccess& clustersNative, std::function allocator, const GPUParam& param, bool deterministicRec); - - template - static void decompressTrack(const o2::tpc::CompressedClusters* clustersCompressed, const GPUParam& param, const uint32_t maxTime, const uint32_t i, uint32_t& offset, Args&... args); - template - static void decompressHits(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t start, const uint32_t end, Args&... args); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc b/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc deleted file mode 100644 index 2ea75b21bf22e..0000000000000 --- a/GPU/GPUTracking/DataCompression/TPCClusterDecompressor.inc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file TPCClusterDecompressor.inc -/// \author David Rohr - -#include "TPCClusterDecompressor.h" -#include "GPUO2DataTypes.h" -#include "GPUParam.h" -#include "GPUTPCCompressionTrackModel.h" -#include -#include -#include -#include - -using namespace GPUCA_NAMESPACE::gpu; -using namespace o2::tpc; - -static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::function func) -{ - const auto cluster = ClusterNative(time, clustersCompressed->flagsA[offset], pad, clustersCompressed->sigmaTimeA[offset], clustersCompressed->sigmaPadA[offset], clustersCompressed->qMaxA[offset], clustersCompressed->qTotA[offset]); - func(cluster, offset); - return cluster; -} - -static inline const auto& decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector& clusterVector) -{ - clusterVector.emplace_back(time, clustersCompressed->flagsA[offset], pad, clustersCompressed->sigmaTimeA[offset], clustersCompressed->sigmaPadA[offset], clustersCompressed->qMaxA[offset], clustersCompressed->qTotA[offset]); - return clusterVector.back(); -} - -static inline auto decompressTrackStore(const o2::tpc::CompressedClusters* clustersCompressed, const uint32_t offset, uint32_t slice, uint32_t row, uint32_t pad, uint32_t time, std::vector (&clusters)[GPUCA_NSLICES][GPUCA_ROW_COUNT], std::atomic_flag (&locks)[GPUCA_NSLICES][GPUCA_ROW_COUNT]) -{ - std::vector& clusterVector = clusters[slice][row]; - auto& lock = locks[slice][row]; - while (lock.test_and_set(std::memory_order_acquire)) { - } - // Note the return type is ClusterNative, not auto&, since a different thread might append another cluster, and the vector expansion can change the cluster pointer, so the cluster reference might be invalid - // TODO: A new version that might use a plain array + counter to fill the clusters should change this and the function return type to auto& - ClusterNative retVal = decompressTrackStore(clustersCompressed, offset, slice, row, pad, time, clusterVector); - lock.clear(std::memory_order_release); - return retVal; -} - -template -inline void TPCClusterDecompressor::decompressTrack(const CompressedClusters* clustersCompressed, const GPUParam& param, const uint32_t maxTime, const uint32_t i, uint32_t& offset, Args&... args) -{ - float zOffset = 0; - uint32_t slice = clustersCompressed->sliceA[i]; - uint32_t row = clustersCompressed->rowA[i]; - GPUTPCCompressionTrackModel track; - uint32_t j; - for (j = 0; j < clustersCompressed->nTrackClusters[i]; j++) { - uint32_t pad = 0, time = 0; - if (j) { - uint8_t tmpSlice = clustersCompressed->sliceLegDiffA[offset - i - 1]; - bool changeLeg = (tmpSlice >= NSLICES); - if (changeLeg) { - tmpSlice -= NSLICES; - } - if (clustersCompressed->nComppressionModes & GPUSettings::CompressionDifferences) { - slice += tmpSlice; - if (slice >= NSLICES) { - slice -= NSLICES; - } - row += clustersCompressed->rowDiffA[offset - i - 1]; - if (row >= GPUCA_ROW_COUNT) { - row -= GPUCA_ROW_COUNT; - } - } else { - slice = tmpSlice; - row = clustersCompressed->rowDiffA[offset - i - 1]; - } - if (changeLeg && track.Mirror()) { - break; - } - if (track.Propagate(param.tpcGeometry.Row2X(row), param.SliceParam[slice].Alpha)) { - break; - } - uint32_t timeTmp = clustersCompressed->timeResA[offset - i - 1]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; - } - time = timeTmp + ClusterNative::packTime(CAMath::Max(0.f, param.tpcGeometry.LinearZ2Time(slice, track.Z() + zOffset))); - float tmpPad = CAMath::Max(0.f, CAMath::Min((float)param.tpcGeometry.NPads(GPUCA_ROW_COUNT - 1), param.tpcGeometry.LinearY2Pad(slice, row, track.Y()))); - pad = clustersCompressed->padResA[offset - i - 1] + ClusterNative::packPad(tmpPad); - time = time & 0xFFFFFF; - pad = (uint16_t)pad; - if (pad >= param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked) { - if (pad >= 0xFFFF - 11968) { // Constant 11968 = (2^15 - MAX_PADS(138) * scalePadPacked(64)) / 2 - pad = 0; - } else { - pad = param.tpcGeometry.NPads(row) * ClusterNative::scalePadPacked - 1; - } - } - if (param.continuousMaxTimeBin > 0 && time >= maxTime) { - if (time >= 0xFFFFFF - 544768) { // Constant 544768 = (2^23 - LHCMAXBUNCHES(3564) * MAXORBITS(256) * scaleTimePacked(64) / BCPERTIMEBIN(8)) / 2) - time = 0; - } else { - time = maxTime; - } - } - } else { - time = clustersCompressed->timeA[i]; - pad = clustersCompressed->padA[i]; - } - const auto& cluster = decompressTrackStore(clustersCompressed, offset, slice, row, pad, time, args...); - float y = param.tpcGeometry.LinearPad2Y(slice, row, cluster.getPad()); - float z = param.tpcGeometry.LinearTime2Z(slice, cluster.getTime()); - if (j == 0) { - zOffset = z; - track.Init(param.tpcGeometry.Row2X(row), y, z - zOffset, param.SliceParam[slice].Alpha, clustersCompressed->qPtA[i], param); - } - if (j + 1 < clustersCompressed->nTrackClusters[i] && track.Filter(y, z - zOffset, row)) { - break; - } - offset++; - } - offset += clustersCompressed->nTrackClusters[i] - j; -} - -static inline const auto& decompressHitsStore(const CompressedClusters* clustersCompressed, uint32_t k, uint32_t time, uint16_t pad, ClusterNative*& cl) -{ - return ((*(cl++) = ClusterNative(time, clustersCompressed->flagsU[k], pad, clustersCompressed->sigmaTimeU[k], clustersCompressed->sigmaPadU[k], clustersCompressed->qMaxU[k], clustersCompressed->qTotU[k]))); -} - -static inline auto decompressHitsStore(const CompressedClusters* clustersCompressed, uint32_t k, uint32_t time, uint16_t pad, std::function func) -{ - const auto cluster = ClusterNative(time, clustersCompressed->flagsU[k], pad, clustersCompressed->sigmaTimeU[k], clustersCompressed->sigmaPadU[k], clustersCompressed->qMaxU[k], clustersCompressed->qTotU[k]); - func(cluster, k); - return cluster; -} - -template -inline void TPCClusterDecompressor::decompressHits(const CompressedClusters* clustersCompressed, const uint32_t start, const uint32_t end, Args&... args) -{ - uint32_t time = 0; - uint16_t pad = 0; - for (uint32_t k = start; k < end; k++) { - /*if (cl >= clustersNative.clustersLinear + nTotalClusters) { - throw std::runtime_error("Bad TPC CTF data, decoded more clusters than announced"); - }*/ - if (clustersCompressed->nComppressionModes & GPUSettings::CompressionDifferences) { - uint32_t timeTmp = clustersCompressed->timeDiffU[k]; - if (timeTmp & 800000) { - timeTmp |= 0xFF000000; - } - time += timeTmp; - pad += clustersCompressed->padDiffU[k]; - } else { - time = clustersCompressed->timeDiffU[k]; - pad = clustersCompressed->padDiffU[k]; - } - decompressHitsStore(clustersCompressed, k, time, pad, args...); - } -} From 68d83608c15f2e90a80cc6f8d2aebbdee4bb37f7 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 13:16:36 +0100 Subject: [PATCH 0480/2205] GPU Clusterizer: Fix should not release an unused event --- GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index af7cc03369afc..dca656e738ef8 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -865,8 +865,12 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) } if (fragment.index == 0) { - runKernel({GetGridAutoStep(lane, RecoStep::TPCClusterFinding), krnlRunRangeNone, {nullptr, transferRunning[lane] == 1 ? &mEvents->stream[lane] : nullptr}}, clustererShadow.mPclusterInRow, GPUCA_ROW_COUNT * sizeof(*clustererShadow.mPclusterInRow)); - transferRunning[lane] = 2; + deviceEvent* waitEvent = nullptr; + if (transferRunning[lane] == 1) { + waitEvent = &mEvents->stream[lane]; + transferRunning[lane] = 2; + } + runKernel({GetGridAutoStep(lane, RecoStep::TPCClusterFinding), krnlRunRangeNone, {nullptr, waitEvent}}, clustererShadow.mPclusterInRow, GPUCA_ROW_COUNT * sizeof(*clustererShadow.mPclusterInRow)); } if (clusterer.mPmemory->counters.nClusters == 0) { From 5b55339f1ed573bdbf60bf43219d335d2ded054a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 13:17:13 +0100 Subject: [PATCH 0481/2205] GPU: Fix RecordMarker must operate on reference, since OpenCL will change the event pointer --- GPU/GPUTracking/Base/GPUReconstructionCPU.h | 2 +- GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.cu | 2 +- GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h | 2 +- .../Base/opencl-common/GPUReconstructionOCL.cxx | 7 ++++++- GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h | 2 +- GPU/GPUTracking/Global/GPUChain.h | 2 +- GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx | 2 +- GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx | 4 ++-- GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx | 8 ++++---- GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx | 2 +- 10 files changed, 19 insertions(+), 14 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.h b/GPU/GPUTracking/Base/GPUReconstructionCPU.h index ac254221c250c..7eaf3e4a5e40d 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.h +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.h @@ -114,7 +114,7 @@ class GPUReconstructionCPU : public GPUReconstructionKernels(), mInternals->Streams[stream])); } +void GPUReconstructionCUDA::RecordMarker(deviceEvent* ev, int32_t stream) { GPUFailedMsg(cudaEventRecord(ev->get(), mInternals->Streams[stream])); } std::unique_ptr GPUReconstructionCUDA::GetThreadContext() { diff --git a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h index b9db625a83f1d..070177fb344f1 100644 --- a/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h +++ b/GPU/GPUTracking/Base/cuda/GPUReconstructionCUDA.h @@ -84,7 +84,7 @@ class GPUReconstructionCUDA : public GPUReconstructionKernels* trackerTraits, std::unique_ptr* vertexerTraits, std::unique_ptr* timeFrame) override; diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx index de32f03340c03..cad56e77c79d5 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.cxx @@ -359,6 +359,11 @@ int32_t GPUReconstructionOCL::InitDevice_Runtime() mInternals = master->mInternals; } + for (uint32_t i = 0; i < mEvents.size(); i++) { + cl_event* events = (cl_event*)mEvents[i].data(); + new (events) cl_event[mEvents[i].size()]; + } + return (0); } @@ -432,7 +437,7 @@ size_t GPUReconstructionOCL::WriteToConstantMemory(size_t offset, const void* sr void GPUReconstructionOCL::ReleaseEvent(deviceEvent ev) { GPUFailedMsg(clReleaseEvent(ev.get())); } -void GPUReconstructionOCL::RecordMarker(deviceEvent ev, int32_t stream) { GPUFailedMsg(clEnqueueMarkerWithWaitList(mInternals->command_queue[stream], 0, nullptr, ev.getEventList())); } +void GPUReconstructionOCL::RecordMarker(deviceEvent* ev, int32_t stream) { GPUFailedMsg(clEnqueueMarkerWithWaitList(mInternals->command_queue[stream], 0, nullptr, ev->getEventList())); } int32_t GPUReconstructionOCL::DoStuckProtection(int32_t stream, deviceEvent event) { diff --git a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h index 02ba0469dee2a..6abe1045b550a 100644 --- a/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h +++ b/GPU/GPUTracking/Base/opencl-common/GPUReconstructionOCL.h @@ -52,7 +52,7 @@ class GPUReconstructionOCL : public GPUReconstructionDeviceBase size_t WriteToConstantMemory(size_t offset, const void* src, size_t size, int32_t stream = -1, deviceEvent* ev = nullptr) override; size_t GPUMemCpy(void* dst, const void* src, size_t size, int32_t stream, int32_t toGPU, deviceEvent* ev = nullptr, deviceEvent* evList = nullptr, int32_t nEvents = 1) override; void ReleaseEvent(deviceEvent ev) override; - void RecordMarker(deviceEvent ev, int32_t stream) override; + void RecordMarker(deviceEvent* ev, int32_t stream) override; virtual int32_t GetOCLPrograms() = 0; virtual bool CheckPlatform(uint32_t i) = 0; diff --git a/GPU/GPUTracking/Global/GPUChain.h b/GPU/GPUTracking/Global/GPUChain.h index 7a36355bf843d..9c67a05eec443 100644 --- a/GPU/GPUTracking/Global/GPUChain.h +++ b/GPU/GPUTracking/Global/GPUChain.h @@ -101,7 +101,7 @@ class GPUChain } } inline bool IsEventDone(deviceEvent* evList, int32_t nEvents = 1) { return mRec->IsEventDone(evList, nEvents); } - inline void RecordMarker(deviceEvent ev, int32_t stream) { mRec->RecordMarker(ev, stream); } + inline void RecordMarker(deviceEvent* ev, int32_t stream) { mRec->RecordMarker(ev, stream); } virtual inline std::unique_ptr GetThreadContext() { return mRec->GetThreadContext(); } inline void SynchronizeGPU() { mRec->SynchronizeGPU(); } inline void ReleaseEvent(deviceEvent ev, bool doGPU = true) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index dca656e738ef8..ae240181eba65 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -934,7 +934,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (transferRunning[lane]) { ReleaseEvent(mEvents->stream[lane], doGPU); } - RecordMarker(mEvents->stream[lane], mRec->NStreams() - 1); + RecordMarker(&mEvents->stream[lane], mRec->NStreams() - 1); transferRunning[lane] = 1; } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index c0679c090c20c..98109447de034 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -37,7 +37,7 @@ int32_t GPUChainTracking::RunTPCCompression() GPUTPCCompression& CompressorShadow = doGPU ? processorsShadow()->tpcCompressor : Compressor; const auto& threadContext = GetThreadContext(); if (mPipelineFinalizationCtx && GetProcessingSettings().doublePipelineClusterizer) { - RecordMarker(mEvents->single, 0); + RecordMarker(&mEvents->single, 0); } if (GetProcessingSettings().tpcCompressionGatherMode == 3) { @@ -124,7 +124,7 @@ int32_t GPUChainTracking::RunTPCCompression() return 1; } if (GetProcessingSettings().tpcCompressionGatherMode == 3) { - RecordMarker(mEvents->stream[outputStream], outputStream); + RecordMarker(&mEvents->stream[outputStream], outputStream); char* deviceFlatPts = (char*)Compressor.mOutput->qTotU; if (GetProcessingSettings().doublePipeline) { const size_t blockSize = CAMath::nextMultipleOf<1024>(copySize / 30); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx index 67a9904a4222f..aba8617ee244d 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingMerger.cxx @@ -33,7 +33,7 @@ void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(int8_t withinSlice uint32_t n = withinSlice == -1 ? NSLICES / 2 : NSLICES; if (GetProcessingSettings().alternateBorderSort && (!mRec->IsGPU() || doGPUall)) { TransferMemoryResourceLinkToHost(RecoStep::TPCMerging, Merger.MemoryResMemory(), 0, &mEvents->init); - RecordMarker(mEvents->single, 0); + RecordMarker(&mEvents->single, 0); for (uint32_t i = 0; i < n; i++) { int32_t stream = i % mRec->NStreams(); runKernel({GetGridAuto(stream, deviceType), krnlRunRangeNone, {nullptr, stream && i < (uint32_t)mRec->NStreams() ? &mEvents->single : nullptr}}, i, withinSlice, mergeMode); @@ -55,7 +55,7 @@ void GPUChainTracking::RunTPCTrackingMerger_MergeBorderTracks(int8_t withinSlice if (i == n - 1) { // Synchronize all execution on stream 0 with the last kernel ne = std::min(n, mRec->NStreams()); for (int32_t j = 1; j < ne; j++) { - RecordMarker(mEvents->slice[j], j); + RecordMarker(&mEvents->slice[j], j); } e = &mEvents->slice[1]; ne--; @@ -251,7 +251,7 @@ int32_t GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) DoDebugAndDump(RecoStep::TPCMerging, 2048, doGPUall, Merger, &GPUTPCGMMerger::DumpFinal, *mDebugFile); if (doGPUall) { - RecordMarker(mEvents->single, 0); + RecordMarker(&mEvents->single, 0); auto* waitEvent = &mEvents->single; if (GetProcessingSettings().keepDisplayMemory || GetProcessingSettings().createO2Output <= 1 || mFractionalQAEnabled) { if (!(GetProcessingSettings().keepDisplayMemory || GetProcessingSettings().createO2Output <= 1)) { @@ -317,7 +317,7 @@ int32_t GPUChainTracking::RunTPCTrackingMerger(bool synchronizeOutput) TransferMemoryResourcesToHost(RecoStep::TPCMerging, &Merger, -1, true); runKernel(GetGridAuto(0, GPUReconstruction::krnlDeviceType::CPU)); } else if (doGPUall) { - RecordMarker(mEvents->single, 0); + RecordMarker(&mEvents->single, 0); TransferMemoryResourceLinkToHost(RecoStep::TPCMerging, Merger.MemoryResOutputO2(), outputStream, nullptr, &mEvents->single); TransferMemoryResourceLinkToHost(RecoStep::TPCMerging, Merger.MemoryResOutputO2Clus(), outputStream); ReleaseEvent(mEvents->single); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx index da4629928789c..c34c01f1e6593 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx @@ -305,7 +305,7 @@ int32_t GPUChainTracking::RunTPCTrackingSlices_internal() SynchronizeGPU(); } else { for (int32_t i = 0; i < mRec->NStreams(); i++) { - RecordMarker(mEvents->stream[i], i); + RecordMarker(&mEvents->stream[i], i); } runKernel({GetGridAuto(0), krnlRunRangeNone, {&mEvents->single, mEvents->stream, mRec->NStreams()}}); for (int32_t i = 0; i < mRec->NStreams(); i++) { From dce7d4a665d1a06113d7d9c1639704854ec7923a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 13:40:57 +0100 Subject: [PATCH 0482/2205] GPU OpenCL: Add .oclCompileFromSources option to force OpenCL compilation from sources --- GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx | 6 +++--- GPU/GPUTracking/Definitions/GPUSettingsList.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx index a118e6d589712..435e69e91f5fe 100644 --- a/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx +++ b/GPU/GPUTracking/Base/opencl2/GPUReconstructionOCL2.cxx @@ -64,14 +64,14 @@ int32_t GPUReconstructionOCL2Backend::GetOCLPrograms() const char* ocl_flags = GPUCA_M_STR(OCL_FLAGS); #ifdef OPENCL2_ENABLED_SPIRV // clang-format off - if (ver >= 2.2f) { - GPUInfo("Reading OpenCL program from SPIR-V IL (Platform version %f)", ver); + if (ver >= 2.2f && !GetProcessingSettings().oclCompileFromSources) { + GPUInfo("Reading OpenCL program from SPIR-V IL (Platform version %4.2f)", ver); mInternals->program = clCreateProgramWithIL(mInternals->context, _binary_GPUReconstructionOCL2Code_spirv_start, _binary_GPUReconstructionOCL2Code_spirv_len, &ocl_error); ocl_flags = ""; } else #endif // clang-format on { - GPUInfo("Compiling OpenCL program from sources (Platform version %f, %s)", ver); + GPUInfo("Compiling OpenCL program from sources (Platform version %4.2f)", ver); size_t program_sizes[1] = {_binary_GPUReconstructionOCL2Code_src_len}; char* programs_sources[1] = {_binary_GPUReconstructionOCL2Code_src_start}; mInternals->program = clCreateProgramWithSource(mInternals->context, (cl_uint)1, (const char**)&programs_sources, program_sizes, &ocl_error); diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index c4e0dadb87659..d5494d04930f5 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -218,7 +218,7 @@ AddHelp("help", 'h') EndConfig() BeginSubConfig(GPUSettingsProcessing, proc, configStandalone, "PROC", 0, "Processing settings", proc) -AddOption(platformNum, int32_t, -1, "", 0, "Platform to use, in case the backend provides multiple platforms (-1 = auto-select)") +AddOption(platformNum, int32_t, -1, "", 0, "Platform to use, in case the backend provides multiple platforms (OpenCL only, -1 = auto-select)") AddOption(deviceNum, int32_t, -1, "gpuDevice", 0, "Set GPU device to use (-1: automatic, -2: for round-robin usage in timeslice-pipeline)") AddOption(gpuDeviceOnly, bool, false, "", 0, "Use only GPU as device (i.e. no CPU for OpenCL)") AddOption(globalInitMutex, bool, false, "", 0, "Use global mutex to synchronize initialization of multiple GPU instances") @@ -291,6 +291,7 @@ AddOption(tpcApplyDebugClusterFilter, bool, false, "", 0, "Apply custom cluster AddOption(RTCcacheFolder, std::string, "./rtccache/", "", 0, "Folder in which the cache file is stored") AddOption(RTCprependCommand, std::string, "", "", 0, "Prepend RTC compilation commands by this string") AddOption(RTCoverrideArchitecture, std::string, "", "", 0, "Override arhcitecture part of RTC compilation command line") +AddOption(oclCompileFromSources, bool, false, "", 0, "Compile OpenCL binary from included source code instead of using included spirv code") AddOption(printSettings, bool, false, "", 0, "Print all settings when initializing") AddVariable(eventDisplay, GPUCA_NAMESPACE::gpu::GPUDisplayFrontendInterface*, nullptr) AddSubConfig(GPUSettingsProcessingRTC, rtc) From 9a1148718de8207fbbb3c0a31d86bd88d1670289 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 13:41:23 +0100 Subject: [PATCH 0483/2205] GPU OpenCL: Improve compiler command line arguments --- GPU/Common/GPUCommonMath.h | 2 +- GPU/GPUTracking/Base/opencl2/CMakeLists.txt | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/GPU/Common/GPUCommonMath.h b/GPU/Common/GPUCommonMath.h index bc842d00c6568..0e5db743d0c57 100644 --- a/GPU/Common/GPUCommonMath.h +++ b/GPU/Common/GPUCommonMath.h @@ -399,7 +399,7 @@ GPUdi() T GPUCommonMath::MaxWithRef(T x, T y, T z, T w, S refX, S refY, S refZ, GPUdi() float GPUCommonMath::InvSqrt(float _x) { -#ifdef GPUCA_NO_FAST_MATH +#if defined(GPUCA_NO_FAST_MATH) || defined(__OPENCL__) return 1.f / Sqrt(_x); #elif defined(__CUDACC__) || defined(__HIPCC__) return __frsqrt_rn(_x); diff --git a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt index 73062ad82f728..0e6b9b8d0123d 100644 --- a/GPU/GPUTracking/Base/opencl2/CMakeLists.txt +++ b/GPU/GPUTracking/Base/opencl2/CMakeLists.txt @@ -23,9 +23,11 @@ endif() set(CL_SRC ${GPUDIR}/Base/opencl-common/GPUReconstructionOCL.cl) set(CL_BIN ${CMAKE_CURRENT_BINARY_DIR}/GPUReconstructionOCL2Code) -set(OCL_FLAGS -ferror-limit=1000 -Dcl_clang_storage_class_specifiers -Wno-invalid-constexpr -Wno-unused-command-line-argument -cl-std=CLC++2021) +set(OCL_FLAGS -Dcl_clang_storage_class_specifiers -cl-std=CLC++2021) if(NOT DEFINED GPUCA_NO_FAST_MATH OR NOT ${GPUCA_NO_FAST_MATH}) - set(OCL_FLAGS ${OCL_FLAGS} -Xclang -fdenormal-fp-math-f32=ieee -cl-mad-enable -cl-no-signed-zeros) + set(OCL_FLAGS ${OCL_FLAGS} -cl-denorms-are-zero -cl-mad-enable -cl-no-signed-zeros -cl-fast-relaxed-math) +else() +set(OCL_FLAGS ${OCL_FLAGS} -cl-fp32-correctly-rounded-divide-sqrt) endif() set(OCL_DEFINECL "-D$,$-D>" "-I$,EXCLUDE,^/usr/include/?>,$-I>" @@ -47,6 +49,7 @@ if(OPENCL2_ENABLED_SPIRV) # BUILD OpenCL2 intermediate code for SPIR-V target -O0 --target=spirv64 -fno-integrated-objemitter + -ferror-limit=1000 -Wno-invalid-constexpr -Wno-unused-command-line-argument ${OCL_FLAGS} ${OCL_DEFINECL} -o ${CL_BIN}.spirv -c ${CL_SRC} @@ -64,6 +67,7 @@ if(OPENCL2_ENABLED) # BUILD OpenCL2 source code for runtime compilation target add_custom_command( OUTPUT ${CL_BIN}.src COMMAND ${LLVM_CLANG} + -Wno-unused-command-line-argument ${OCL_FLAGS} ${OCL_DEFINECL} -cl-no-stdinc From 0c01d1b7ab0bf8eb4bf7a8a36480847ada46c763 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sat, 16 Nov 2024 17:58:25 +0100 Subject: [PATCH 0484/2205] GPU TPC: Fix segfault when TPC occupancy map is not requested --- GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx index c34c01f1e6593..8db15fb1aef7e 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx @@ -164,9 +164,11 @@ int32_t GPUChainTracking::RunTPCTrackingSlices_internal() TransferMemoryResourceLinkToGPU(RecoStep::TPCSliceTracking, mInputsHost->mResourceOccupancyMap, streamOccMap, &mEvents->init); } } - uint32_t& occupancyTotal = *mInputsHost->mTPCClusterOccupancyMap; - occupancyTotal = CAMath::Float2UIntRn(mRec->MemoryScalers()->nTPCHits / (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasNHBFPerTF ? mIOPtrs.settingsTF->nHBFPerTF : 128)); - mRec->UpdateParamOccupancyMap(param().rec.tpc.occupancyMapTimeBins ? mInputsHost->mTPCClusterOccupancyMap + 2 : nullptr, param().rec.tpc.occupancyMapTimeBins ? mInputsShadow->mTPCClusterOccupancyMap + 2 : nullptr, occupancyTotal, streamOccMap); + if (param().rec.tpc.occupancyMapTimeBins || param().rec.tpc.sysClusErrorC12Norm) { + uint32_t& occupancyTotal = *mInputsHost->mTPCClusterOccupancyMap; + occupancyTotal = CAMath::Float2UIntRn(mRec->MemoryScalers()->nTPCHits / (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasNHBFPerTF ? mIOPtrs.settingsTF->nHBFPerTF : 128)); + mRec->UpdateParamOccupancyMap(param().rec.tpc.occupancyMapTimeBins ? mInputsHost->mTPCClusterOccupancyMap + 2 : nullptr, param().rec.tpc.occupancyMapTimeBins ? mInputsShadow->mTPCClusterOccupancyMap + 2 : nullptr, occupancyTotal, streamOccMap); + } int32_t streamMap[NSLICES]; From 901995584e0a1cff9a80d853b1e7b65f399d5fa2 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 18 Nov 2024 02:33:42 +0100 Subject: [PATCH 0485/2205] extend opt. max-tf-per-file to raw-tf reader, move it to device --- Detectors/CTF/workflow/src/CTFReaderSpec.cxx | 7 ++++++ .../CTF/workflow/src/ctf-reader-workflow.cxx | 7 ------ Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx | 23 +++++++++++++++---- Detectors/Raw/TFReaderDD/src/TFReaderSpec.h | 1 + .../Raw/TFReaderDD/src/tf-reader-workflow.cxx | 8 ------- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx index 9b16e65c3a2b7..70bb589e8836a 100644 --- a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx +++ b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx @@ -148,6 +148,10 @@ void CTFReaderSpec::init(InitContext& ic) mUseLocalTFCounter = ic.options().get("local-tf-counter"); mImposeRunStartMS = ic.options().get("impose-run-start-timstamp"); mInput.checkTFLimitBeforeReading = ic.options().get("limit-tf-before-reading"); + mInput.maxTFs = ic.options().get("max-tf"); + mInput.maxTFs = mInput.maxTFs > 0 ? mInput.maxTFs : 0x7fffffff; + mInput.maxTFsPerFile = ic.options().get("max-tf-per-file"); + mInput.maxTFsPerFile = mInput.maxTFsPerFile > 0 ? mInput.maxTFsPerFile : 0x7fffffff; mRunning = true; mFileFetcher = std::make_unique(mInput.inpdata, mInput.tffileRegex, mInput.remoteRegex, mInput.copyCmd); mFileFetcher->setMaxFilesInQueue(mInput.maxFileCache); @@ -474,6 +478,9 @@ DataProcessorSpec getCTFReaderSpec(const CTFReaderInp& inp) options.emplace_back(ConfigParamSpec{"local-tf-counter", VariantType::Bool, false, {"reassign header.tfCounter from local TF counter"}}); options.emplace_back(ConfigParamSpec{"fetch-failure-threshold", VariantType::Float, 0.f, {"Fail if too many failures( >0: fraction, <0: abs number, 0: no threshold)"}}); options.emplace_back(ConfigParamSpec{"limit-tf-before-reading", VariantType::Bool, false, {"Check TF limiting before reading new TF, otherwhise before injecting it"}}); + options.emplace_back(ConfigParamSpec{"max-tf", VariantType::Int, -1, {"max CTFs to process (<= 0 : infinite)"}}); + options.emplace_back(ConfigParamSpec{"max-tf-per-file", VariantType::Int, -1, {"max TFs to process per ctf file (<= 0 : infinite)"}}); + if (!inp.metricChannel.empty()) { options.emplace_back(ConfigParamSpec{"channel-config", VariantType::String, inp.metricChannel, {"Out-of-band channel config for TF throttling"}}); } diff --git a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx index a12c9c10f9dd8..90d259f4e3a5c 100644 --- a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx +++ b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx @@ -54,8 +54,6 @@ void customize(std::vector& workflowOptions) options.push_back(ConfigParamSpec{"ctf-input", VariantType::String, "none", {"comma-separated list CTF input files"}}); options.push_back(ConfigParamSpec{"onlyDet", VariantType::String, std::string{DetID::ALL}, {"comma-separated list of detectors to accept. Overrides skipDet"}}); options.push_back(ConfigParamSpec{"skipDet", VariantType::String, std::string{DetID::NONE}, {"comma-separate list of detectors to skip"}}); - options.push_back(ConfigParamSpec{"max-tf", VariantType::Int, -1, {"max CTFs to process (<= 0 : infinite)"}}); - options.push_back(ConfigParamSpec{"max-tf-per-file", VariantType::Int, -1, {"max TFs to process per ctf file (<= 0 : infinite)"}}); options.push_back(ConfigParamSpec{"loop", VariantType::Int, 0, {"loop N times (infinite for N<0)"}}); options.push_back(ConfigParamSpec{"delay", VariantType::Float, 0.f, {"delay in seconds between consecutive TFs sending"}}); options.push_back(ConfigParamSpec{"copy-cmd", VariantType::String, "alien_cp ?src file://?dst", {"copy command for remote files or no-copy to avoid copying"}}); // Use "XrdSecPROTOCOL=sss,unix xrdcp -N root://eosaliceo2.cern.ch/?src ?dst" for direct EOS access @@ -117,11 +115,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (ctfInput.delay_us < 0) { ctfInput.delay_us = 0; } - int n = configcontext.options().get("max-tf"); - ctfInput.maxTFs = n > 0 ? n : 0x7fffffff; - - n = configcontext.options().get("max-tf-per-file"); - ctfInput.maxTFsPerFile = n > 0 ? n : 0x7fffffff; ctfInput.maxFileCache = std::max(1, configcontext.options().get("max-cached-files")); diff --git a/Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx b/Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx index 594d26b5682c6..58a2a775537d4 100644 --- a/Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx +++ b/Detectors/Raw/TFReaderDD/src/TFReaderSpec.cxx @@ -99,6 +99,12 @@ TFReaderSpec::TFReaderSpec(const TFReaderInp& rinp) : mInput(rinp) void TFReaderSpec::init(o2f::InitContext& ic) { mInput.tfIDs = o2::RangeTokenizer::tokenize(ic.options().get("select-tf-ids")); + mInput.maxTFs = ic.options().get("max-tf"); + mInput.maxTFs = mInput.maxTFs > 0 ? mInput.maxTFs : 0x7fffffff; + mInput.maxTFsPerFile = ic.options().get("max-tf-per-file"); + mInput.maxTFsPerFile = mInput.maxTFsPerFile > 0 ? mInput.maxTFsPerFile : 0x7fffffff; + mInput.maxTFCache = std::max(1, ic.options().get("max-cached-tf")); + mInput.maxFileCache = std::max(1, ic.options().get("max-cached-files")); mFileFetcher = std::make_unique(mInput.inpdata, mInput.tffileRegex, mInput.remoteRegex, mInput.copyCmd); mFileFetcher->setMaxFilesInQueue(mInput.maxFileCache); mFileFetcher->setMaxLoops(mInput.maxLoops); @@ -417,15 +423,17 @@ void TFReaderSpec::TFBuilder() } mTFBuilderCounter++; } - if (!acceptTF) { - continue; - } if (mRunning && tf) { - mWaitSendingLast = true; - mTFQueue.push(std::move(tf)); + if (acceptTF) { + mWaitSendingLast = true; + mTFQueue.push(std::move(tf)); + } } else { break; } + if (mInput.maxTFsPerFile > 0 && mInput.maxTFsPerFile >= locID) { // go to next file + break; + } } // remove already processed file from the queue, unless they are needed for further looping if (mFileFetcher) { @@ -527,6 +535,11 @@ o2f::DataProcessorSpec o2::rawdd::getTFReaderSpec(o2::rawdd::TFReaderInp& rinp) } spec.options.emplace_back(o2f::ConfigParamSpec{"select-tf-ids", o2f::VariantType::String, "", {"comma-separated list TF IDs to inject (from cumulative counter of TFs seen)"}}); spec.options.emplace_back(o2f::ConfigParamSpec{"fetch-failure-threshold", o2f::VariantType::Float, 0.f, {"Fatil if too many failures( >0: fraction, <0: abs number, 0: no threshold)"}}); + spec.options.emplace_back(o2f::ConfigParamSpec{"max-tf", o2f::VariantType::Int, -1, {"max TF ID to process (<= 0 : infinite)"}}); + spec.options.emplace_back(o2f::ConfigParamSpec{"max-tf-per-file", o2f::VariantType::Int, -1, {"max TFs to process per raw-tf file (<= 0 : infinite)"}}); + spec.options.emplace_back(o2f::ConfigParamSpec{"max-cached-tf", o2f::VariantType::Int, 3, {"max TFs to cache in memory"}}); + spec.options.emplace_back(o2f::ConfigParamSpec{"max-cached-files", o2f::VariantType::Int, 3, {"max TF files queued (copied for remote source)"}}); + spec.algorithm = o2f::adaptFromTask(rinp); return spec; diff --git a/Detectors/Raw/TFReaderDD/src/TFReaderSpec.h b/Detectors/Raw/TFReaderDD/src/TFReaderSpec.h index b4bb07fad24be..e3a5b5c920010 100644 --- a/Detectors/Raw/TFReaderDD/src/TFReaderSpec.h +++ b/Detectors/Raw/TFReaderDD/src/TFReaderSpec.h @@ -43,6 +43,7 @@ struct TFReaderInp { int64_t delay_us = 0; int maxLoops = 0; int maxTFs = -1; + int maxTFsPerFile = -1; bool sendDummyForMissing = true; bool sup0xccdb = false; std::vector hdVec; diff --git a/Detectors/Raw/TFReaderDD/src/tf-reader-workflow.cxx b/Detectors/Raw/TFReaderDD/src/tf-reader-workflow.cxx index c468d1660fcc7..7d8ee09fe474f 100644 --- a/Detectors/Raw/TFReaderDD/src/tf-reader-workflow.cxx +++ b/Detectors/Raw/TFReaderDD/src/tf-reader-workflow.cxx @@ -28,20 +28,16 @@ void customize(std::vector& workflowOptions) options.push_back(ConfigParamSpec{"onlyDet", VariantType::String, "all", {"list of dectors"}}); options.push_back(ConfigParamSpec{"raw-only-det", VariantType::String, "none", {"do not open non-raw channel for these detectors"}}); options.push_back(ConfigParamSpec{"non-raw-only-det", VariantType::String, "none", {"do not open raw channel for these detectors"}}); - options.push_back(ConfigParamSpec{"max-tf", VariantType::Int, -1, {"max TF ID to process (<= 0 : infinite)"}}); options.push_back(ConfigParamSpec{"loop", VariantType::Int, 0, {"loop N times (-1 = infinite)"}}); options.push_back(ConfigParamSpec{"delay", VariantType::Float, 0.f, {"delay in seconds between consecutive TFs sending"}}); options.push_back(ConfigParamSpec{"copy-cmd", VariantType::String, "alien_cp ?src file://?dst", {"copy command for remote files"}}); // Use "XrdSecPROTOCOL=sss,unix xrdcp -N root://eosaliceo2.cern.ch/?src ?dst" for direct EOS access options.push_back(ConfigParamSpec{"tf-file-regex", VariantType::String, ".+\\.tf$", {"regex string to identify TF files"}}); options.push_back(ConfigParamSpec{"remote-regex", VariantType::String, "^(alien://|)/alice/data/.+", {"regex string to identify remote files"}}); // Use "^/eos/aliceo2/.+" for direct EOS access - options.push_back(ConfigParamSpec{"max-cached-tf", VariantType::Int, 3, {"max TFs to cache in memory"}}); - options.push_back(ConfigParamSpec{"max-cached-files", VariantType::Int, 3, {"max TF files queued (copied for remote source)"}}); options.push_back(ConfigParamSpec{"tf-reader-verbosity", VariantType::Int, 0, {"verbosity level (1 or 2: check RDH, print DH/DPH for 1st or all slices, >2 print RDH)"}}); options.push_back(ConfigParamSpec{"raw-channel-config", VariantType::String, "", {"optional raw FMQ channel for non-DPL output"}}); options.push_back(ConfigParamSpec{"send-diststf-0xccdb", VariantType::Bool, false, {"send explicit FLP/DISTSUBTIMEFRAME/0xccdb output"}}); options.push_back(ConfigParamSpec{"disable-dummy-output", VariantType::Bool, false, {"Disable sending empty output if corresponding data is not found in the data"}}); options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"semicolon separated key=value strings"}}); - options.push_back(ConfigParamSpec{"timeframes-shm-limit", VariantType::String, "0", {"Minimum amount of SHM required in order to publish data"}}); options.push_back(ConfigParamSpec{"metric-feedback-channel-format", VariantType::String, "name=metric-feedback,type=pull,method=connect,address=ipc://{}metric-feedback-{},transport=shmem,rateLogging=0", {"format for the metric-feedback channel for TF rate limiting"}}); @@ -59,8 +55,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) o2::rawdd::TFReaderInp rinp; rinp.inpdata = configcontext.options().get("input-data"); rinp.maxLoops = configcontext.options().get("loop"); - int n = configcontext.options().get("max-tf"); - rinp.maxTFs = n > 0 ? n : 0x7fffffff; auto detlistSelect = configcontext.options().get("onlyDet"); if (detlistSelect == "all") { // Exclude FOCAL from default detlist (must be selected on request) @@ -74,8 +68,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) rinp.rawChannelConfig = configcontext.options().get("raw-channel-config"); rinp.delay_us = uint64_t(1e6 * configcontext.options().get("delay")); // delay in microseconds rinp.verbosity = configcontext.options().get("tf-reader-verbosity"); - rinp.maxTFCache = std::max(1, configcontext.options().get("max-cached-tf")); - rinp.maxFileCache = std::max(1, configcontext.options().get("max-cached-files")); rinp.copyCmd = configcontext.options().get("copy-cmd"); rinp.tffileRegex = configcontext.options().get("tf-file-regex"); rinp.remoteRegex = configcontext.options().get("remote-regex"); From 348b1941d5873138f9f845eecf8f611b7f9d8ff5 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 17 Nov 2024 19:42:38 +0100 Subject: [PATCH 0486/2205] Optional ordering of objects in CCDBPopulator If an option --ordering-latency with positive value T (in ms) is provided than every incoming object will be buffered and uploaded only if no object with the same CCDB path and earlier start of validity was received in preceding T ms. All remaining cached objects are uploaded at EOR (or stop() method call). --- CCDB/include/CCDB/CcdbObjectInfo.h | 23 ++ Detectors/Calibration/README.md | 6 +- .../Calibration/workflow/CCDBPopulatorSpec.h | 300 +++++++++++------- 3 files changed, 220 insertions(+), 109 deletions(-) diff --git a/CCDB/include/CCDB/CcdbObjectInfo.h b/CCDB/include/CCDB/CcdbObjectInfo.h index 6db4cffd63b85..117ca1123104f 100644 --- a/CCDB/include/CCDB/CcdbObjectInfo.h +++ b/CCDB/include/CCDB/CcdbObjectInfo.h @@ -93,6 +93,16 @@ class CcdbObjectInfo [[nodiscard]] long getEndValidityTimestamp() const { return mEnd; } void setEndValidityTimestamp(long end) { mEnd = end; } + bool operator<(const CcdbObjectInfo& other) const + { + return mStart < other.mStart; + } + + bool operator>(const CcdbObjectInfo& other) const + { + return mStart > other.mStart; + } + private: std::string mObjType{}; // object type (e.g. class) std::string mFileName{}; // file name in the CCDB @@ -107,4 +117,17 @@ class CcdbObjectInfo } // namespace o2::ccdb +namespace std +{ +// defining std::hash for InteractionRecord to be used with std containers +template <> +struct hash { + public: + size_t operator()(const o2::ccdb::CcdbObjectInfo& info) const + { + return info.getStartValidityTimestamp(); + } +}; +} // namespace std + #endif // O2_CCDB_CCDBOBJECTINFO_H_ diff --git a/Detectors/Calibration/README.md b/Detectors/Calibration/README.md index 606493ea0cc32..be519be405c07 100644 --- a/Detectors/Calibration/README.md +++ b/Detectors/Calibration/README.md @@ -161,7 +161,11 @@ o2-calibration-ccdb-populator-workflow --sspec-min 0 --sspec-max 1 -b then the `ObjA` will be uploaded only to the default server (`http://alice-ccdb.cern.ch`), `ObjB` will be uploaded to both default and `local` server and `ObjC` will be uploaded to the `local` server only. -By default the ccdb-populator-workflow will not produce `fatal` on failed upload. To require it an option `--fatal-on-failure` can be used. +By default the `ccdb-populator-workflow` will not produce `fatal` on failed upload. To require it an option `--fatal-on-failure` can be used. + +By default the `ccdb-populator-workflow` uploads objects as it gets them. In case there is a danger that objects of the same URL will arrive in the order not sorted in SOV +(which may lead to screaning of the object with later SOV by other object if earlier ROF) one can use an option `--ordering-latency ` of the `ccdb-populator-workflow`. +Then every incoming object will be buffered and uploaded only if no object with the same CCDB path and earlier start of validity was received in preceding N milliseconds. All remaining cached objects are uploaded at EOR (or stop() method call). need to enforce this on the importParticles level of individual generators + for (auto& p : mParticles) { + auto st = o2::mcgenstatus::MCGenStatusEncoding(p.GetStatusCode(), p.GetStatusCode()).fullEncoding; + p.SetStatusCode(st); + p.SetBit(ParticleStatus::kToBeDone, true); + } + + return true; +} + +template +std::string GeneratorHybrid::jsonValueToString(const T& value) +{ + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + value.Accept(writer); + return buffer.GetString(); +} + +Bool_t GeneratorHybrid::parseJSON(const std::string& path) +{ + // Parse JSON file to build map + std::ifstream fileStream(path, std::ios::in); + if (!fileStream.is_open()) { + LOG(error) << "Cannot open " << path; + return false; + } + rapidjson::IStreamWrapper isw(fileStream); + rapidjson::Document doc; + doc.ParseStream(isw); + if (doc.HasParseError()) { + LOG(error) << "Error parsing provided json file " << path; + LOG(error) << " - Error -> " << rapidjson::GetParseError_En(doc.GetParseError()); + return false; + } + + // Put the generator names in mInputGens + if (doc.HasMember("generators")) { + const auto& gens = doc["generators"]; + for (const auto& gen : gens.GetArray()) { + // push in mInputGens the "name" of the generator + std::string name = gen["name"].GetString(); + mInputGens.push_back(name); + if (gen.HasMember("config")) { + if (name == "boxgen") { + const auto& boxconf = gen["config"]; + auto boxConfig = TBufferJSON::FromJSON(jsonValueToString(boxconf).c_str()); + mBoxGenConfigs.push_back(std::move(boxConfig)); + mConfigs.push_back("boxgen_" + std::to_string(mBoxGenConfigs.size() - 1)); + continue; + } else if (name == "pythia8") { + const auto& pythia8conf = gen["config"]; + auto pythia8Config = TBufferJSON::FromJSON(jsonValueToString(pythia8conf).c_str()); + mPythia8GenConfigs.push_back(std::move(pythia8Config)); + mConfigs.push_back("pythia8_" + std::to_string(mPythia8GenConfigs.size() - 1)); + continue; + } else if (name == "extkinO2") { + const auto& o2kineconf = gen["config"]; + auto o2kineConfig = TBufferJSON::FromJSON(jsonValueToString(o2kineconf).c_str()); + mO2KineGenConfigs.push_back(std::move(o2kineConfig)); + mConfigs.push_back("extkinO2_" + std::to_string(mO2KineGenConfigs.size() - 1)); + continue; + } else if (name == "external") { + const auto& extconf = gen["config"]; + auto extConfig = TBufferJSON::FromJSON(jsonValueToString(extconf).c_str()); + mExternalGenConfigs.push_back(std::move(extConfig)); + mConfigs.push_back("external_" + std::to_string(mExternalGenConfigs.size() - 1)); + continue; + } else if (name == "hepmc") { + const auto& genconf = gen["config"]; + const auto& cmdconf = genconf["configcmd"]; + const auto& hepmcconf = genconf["confighepmc"]; + auto cmdConfig = TBufferJSON::FromJSON(jsonValueToString(cmdconf).c_str()); + auto hepmcConfig = TBufferJSON::FromJSON(jsonValueToString(hepmcconf).c_str()); + mFileOrCmdGenConfigs.push_back(std::move(cmdConfig)); + mHepMCGenConfigs.push_back(std::move(hepmcConfig)); + mConfigs.push_back("hepmc_" + std::to_string(mFileOrCmdGenConfigs.size() - 1)); + continue; + } else { + mConfigs.push_back(""); + } + } else { + if (name == "boxgen" || name == "pythia8" || name == "extkinO2" || name == "external" || name == "hepmc") { + LOG(fatal) << "No configuration provided for generator " << name; + return false; + } else { + mConfigs.push_back(""); + } + } + } + } + + // Get fractions and put them in mFractions + if (doc.HasMember("fractions")) { + const auto& fractions = doc["fractions"]; + for (const auto& frac : fractions.GetArray()) { + mFractions.push_back(frac.GetInt()); + } + } else { + // Set fractions to unity for all generators in case they are not provided + const auto& gens = doc["generators"]; + for (const auto& gen : gens.GetArray()) { + mFractions.push_back(1); + } + } + return true; +} + +} // namespace eventgen +} // namespace o2 + +ClassImp(o2::eventgen::GeneratorHybrid); \ No newline at end of file diff --git a/Generators/src/GeneratorHybridParam.cxx b/Generators/src/GeneratorHybridParam.cxx new file mode 100644 index 0000000000000..e15fbb8ee4ba4 --- /dev/null +++ b/Generators/src/GeneratorHybridParam.cxx @@ -0,0 +1,15 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \author M. Giacalone - October 2024 + +#include "Generators/GeneratorHybridParam.h" +O2ParamImpl(o2::eventgen::GeneratorHybridParam); \ No newline at end of file diff --git a/Generators/src/GeneratorPythia8.cxx b/Generators/src/GeneratorPythia8.cxx index a2740a37af19f..a27980a77c992 100644 --- a/Generators/src/GeneratorPythia8.cxx +++ b/Generators/src/GeneratorPythia8.cxx @@ -63,6 +63,27 @@ GeneratorPythia8::GeneratorPythia8() : Generator("ALICEo2", "ALICEo2 Pythia8 Gen /*****************************************************************/ +GeneratorPythia8::GeneratorPythia8(Pythia8GenConfig const& pars) : Generator("ALICEo2", "ALICEo2 Pythia8 Generator") +{ + /** constructor **/ + + mInterface = reinterpret_cast(&mPythia); + mInterfaceName = "pythia8"; + + LOG(info) << "Instance \'Pythia8\' generator with following parameters"; + LOG(info) << "config: " << pars.config; + LOG(info) << "hooksFileName: " << pars.hooksFileName; + LOG(info) << "hooksFuncName: " << pars.hooksFuncName; + + mGenConfig = std::make_unique(pars); + + setConfig(pars.config); + setHooksFileName(pars.hooksFileName); + setHooksFuncName(pars.hooksFuncName); +} + +/*****************************************************************/ + GeneratorPythia8::GeneratorPythia8(const Char_t* name, const Char_t* title) : Generator(name, title) { /** constructor **/ @@ -557,7 +578,8 @@ void GeneratorPythia8::pruneEvent(Pythia8::Event& event, Select select) } } } - if (GeneratorPythia8Param::Instance().verbose) { + int verbose = mGenConfig->verbose; + if (verbose) { LOG(info) << "Pythia event was pruned from " << event.size() << " to " << pruned.size() << " particles"; } @@ -570,7 +592,7 @@ void GeneratorPythia8::initUserFilterCallback() { mUserFilterFcn = [](Pythia8::Particle const&) -> bool { return true; }; - auto& filter = GeneratorPythia8Param::Instance().particleFilter; + std::string filter = mGenConfig->particleFilter; if (filter.size() > 0) { LOG(info) << "Initializing the callback for user-based particle pruning " << filter; auto expandedFileName = o2::utils::expandShellVarsInFileName(filter); @@ -599,7 +621,8 @@ Bool_t // event record in the AOD. std::function partonSelect = [](const Pythia8::Particle&) { return true; }; - if (not GeneratorPythia8Param::Instance().includePartonEvent) { + bool includeParton = mGenConfig->includePartonEvent; + if (not includeParton) { // Select pythia particles partonSelect = [](const Pythia8::Particle& particle) { diff --git a/Generators/src/GeneratorsLinkDef.h b/Generators/src/GeneratorsLinkDef.h index 222004e0957cb..18428a808a86b 100644 --- a/Generators/src/GeneratorsLinkDef.h +++ b/Generators/src/GeneratorsLinkDef.h @@ -29,10 +29,12 @@ #pragma link C++ class o2::eventgen::Generator + ; #pragma link C++ class o2::eventgen::GeneratorTGenerator + ; #pragma link C++ class o2::eventgen::GeneratorExternalParam + ; +#pragma link C++ class o2::eventgen::ExternalGenConfig + ; #pragma link C++ class o2::eventgen::GeneratorGeantinos + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorExternalParam> + ; #ifdef GENERATORS_WITH_HEPMC3 #pragma link C++ class o2::eventgen::GeneratorHepMC + ; +#pragma link C++ class o2::eventgen::HepMCGenConfig + ; #pragma link C++ class o2::eventgen::GeneratorHepMCParam + ; #endif #ifdef GENERATORS_WITH_PYTHIA6 @@ -44,6 +46,7 @@ #pragma link C++ class o2::eventgen::GeneratorPythia8 + ; #pragma link C++ class o2::eventgen::DecayerPythia8 + ; #pragma link C++ class o2::eventgen::GeneratorPythia8Param + ; +#pragma link C++ class o2::eventgen::Pythia8GenConfig + ; #pragma link C++ class o2::eventgen::DecayerPythia8Param + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorPythia8Param> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::DecayerPythia8Param> + ; @@ -51,7 +54,10 @@ #endif #pragma link C++ class o2::eventgen::GeneratorFromFile + ; #pragma link C++ class o2::eventgen::GeneratorFromO2Kine + ; +#pragma link C++ class o2::eventgen::GeneratorHybrid + ; +#pragma link C++ class o2::eventgen::GeneratorHybridParam + ; #pragma link C++ class o2::eventgen::GeneratorFromO2KineParam + ; +#pragma link C++ class o2::eventgen::O2KineGenConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorFromO2KineParam> + ; #pragma link C++ class o2::eventgen::PrimaryGenerator + ; #pragma link C++ class o2::eventgen::PrimaryGeneratorParam + ; @@ -62,6 +68,7 @@ #pragma link C++ class o2::eventgen::TriggerParticleParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::TriggerParticleParam> + ; #pragma link C++ class o2::eventgen::BoxGunParam + ; +#pragma link C++ class o2::eventgen::BoxGenConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::BoxGunParam> + ; #pragma link C++ class o2::eventgen::QEDGenParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::QEDGenParam> + ; @@ -71,6 +78,7 @@ #pragma link C++ class o2::eventgen::GeneratorTParticleParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorTParticleParam> + ; #pragma link C++ class o2::eventgen::GeneratorFileOrCmdParam + ; +#pragma link C++ class o2::eventgen::FileOrCmdGenConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorFileOrCmdParam> + ; #pragma link C++ class o2::eventgen::BoxGenerator + ; diff --git a/run/CMakeLists.txt b/run/CMakeLists.txt index fccb3f0085642..f21ecafb0528a 100644 --- a/run/CMakeLists.txt +++ b/run/CMakeLists.txt @@ -331,3 +331,7 @@ set_tests_properties(o2sim_G4_checklogs endif() install(FILES o2-sim-client.py PERMISSIONS GROUP_READ GROUP_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ WORLD_EXECUTE WORLD_READ DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(DIRECTORY SimExamples/ + DESTINATION examples + PATTERN * + PERMISSIONS GROUP_READ GROUP_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ WORLD_EXECUTE WORLD_READ) \ No newline at end of file diff --git a/run/SimExamples/Hybrid/README.md b/run/SimExamples/Hybrid/README.md new file mode 100644 index 0000000000000..3c3cba37748bf --- /dev/null +++ b/run/SimExamples/Hybrid/README.md @@ -0,0 +1,18 @@ + + +The usage of the Hybrid generator with the o2-sim is presented in this short manual. +All the other generators are implemented as sub-generators and they can be called thanks to a +JSON file, fed to o2-sim via the GeneratorHybrid.configFile parameter. The O2sim package needs to be loaded in order to use this example. + +The example can be run automatically using the runo2sim.sh script, which contains most of the +available generators in O2. The JSON template can be generated using the ${O2DPG_ROOT}/MC/bin/o2_hybrid_gen.py script. To use this example the user can simply copy the entire Hybrid example folder and execute the script after giving it execution permissions (`chmod +x runo2sim.sh`). + +# Files description + +- **runo2sim.sh** → allows to use the hybrid generator example +- **hybridconfig.json** → example JSON file for the hybrid generator configuration +- **example.optns** → options file to be used in EPOS4 implemented as subgenerator in this example (the .optns must be available in the current working directory) +- **evtpool.root** → cached events to be used with the extkinO2 generator +- **epos4.hepmc** → EPOS4 events stored as hepmc file \ No newline at end of file diff --git a/run/SimExamples/Hybrid/example.optns b/run/SimExamples/Hybrid/example.optns new file mode 100644 index 0000000000000..99f865c2a05b3 --- /dev/null +++ b/run/SimExamples/Hybrid/example.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collision no hydro no hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core off !core/corona not activated +hydro off !hydro not activated +eos off !eos not activated +hacas off !hadronic cascade not activated +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 100000 diff --git a/run/SimExamples/Hybrid/hybridconfig.json b/run/SimExamples/Hybrid/hybridconfig.json new file mode 100644 index 0000000000000..ec36930c569fe --- /dev/null +++ b/run/SimExamples/Hybrid/hybridconfig.json @@ -0,0 +1,104 @@ +{ + "generators": [ + { + "name": "pythia8", + "config": { + "config": "$O2_ROOT/share/Generators/egconfig/pythia8_inel.cfg", + "hooksFileName": "", + "hooksFuncName": "", + "includePartonEvent": false, + "particleFilter": "", + "verbose": 0 + } + }, + { + "name": "boxgen", + "config": { + "pdg": 13, + "number": 1, + "eta": [ + -4, + -2.5 + ], + "prange": [ + 0.1, + 5 + ], + "phirange": [ + 0, + 360 + ] + } + }, + { + "name": "boxgen", + "config": { + "pdg": 22, + "number": 1, + "eta": [ + -4, + -2.5 + ], + "prange": [ + 0.1, + 5 + ], + "phirange": [ + 0, + 360 + ] + } + }, + { + "name": "external", + "config": { + "fileName": "${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV.C", + "funcName": "GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV()" + } + }, + { + "name": "extkinO2", + "config": { + "skipNonTrackable": true, + "continueMode": false, + "roundRobin": false, + "randomize": false, + "rngseed": 0, + "randomphi": false, + "fileName": "${PWD}/evtpool.root" + } + }, + { + "name": "hepmc", + "config": { + "configcmd": { + "fileNames": "", + "cmd": "" + }, + "confighepmc": { + "version": 2, + "eventsToSkip": 0, + "fileName": "${PWD}/slight.hepmc", + "prune": false + } + } + }, + { + "name": "pythia8pp" + }, + { + "name": "pythia8hf", + "config": "" + } + ], + "fractions": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ] +} \ No newline at end of file diff --git a/run/SimExamples/Hybrid/runo2sim.sh b/run/SimExamples/Hybrid/runo2sim.sh new file mode 100644 index 0000000000000..83a7f327abdaa --- /dev/null +++ b/run/SimExamples/Hybrid/runo2sim.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# Hybrid generator simulation example: +# the simulation is configured using a JSON file (hybridconfig.json in this folder), whose +# template can be generated using the script ${O2DPG_ROOT}/MC/bin/o2_hybrid_gen.py +set -x +if [ ! "${O2DPG_ROOT}" ]; then + echo "This needs O2DPG loaded; alienv enter ..." + exit 1 +fi + +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 2 + +NEV=-1 +more="" +JOBS=2 + +usage() +{ + cat </dev/stderr + exit 3 + ;; + esac + shift +done + +# Set number of events in optns file +if [ ! $NEV -eq -1 ]; then + echo "Setting number of events to $NEV" +else + echo "Number of events not set, defaulting to 10..." + NEV=10 +fi + +# Generation of 1000 events using STARlight in a slight.hepmc file +${O2_ROOT}/examples/HepMC_STARlight/run-starlight.sh + +# Generation of event pool with pythia8 (10000 events) in a evtpool.root file +${O2DPG_ROOT}/MC/run/examples/event_pool.sh --make + +# Starting simulation with Hybrid generator +${O2_ROOT}/bin/o2-sim --noGeant -j $JOBS --field ccdb --vertexMode kCCDB --run 300000 --configKeyValues "MFTBase.buildAlignment=true;GeneratorHybrid.configFile=$PWD/hybridconfig.json;GeneratorHybrid.randomize=false;${more}" -g hybrid -o genevents --timestamp 1546300800000 --seed 836302859 -n $NEV \ No newline at end of file diff --git a/run/SimExamples/README.md b/run/SimExamples/README.md index 5615848202fca..139c24693b3ed 100644 --- a/run/SimExamples/README.md +++ b/run/SimExamples/README.md @@ -14,6 +14,8 @@ * \subpage refrunSimExamplesAliRoot_AMPT * \subpage refrunSimExamplesHepMC * \subpage refrunSimExamplesHepMC_STARlight +* \subpage refrunSimExamplesHepMC_EPOS4 +* \subpage refrunSimExamplesHybrid * \subpage refrunSimExamplesJet_Embedding_Pythia8 * \subpage refrunSimExamplesMcTracksToAOD * \subpage refrunSimExamplesMcTracksToAOD From 15dcbf65aec1e5473c1b3de3ed839bb40e148873 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:49:34 +0100 Subject: [PATCH 0497/2205] Fix a few --compression options (#13717) --- Framework/AODMerger/src/aodMerger.cxx | 2 +- Framework/AODMerger/src/aodStrainer.cxx | 2 +- Framework/AODMerger/src/aodThinner.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/AODMerger/src/aodMerger.cxx b/Framework/AODMerger/src/aodMerger.cxx index aa27d4f617b3b..f474cb0d37e43 100644 --- a/Framework/AODMerger/src/aodMerger.cxx +++ b/Framework/AODMerger/src/aodMerger.cxx @@ -48,7 +48,7 @@ int main(int argc, char* argv[]) {"max-size", required_argument, nullptr, 2}, {"skip-non-existing-files", no_argument, nullptr, 3}, {"skip-parent-files-list", no_argument, nullptr, 4}, - {"compression", no_argument, nullptr, 5}, + {"compression", required_argument, nullptr, 5}, {"verbosity", required_argument, nullptr, 'v'}, {"help", no_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}}; diff --git a/Framework/AODMerger/src/aodStrainer.cxx b/Framework/AODMerger/src/aodStrainer.cxx index 0ecb8d0d81659..fc54aa9c533cf 100644 --- a/Framework/AODMerger/src/aodStrainer.cxx +++ b/Framework/AODMerger/src/aodStrainer.cxx @@ -71,7 +71,7 @@ int main(int argc, char* argv[]) } else if (c == 4) { downsampling = atof(optarg); } else if (c == 5) { - compression = atof(optarg); + compression = atoi(optarg); } else if (c == 'h') { printf("AO2D strainer tool. Options: \n"); printf(" --input <%s> Contains path to files to be merged. Default: %s\n", inputAO2D.c_str(), inputAO2D.c_str()); diff --git a/Framework/AODMerger/src/aodThinner.cxx b/Framework/AODMerger/src/aodThinner.cxx index f9fb31f9ad08d..5da17032c80d4 100644 --- a/Framework/AODMerger/src/aodThinner.cxx +++ b/Framework/AODMerger/src/aodThinner.cxx @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) {"input", required_argument, nullptr, 'i'}, {"output", required_argument, nullptr, 'o'}, {"overwrite", no_argument, nullptr, 'O'}, - {"compression", no_argument, nullptr, 'c'}, + {"compression", required_argument, nullptr, 'c'}, {"help", no_argument, nullptr, 'h'}, {nullptr, 0, nullptr, 0}}; From d3d07ddc000977f4e53ee70aa15f413b41cc47bb Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 19 Nov 2024 21:16:10 +0100 Subject: [PATCH 0498/2205] Protect its/mft decoder agains decreasing row in the same column Discard cable data if this happens. A new error ChipPixelData::DecreasingRow is added. --- .../ITSMFTReconstruction/AlpideCoder.h | 51 +++++++++++-------- .../ITSMFTReconstruction/DecodingStat.h | 3 ++ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h index 321ed52258ff2..b14a6b3f6b62f 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/AlpideCoder.h @@ -273,33 +273,44 @@ class AlpideCoder uint16_t row = pixID >> 1; // abs id of left column in double column uint16_t colD = (region * NDColInReg + dColID) << 1; // TODO consider <<4 instead of *NDColInReg? - bool rightC = (row & 0x1) ? !(pixID & 0x1) : (pixID & 0x1); // true for right column / lalse for left + bool rightC = (row & 0x1) ? !(pixID & 0x1) : (pixID & 0x1); // true for right column / false for left - if (row == rowPrev && colD == colDPrev) { - // this is a special test to exclude repeated data of the same pixel fired + if (colD == colDPrev) { + bool skip = false; + if (row == rowPrev) { // this is a special test to exclude repeated data of the same pixel fired + skip = true; #ifdef ALPIDE_DECODING_STAT - chipData.setError(ChipStat::RepeatingPixel); - chipData.addErrorInfo((uint64_t(colD + rightC) << 16) | uint64_t(row)); + chipData.setError(ChipStat::RepeatingPixel); + chipData.addErrorInfo((uint64_t(colD + rightC) << 16) | uint64_t(row)); #endif - if ((dataS & (~MaskDColID)) == DATALONG) { // skip pattern w/o decoding - uint8_t hitsPattern = 0; - if (!buffer.next(hitsPattern)) { + } else if (rowPrev < 0xffff && row < rowPrev) { #ifdef ALPIDE_DECODING_STAT - chipData.setError(ChipStat::TruncatedLondData); + chipData.setError(ChipStat::DecreasingRow); + chipData.addErrorInfo((uint64_t(colD + rightC) << 16) | uint64_t(row)); #endif - return unexpectedEOF("CHIP_DATA_LONG:Pattern"); // abandon cable data - } - if (hitsPattern & (~MaskHitMap)) { + return unexpectedEOF("DECREASING_ROW"); // abandon cable data + } + if (skip) { + if ((dataS & (~MaskDColID)) == DATALONG) { // skip pattern w/o decoding + uint8_t hitsPattern = 0; + if (!buffer.next(hitsPattern)) { #ifdef ALPIDE_DECODING_STAT - chipData.setError(ChipStat::WrongDataLongPattern); + chipData.setError(ChipStat::TruncatedLondData); #endif - return unexpectedEOF("CHIP_DATA_LONG:Pattern"); // abandon cable data + return unexpectedEOF("CHIP_DATA_LONG:Pattern"); // abandon cable data + } + if (hitsPattern & (~MaskHitMap)) { +#ifdef ALPIDE_DECODING_STAT + chipData.setError(ChipStat::WrongDataLongPattern); +#endif + return unexpectedEOF("CHIP_DATA_LONG:Pattern"); // abandon cable data + } + LOGP(debug, "hitsPattern: {:#b} expect {:#b}", int(hitsPattern), int(expectInp)); } - LOGP(debug, "hitsPattern: {:#b} expect {:#b}", int(hitsPattern), int(expectInp)); + expectInp = ExpectChipTrailer | ExpectData | ExpectRegion; + continue; // end of DATA(SHORT or LONG) processing } - expectInp = ExpectChipTrailer | ExpectData | ExpectRegion; - continue; // end of DATA(SHORT or LONG) processing - } else if (colD != colDPrev) { + } else { // if we start new double column, transfer the hits accumulated in the right column buffer of prev. double column if (colD < colDPrev && colDPrev != 0xffff) { #ifdef ALPIDE_DECODING_STAT @@ -321,7 +332,7 @@ class AlpideCoder // are first collected in the temporary buffer // real columnt id is col = colD + 1; if (rightC) { - rightColHits[nRightCHits++] = row; // col = colD+1 + rightColHits[nRightCHits++] = row; } else { addHit(chipData, row, colD); // col = colD, left column hits are added directly to the container } @@ -355,7 +366,7 @@ class AlpideCoder if (rightC) { // same as above rightColHits[nRightCHits++] = rowE; } else { - addHit(chipData, rowE, colD + rightC); // left column hits are added directly to the container + addHit(chipData, rowE, colD); // left column hits are added directly to the container } } } diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h index 705e814fb4904..9a57228ddce1e 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h @@ -68,6 +68,7 @@ struct ChipStat { FlushedIncomplete, // ALPIDE MEB was flushed by the busy handling StrobeExtended, // ALPIDE received a second trigger while the strobe was still open WrongAlpideChipID, // Impossible for given cable ALPIDE ChipOnModule ID + DecreasingRow, // Decreasing row in the same column NErrorsDefined }; @@ -106,6 +107,7 @@ struct ChipStat { "FlushedIncomplete", // ALPIDE MEB was flushed by the busy handling "StrobeExtended", // ALPIDE received a second trigger while the strobe was still open "Wrong Alpide ChipID", // Impossible for given cable ALPIDE ChipOnModule ID + "Decreasing row", // Decreasing row in the same column }; static constexpr std::array ErrActions = { @@ -143,6 +145,7 @@ struct ChipStat { ErrActPropagate | ErrActDump, // ALPIDE MEB was flushed by the busy handling ErrActPropagate | ErrActDump, // ALPIDE received a second trigger while the strobe was still open ErrActPropagate | ErrActDump, // Impossible for given cable ALPIDE ChipOnModule ID + ErrActPropagate | ErrActDump, // Decreasing row in the same column }; uint16_t feeID = -1; size_t nHits = 0; From 07a2041a974e7ba3de44e99d6a50af2aaf3379a8 Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Wed, 20 Nov 2024 14:05:08 +0100 Subject: [PATCH 0499/2205] Add the TPC pid clusters to the analysis data model (#13617) --- .../AODProducerWorkflowSpec.h | 1 + Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 3 ++ .../include/Framework/AnalysisDataModel.h | 34 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index a85c7f74fa354..94f4526fe30a1 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -374,6 +374,7 @@ class AODProducerWorkflowDPL : public Task uint8_t itsClusterMap = 0; uint8_t tpcNClsFindable = 0; int8_t tpcNClsFindableMinusFound = 0; + int8_t tpcNClsFindableMinusPID = 0; int8_t tpcNClsFindableMinusCrossedRows = 0; uint8_t tpcNClsShared = 0; uint8_t trdPattern = 0; diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 8bcd590bb0e5c..6c3a418612478 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -334,6 +334,7 @@ void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracks extraInfoHolder.itsClusterSizes, extraInfoHolder.tpcNClsFindable, extraInfoHolder.tpcNClsFindableMinusFound, + // extraInfoHolder.tpcNClsFindableMinusPID, extraInfoHolder.tpcNClsFindableMinusCrossedRows, extraInfoHolder.tpcNClsShared, extraInfoHolder.trdPattern, @@ -2495,6 +2496,8 @@ AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrac extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found; extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed; extraInfoHolder.tpcNClsShared = tpcClData.shared; + uint32_t clsUsedForPID = tpcOrig.getdEdx().NHitsIROC + tpcOrig.getdEdx().NHitsOROC1 + tpcOrig.getdEdx().NHitsOROC2 + tpcOrig.getdEdx().NHitsOROC3; + extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID; if (src == GIndex::TPC) { // standalone TPC track should set its time from their timebins range if (needBCSlice) { double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS; // central value diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index b19552a14672d..c90e46bf6da06 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -243,6 +243,7 @@ DECLARE_SOA_COLUMN(ITSClusterSizes, itsClusterSizes, uint32_t); DECLARE_SOA_COLUMN(ITSClusterMap, itsClusterMap, uint8_t); //! Old cluster ITS cluster map, kept for version 0 compatibility DECLARE_SOA_COLUMN(TPCNClsFindable, tpcNClsFindable, uint8_t); //! Findable TPC clusters for this track geometry DECLARE_SOA_COLUMN(TPCNClsFindableMinusFound, tpcNClsFindableMinusFound, int8_t); //! TPC Clusters: Findable - Found +DECLARE_SOA_COLUMN(TPCNClsFindableMinusPID, tpcNClsFindableMinusPID, int8_t); //! TPC Clusters: Findable - Found clusters used for PID DECLARE_SOA_COLUMN(TPCNClsFindableMinusCrossedRows, tpcNClsFindableMinusCrossedRows, int8_t); //! TPC Clusters: Findable - crossed rows DECLARE_SOA_COLUMN(TPCNClsShared, tpcNClsShared, uint8_t); //! Number of shared TPC clusters DECLARE_SOA_COLUMN(TRDPattern, trdPattern, uint8_t); //! Contributor to the track on TRD layer in bits 0-5, starting from the innermost, bit 6 indicates a potentially split tracklet, bit 7 if the track crossed a padrow @@ -410,6 +411,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(PIDForTracking, pidForTracking, //! PID hypothesis us [](uint32_t flags) -> uint32_t { return flags >> 28; }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNClsFound, tpcNClsFound, //! Number of found TPC clusters [](uint8_t tpcNClsFindable, int8_t tpcNClsFindableMinusFound) -> int16_t { return (int16_t)tpcNClsFindable - tpcNClsFindableMinusFound; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNClsPID, tpcNClsPID, //! Number of found TPC clusters used for PID + [](uint8_t tpcNClsFindable, int8_t tpcNClsFindableMinusPID) -> int16_t { return (int16_t)tpcNClsFindable - tpcNClsFindableMinusPID; }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, //! Number of crossed TPC Rows [](uint8_t tpcNClsFindable, int8_t TPCNClsFindableMinusCrossedRows) -> int16_t { return (int16_t)tpcNClsFindable - TPCNClsFindableMinusCrossedRows; }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNCls, itsNCls, //! Number of ITS clusters @@ -600,10 +603,41 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "T track::TPCFractionSharedCls, track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); +DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_002, "TracksExtra", "AOD", "TRACKEXTRA", 2, // On disk version of TracksExtra, version 2 + track::TPCInnerParam, track::Flags, track::ITSClusterSizes, + track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusPID, track::TPCNClsFindableMinusCrossedRows, + track::TPCNClsShared, track::v001::extensions::TPCDeltaTFwd, track::v001::extensions::TPCDeltaTBwd, + track::TRDPattern, track::ITSChi2NCl, track::TPCChi2NCl, track::TRDChi2, track::TOFChi2, + track::TPCSignal, track::TRDSignal, track::Length, track::TOFExpMom, + track::PIDForTracking, + track::IsPVContributor, + track::HasITS, track::HasTPC, + track::HasTRD, track::HasTOF, + track::TPCNClsFound, + track::TPCNClsCrossedRows, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + track::v001::ITSClsSizeInLayer, + track::v001::IsITSAfterburner, + track::TOFExpTimeEl, + track::TOFExpTimeMu, + track::TOFExpTimePi, + track::TOFExpTimeKa, + track::TOFExpTimePr, + track::TOFExpTimeDe, + track::TOFExpTimeTr, + track::TOFExpTimeHe, + track::TOFExpTimeAl, + track::TPCCrossedRowsOverFindableCls, + track::TPCFoundOverFindableCls, + track::TPCFractionSharedCls, + track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); + DECLARE_SOA_EXTENDED_TABLE(TracksExtra_000, StoredTracksExtra_000, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) track::DetectorMap); DECLARE_SOA_EXTENDED_TABLE(TracksExtra_001, StoredTracksExtra_001, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) track::v001::DetectorMap); +DECLARE_SOA_EXTENDED_TABLE(TracksExtra_002, StoredTracksExtra_002, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) + track::v001::DetectorMap); DECLARE_SOA_TABLE(Run2TrackExtras, "AOD", "RUN2TRACKEXTRA", track::ITSSignal); From c3ffb66878b29d24082a75dacbd75d65b287604c Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:47:13 +0100 Subject: [PATCH 0500/2205] DPL: write support for TTree using arrow::Dataset API (#13718) --- .../include/Framework/RootArrowFilesystem.h | 32 ++ Framework/Core/src/RootArrowFilesystem.cxx | 302 +++++++++++++++++- Framework/Core/src/TableTreeHelpers.cxx | 2 +- Framework/Core/test/test_Root2ArrowTable.cxx | 108 +++++++ 4 files changed, 441 insertions(+), 3 deletions(-) diff --git a/Framework/Core/include/Framework/RootArrowFilesystem.h b/Framework/Core/include/Framework/RootArrowFilesystem.h index df00ce4fa8a76..7c8385ccd2b9d 100644 --- a/Framework/Core/include/Framework/RootArrowFilesystem.h +++ b/Framework/Core/include/Framework/RootArrowFilesystem.h @@ -87,6 +87,11 @@ class TTreeFileSystem : public VirtualRootFileSystemBase { return std::dynamic_pointer_cast(shared_from_this()); }; + + arrow::Result> OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) override; + virtual TTree* GetTree(arrow::dataset::FileSource source) = 0; }; @@ -128,6 +133,10 @@ class TFileFileSystem : public VirtualRootFileSystemBase std::shared_ptr GetSubFilesystem(arrow::dataset::FileSource source) override; + arrow::Result> OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) override; + // We can go back to the TFile in case this is needed. TDirectoryFile* GetFile() { @@ -218,6 +227,29 @@ class TTreeFileFormat : public arrow::dataset::FileFormat const std::shared_ptr& fragment) const override; }; +// An arrow outputstream which allows to write to a ttree +class TTreeOutputStream : public arrow::io::OutputStream +{ + public: + TTreeOutputStream(TTree* t); + + arrow::Status Close() override; + + arrow::Result Tell() const override; + + arrow::Status Write(const void* data, int64_t nbytes) override; + + bool closed() const override; + + TTree* GetTree() + { + return mTree; + } + + private: + TTree* mTree; +}; + } // namespace o2::framework #endif // O2_FRAMEWORK_ROOT_ARROW_FILESYSTEM_H_ diff --git a/Framework/Core/src/RootArrowFilesystem.cxx b/Framework/Core/src/RootArrowFilesystem.cxx index 46489141c3173..7581ee57e5b9f 100644 --- a/Framework/Core/src/RootArrowFilesystem.cxx +++ b/Framework/Core/src/RootArrowFilesystem.cxx @@ -11,6 +11,7 @@ #include "Framework/RootArrowFilesystem.h" #include "Framework/Endian.h" #include "Framework/RuntimeError.h" +#include "Framework/Signpost.h" #include #include #include @@ -24,6 +25,13 @@ #include #include #include +#include +#include +#include +#include + + +O2_DECLARE_DYNAMIC_LOG(root_arrow_fs); namespace { @@ -76,6 +84,7 @@ auto arrowTypeFromROOT(EDataType type, int size) } namespace o2::framework { +using arrow::Status; TFileFileSystem::TFileFileSystem(TDirectoryFile* f, size_t readahead) : VirtualRootFileSystemBase(), @@ -116,6 +125,15 @@ arrow::Result TFileFileSystem::GetFileInfo(const std::strin return result; } +arrow::Result> TFileFileSystem::OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) +{ + auto* t = new TTree(path.c_str(), "should put a name here"); + auto stream = std::make_shared(t); + return stream; +} + arrow::Result VirtualRootFileSystemBase::GetFileInfo(std::string const&) { arrow::fs::FileInfo result; @@ -267,9 +285,279 @@ arrow::Result> TTreeFileFormat::Ma return std::dynamic_pointer_cast(fragment); } +// An arrow outputstream which allows to write to a ttree +TTreeOutputStream::TTreeOutputStream(TTree* t) + : mTree(t) +{ +} + +arrow::Status TTreeOutputStream::Close() +{ + mTree->GetCurrentFile()->Close(); + return arrow::Status::OK(); +} + +arrow::Result TTreeOutputStream::Tell() const +{ + return arrow::Result(arrow::Status::NotImplemented("Cannot move")); +} + +arrow::Status TTreeOutputStream::Write(const void* data, int64_t nbytes) +{ + return arrow::Status::NotImplemented("Cannot write raw bytes to a TTree"); +} + +bool TTreeOutputStream::closed() const +{ + return mTree->GetCurrentFile()->IsOpen() == false; +} + +char const* rootSuffixFromArrow(arrow::Type::type id) +{ + switch (id) { + case arrow::Type::BOOL: + return "/O"; + case arrow::Type::UINT8: + return "/b"; + case arrow::Type::UINT16: + return "/s"; + case arrow::Type::UINT32: + return "/i"; + case arrow::Type::UINT64: + return "/l"; + case arrow::Type::INT8: + return "/B"; + case arrow::Type::INT16: + return "/S"; + case arrow::Type::INT32: + return "/I"; + case arrow::Type::INT64: + return "/L"; + case arrow::Type::FLOAT: + return "/F"; + case arrow::Type::DOUBLE: + return "/D"; + default: + throw runtime_error("Unsupported arrow column type"); + } +} + +class TTreeFileWriter : public arrow::dataset::FileWriter +{ + std::vector branches; + std::vector sizesBranches; + std::vector> valueArrays; + std::vector> sizeArrays; + std::vector> valueTypes; + + std::vector valuesIdealBasketSize; + std::vector sizeIdealBasketSize; + + std::vector typeSizes; + std::vector listSizes; + bool firstBasket = true; + + // This is to create a batsket size according to the first batch. + void finaliseBasketSize(std::shared_ptr firstBatch) + { + O2_SIGNPOST_ID_FROM_POINTER(sid, root_arrow_fs, this); + O2_SIGNPOST_START(root_arrow_fs, sid, "finaliseBasketSize", "First batch with %lli rows received and %zu columns", + firstBatch->num_rows(), firstBatch->columns().size()); + for (size_t i = 0; i < branches.size(); i++) { + auto* branch = branches[i]; + auto* sizeBranch = sizesBranches[i]; + + int valueSize = valueTypes[i]->byte_width(); + if (listSizes[i] == 1) { + O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s exists and uses %d bytes per entry for %lli entries.", + branch->GetName(), valueSize, firstBatch->num_rows()); + assert(sizeBranch == nullptr); + branch->SetBasketSize(1024 + firstBatch->num_rows() * valueSize); + } else if (listSizes[i] == -1) { + O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s exists and uses %d bytes per entry.", + branch->GetName(), valueSize); + // This should probably lookup the + auto column = firstBatch->GetColumnByName(branch->GetName()); + auto list = std::static_pointer_cast(column); + O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s needed. Associated size branch %s and there are %lli entries of size %d in that list.", + branch->GetName(), sizeBranch->GetName(), list->length(), valueSize); + branch->SetBasketSize(1024 + firstBatch->num_rows() * valueSize * list->length()); + sizeBranch->SetBasketSize(1024 + firstBatch->num_rows() * 4); + } else { + O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s needed. There are %lli entries per array of size %d in that list.", + branch->GetName(), listSizes[i], valueSize); + assert(sizeBranch == nullptr); + branch->SetBasketSize(1024 + firstBatch->num_rows() * valueSize * listSizes[i]); + } + + auto field = firstBatch->schema()->field(i); + if (field->name().starts_with("fIndexArray")) { + // One int per array to keep track of the size + int idealBasketSize = 4 * firstBatch->num_rows() + 1024 + field->type()->byte_width() * firstBatch->num_rows(); // minimal additional size needed, otherwise we get 2 baskets + int basketSize = std::max(32000, idealBasketSize); // keep a minimum value + sizeBranch->SetBasketSize(basketSize); + branch->SetBasketSize(basketSize); + } + } + O2_SIGNPOST_END(root_arrow_fs, sid, "finaliseBasketSize", "Done"); + } + + public: + // Create the TTree based on the physical_schema, not the one in the batch. + // The write method will have to reconcile the two schemas. + TTreeFileWriter(std::shared_ptr schema, std::shared_ptr options, + std::shared_ptr destination, + arrow::fs::FileLocator destination_locator) + : FileWriter(schema, options, destination, destination_locator) + { + // Batches have the same number of entries for each column. + auto treeStream = std::dynamic_pointer_cast(destination_); + TTree* tree = treeStream->GetTree(); + + for (auto i = 0u; i < schema->fields().size(); ++i) { + auto& field = schema->field(i); + listSizes.push_back(1); + + int valuesIdealBasketSize = 0; + // Construct all the needed branches. + switch (field->type()->id()) { + case arrow::Type::FIXED_SIZE_LIST: { + listSizes.back() = std::static_pointer_cast(field->type())->list_size(); + valuesIdealBasketSize = 1024 + valueTypes.back()->byte_width() * listSizes.back(); + valueTypes.push_back(field->type()->field(0)->type()); + sizesBranches.push_back(nullptr); + std::string leafList = fmt::format("{}[{}]{}", field->name(), listSizes.back(), rootSuffixFromArrow(valueTypes.back()->id())); + branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + } break; + case arrow::Type::LIST: { + valueTypes.push_back(field->type()->field(0)->type()); + listSizes.back() = 0; // VLA, we need to calculate it on the fly; + std::string leafList = fmt::format("{}[{}_size]{}", field->name(), field->name(), rootSuffixFromArrow(valueTypes.back()->id())); + std::string sizeLeafList = field->name() + "_size/I"; + sizesBranches.push_back(tree->Branch((field->name() + "_size").c_str(), (char*)nullptr, sizeLeafList.c_str())); + branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + // Notice that this could be replaced by a better guess of the + // average size of the list elements, but this is not trivial. + } break; + default: { + valueTypes.push_back(field->type()); + std::string leafList = field->name() + rootSuffixFromArrow(valueTypes.back()->id()); + sizesBranches.push_back(nullptr); + branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + } break; + } + } + // We create the branches from the schema + } + + arrow::Status Write(const std::shared_ptr& batch) override + { + if (firstBasket) { + firstBasket = false; + finaliseBasketSize(batch); + } + + // Support writing empty tables + if (batch->columns().empty() || batch->num_rows() == 0) { + return arrow::Status::OK(); + } + + // Batches have the same number of entries for each column. + auto treeStream = std::dynamic_pointer_cast(destination_); + TTree* tree = treeStream->GetTree(); + + // Caches for the vectors of bools. + std::vector> caches; + + for (auto i = 0u; i < batch->columns().size(); ++i) { + auto column = batch->column(i); + auto& field = batch->schema()->field(i); + + valueArrays.push_back(nullptr); + + switch (field->type()->id()) { + case arrow::Type::FIXED_SIZE_LIST: { + auto list = std::static_pointer_cast(column); + valueArrays.back() = list->values(); + } break; + case arrow::Type::LIST: { + auto list = std::static_pointer_cast(column); + valueArrays.back() = list; + } break; + default: + valueArrays.back() = column; + } + } + + int64_t pos = 0; + while (pos < batch->num_rows()) { + for (size_t bi = 0; bi < branches.size(); ++bi) { + auto* branch = branches[bi]; + auto* sizeBranch = sizesBranches[bi]; + auto array = batch->column(bi); + auto& field = batch->schema()->field(bi); + auto& listSize = listSizes[bi]; + auto valueType = valueTypes[bi]; + auto valueArray = valueArrays[bi]; + + if (field->type()->id() == arrow::Type::BOOL) { + auto boolArray = std::static_pointer_cast(array); + int64_t length = boolArray->length(); + arrow::UInt8Builder builder; + auto ok = builder.Reserve(length); + + for (int64_t i = 0; i < length; ++i) { + if (boolArray->IsValid(i)) { + // Expand each boolean value (true/false) to uint8 (1/0) + uint8_t value = boolArray->Value(i) ? 1 : 0; + auto ok = builder.Append(value); + } else { + // Append null for invalid entries + auto ok = builder.AppendNull(); + } + } + + ok = builder.Finish(&caches[bi]); + branch->SetAddress((void*)(caches[bi]->values()->data())); + continue; + } + switch (field->type()->id()) { + case arrow::Type::LIST: { + auto list = std::static_pointer_cast(array); + listSize = list->value_length(pos); + uint8_t const* buffer = std::static_pointer_cast(valueArray)->values()->data() + array->offset() + list->value_offset(pos) * valueType->byte_width(); + branch->SetAddress((void*)buffer); + sizeBranch->SetAddress(&listSize); + }; + break; + case arrow::Type::FIXED_SIZE_LIST: + default: { + uint8_t const* buffer = std::static_pointer_cast(valueArray)->values()->data() + array->offset() + pos * listSize * valueType->byte_width(); + branch->SetAddress((void*)buffer); + }; + } + } + tree->Fill(); + ++pos; + } + return arrow::Status::OK(); + } + + arrow::Future<> FinishInternal() override + { + auto treeStream = std::dynamic_pointer_cast(destination_); + TTree* tree = treeStream->GetTree(); + tree->Write("", TObject::kOverwrite); + tree->SetDirectory(nullptr); + + return {}; + }; +}; + arrow::Result> TTreeFileFormat::MakeWriter(std::shared_ptr destination, std::shared_ptr schema, std::shared_ptr options, arrow::fs::FileLocator destination_locator) const { - throw std::runtime_error("Unsupported operation"); + auto writer = std::make_shared(schema, options, destination, destination_locator); + return std::dynamic_pointer_cast(writer); } std::shared_ptr TTreeFileFormat::DefaultWriteOptions() @@ -401,8 +689,10 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( int64_t listSize = 1; if (auto fixedSizeList = std::dynamic_pointer_cast(physicalField->type())) { listSize = fixedSizeList->list_size(); + typeSize = fixedSizeList->field(0)->type()->byte_width(); } else if (auto vlaListType = std::dynamic_pointer_cast(physicalField->type())) { listSize = -1; + typeSize = fixedSizeList->field(0)->type()->byte_width(); } if (listSize == -1) { mSizeBranch = branch->GetTree()->GetBranch((std::string{branch->GetName()} + "_size").c_str()); @@ -474,6 +764,15 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( return generator; } + +arrow::Result> TTreeFileSystem::OpenOutputStream( + const std::string& path, + const std::shared_ptr& metadata) +{ + auto stream = std::make_shared(GetTree({path, shared_from_this()})); + return stream; +} + TBufferFileFS::TBufferFileFS(TBufferFile* f) : VirtualRootFileSystemBase(), mBuffer(f), @@ -512,5 +811,4 @@ std::shared_ptr TBufferFileFS::GetSubFilesystem(arrow } return mFilesystem; } - } // namespace o2::framework diff --git a/Framework/Core/src/TableTreeHelpers.cxx b/Framework/Core/src/TableTreeHelpers.cxx index c20febaac517d..d0fdd0ced5779 100644 --- a/Framework/Core/src/TableTreeHelpers.cxx +++ b/Framework/Core/src/TableTreeHelpers.cxx @@ -512,7 +512,7 @@ void TreeToTable::addAllColumns(TTree* tree, std::vector&& names) if (strncmp(reader->branch()->GetName(), "fIndexArray", strlen("fIndexArray")) == 0) { std::string sizeBranchName = reader->branch()->GetName(); sizeBranchName += "_size"; - TBranch* sizeBranch = (TBranch*)tree->GetBranch(sizeBranchName.c_str()); + auto* sizeBranch = (TBranch*)tree->GetBranch(sizeBranchName.c_str()); if (sizeBranch) { tree->AddBranchToCache(sizeBranch); } diff --git a/Framework/Core/test/test_Root2ArrowTable.cxx b/Framework/Core/test/test_Root2ArrowTable.cxx index 599f1062c63a0..03f0977a4c0c4 100644 --- a/Framework/Core/test/test_Root2ArrowTable.cxx +++ b/Framework/Core/test/test_Root2ArrowTable.cxx @@ -358,4 +358,112 @@ TEST_CASE("RootTree2Dataset") REQUIRE(result.ok()); REQUIRE((*result)->columns().size() == 7); REQUIRE((*result)->num_rows() == 100); + + { + auto int_array = std::static_pointer_cast((*result)->GetColumnByName("ev")); + for (int64_t j = 0; j < int_array->length(); j++) { + REQUIRE(int_array->Value(j) == j + 1); + } + } + + { + auto list_array = std::static_pointer_cast((*result)->GetColumnByName("xyz")); + + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto float_array = std::static_pointer_cast(value_slice); + + REQUIRE(float_array->Value(0) == 1); + REQUIRE(float_array->Value(1) == 2); + REQUIRE(float_array->Value(2) == i + 1); + } + } + + { + auto list_array = std::static_pointer_cast((*result)->GetColumnByName("ij")); + + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto int_array = std::static_pointer_cast(value_slice); + REQUIRE(int_array->Value(0) == i); + REQUIRE(int_array->Value(1) == i + 1); + } + } + + auto* output = new TMemFile("foo", "RECREATE"); + auto outFs = std::make_shared(output, 0); + arrow::fs::FileLocator locator{outFs, "/DF_3"}; + + auto destination = outFs->OpenOutputStream(locator.path, {}); + REQUIRE(destination.ok()); + + auto writer = format->MakeWriter(*destination, schema, {}, locator); + auto success = writer->get()->Write(*result); + auto rootDestination = std::dynamic_pointer_cast(*destination); + + REQUIRE(success.ok()); + // Let's read it back... + arrow::dataset::FileSource source2("/DF_3", outFs); + auto newTreeFS = outFs->GetSubFilesystem(source2); + + REQUIRE(format->IsSupported(source) == true); + + auto schemaOptWritten = format->Inspect(source); + REQUIRE(schemaOptWritten.ok()); + auto schemaWritten = *schemaOptWritten; + REQUIRE(schemaWritten->num_fields() == 7); + REQUIRE(schemaWritten->field(0)->type()->id() == arrow::float32()->id()); + REQUIRE(schemaWritten->field(1)->type()->id() == arrow::float32()->id()); + REQUIRE(schemaWritten->field(2)->type()->id() == arrow::float32()->id()); + REQUIRE(schemaWritten->field(3)->type()->id() == arrow::float64()->id()); + REQUIRE(schemaWritten->field(4)->type()->id() == arrow::int32()->id()); + REQUIRE(schemaWritten->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); + REQUIRE(schemaWritten->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + + auto fragmentWritten = format->MakeFragment(source, {}, schema); + REQUIRE(fragmentWritten.ok()); + auto optionsWritten = std::make_shared(); + options->dataset_schema = schemaWritten; + auto scannerWritten = format->ScanBatchesAsync(optionsWritten, *fragment); + REQUIRE(scannerWritten.ok()); + auto batchesWritten = (*scanner)(); + auto resultWritten = batches.result(); + REQUIRE(resultWritten.ok()); + REQUIRE((*resultWritten)->columns().size() == 7); + REQUIRE((*resultWritten)->num_rows() == 100); + + { + auto int_array = std::static_pointer_cast((*resultWritten)->GetColumnByName("ev")); + for (int64_t j = 0; j < int_array->length(); j++) { + REQUIRE(int_array->Value(j) == j + 1); + } + } + + { + auto list_array = std::static_pointer_cast((*result)->GetColumnByName("xyz")); + + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto float_array = std::static_pointer_cast(value_slice); + + REQUIRE(float_array->Value(0) == 1); + REQUIRE(float_array->Value(1) == 2); + REQUIRE(float_array->Value(2) == i + 1); + } + } + + { + auto list_array = std::static_pointer_cast((*result)->GetColumnByName("ij")); + + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto int_array = std::static_pointer_cast(value_slice); + REQUIRE(int_array->Value(0) == i); + REQUIRE(int_array->Value(1) == i + 1); + } + } } From 929bb79415f510ec2faaebc83df0df459d62507d Mon Sep 17 00:00:00 2001 From: swenzel Date: Thu, 21 Nov 2024 16:24:50 +0100 Subject: [PATCH 0501/2205] Fix GeneratorPythia8 construction Fixes smaller issues introduced with the hybrid generator refactoring: - Make sure that internal configuration object is never null; In fact, it does not need to be a pointer. - Make sure the internal configuration struct is initialized from the GeneratorPythia8Param configurable when using the default constructor. This commit fixes an issue/segfault when running the following command o2-sim-dpl-eventgen --generator external --nEvents 200 --aggregate-timeframe 10000 --configFile ${O2DPG_ROOT}/MC/config/ALICE3/ini/pythia8_pp_136tev.ini -b (which defaults constructs a Pythia8 generator) --- .../include/Generators/GeneratorPythia8.h | 4 +- Generators/src/GeneratorPythia8.cxx | 37 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Generators/include/Generators/GeneratorPythia8.h b/Generators/include/Generators/GeneratorPythia8.h index b5abbb2600545..926003c55259b 100644 --- a/Generators/include/Generators/GeneratorPythia8.h +++ b/Generators/include/Generators/GeneratorPythia8.h @@ -90,7 +90,7 @@ class GeneratorPythia8 : public Generator /** default constructor **/ GeneratorPythia8(); /** constructor **/ - GeneratorPythia8(Pythia8GenConfig const& pars); + GeneratorPythia8(Pythia8GenConfig const&); /** constructor **/ GeneratorPythia8(const Char_t* name, const Char_t* title = "ALICEo2 Pythia8 Generator"); /** destructor **/ @@ -285,7 +285,7 @@ class GeneratorPythia8 : public Generator long mInitialRNGSeed = -1; // initial seed for Pythia random number state; // will be transported to Pythia in the Init function through the Pythia::readString("Random:seed") mechanism. // Value of -1 means unitialized; 0 will be time-dependent and values >1 <= MAX_SEED concrete reproducible seeding - std::unique_ptr mGenConfig; // configuration object + Pythia8GenConfig mGenConfig; // configuration object constexpr static long MAX_SEED = 900000000; diff --git a/Generators/src/GeneratorPythia8.cxx b/Generators/src/GeneratorPythia8.cxx index a27980a77c992..8c9b4fcffdff2 100644 --- a/Generators/src/GeneratorPythia8.cxx +++ b/Generators/src/GeneratorPythia8.cxx @@ -53,17 +53,23 @@ GeneratorPythia8::GeneratorPythia8() : Generator("ALICEo2", "ALICEo2 Pythia8 Gen mInterfaceName = "pythia8"; auto& param = GeneratorPythia8Param::Instance(); - LOG(info) << "Instance \'Pythia8\' generator with following parameters"; + LOG(info) << "Default Instance \'Pythia8\' generator with following parameters"; LOG(info) << param; - setConfig(param.config); - setHooksFileName(param.hooksFileName); - setHooksFuncName(param.hooksFuncName); + // convert the outside singleton config to the internally used one + o2::eventgen::Pythia8GenConfig config{param.config, + param.hooksFileName, param.hooksFuncName, param.includePartonEvent, param.particleFilter, param.verbose}; + mGenConfig = config; + + setConfig(config.config); + setHooksFileName(config.hooksFileName); + setHooksFuncName(config.hooksFuncName); + // TODO: use constructor delegation to other interface } /*****************************************************************/ -GeneratorPythia8::GeneratorPythia8(Pythia8GenConfig const& pars) : Generator("ALICEo2", "ALICEo2 Pythia8 Generator") +GeneratorPythia8::GeneratorPythia8(Pythia8GenConfig const& config) : Generator("ALICEo2", "ALICEo2 Pythia8 Generator") { /** constructor **/ @@ -71,15 +77,15 @@ GeneratorPythia8::GeneratorPythia8(Pythia8GenConfig const& pars) : Generator("AL mInterfaceName = "pythia8"; LOG(info) << "Instance \'Pythia8\' generator with following parameters"; - LOG(info) << "config: " << pars.config; - LOG(info) << "hooksFileName: " << pars.hooksFileName; - LOG(info) << "hooksFuncName: " << pars.hooksFuncName; + LOG(info) << "config: " << config.config; + LOG(info) << "hooksFileName: " << config.hooksFileName; + LOG(info) << "hooksFuncName: " << config.hooksFuncName; - mGenConfig = std::make_unique(pars); + mGenConfig = config; - setConfig(pars.config); - setHooksFileName(pars.hooksFileName); - setHooksFuncName(pars.hooksFuncName); + setConfig(mGenConfig.config); + setHooksFileName(mGenConfig.hooksFileName); + setHooksFuncName(mGenConfig.hooksFuncName); } /*****************************************************************/ @@ -578,8 +584,7 @@ void GeneratorPythia8::pruneEvent(Pythia8::Event& event, Select select) } } } - int verbose = mGenConfig->verbose; - if (verbose) { + if (mGenConfig.verbose) { LOG(info) << "Pythia event was pruned from " << event.size() << " to " << pruned.size() << " particles"; } @@ -592,7 +597,7 @@ void GeneratorPythia8::initUserFilterCallback() { mUserFilterFcn = [](Pythia8::Particle const&) -> bool { return true; }; - std::string filter = mGenConfig->particleFilter; + std::string filter = mGenConfig.particleFilter; if (filter.size() > 0) { LOG(info) << "Initializing the callback for user-based particle pruning " << filter; auto expandedFileName = o2::utils::expandShellVarsInFileName(filter); @@ -621,7 +626,7 @@ Bool_t // event record in the AOD. std::function partonSelect = [](const Pythia8::Particle&) { return true; }; - bool includeParton = mGenConfig->includePartonEvent; + bool includeParton = mGenConfig.includePartonEvent; if (not includeParton) { // Select pythia particles From 7f54d8fcd98d3bf73b4d325477b8701c4fe6b99e Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 22 Nov 2024 07:44:05 +0100 Subject: [PATCH 0502/2205] Fix for failing dataflow build (#13721) --- Generators/CMakeLists.txt | 11 +++++++---- Generators/src/GeneratorFactory.cxx | 8 ++++++-- Generators/src/GeneratorsLinkDef.h | 6 ++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Generators/CMakeLists.txt b/Generators/CMakeLists.txt index 3b32d076aec1a..d60d185817c84 100644 --- a/Generators/CMakeLists.txt +++ b/Generators/CMakeLists.txt @@ -24,8 +24,6 @@ o2_add_library(Generators src/GeneratorTGenerator.cxx src/GeneratorExternalParam.cxx src/GeneratorFromFile.cxx - src/GeneratorHybrid.cxx - src/GeneratorHybridParam.cxx src/GeneratorFromO2KineParam.cxx src/GeneratorFileOrCmd.cxx src/GeneratorFileOrCmdParam.cxx @@ -50,6 +48,8 @@ o2_add_library(Generators $<$:src/GeneratorHepMC.cxx> $<$:src/GeneratorHepMCParam.cxx> $<$:src/AODToHepMC.cxx> + $<$,$>:src/GeneratorHybrid.cxx> + $<$,$>:src/GeneratorHybridParam.cxx> PUBLIC_LINK_LIBRARIES FairRoot::Base O2::SimConfig O2::CommonUtils O2::DetectorsBase O2::ZDCBase O2::SimulationDataFormat ${pythiaTarget} ${hepmcTarget} FairRoot::Gen @@ -70,8 +70,6 @@ set(headers include/Generators/GeneratorTGenerator.h include/Generators/GeneratorExternalParam.h include/Generators/GeneratorFromFile.h - include/Generators/GeneratorHybrid.h - include/Generators/GeneratorHybridParam.h include/Generators/GeneratorFromO2KineParam.h include/Generators/GeneratorFileOrCmd.h include/Generators/GeneratorFileOrCmdParam.h @@ -104,6 +102,11 @@ if(HepMC3_FOUND) list(APPEND headers include/Generators/GeneratorHepMCParam.h) endif() +if(pythia_FOUND AND HepMC3_FOUND) + list(APPEND headers include/Generators/GeneratorHybrid.h) + list(APPEND headers include/Generators/GeneratorHybridParam.h) +endif() + o2_target_root_dictionary(Generators HEADERS ${headers}) o2_add_test_root_macro(share/external/extgen.C diff --git a/Generators/src/GeneratorFactory.cxx b/Generators/src/GeneratorFactory.cxx index 92be3773b54ee..8233024a4c2d7 100644 --- a/Generators/src/GeneratorFactory.cxx +++ b/Generators/src/GeneratorFactory.cxx @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #ifdef GENERATORS_WITH_PYTHIA8 @@ -27,12 +26,15 @@ #endif #include #include -#include #include "Generators/GeneratorFromO2KineParam.h" #ifdef GENERATORS_WITH_HEPMC3 #include #include #endif +#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3) +#include +#include +#endif #include #include #include @@ -260,6 +262,7 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair primGen->AddGenerator(boxGen); } } +#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3) } else if (genconfig.compare("hybrid") == 0) { // hybrid using multiple generators LOG(info) << "Init hybrid generator"; auto& hybridparam = GeneratorHybridParam::Instance(); @@ -276,6 +279,7 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair } auto hybrid = new o2::eventgen::GeneratorHybrid(config); primGen->AddGenerator(hybrid); +#endif } else { LOG(fatal) << "Invalid generator"; } diff --git a/Generators/src/GeneratorsLinkDef.h b/Generators/src/GeneratorsLinkDef.h index 18428a808a86b..41e14b02f18b9 100644 --- a/Generators/src/GeneratorsLinkDef.h +++ b/Generators/src/GeneratorsLinkDef.h @@ -52,10 +52,12 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::DecayerPythia8Param> + ; #pragma link C++ class o2::eventgen::GeneratorFactory + ; #endif -#pragma link C++ class o2::eventgen::GeneratorFromFile + ; -#pragma link C++ class o2::eventgen::GeneratorFromO2Kine + ; +#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3) #pragma link C++ class o2::eventgen::GeneratorHybrid + ; #pragma link C++ class o2::eventgen::GeneratorHybridParam + ; +#endif +#pragma link C++ class o2::eventgen::GeneratorFromFile + ; +#pragma link C++ class o2::eventgen::GeneratorFromO2Kine + ; #pragma link C++ class o2::eventgen::GeneratorFromO2KineParam + ; #pragma link C++ class o2::eventgen::O2KineGenConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorFromO2KineParam> + ; From 00c02574bd1dc0f7e46bf4d74ab673b9dea9ac2d Mon Sep 17 00:00:00 2001 From: Christian Sonnabend Date: Fri, 22 Nov 2024 11:00:20 +0100 Subject: [PATCH 0503/2205] ORT library in the O2 framework (#13709) --- Common/CMakeLists.txt | 1 + Common/ML/CMakeLists.txt | 15 + Common/ML/include/ML/3rdparty/GPUORTFloat16.h | 867 ++++++++++++++++++ Common/ML/include/ML/ort_interface.h | 92 ++ Common/ML/src/ort_interface.cxx | 280 ++++++ 5 files changed, 1255 insertions(+) create mode 100644 Common/ML/CMakeLists.txt create mode 100644 Common/ML/include/ML/3rdparty/GPUORTFloat16.h create mode 100644 Common/ML/include/ML/ort_interface.h create mode 100644 Common/ML/src/ort_interface.cxx diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index f435e269575aa..0b92758e45f43 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -16,5 +16,6 @@ add_subdirectory(Types) add_subdirectory(Utils) add_subdirectory(SimConfig) add_subdirectory(DCAFitter) +add_subdirectory(ML) o2_data_file(COPY maps DESTINATION Common) diff --git a/Common/ML/CMakeLists.txt b/Common/ML/CMakeLists.txt new file mode 100644 index 0000000000000..74287e774efa1 --- /dev/null +++ b/Common/ML/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2_add_library(ML + SOURCES src/ort_interface.cxx + TARGETVARNAME targetName + PRIVATE_LINK_LIBRARIES O2::Framework ONNXRuntime::ONNXRuntime) diff --git a/Common/ML/include/ML/3rdparty/GPUORTFloat16.h b/Common/ML/include/ML/3rdparty/GPUORTFloat16.h new file mode 100644 index 0000000000000..db65328409d3c --- /dev/null +++ b/Common/ML/include/ML/3rdparty/GPUORTFloat16.h @@ -0,0 +1,867 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// This code was created from: +// - https://github.com/microsoft/onnxruntime/blob/main/include/onnxruntime/core/session/onnxruntime_float16.h +// - https://github.com/microsoft/onnxruntime/blob/main/include/onnxruntime/core/session/onnxruntime_cxx_api.h + +#include +#include +#include +#include + +namespace o2 +{ + +namespace OrtDataType +{ + +namespace detail +{ + +enum class endian { +#if defined(_WIN32) + little = 0, + big = 1, + native = little, +#elif defined(__GNUC__) || defined(__clang__) + little = __ORDER_LITTLE_ENDIAN__, + big = __ORDER_BIG_ENDIAN__, + native = __BYTE_ORDER__, +#else +#error OrtDataType::detail::endian is not implemented in this environment. +#endif +}; + +static_assert( + endian::native == endian::little || endian::native == endian::big, + "Only little-endian or big-endian native byte orders are supported."); + +} // namespace detail + +///

+/// Shared implementation between public and internal classes. CRTP pattern. +/// +template +struct Float16Impl { + protected: + /// + /// Converts from float to uint16_t float16 representation + /// + /// + /// + constexpr static uint16_t ToUint16Impl(float v) noexcept; + + /// + /// Converts float16 to float + /// + /// float representation of float16 value + float ToFloatImpl() const noexcept; + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + uint16_t AbsImpl() const noexcept + { + return static_cast(val & ~kSignMask); + } + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + uint16_t NegateImpl() const noexcept + { + return IsNaN() ? val : static_cast(val ^ kSignMask); + } + + public: + // uint16_t special values + static constexpr uint16_t kSignMask = 0x8000U; + static constexpr uint16_t kBiasedExponentMask = 0x7C00U; + static constexpr uint16_t kPositiveInfinityBits = 0x7C00U; + static constexpr uint16_t kNegativeInfinityBits = 0xFC00U; + static constexpr uint16_t kPositiveQNaNBits = 0x7E00U; + static constexpr uint16_t kNegativeQNaNBits = 0xFE00U; + static constexpr uint16_t kEpsilonBits = 0x4170U; + static constexpr uint16_t kMinValueBits = 0xFBFFU; // Minimum normal number + static constexpr uint16_t kMaxValueBits = 0x7BFFU; // Largest normal number + static constexpr uint16_t kOneBits = 0x3C00U; + static constexpr uint16_t kMinusOneBits = 0xBC00U; + + uint16_t val{0}; + + Float16Impl() = default; + + /// + /// Checks if the value is negative + /// + /// true if negative + bool IsNegative() const noexcept + { + return static_cast(val) < 0; + } + + /// + /// Tests if the value is NaN + /// + /// true if NaN + bool IsNaN() const noexcept + { + return AbsImpl() > kPositiveInfinityBits; + } + + /// + /// Tests if the value is finite + /// + /// true if finite + bool IsFinite() const noexcept + { + return AbsImpl() < kPositiveInfinityBits; + } + + /// + /// Tests if the value represents positive infinity. + /// + /// true if positive infinity + bool IsPositiveInfinity() const noexcept + { + return val == kPositiveInfinityBits; + } + + /// + /// Tests if the value represents negative infinity + /// + /// true if negative infinity + bool IsNegativeInfinity() const noexcept + { + return val == kNegativeInfinityBits; + } + + /// + /// Tests if the value is either positive or negative infinity. + /// + /// True if absolute value is infinity + bool IsInfinity() const noexcept + { + return AbsImpl() == kPositiveInfinityBits; + } + + /// + /// Tests if the value is NaN or zero. Useful for comparisons. + /// + /// True if NaN or zero. + bool IsNaNOrZero() const noexcept + { + auto abs = AbsImpl(); + return (abs == 0 || abs > kPositiveInfinityBits); + } + + /// + /// Tests if the value is normal (not zero, subnormal, infinite, or NaN). + /// + /// True if so + bool IsNormal() const noexcept + { + auto abs = AbsImpl(); + return (abs < kPositiveInfinityBits) // is finite + && (abs != 0) // is not zero + && ((abs & kBiasedExponentMask) != 0); // is not subnormal (has a non-zero exponent) + } + + /// + /// Tests if the value is subnormal (denormal). + /// + /// True if so + bool IsSubnormal() const noexcept + { + auto abs = AbsImpl(); + return (abs < kPositiveInfinityBits) // is finite + && (abs != 0) // is not zero + && ((abs & kBiasedExponentMask) == 0); // is subnormal (has a zero exponent) + } + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + Derived Abs() const noexcept { return Derived::FromBits(AbsImpl()); } + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + Derived Negate() const noexcept { return Derived::FromBits(NegateImpl()); } + + /// + /// IEEE defines that positive and negative zero are equal, this gives us a quick equality check + /// for two values by or'ing the private bits together and stripping the sign. They are both zero, + /// and therefore equivalent, if the resulting value is still zero. + /// + /// first value + /// second value + /// True if both arguments represent zero + static bool AreZero(const Float16Impl& lhs, const Float16Impl& rhs) noexcept + { + return static_cast((lhs.val | rhs.val) & ~kSignMask) == 0; + } + + bool operator==(const Float16Impl& rhs) const noexcept + { + if (IsNaN() || rhs.IsNaN()) { + // IEEE defines that NaN is not equal to anything, including itself. + return false; + } + return val == rhs.val; + } + + bool operator!=(const Float16Impl& rhs) const noexcept { return !(*this == rhs); } + + bool operator<(const Float16Impl& rhs) const noexcept + { + if (IsNaN() || rhs.IsNaN()) { + // IEEE defines that NaN is unordered with respect to everything, including itself. + return false; + } + + const bool left_is_negative = IsNegative(); + if (left_is_negative != rhs.IsNegative()) { + // When the signs of left and right differ, we know that left is less than right if it is + // the negative value. The exception to this is if both values are zero, in which case IEEE + // says they should be equal, even if the signs differ. + return left_is_negative && !AreZero(*this, rhs); + } + return (val != rhs.val) && ((val < rhs.val) ^ left_is_negative); + } +}; + +// The following Float16_t conversions are based on the code from +// Eigen library. + +// The conversion routines are Copyright (c) Fabian Giesen, 2016. +// The original license follows: +// +// Copyright (c) Fabian Giesen, 2016 +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +namespace detail +{ +union float32_bits { + unsigned int u; + float f; +}; +}; // namespace detail + +template +inline constexpr uint16_t Float16Impl::ToUint16Impl(float v) noexcept +{ + detail::float32_bits f{}; + f.f = v; + + constexpr detail::float32_bits f32infty = {255 << 23}; + constexpr detail::float32_bits f16max = {(127 + 16) << 23}; + constexpr detail::float32_bits denorm_magic = {((127 - 15) + (23 - 10) + 1) << 23}; + constexpr unsigned int sign_mask = 0x80000000u; + uint16_t val = static_cast(0x0u); + + unsigned int sign = f.u & sign_mask; + f.u ^= sign; + + // NOTE all the integer compares in this function can be safely + // compiled into signed compares since all operands are below + // 0x80000000. Important if you want fast straight SSE2 code + // (since there's no unsigned PCMPGTD). + + if (f.u >= f16max.u) { // result is Inf or NaN (all exponent bits set) + val = (f.u > f32infty.u) ? 0x7e00 : 0x7c00; // NaN->qNaN and Inf->Inf + } else { // (De)normalized number or zero + if (f.u < (113 << 23)) { // resulting FP16 is subnormal or zero + // use a magic value to align our 10 mantissa bits at the bottom of + // the float. as long as FP addition is round-to-nearest-even this + // just works. + f.f += denorm_magic.f; + + // and one integer subtract of the bias later, we have our final float! + val = static_cast(f.u - denorm_magic.u); + } else { + unsigned int mant_odd = (f.u >> 13) & 1; // resulting mantissa is odd + + // update exponent, rounding bias part 1 + // Equivalent to `f.u += ((unsigned int)(15 - 127) << 23) + 0xfff`, but + // without arithmetic overflow. + f.u += 0xc8000fffU; + // rounding bias part 2 + f.u += mant_odd; + // take the bits! + val = static_cast(f.u >> 13); + } + } + + val |= static_cast(sign >> 16); + return val; +} + +template +inline float Float16Impl::ToFloatImpl() const noexcept +{ + constexpr detail::float32_bits magic = {113 << 23}; + constexpr unsigned int shifted_exp = 0x7c00 << 13; // exponent mask after shift + detail::float32_bits o{}; + + o.u = (val & 0x7fff) << 13; // exponent/mantissa bits + unsigned int exp = shifted_exp & o.u; // just the exponent + o.u += (127 - 15) << 23; // exponent adjust + + // handle exponent special cases + if (exp == shifted_exp) { // Inf/NaN? + o.u += (128 - 16) << 23; // extra exp adjust + } else if (exp == 0) { // Zero/Denormal? + o.u += 1 << 23; // extra exp adjust + o.f -= magic.f; // re-normalize + } + + // Attempt to workaround the Internal Compiler Error on ARM64 + // for bitwise | operator, including std::bitset +#if (defined _MSC_VER) && (defined _M_ARM || defined _M_ARM64 || defined _M_ARM64EC) + if (IsNegative()) { + return -o.f; + } +#else + // original code: + o.u |= (val & 0x8000U) << 16U; // sign bit +#endif + return o.f; +} + +/// Shared implementation between public and internal classes. CRTP pattern. +template +struct BFloat16Impl { + protected: + /// + /// Converts from float to uint16_t float16 representation + /// + /// + /// + static uint16_t ToUint16Impl(float v) noexcept; + + /// + /// Converts bfloat16 to float + /// + /// float representation of bfloat16 value + float ToFloatImpl() const noexcept; + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + uint16_t AbsImpl() const noexcept + { + return static_cast(val & ~kSignMask); + } + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + uint16_t NegateImpl() const noexcept + { + return IsNaN() ? val : static_cast(val ^ kSignMask); + } + + public: + // uint16_t special values + static constexpr uint16_t kSignMask = 0x8000U; + static constexpr uint16_t kBiasedExponentMask = 0x7F80U; + static constexpr uint16_t kPositiveInfinityBits = 0x7F80U; + static constexpr uint16_t kNegativeInfinityBits = 0xFF80U; + static constexpr uint16_t kPositiveQNaNBits = 0x7FC1U; + static constexpr uint16_t kNegativeQNaNBits = 0xFFC1U; + static constexpr uint16_t kSignaling_NaNBits = 0x7F80U; + static constexpr uint16_t kEpsilonBits = 0x0080U; + static constexpr uint16_t kMinValueBits = 0xFF7FU; + static constexpr uint16_t kMaxValueBits = 0x7F7FU; + static constexpr uint16_t kRoundToNearest = 0x7FFFU; + static constexpr uint16_t kOneBits = 0x3F80U; + static constexpr uint16_t kMinusOneBits = 0xBF80U; + + uint16_t val{0}; + + BFloat16Impl() = default; + + /// + /// Checks if the value is negative + /// + /// true if negative + bool IsNegative() const noexcept + { + return static_cast(val) < 0; + } + + /// + /// Tests if the value is NaN + /// + /// true if NaN + bool IsNaN() const noexcept + { + return AbsImpl() > kPositiveInfinityBits; + } + + /// + /// Tests if the value is finite + /// + /// true if finite + bool IsFinite() const noexcept + { + return AbsImpl() < kPositiveInfinityBits; + } + + /// + /// Tests if the value represents positive infinity. + /// + /// true if positive infinity + bool IsPositiveInfinity() const noexcept + { + return val == kPositiveInfinityBits; + } + + /// + /// Tests if the value represents negative infinity + /// + /// true if negative infinity + bool IsNegativeInfinity() const noexcept + { + return val == kNegativeInfinityBits; + } + + /// + /// Tests if the value is either positive or negative infinity. + /// + /// True if absolute value is infinity + bool IsInfinity() const noexcept + { + return AbsImpl() == kPositiveInfinityBits; + } + + /// + /// Tests if the value is NaN or zero. Useful for comparisons. + /// + /// True if NaN or zero. + bool IsNaNOrZero() const noexcept + { + auto abs = AbsImpl(); + return (abs == 0 || abs > kPositiveInfinityBits); + } + + /// + /// Tests if the value is normal (not zero, subnormal, infinite, or NaN). + /// + /// True if so + bool IsNormal() const noexcept + { + auto abs = AbsImpl(); + return (abs < kPositiveInfinityBits) // is finite + && (abs != 0) // is not zero + && ((abs & kBiasedExponentMask) != 0); // is not subnormal (has a non-zero exponent) + } + + /// + /// Tests if the value is subnormal (denormal). + /// + /// True if so + bool IsSubnormal() const noexcept + { + auto abs = AbsImpl(); + return (abs < kPositiveInfinityBits) // is finite + && (abs != 0) // is not zero + && ((abs & kBiasedExponentMask) == 0); // is subnormal (has a zero exponent) + } + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + Derived Abs() const noexcept { return Derived::FromBits(AbsImpl()); } + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + Derived Negate() const noexcept { return Derived::FromBits(NegateImpl()); } + + /// + /// IEEE defines that positive and negative zero are equal, this gives us a quick equality check + /// for two values by or'ing the private bits together and stripping the sign. They are both zero, + /// and therefore equivalent, if the resulting value is still zero. + /// + /// first value + /// second value + /// True if both arguments represent zero + static bool AreZero(const BFloat16Impl& lhs, const BFloat16Impl& rhs) noexcept + { + // IEEE defines that positive and negative zero are equal, this gives us a quick equality check + // for two values by or'ing the private bits together and stripping the sign. They are both zero, + // and therefore equivalent, if the resulting value is still zero. + return static_cast((lhs.val | rhs.val) & ~kSignMask) == 0; + } +}; + +template +inline uint16_t BFloat16Impl::ToUint16Impl(float v) noexcept +{ + uint16_t result; + if (std::isnan(v)) { + result = kPositiveQNaNBits; + } else { + auto get_msb_half = [](float fl) { + uint16_t result; +#ifdef __cpp_if_constexpr + if constexpr (detail::endian::native == detail::endian::little) +#else + if (detail::endian::native == detail::endian::little) +#endif + { + std::memcpy(&result, reinterpret_cast(&fl) + sizeof(uint16_t), sizeof(uint16_t)); + } else { + std::memcpy(&result, &fl, sizeof(uint16_t)); + } + return result; + }; + + uint16_t upper_bits = get_msb_half(v); + union { + uint32_t U32; + float F32; + }; + F32 = v; + U32 += (upper_bits & 1) + kRoundToNearest; + result = get_msb_half(F32); + } + return result; +} + +template +inline float BFloat16Impl::ToFloatImpl() const noexcept +{ + if (IsNaN()) { + return std::numeric_limits::quiet_NaN(); + } + float result; + char* const first = reinterpret_cast(&result); + char* const second = first + sizeof(uint16_t); +#ifdef __cpp_if_constexpr + if constexpr (detail::endian::native == detail::endian::little) +#else + if (detail::endian::native == detail::endian::little) +#endif + { + std::memset(first, 0, sizeof(uint16_t)); + std::memcpy(second, &val, sizeof(uint16_t)); + } else { + std::memcpy(first, &val, sizeof(uint16_t)); + std::memset(second, 0, sizeof(uint16_t)); + } + return result; +} + +/** \brief IEEE 754 half-precision floating point data type + * + * \details This struct is used for converting float to float16 and back + * so the user could feed inputs and fetch outputs using these type. + * + * The size of the structure should align with uint16_t and one can freely cast + * uint16_t buffers to/from Ort::Float16_t to feed and retrieve data. + * + * \code{.unparsed} + * // This example demonstrates converion from float to float16 + * constexpr float values[] = {1.f, 2.f, 3.f, 4.f, 5.f}; + * std::vector fp16_values; + * fp16_values.reserve(std::size(values)); + * std::transform(std::begin(values), std::end(values), std::back_inserter(fp16_values), + * [](float value) { return Ort::Float16_t(value); }); + * + * \endcode + */ +struct Float16_t : OrtDataType::Float16Impl { + private: + /// + /// Constructor from a 16-bit representation of a float16 value + /// No conversion is done here. + /// + /// 16-bit representation + constexpr explicit Float16_t(uint16_t v) noexcept { val = v; } + + public: + using Base = OrtDataType::Float16Impl; + + /// + /// Default constructor + /// + Float16_t() = default; + + /// + /// Explicit conversion to uint16_t representation of float16. + /// + /// uint16_t bit representation of float16 + /// new instance of Float16_t + constexpr static Float16_t FromBits(uint16_t v) noexcept { return Float16_t(v); } + + /// + /// __ctor from float. Float is converted into float16 16-bit representation. + /// + /// float value + explicit Float16_t(float v) noexcept { val = Base::ToUint16Impl(v); } + + /// + /// Converts float16 to float + /// + /// float representation of float16 value + float ToFloat() const noexcept { return Base::ToFloatImpl(); } + + /// + /// Checks if the value is negative + /// + /// true if negative + using Base::IsNegative; + + /// + /// Tests if the value is NaN + /// + /// true if NaN + using Base::IsNaN; + + /// + /// Tests if the value is finite + /// + /// true if finite + using Base::IsFinite; + + /// + /// Tests if the value represents positive infinity. + /// + /// true if positive infinity + using Base::IsPositiveInfinity; + + /// + /// Tests if the value represents negative infinity + /// + /// true if negative infinity + using Base::IsNegativeInfinity; + + /// + /// Tests if the value is either positive or negative infinity. + /// + /// True if absolute value is infinity + using Base::IsInfinity; + + /// + /// Tests if the value is NaN or zero. Useful for comparisons. + /// + /// True if NaN or zero. + using Base::IsNaNOrZero; + + /// + /// Tests if the value is normal (not zero, subnormal, infinite, or NaN). + /// + /// True if so + using Base::IsNormal; + + /// + /// Tests if the value is subnormal (denormal). + /// + /// True if so + using Base::IsSubnormal; + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + using Base::Abs; + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + using Base::Negate; + + /// + /// IEEE defines that positive and negative zero are equal, this gives us a quick equality check + /// for two values by or'ing the private bits together and stripping the sign. They are both zero, + /// and therefore equivalent, if the resulting value is still zero. + /// + /// first value + /// second value + /// True if both arguments represent zero + using Base::AreZero; + + /// + /// User defined conversion operator. Converts Float16_t to float. + /// + explicit operator float() const noexcept { return ToFloat(); } + + using Base::operator==; + using Base::operator!=; + using Base::operator<; +}; + +static_assert(sizeof(Float16_t) == sizeof(uint16_t), "Sizes must match"); + +/** \brief bfloat16 (Brain Floating Point) data type + * + * \details This struct is used for converting float to bfloat16 and back + * so the user could feed inputs and fetch outputs using these type. + * + * The size of the structure should align with uint16_t and one can freely cast + * uint16_t buffers to/from Ort::BFloat16_t to feed and retrieve data. + * + * \code{.unparsed} + * // This example demonstrates converion from float to float16 + * constexpr float values[] = {1.f, 2.f, 3.f, 4.f, 5.f}; + * std::vector bfp16_values; + * bfp16_values.reserve(std::size(values)); + * std::transform(std::begin(values), std::end(values), std::back_inserter(bfp16_values), + * [](float value) { return Ort::BFloat16_t(value); }); + * + * \endcode + */ +struct BFloat16_t : OrtDataType::BFloat16Impl { + private: + /// + /// Constructor from a uint16_t representation of bfloat16 + /// used in FromBits() to escape overload resolution issue with + /// constructor from float. + /// No conversion is done. + /// + /// 16-bit bfloat16 value + constexpr explicit BFloat16_t(uint16_t v) noexcept { val = v; } + + public: + using Base = OrtDataType::BFloat16Impl; + + BFloat16_t() = default; + + /// + /// Explicit conversion to uint16_t representation of bfloat16. + /// + /// uint16_t bit representation of bfloat16 + /// new instance of BFloat16_t + static constexpr BFloat16_t FromBits(uint16_t v) noexcept { return BFloat16_t(v); } + + /// + /// __ctor from float. Float is converted into bfloat16 16-bit representation. + /// + /// float value + explicit BFloat16_t(float v) noexcept { val = Base::ToUint16Impl(v); } + + /// + /// Converts bfloat16 to float + /// + /// float representation of bfloat16 value + float ToFloat() const noexcept { return Base::ToFloatImpl(); } + + /// + /// Checks if the value is negative + /// + /// true if negative + using Base::IsNegative; + + /// + /// Tests if the value is NaN + /// + /// true if NaN + using Base::IsNaN; + + /// + /// Tests if the value is finite + /// + /// true if finite + using Base::IsFinite; + + /// + /// Tests if the value represents positive infinity. + /// + /// true if positive infinity + using Base::IsPositiveInfinity; + + /// + /// Tests if the value represents negative infinity + /// + /// true if negative infinity + using Base::IsNegativeInfinity; + + /// + /// Tests if the value is either positive or negative infinity. + /// + /// True if absolute value is infinity + using Base::IsInfinity; + + /// + /// Tests if the value is NaN or zero. Useful for comparisons. + /// + /// True if NaN or zero. + using Base::IsNaNOrZero; + + /// + /// Tests if the value is normal (not zero, subnormal, infinite, or NaN). + /// + /// True if so + using Base::IsNormal; + + /// + /// Tests if the value is subnormal (denormal). + /// + /// True if so + using Base::IsSubnormal; + + /// + /// Creates an instance that represents absolute value. + /// + /// Absolute value + using Base::Abs; + + /// + /// Creates a new instance with the sign flipped. + /// + /// Flipped sign instance + using Base::Negate; + + /// + /// IEEE defines that positive and negative zero are equal, this gives us a quick equality check + /// for two values by or'ing the private bits together and stripping the sign. They are both zero, + /// and therefore equivalent, if the resulting value is still zero. + /// + /// first value + /// second value + /// True if both arguments represent zero + using Base::AreZero; + + /// + /// User defined conversion operator. Converts BFloat16_t to float. + /// + explicit operator float() const noexcept { return ToFloat(); } + + // We do not have an inherited impl for the below operators + // as the internal class implements them a little differently + bool operator==(const BFloat16_t& rhs) const noexcept; + bool operator!=(const BFloat16_t& rhs) const noexcept { return !(*this == rhs); } + bool operator<(const BFloat16_t& rhs) const noexcept; +}; + +static_assert(sizeof(BFloat16_t) == sizeof(uint16_t), "Sizes must match"); + +} // namespace OrtDataType + +} // namespace o2 \ No newline at end of file diff --git a/Common/ML/include/ML/ort_interface.h b/Common/ML/include/ML/ort_interface.h new file mode 100644 index 0000000000000..e2049b8508cb4 --- /dev/null +++ b/Common/ML/include/ML/ort_interface.h @@ -0,0 +1,92 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ort_interface.h +/// \author Christian Sonnabend +/// \brief A header library for loading ONNX models and inferencing them on CPU and GPU + +#ifndef O2_ML_ONNX_INTERFACE_H +#define O2_ML_ONNX_INTERFACE_H + +// C++ and system includes +#include +#include +#include +#include +#include + +// O2 includes +#include "Framework/Logger.h" + +namespace o2 +{ + +namespace ml +{ + +class OrtModel +{ + + public: + // Constructor + OrtModel() = default; + OrtModel(std::unordered_map optionsMap) { reset(optionsMap); } + void init(std::unordered_map optionsMap) { reset(optionsMap); } + void reset(std::unordered_map); + + virtual ~OrtModel() = default; + + // Conversion + template + std::vector v2v(std::vector&, bool = true); + + // Inferencing + template // class I is the input data type, e.g. float, class O is the output data type, e.g. OrtDataType::Float16_t from O2/Common/ML/include/ML/GPUORTFloat16.h + std::vector inference(std::vector&); + + template // class I is the input data type, e.g. float, class O is the output data type, e.g. O2::gpu::OrtDataType::Float16_t from O2/GPU/GPUTracking/ML/convert_float16.h + std::vector inference(std::vector>&); + + // template // class I is the input data type, e.g. float, class T the throughput data type and class O is the output data type + // std::vector inference(std::vector&); + + // Reset session + void resetSession(); + + std::vector> getNumInputNodes() const { return mInputShapes; } + std::vector> getNumOutputNodes() const { return mOutputShapes; } + std::vector getInputNames() const { return mInputNames; } + std::vector getOutputNames() const { return mOutputNames; } + + void setActiveThreads(int threads) { intraOpNumThreads = threads; } + + private: + // ORT variables -> need to be hidden as Pimpl + struct OrtVariables; + OrtVariables* pImplOrt; + + // Input & Output specifications of the loaded network + std::vector inputNamesChar, outputNamesChar; + std::vector mInputNames, mOutputNames; + std::vector> mInputShapes, mOutputShapes; + + // Environment settings + std::string modelPath, device = "cpu", dtype = "float"; // device options should be cpu, rocm, migraphx, cuda + int intraOpNumThreads = 0, deviceId = 0, enableProfiling = 0, loggingLevel = 0, allocateDeviceMemory = 0, enableOptimizations = 0; + + std::string printShape(const std::vector&); +}; + +} // namespace ml + +} // namespace o2 + +#endif // O2_ML_ORT_INTERFACE_H diff --git a/Common/ML/src/ort_interface.cxx b/Common/ML/src/ort_interface.cxx new file mode 100644 index 0000000000000..27ac8eee16b7b --- /dev/null +++ b/Common/ML/src/ort_interface.cxx @@ -0,0 +1,280 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file ort_interface.cxx +/// \author Christian Sonnabend +/// \brief A header library for loading ONNX models and inferencing them on CPU and GPU + +#include "ML/ort_interface.h" +#include "ML/3rdparty/GPUORTFloat16.h" + +// ONNX includes +#include + +namespace o2 +{ + +namespace ml +{ + +struct OrtModel::OrtVariables { // The actual implementation is hidden in the .cxx file + // ORT runtime objects + Ort::RunOptions runOptions; + std::shared_ptr env = nullptr; + std::shared_ptr session = nullptr; ///< ONNX session + Ort::SessionOptions sessionOptions; + Ort::AllocatorWithDefaultOptions allocator; + Ort::MemoryInfo memoryInfo = Ort::MemoryInfo("Cpu", OrtAllocatorType::OrtDeviceAllocator, 0, OrtMemType::OrtMemTypeDefault); +}; + +void OrtModel::reset(std::unordered_map optionsMap) +{ + + pImplOrt = new OrtVariables(); + + // Load from options map + if (!optionsMap.contains("model-path")) { + LOG(fatal) << "(ORT) Model path cannot be empty!"; + } + modelPath = optionsMap["model-path"]; + device = (optionsMap.contains("device") ? optionsMap["device"] : "CPU"); + dtype = (optionsMap.contains("dtype") ? optionsMap["dtype"] : "float"); + deviceId = (optionsMap.contains("device-id") ? std::stoi(optionsMap["device-id"]) : 0); + allocateDeviceMemory = (optionsMap.contains("allocate-device-memory") ? std::stoi(optionsMap["allocate-device-memory"]) : 0); + intraOpNumThreads = (optionsMap.contains("intra-op-num-threads") ? std::stoi(optionsMap["intra-op-num-threads"]) : 0); + loggingLevel = (optionsMap.contains("logging-level") ? std::stoi(optionsMap["logging-level"]) : 0); + enableProfiling = (optionsMap.contains("enable-profiling") ? std::stoi(optionsMap["enable-profiling"]) : 0); + enableOptimizations = (optionsMap.contains("enable-optimizations") ? std::stoi(optionsMap["enable-optimizations"]) : 0); + + std::string dev_mem_str = "Hip"; +#ifdef ORT_ROCM_BUILD + if (device == "ROCM") { + Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_ROCM(pImplOrt->sessionOptions, deviceId)); + LOG(info) << "(ORT) ROCM execution provider set"; + } +#endif +#ifdef ORT_MIGRAPHX_BUILD + if (device == "MIGRAPHX") { + Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_MIGraphX(pImplOrt->sessionOptions, deviceId)); + LOG(info) << "(ORT) MIGraphX execution provider set"; + } +#endif +#ifdef ORT_CUDA_BUILD + if (device == "CUDA") { + Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CUDA(pImplOrt->sessionOptions, deviceId)); + LOG(info) << "(ORT) CUDA execution provider set"; + dev_mem_str = "Cuda"; + } +#endif + + if (allocateDeviceMemory) { + pImplOrt->memoryInfo = Ort::MemoryInfo(dev_mem_str.c_str(), OrtAllocatorType::OrtDeviceAllocator, deviceId, OrtMemType::OrtMemTypeDefault); + LOG(info) << "(ORT) Memory info set to on-device memory"; + } + + if (device == "CPU") { + (pImplOrt->sessionOptions).SetIntraOpNumThreads(intraOpNumThreads); + if (intraOpNumThreads > 1) { + (pImplOrt->sessionOptions).SetExecutionMode(ExecutionMode::ORT_PARALLEL); + } else if (intraOpNumThreads == 1) { + (pImplOrt->sessionOptions).SetExecutionMode(ExecutionMode::ORT_SEQUENTIAL); + } + LOG(info) << "(ORT) CPU execution provider set with " << intraOpNumThreads << " threads"; + } + + (pImplOrt->sessionOptions).DisableMemPattern(); + (pImplOrt->sessionOptions).DisableCpuMemArena(); + + if (enableProfiling) { + if (optionsMap.contains("profiling-output-path")) { + (pImplOrt->sessionOptions).EnableProfiling((optionsMap["profiling-output-path"] + "/ORT_LOG_").c_str()); + } else { + LOG(warning) << "(ORT) If profiling is enabled, optionsMap[\"profiling-output-path\"] should be set. Disabling profiling for now."; + (pImplOrt->sessionOptions).DisableProfiling(); + } + } else { + (pImplOrt->sessionOptions).DisableProfiling(); + } + (pImplOrt->sessionOptions).SetGraphOptimizationLevel(GraphOptimizationLevel(enableOptimizations)); + (pImplOrt->sessionOptions).SetLogSeverityLevel(OrtLoggingLevel(loggingLevel)); + + pImplOrt->env = std::make_shared(OrtLoggingLevel(loggingLevel), (optionsMap["onnx-environment-name"].empty() ? "onnx_model_inference" : optionsMap["onnx-environment-name"].c_str())); + pImplOrt->session = std::make_shared(*(pImplOrt->env), modelPath.c_str(), pImplOrt->sessionOptions); + + for (size_t i = 0; i < (pImplOrt->session)->GetInputCount(); ++i) { + mInputNames.push_back((pImplOrt->session)->GetInputNameAllocated(i, pImplOrt->allocator).get()); + } + for (size_t i = 0; i < (pImplOrt->session)->GetInputCount(); ++i) { + mInputShapes.emplace_back((pImplOrt->session)->GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + } + for (size_t i = 0; i < (pImplOrt->session)->GetOutputCount(); ++i) { + mOutputNames.push_back((pImplOrt->session)->GetOutputNameAllocated(i, pImplOrt->allocator).get()); + } + for (size_t i = 0; i < (pImplOrt->session)->GetOutputCount(); ++i) { + mOutputShapes.emplace_back((pImplOrt->session)->GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + } + + inputNamesChar.resize(mInputNames.size(), nullptr); + std::transform(std::begin(mInputNames), std::end(mInputNames), std::begin(inputNamesChar), + [&](const std::string& str) { return str.c_str(); }); + outputNamesChar.resize(mOutputNames.size(), nullptr); + std::transform(std::begin(mOutputNames), std::end(mOutputNames), std::begin(outputNamesChar), + [&](const std::string& str) { return str.c_str(); }); + + // Print names + if (loggingLevel > 1) { + LOG(info) << "Input Nodes:"; + for (size_t i = 0; i < mInputNames.size(); i++) { + LOG(info) << "\t" << mInputNames[i] << " : " << printShape(mInputShapes[i]); + } + + LOG(info) << "Output Nodes:"; + for (size_t i = 0; i < mOutputNames.size(); i++) { + LOG(info) << "\t" << mOutputNames[i] << " : " << printShape(mOutputShapes[i]); + } + } +} + +void OrtModel::resetSession() +{ + pImplOrt->session = std::make_shared(*(pImplOrt->env), modelPath.c_str(), pImplOrt->sessionOptions); +} + +template +std::vector OrtModel::v2v(std::vector& input, bool clearInput) +{ + if constexpr (std::is_same_v) { + return input; + } else { + std::vector output(input.size()); + std::transform(std::begin(input), std::end(input), std::begin(output), [](I f) { return O(f); }); + if (clearInput) { + input.clear(); + } + return output; + } +} + +template // class I is the input data type, e.g. float, class O is the output data type, e.g. O2::gpu::OrtDataType::Float16_t from O2/GPU/GPUTracking/ML/convert_float16.h +std::vector OrtModel::inference(std::vector& input) +{ + std::vector inputShape{(int64_t)(input.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + std::vector inputTensor; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(input.data()), input.size(), inputShape.data(), inputShape.size())); + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + O* outputValues = reinterpret_cast(outputTensors[0].template GetTensorMutableData()); + std::vector outputValuesVec{outputValues, outputValues + inputShape[0] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +template // class I is the input data type, e.g. float, class O is the output data type, e.g. O2::gpu::OrtDataType::Float16_t from O2/GPU/GPUTracking/ML/convert_float16.h +std::vector OrtModel::inference(std::vector>& input) +{ + std::vector inputTensor; + for (auto i : input) { + std::vector inputShape{(int64_t)(i.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(i.data()), i.size(), inputShape.data(), inputShape.size())); + } + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + O* outputValues = reinterpret_cast(outputTensors[0].template GetTensorMutableData()); + std::vector outputValuesVec{outputValues, outputValues + inputTensor.size() / mInputShapes[0][1] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +std::string OrtModel::printShape(const std::vector& v) +{ + std::stringstream ss(""); + for (size_t i = 0; i < v.size() - 1; i++) { + ss << v[i] << "x"; + } + ss << v[v.size() - 1]; + return ss.str(); +} + +template <> +std::vector OrtModel::inference(std::vector& input) +{ + std::vector inputShape{(int64_t)(input.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + std::vector inputTensor; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, input.data(), input.size(), inputShape.data(), inputShape.size())); + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + float* outputValues = outputTensors[0].template GetTensorMutableData(); + std::vector outputValuesVec{outputValues, outputValues + inputShape[0] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +template <> +std::vector OrtModel::inference(std::vector& input) +{ + std::vector inputShape{(int64_t)(input.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + std::vector inputTensor; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(input.data()), input.size(), inputShape.data(), inputShape.size())); + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + float* outputValues = outputTensors[0].template GetTensorMutableData(); + std::vector outputValuesVec{outputValues, outputValues + inputShape[0] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +template <> +std::vector OrtModel::inference(std::vector& input) +{ + std::vector inputShape{(int64_t)(input.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + std::vector inputTensor; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(input.data()), input.size(), inputShape.data(), inputShape.size())); + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + OrtDataType::Float16_t* outputValues = reinterpret_cast(outputTensors[0].template GetTensorMutableData()); + std::vector outputValuesVec{outputValues, outputValues + inputShape[0] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +template <> +std::vector OrtModel::inference(std::vector& input) +{ + std::vector inputShape{(int64_t)(input.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + std::vector inputTensor; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(input.data()), input.size(), inputShape.data(), inputShape.size())); + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + OrtDataType::Float16_t* outputValues = reinterpret_cast(outputTensors[0].template GetTensorMutableData()); + std::vector outputValuesVec{outputValues, outputValues + inputShape[0] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +template <> +std::vector OrtModel::inference(std::vector>& input) +{ + std::vector inputTensor; + for (auto i : input) { + std::vector inputShape{(int64_t)(i.size() / mInputShapes[0][1]), (int64_t)mInputShapes[0][1]}; + inputTensor.emplace_back(Ort::Value::CreateTensor(pImplOrt->memoryInfo, reinterpret_cast(i.data()), i.size(), inputShape.data(), inputShape.size())); + } + // input.clear(); + auto outputTensors = (pImplOrt->session)->Run(pImplOrt->runOptions, inputNamesChar.data(), inputTensor.data(), inputTensor.size(), outputNamesChar.data(), outputNamesChar.size()); + OrtDataType::Float16_t* outputValues = reinterpret_cast(outputTensors[0].template GetTensorMutableData()); + std::vector outputValuesVec{outputValues, outputValues + inputTensor.size() / mInputShapes[0][1] * mOutputShapes[0][1]}; + outputTensors.clear(); + return outputValuesVec; +} + +} // namespace ml + +} // namespace o2 From 0c734187a7f2f5626e3a5916c62b5ea2385108f9 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Fri, 15 Nov 2024 12:37:52 +0100 Subject: [PATCH 0504/2205] register available_managed_shm metric only for readout-proxy --- Framework/Core/src/CommonServices.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index bc750181d54e2..23375b76487b9 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -768,8 +768,11 @@ auto sendRelayerMetrics(ServiceRegistryRef registry, DataProcessingStats& stats) using namespace fair::mq::shmem; auto& spec = registry.get(); + auto hasMetric = [&runningWorkflow](const DataProcessingStats::MetricSpec& metric) -> bool { + return metric.metricId == static_cast(ProcessingStatsId::AVAILABLE_MANAGED_SHM_BASE) + (runningWorkflow.shmSegmentId % 512); + }; // FIXME: Ugly, but we do it only every 5 seconds... - if (spec.name == "readout-proxy") { + if (std::find_if(stats.metricSpecs.begin(), stats.metricSpecs.end(), hasMetric) != stats.metricSpecs.end()) { auto device = registry.get().device(); long freeMemory = -1; try { @@ -1105,6 +1108,9 @@ o2::framework::ServiceSpec CommonServices::dataProcessingStats() .sendInitialValue = true}}; for (auto& metric : metrics) { + if (metric.metricId == (int)ProcessingStatsId::AVAILABLE_MANAGED_SHM_BASE + (runningWorkflow.shmSegmentId % 512) && spec.name.compare("readout-proxy") != 0) { + continue; + } stats->registerMetric(metric); } From 32451dc4cc345ccbaf2f6bbcd6594e4cf5b2a911 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Fri, 22 Nov 2024 15:32:52 +0100 Subject: [PATCH 0505/2205] DPL Analysis: add tf-offset option to mctracks-to-aod converter (#13711) --- run/o2sim_mctracks_to_aod.cxx | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/run/o2sim_mctracks_to_aod.cxx b/run/o2sim_mctracks_to_aod.cxx index 74807fd2a3ce9..f7a85e62a3f9b 100644 --- a/run/o2sim_mctracks_to_aod.cxx +++ b/run/o2sim_mctracks_to_aod.cxx @@ -49,14 +49,13 @@ struct MctracksToAod { "Interaction rate to simulate"}; Configurable filt{"filter-mctracks", false, "Filter tracks"}; + Configurable tfOffset{"tf-offset", 0, "Start TF counter from an offset"}; /** @} */ /** Number of timeframes */ uint64_t mTimeFrame = 0; /** Interaction simulation */ InteractionSampler mSampler; - /** Whether to filter tracks */ - bool mFilter; /** Initialize */ void init(o2::framework::InitContext& /*ic*/) @@ -64,13 +63,14 @@ struct MctracksToAod { mSampler.setInteractionRate(IR); mSampler.setFirstIR({0, 0}); mSampler.init(); - mFilter = filt; + + mTimeFrame = tfOffset; } /** Run the conversion */ void run(o2::framework::ProcessingContext& pc) { - LOG(info) << "=== Running extended MC AOD exporter ==="; + LOG(debug) << "=== Running extended MC AOD exporter ==="; using namespace o2::aodmchelpers; using McHeader = o2::dataformats::MCEventHeader; using McTrack = o2::MCTrack; @@ -78,11 +78,17 @@ struct MctracksToAod { auto nParts = pc.inputs().getNofParts(0); auto nPartsVerify = pc.inputs().getNofParts(1); + + using o2::framework::Lifetime; + using o2::framework::Output; + if (nParts != nPartsVerify) { LOG(warn) << "Mismatch between number of MC headers and " << "number of track vectors: " << nParts << " != " << nPartsVerify << ", shipping the empty timeframe"; + pc.outputs().snapshot(Output{"TFF", "TFFilename", 0}, ""); + pc.outputs().snapshot(Output{"TFN", "TFNumber", 0}, ++mTimeFrame); return; } // TODO: include BC simulation @@ -115,18 +121,15 @@ struct MctracksToAod { tracks, preselect, offset, - mFilter, + (bool)filt, false); LOG(debug) << "Increment BC counter"; bcCounter++; } - using o2::framework::Lifetime; - using o2::framework::Output; - ++mTimeFrame; pc.outputs().snapshot(Output{"TFF", "TFFilename", 0}, ""); - pc.outputs().snapshot(Output{"TFN", "TFNumber", 0}, mTimeFrame); + pc.outputs().snapshot(Output{"TFN", "TFNumber", 0}, ++mTimeFrame); } }; From 20973f4f92cf1fc7a881ebc03a078263b97d31fa Mon Sep 17 00:00:00 2001 From: shahoian Date: Thu, 21 Nov 2024 18:46:30 +0100 Subject: [PATCH 0506/2205] Add TPC sh.clusters info to study output --- .../study/include/GlobalTrackingStudy/TrackInfoExt.h | 3 ++- Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h index ea79d5d4a2c92..6fd06e5265946 100644 --- a/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h +++ b/Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackInfoExt.h @@ -41,6 +41,7 @@ struct TrackInfoExt { float q2ptITSTPC = 0.f; float q2ptITSTPCTRD = 0.f; uint16_t nClTPC = 0; + uint16_t nClTPCShared = 0; uint8_t pattITS = 0; uint8_t nClITS = 0; uint8_t rowMinTPC = 0; @@ -54,7 +55,7 @@ struct TrackInfoExt { float getTPCInY0() const { return innerTPCPos0[1]; } float getTPCInZ0() const { return innerTPCPos0[2]; } - ClassDefNV(TrackInfoExt, 3); + ClassDefNV(TrackInfoExt, 4); }; } // namespace dataformats diff --git a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx index 5a67bd344f271..ba453b944a742 100644 --- a/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx +++ b/Detectors/GlobalTrackingWorkflow/study/src/TrackingStudy.cxx @@ -250,6 +250,7 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) auto fillTPCClInfo = [&recoData, this](const o2::tpc::TrackTPC& trc, o2::dataformats::TrackInfoExt& trExt, float timestampTB = -1e9) { const auto clRefs = recoData.getTPCTracksClusterRefs(); + const auto shMap = recoData.clusterShMapTPC.data(); if (recoData.inputsTPCclusters) { uint8_t clSect = 0, clRow = 0, clRowP = -1; uint32_t clIdx = 0; @@ -259,6 +260,9 @@ void TrackingStudySpec::process(o2::globaltracking::RecoContainer& recoData) trExt.rowCountTPC++; clRowP = clRow; } + if (shMap[clRefs[ic + trc.getClusterRef().getFirstEntry()]]) { + trExt.nClTPCShared++; + } } trc.getClusterReference(clRefs, trc.getNClusterReferences() - 1, clSect, clRow, clIdx); trExt.rowMinTPC = clRow; From ce63ff8c1c90453fa45b8b97eb03c02075c70469 Mon Sep 17 00:00:00 2001 From: shahoian Date: Wed, 20 Nov 2024 15:58:31 +0100 Subject: [PATCH 0507/2205] Object to provide TB to cut due to the Altro sync. procedure --- DataFormats/Detectors/TPC/CMakeLists.txt | 3 +- .../include/DataFormatsTPC/AltroSyncSignal.h | 30 +++++++++++++++++++ .../Detectors/TPC/src/DataFormatsTPCLinkDef.h | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h diff --git a/DataFormats/Detectors/TPC/CMakeLists.txt b/DataFormats/Detectors/TPC/CMakeLists.txt index b2f9eb9e53e85..b8b93c308e85d 100644 --- a/DataFormats/Detectors/TPC/CMakeLists.txt +++ b/DataFormats/Detectors/TPC/CMakeLists.txt @@ -63,7 +63,8 @@ o2_target_root_dictionary( include/DataFormatsTPC/VDriftCorrFact.h include/DataFormatsTPC/CalibdEdxCorrection.h include/DataFormatsTPC/BetheBlochAleph.h - include/DataFormatsTPC/PIDResponse.h) + include/DataFormatsTPC/PIDResponse.h + include/DataFormatsTPC/AltroSyncSignal.h) o2_add_test( ClusterNative diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h new file mode 100644 index 0000000000000..d98dd1c5f6eff --- /dev/null +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h @@ -0,0 +1,30 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file AltroSyncSignal.h +/// \brief Definition of the timebin from which syncronization starts + +#include "GPUCommonRtypes.h" + +namespace o2::tpc +{ +struct AltroSyncSignal { + int periodTF = 10; // signal repeats every period-th TF + int timebin = 141192.; // every 10 TF, orbit 31, Time bin 384, BC 4 -> 141195, but clusters can be affected before that + + int getTB2Cut(uint32_t tfCounter) const + { + return periodTF > 0 && (tfCounter % periodTF) == 1 && tfCounter > periodTF ? timebin : -1; + } + + ClassDefNV(AltroSyncSignal, 1); +}; +} // namespace o2::tpc diff --git a/DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h b/DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h index 676a4e0144be0..f248a74950a1f 100644 --- a/DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h +++ b/DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h @@ -73,5 +73,6 @@ #pragma link C++ class o2::tpc::TriggerWordDLBZS + ; #pragma link C++ class o2::tpc::TriggerInfoDLBZS + ; #pragma link C++ class std::vector < o2::tpc::TriggerInfoDLBZS> + ; +#pragma link C++ class o2::tpc::AltroSyncSignal + ; #endif From 580d660289f73e517a43023472357c835dceceb1 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 24 Nov 2024 17:19:09 +0100 Subject: [PATCH 0508/2205] fix typo: remove stray . in the int value --- .../Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h index d98dd1c5f6eff..0717c7bcbb02c 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h @@ -18,7 +18,7 @@ namespace o2::tpc { struct AltroSyncSignal { int periodTF = 10; // signal repeats every period-th TF - int timebin = 141192.; // every 10 TF, orbit 31, Time bin 384, BC 4 -> 141195, but clusters can be affected before that + int timebin = 141192; // every 10 TF, orbit 31, Time bin 384, BC 4 -> 141195, but clusters can be affected before that int getTB2Cut(uint32_t tfCounter) const { From 567d25ac1880faac811dcbaa6b30246f28e2d176 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 24 Nov 2024 18:01:08 +0100 Subject: [PATCH 0509/2205] Fix another typo in AltroSyncSignal::timebin default value --- .../Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h index 0717c7bcbb02c..6dee49e4ed6c6 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/AltroSyncSignal.h @@ -18,7 +18,7 @@ namespace o2::tpc { struct AltroSyncSignal { int periodTF = 10; // signal repeats every period-th TF - int timebin = 141192; // every 10 TF, orbit 31, Time bin 384, BC 4 -> 141195, but clusters can be affected before that + int timebin = 14192; // every 10 TF, orbit 31, Time bin 384, BC 4 -> 14195, but clusters can be affected before that int getTB2Cut(uint32_t tfCounter) const { From 6cfdeaeaca0f2a1f112e7fd4b2310e3d55652e96 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 24 Nov 2024 19:21:28 +0100 Subject: [PATCH 0510/2205] DPL: improve arrow::Dataset integration (#13725) - Modularise filesystem to allow easier navigation and support for multiple formats. - Add initial support to multiplex multiple tables on top of the same tree. - Improve support for writing boolean fields. --- .../include/Framework/RootArrowFilesystem.h | 36 ++++- Framework/Core/src/RootArrowFilesystem.cxx | 153 +++++++++++++----- Framework/Core/test/test_Root2ArrowTable.cxx | 146 ++++++++++++----- 3 files changed, 250 insertions(+), 85 deletions(-) diff --git a/Framework/Core/include/Framework/RootArrowFilesystem.h b/Framework/Core/include/Framework/RootArrowFilesystem.h index 7c8385ccd2b9d..48d817bc9ddf2 100644 --- a/Framework/Core/include/Framework/RootArrowFilesystem.h +++ b/Framework/Core/include/Framework/RootArrowFilesystem.h @@ -17,6 +17,8 @@ #include #include +class TFile; +class TBranch; class TTree; class TBufferFile; class TDirectoryFile; @@ -227,11 +229,38 @@ class TTreeFileFormat : public arrow::dataset::FileFormat const std::shared_ptr& fragment) const override; }; -// An arrow outputstream which allows to write to a ttree +// An arrow outputstream which allows to write to a TDirectoryFile. +// This will point to the location of the file itself. You can +// specify the location of the actual object inside it by passing the +// associated path to the Write() API. +class TDirectoryFileOutputStream : public arrow::io::OutputStream +{ + public: + TDirectoryFileOutputStream(TDirectoryFile*); + + arrow::Status Close() override; + + arrow::Result Tell() const override; + + arrow::Status Write(const void* data, int64_t nbytes) override; + + bool closed() const override; + + TDirectoryFile* GetDirectory() + { + return mDirectory; + } + + private: + TDirectoryFile* mDirectory; +}; + +// An arrow outputstream which allows to write to a TTree. Eventually +// with a prefix for the branches. class TTreeOutputStream : public arrow::io::OutputStream { public: - TTreeOutputStream(TTree* t); + TTreeOutputStream(TTree*, std::string branchPrefix); arrow::Status Close() override; @@ -241,6 +270,8 @@ class TTreeOutputStream : public arrow::io::OutputStream bool closed() const override; + TBranch* CreateBranch(char const* branchName, char const* sizeBranch); + TTree* GetTree() { return mTree; @@ -248,6 +279,7 @@ class TTreeOutputStream : public arrow::io::OutputStream private: TTree* mTree; + std::string mBranchPrefix; }; } // namespace o2::framework diff --git a/Framework/Core/src/RootArrowFilesystem.cxx b/Framework/Core/src/RootArrowFilesystem.cxx index 7581ee57e5b9f..7e331814272a6 100644 --- a/Framework/Core/src/RootArrowFilesystem.cxx +++ b/Framework/Core/src/RootArrowFilesystem.cxx @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -28,8 +27,11 @@ #include #include #include +#include #include +#include +#include O2_DECLARE_DYNAMIC_LOG(root_arrow_fs); @@ -100,7 +102,6 @@ std::shared_ptr TFileFileSystem::GetSubFilesystem(arr return std::shared_ptr(new SingleTreeFileSystem(tree)); } - auto directory = (TDirectoryFile*)mFile->GetObjectChecked(source.path().c_str(), TClass::GetClass()); if (directory) { return std::shared_ptr(new TFileFileSystem(directory, 50 * 1024 * 1024)); @@ -129,8 +130,15 @@ arrow::Result> TFileFileSystem::OpenOut const std::string& path, const std::shared_ptr& metadata) { - auto* t = new TTree(path.c_str(), "should put a name here"); - auto stream = std::make_shared(t); + if (path == "/") { + return std::make_shared(this->GetFile()); + } + + auto* dir = dynamic_cast(this->GetFile()->Get(path.c_str())); + if (!dir) { + throw runtime_error_f("Unable to open directory %s in file %s", path.c_str(), GetFile()->GetName()); + } + auto stream = std::make_shared(dir); return stream; } @@ -286,13 +294,46 @@ arrow::Result> TTreeFileFormat::Ma } // An arrow outputstream which allows to write to a ttree -TTreeOutputStream::TTreeOutputStream(TTree* t) - : mTree(t) +TDirectoryFileOutputStream::TDirectoryFileOutputStream(TDirectoryFile* f) + : mDirectory(f) +{ +} + +arrow::Status TDirectoryFileOutputStream::Close() +{ + mDirectory->GetFile()->Close(); + return arrow::Status::OK(); +} + +arrow::Result TDirectoryFileOutputStream::Tell() const +{ + return arrow::Result(arrow::Status::NotImplemented("Cannot move")); +} + +arrow::Status TDirectoryFileOutputStream::Write(const void* data, int64_t nbytes) +{ + return arrow::Status::NotImplemented("Cannot write raw bytes to a TTree"); +} + +bool TDirectoryFileOutputStream::closed() const +{ + return mDirectory->GetFile()->IsOpen() == false; +} + +// An arrow outputstream which allows to write to a ttree +// @a branch prefix is to be used to identify a set of branches which all belong to +// the same table. +TTreeOutputStream::TTreeOutputStream(TTree* f, std::string branchPrefix) + : mTree(f), + mBranchPrefix(std::move(branchPrefix)) { } arrow::Status TTreeOutputStream::Close() { + if (mTree->GetCurrentFile() == nullptr) { + return arrow::Status::Invalid("Cannot close a tree not attached to a file"); + } mTree->GetCurrentFile()->Close(); return arrow::Status::OK(); } @@ -309,9 +350,18 @@ arrow::Status TTreeOutputStream::Write(const void* data, int64_t nbytes) bool TTreeOutputStream::closed() const { + // A standalone tree is never closed. + if (mTree->GetCurrentFile() == nullptr) { + return false; + } return mTree->GetCurrentFile()->IsOpen() == false; } +TBranch* TTreeOutputStream::CreateBranch(char const* branchName, char const* sizeBranch) +{ + return mTree->Branch((mBranchPrefix + "/" + branchName).c_str(), (char*)nullptr, (mBranchPrefix + sizeBranch).c_str()); +} + char const* rootSuffixFromArrow(arrow::Type::type id) { switch (id) { @@ -411,8 +461,24 @@ class TTreeFileWriter : public arrow::dataset::FileWriter : FileWriter(schema, options, destination, destination_locator) { // Batches have the same number of entries for each column. + auto directoryStream = std::dynamic_pointer_cast(destination_); auto treeStream = std::dynamic_pointer_cast(destination_); - TTree* tree = treeStream->GetTree(); + + if (directoryStream.get()) { + TDirectoryFile* dir = directoryStream->GetDirectory(); + dir->cd(); + auto* tree = new TTree(destination_locator_.path.c_str(), ""); + treeStream = std::make_shared(tree, ""); + } else if (treeStream.get()) { + // We already have a tree stream, let's derive a new one + // with the destination_locator_.path as prefix for the branches + // This way we can multiplex multiple tables in the same tree. + auto tree = treeStream->GetTree(); + treeStream = std::make_shared(tree, destination_locator_.path); + } else { + // I could simply set a prefix here to merge to an already existing tree. + throw std::runtime_error("Unsupported backend."); + } for (auto i = 0u; i < schema->fields().size(); ++i) { auto& field = schema->field(i); @@ -427,15 +493,15 @@ class TTreeFileWriter : public arrow::dataset::FileWriter valueTypes.push_back(field->type()->field(0)->type()); sizesBranches.push_back(nullptr); std::string leafList = fmt::format("{}[{}]{}", field->name(), listSizes.back(), rootSuffixFromArrow(valueTypes.back()->id())); - branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + branches.push_back(treeStream->CreateBranch(field->name().c_str(), leafList.c_str())); } break; case arrow::Type::LIST: { valueTypes.push_back(field->type()->field(0)->type()); listSizes.back() = 0; // VLA, we need to calculate it on the fly; std::string leafList = fmt::format("{}[{}_size]{}", field->name(), field->name(), rootSuffixFromArrow(valueTypes.back()->id())); std::string sizeLeafList = field->name() + "_size/I"; - sizesBranches.push_back(tree->Branch((field->name() + "_size").c_str(), (char*)nullptr, sizeLeafList.c_str())); - branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + sizesBranches.push_back(treeStream->CreateBranch((field->name() + "_size").c_str(), sizeLeafList.c_str())); + branches.push_back(treeStream->CreateBranch(field->name().c_str(), leafList.c_str())); // Notice that this could be replaced by a better guess of the // average size of the list elements, but this is not trivial. } break; @@ -443,7 +509,7 @@ class TTreeFileWriter : public arrow::dataset::FileWriter valueTypes.push_back(field->type()); std::string leafList = field->name() + rootSuffixFromArrow(valueTypes.back()->id()); sizesBranches.push_back(nullptr); - branches.push_back(tree->Branch(field->name().c_str(), (char*)nullptr, leafList.c_str())); + branches.push_back(treeStream->CreateBranch(field->name().c_str(), leafList.c_str())); } break; } } @@ -463,11 +529,18 @@ class TTreeFileWriter : public arrow::dataset::FileWriter } // Batches have the same number of entries for each column. + auto directoryStream = std::dynamic_pointer_cast(destination_); + TTree* tree = nullptr; + if (directoryStream.get()) { + TDirectoryFile* dir = directoryStream->GetDirectory(); + tree = (TTree*)dir->Get(destination_locator_.path.c_str()); + } auto treeStream = std::dynamic_pointer_cast(destination_); - TTree* tree = treeStream->GetTree(); - // Caches for the vectors of bools. - std::vector> caches; + if (!tree) { + // I could simply set a prefix here to merge to an already existing tree. + throw std::runtime_error("Unsupported backend."); + } for (auto i = 0u; i < batch->columns().size(); ++i) { auto column = batch->column(i); @@ -484,24 +557,11 @@ class TTreeFileWriter : public arrow::dataset::FileWriter auto list = std::static_pointer_cast(column); valueArrays.back() = list; } break; - default: - valueArrays.back() = column; - } - } - - int64_t pos = 0; - while (pos < batch->num_rows()) { - for (size_t bi = 0; bi < branches.size(); ++bi) { - auto* branch = branches[bi]; - auto* sizeBranch = sizesBranches[bi]; - auto array = batch->column(bi); - auto& field = batch->schema()->field(bi); - auto& listSize = listSizes[bi]; - auto valueType = valueTypes[bi]; - auto valueArray = valueArrays[bi]; + case arrow::Type::BOOL: { + // In case of arrays of booleans, we need to go back to their + // char based representation for ROOT to save them. + auto boolArray = std::static_pointer_cast(column); - if (field->type()->id() == arrow::Type::BOOL) { - auto boolArray = std::static_pointer_cast(array); int64_t length = boolArray->length(); arrow::UInt8Builder builder; auto ok = builder.Reserve(length); @@ -516,11 +576,24 @@ class TTreeFileWriter : public arrow::dataset::FileWriter auto ok = builder.AppendNull(); } } + valueArrays.back() = *builder.Finish(); + } break; + default: + valueArrays.back() = column; + } + } + + int64_t pos = 0; + while (pos < batch->num_rows()) { + for (size_t bi = 0; bi < branches.size(); ++bi) { + auto* branch = branches[bi]; + auto* sizeBranch = sizesBranches[bi]; + auto array = batch->column(bi); + auto& field = batch->schema()->field(bi); + auto& listSize = listSizes[bi]; + auto valueType = valueTypes[bi]; + auto valueArray = valueArrays[bi]; - ok = builder.Finish(&caches[bi]); - branch->SetAddress((void*)(caches[bi]->values()->data())); - continue; - } switch (field->type()->id()) { case arrow::Type::LIST: { auto list = std::static_pointer_cast(array); @@ -764,13 +837,16 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( return generator; } - arrow::Result> TTreeFileSystem::OpenOutputStream( const std::string& path, const std::shared_ptr& metadata) { - auto stream = std::make_shared(GetTree({path, shared_from_this()})); - return stream; + arrow::dataset::FileSource source{path, shared_from_this()}; + auto prefix = metadata->Get("branch_prefix"); + if (prefix.ok()) { + return std::make_shared(GetTree(source), *prefix); + } + return std::make_shared(GetTree(source), ""); } TBufferFileFS::TBufferFileFS(TBufferFile* f) @@ -782,7 +858,6 @@ TBufferFileFS::TBufferFileFS(TBufferFile* f) TTreeFileSystem::~TTreeFileSystem() = default; - arrow::Result TBufferFileFS::GetFileInfo(const std::string& path) { arrow::fs::FileInfo result; diff --git a/Framework/Core/test/test_Root2ArrowTable.cxx b/Framework/Core/test/test_Root2ArrowTable.cxx index 03f0977a4c0c4..a659d488ae24a 100644 --- a/Framework/Core/test/test_Root2ArrowTable.cxx +++ b/Framework/Core/test/test_Root2ArrowTable.cxx @@ -20,13 +20,18 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include #include +#include #include #include #include @@ -259,6 +264,82 @@ TEST_CASE("RootTree2Fragment") REQUIRE((*result)->num_rows() == 1000); } +bool validateContents(std::shared_ptr batch) +{ + { + auto int_array = std::static_pointer_cast(batch->GetColumnByName("ev")); + REQUIRE(int_array->length() == 100); + for (int64_t j = 0; j < int_array->length(); j++) { + REQUIRE(int_array->Value(j) == j + 1); + } + } + + { + auto list_array = std::static_pointer_cast(batch->GetColumnByName("xyz")); + + REQUIRE(list_array->length() == 100); + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto float_array = std::static_pointer_cast(value_slice); + + REQUIRE(float_array->Value(0) == 1); + REQUIRE(float_array->Value(1) == 2); + REQUIRE(float_array->Value(2) == i + 1); + } + } + + { + auto list_array = std::static_pointer_cast(batch->GetColumnByName("ij")); + + REQUIRE(list_array->length() == 100); + // Iterate over the FixedSizeListArray + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto int_array = std::static_pointer_cast(value_slice); + REQUIRE(int_array->Value(0) == i); + REQUIRE(int_array->Value(1) == i + 1); + } + } + + { + auto bool_array = std::static_pointer_cast(batch->GetColumnByName("bools")); + + REQUIRE(bool_array->length() == 100); + for (int64_t j = 0; j < bool_array->length(); j++) { + REQUIRE(bool_array->Value(j) == (j % 3 == 0)); + } + } + + { + auto list_array = std::static_pointer_cast(batch->GetColumnByName("manyBools")); + + REQUIRE(list_array->length() == 100); + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + auto bool_array = std::static_pointer_cast(value_slice); + REQUIRE(bool_array->Value(0) == (i % 4 == 0)); + REQUIRE(bool_array->Value(1) == (i % 5 == 0)); + } + } + return true; +} + +bool validateSchema(std::shared_ptr schema) +{ + REQUIRE(schema->num_fields() == 9); + REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); + REQUIRE(schema->field(3)->type()->id() == arrow::float64()->id()); + REQUIRE(schema->field(4)->type()->id() == arrow::int32()->id()); + REQUIRE(schema->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); + REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + REQUIRE(schema->field(7)->type()->id() == arrow::boolean()->id()); + REQUIRE(schema->field(8)->type()->id() == arrow::fixed_size_list(arrow::boolean(), 2)->id()); + return true; +} + TEST_CASE("RootTree2Dataset") { using namespace o2::framework; @@ -307,6 +388,9 @@ TEST_CASE("RootTree2Dataset") Float_t px = 0, py = 1, pz = 2; Double_t random; Int_t ev; + bool oneBool; + bool manyBool[2]; + t->Branch("px", &px, "px/F"); t->Branch("py", &py, "py/F"); t->Branch("pz", &pz, "pz/F"); @@ -314,6 +398,8 @@ TEST_CASE("RootTree2Dataset") t->Branch("ev", &ev, "ev/I"); t->Branch("xyz", xyz, "xyz[3]/F"); t->Branch("ij", ij, "ij[2]/I"); + t->Branch("bools", &oneBool, "bools/O"); + t->Branch("manyBools", &manyBool, "manyBools[2]/O"); // fill the tree for (Int_t i = 0; i < 100; i++) { xyz[0] = 1; @@ -326,6 +412,9 @@ TEST_CASE("RootTree2Dataset") ij[1] = i + 1; random = gRandom->Rndm(); ev = i + 1; + oneBool = (i % 3 == 0); + manyBool[0] = (i % 4 == 0); + manyBool[1] = (i % 5 == 0); t->Fill(); } } @@ -339,7 +428,7 @@ TEST_CASE("RootTree2Dataset") auto schemaOpt = format->Inspect(source); REQUIRE(schemaOpt.ok()); auto schema = *schemaOpt; - REQUIRE(schema->num_fields() == 7); + REQUIRE(schema->num_fields() == 9); REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); @@ -347,6 +436,9 @@ TEST_CASE("RootTree2Dataset") REQUIRE(schema->field(4)->type()->id() == arrow::int32()->id()); REQUIRE(schema->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + REQUIRE(schema->field(7)->type()->id() == arrow::boolean()->id()); + REQUIRE(schema->field(8)->type()->id() == arrow::fixed_size_list(arrow::boolean(), 2)->id()); + auto fragment = format->MakeFragment(source, {}, schema); REQUIRE(fragment.ok()); auto options = std::make_shared(); @@ -356,7 +448,7 @@ TEST_CASE("RootTree2Dataset") auto batches = (*scanner)(); auto result = batches.result(); REQUIRE(result.ok()); - REQUIRE((*result)->columns().size() == 7); + REQUIRE((*result)->columns().size() == 9); REQUIRE((*result)->num_rows() == 100); { @@ -394,14 +486,16 @@ TEST_CASE("RootTree2Dataset") auto* output = new TMemFile("foo", "RECREATE"); auto outFs = std::make_shared(output, 0); - arrow::fs::FileLocator locator{outFs, "/DF_3"}; - auto destination = outFs->OpenOutputStream(locator.path, {}); + // Open a stream at toplevel + auto destination = outFs->OpenOutputStream("/", {}); REQUIRE(destination.ok()); + // Write to the /DF_3 tree at top level + arrow::fs::FileLocator locator{outFs, "/DF_3"}; auto writer = format->MakeWriter(*destination, schema, {}, locator); auto success = writer->get()->Write(*result); - auto rootDestination = std::dynamic_pointer_cast(*destination); + auto rootDestination = std::dynamic_pointer_cast(*destination); REQUIRE(success.ok()); // Let's read it back... @@ -413,14 +507,7 @@ TEST_CASE("RootTree2Dataset") auto schemaOptWritten = format->Inspect(source); REQUIRE(schemaOptWritten.ok()); auto schemaWritten = *schemaOptWritten; - REQUIRE(schemaWritten->num_fields() == 7); - REQUIRE(schemaWritten->field(0)->type()->id() == arrow::float32()->id()); - REQUIRE(schemaWritten->field(1)->type()->id() == arrow::float32()->id()); - REQUIRE(schemaWritten->field(2)->type()->id() == arrow::float32()->id()); - REQUIRE(schemaWritten->field(3)->type()->id() == arrow::float64()->id()); - REQUIRE(schemaWritten->field(4)->type()->id() == arrow::int32()->id()); - REQUIRE(schemaWritten->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); - REQUIRE(schemaWritten->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); + REQUIRE(validateSchema(schemaWritten)); auto fragmentWritten = format->MakeFragment(source, {}, schema); REQUIRE(fragmentWritten.ok()); @@ -431,39 +518,10 @@ TEST_CASE("RootTree2Dataset") auto batchesWritten = (*scanner)(); auto resultWritten = batches.result(); REQUIRE(resultWritten.ok()); - REQUIRE((*resultWritten)->columns().size() == 7); + REQUIRE((*resultWritten)->columns().size() == 9); REQUIRE((*resultWritten)->num_rows() == 100); + validateContents(*resultWritten); { - auto int_array = std::static_pointer_cast((*resultWritten)->GetColumnByName("ev")); - for (int64_t j = 0; j < int_array->length(); j++) { - REQUIRE(int_array->Value(j) == j + 1); - } - } - - { - auto list_array = std::static_pointer_cast((*result)->GetColumnByName("xyz")); - - // Iterate over the FixedSizeListArray - for (int64_t i = 0; i < list_array->length(); i++) { - auto value_slice = list_array->value_slice(i); - auto float_array = std::static_pointer_cast(value_slice); - - REQUIRE(float_array->Value(0) == 1); - REQUIRE(float_array->Value(1) == 2); - REQUIRE(float_array->Value(2) == i + 1); - } - } - - { - auto list_array = std::static_pointer_cast((*result)->GetColumnByName("ij")); - - // Iterate over the FixedSizeListArray - for (int64_t i = 0; i < list_array->length(); i++) { - auto value_slice = list_array->value_slice(i); - auto int_array = std::static_pointer_cast(value_slice); - REQUIRE(int_array->Value(0) == i); - REQUIRE(int_array->Value(1) == i + 1); - } } } From 4f7d71b64ef2a208e49afa8d4aa6a65bd0ef247a Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sun, 24 Nov 2024 18:08:34 +0100 Subject: [PATCH 0511/2205] GPU: fix bug when filling subthreshold clusters --- GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx index 0b1c282f3b2f0..d817278404534 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx @@ -223,7 +223,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ bool dodEdx = param.par.dodEdx && param.dodEdxDownscaled && param.rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg; dodEdx = AttachClustersPropagate(merger, cluster.slice, lastRow, cluster.row, iTrk, cluster.leg == clusters[maxN - 1].leg, prop, inFlyDirection, GPUCA_MAX_SIN_PHI, dodEdx); if (dodEdx) { - dEdx.fillSubThreshold(lastRow - 1, param); + dEdx.fillSubThreshold(lastRow - wayDirection, param); } } From 5c590eb06f53a038928950fa8cb858280325ca6d Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 25 Nov 2024 10:44:46 +0100 Subject: [PATCH 0512/2205] ITS: TrackExtensionStudy (#13568) * ITS: Tracker add constexpr Signed-off-by: Felix Schlepper * ITS: TrackExtension fix dangling reference on vector reallocation Signed-off-by: Felix Schlepper * ITS: TrackExtensionStudy add missed/empty cluster patterns Signed-off-by: Felix Schlepper * ITS: TrackExtensionStudy require MC Signed-off-by: Felix Schlepper * ITS: TrackExtensionStudy Efficiencies Signed-off-by: Felix Schlepper * ITS: TrackerTraits getBinsRect mark as const Signed-off-by: Felix Schlepper * ITS: TrackerTraits mark getEmptyBinsRect as consteval Avoid invalid read on first call. Signed-off-by: Felix Schlepper * ITS: TrackerTraits move function for readability Signed-off-by: Felix Schlepper * ITS: TrackExtensionStudy more plots * ITS: TrackerTraits: getBinsRect check layer requested * ITS: TrackExtension allow steering of cuts&directions * ITS: TrackExtension switch to fmt for macos --------- Signed-off-by: Felix Schlepper --- .../ITS/postprocessing/studies/CMakeLists.txt | 4 +- .../include/ITSStudies/TrackExtension.h | 2 +- .../studies/macros/CMakeLists.txt | 16 + .../studies/macros/PostTrackExtension.notest | 629 ++++++++++++++++++ .../studies/src/TrackExtension.cxx | 358 +++++++--- .../standalone-postprocessing-workflow.cxx | 7 +- .../include/ITStracking/Configuration.h | 8 +- .../tracking/include/ITStracking/Tracker.h | 2 +- .../include/ITStracking/TrackerTraits.h | 36 +- .../include/ITStracking/TrackingConfigParam.h | 4 +- .../tracking/include/ITStracking/Vertexer.h | 2 +- Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx | 16 +- .../ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 49 +- 13 files changed, 988 insertions(+), 145 deletions(-) create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/macros/CMakeLists.txt create mode 100644 Detectors/ITSMFT/ITS/postprocessing/studies/macros/PostTrackExtension.notest diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt index 361ab4db4fb8e..9794b69631d57 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/CMakeLists.txt @@ -30,4 +30,6 @@ o2_target_root_dictionary(ITSPostprocessing HEADERS include/ITSStudies/ITSStudiesConfigParam.h include/ITSStudies/TrackCuts.h include/ITSStudies/TrackMethods.h -LINKDEF src/ITSStudiesLinkDef.h) \ No newline at end of file +LINKDEF src/ITSStudiesLinkDef.h) + +add_subdirectory(macros) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h index 2567000746559..fd5b93b0f9509 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/TrackExtension.h @@ -24,7 +24,7 @@ class MCKinematicsReader; namespace its::study { using mask_t = o2::dataformats::GlobalTrackID::mask_t; -o2::framework::DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader); +o2::framework::DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, std::shared_ptr kineReader); } // namespace its::study } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/macros/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/studies/macros/CMakeLists.txt new file mode 100644 index 0000000000000..2d78e4077ec53 --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/macros/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +# o2_add_test_root_macro( +# PostTrackExtension.C +# PUBLIC_LINK_LIBRARIES ROOT::Hist ROOT::RIO ROOT::Core ROOT::Gpad +# LABELS its-study +# COMPILE_ONLY) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/macros/PostTrackExtension.notest b/Detectors/ITSMFT/ITS/postprocessing/studies/macros/PostTrackExtension.notest new file mode 100644 index 0000000000000..4a7c9c4159a4b --- /dev/null +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/macros/PostTrackExtension.notest @@ -0,0 +1,629 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TStyle.h" +#include "TFile.h" +#include "TError.h" +#include "TColor.h" +#include "TCanvas.h" +#include "TH2D.h" +#include "TF1.h" +#include "TEfficiency.h" +#include "TMarker.h" +#include "TLegend.h" +#include "TTree.h" +#include "TLatex.h" + +#include +#include +#include +#endif + +static constexpr std::array bitPatternsBefore{15, 30, 31, 60, 62, 63, 120, 124, 126}; +static constexpr std::array bitPatternsAfter{31, 47, 61, 62, 63, 79, 94, 95, 111, 121, 122, 123, 124, 125, 126, 127}; +inline bool bitsCleared(uint8_t b, uint8_t a) { return (a == b) ? true : (b & ~(a & b)) != 0; } +static constexpr std::array patternColors = { + kRed, // Red + kBlue, // Blue + kGreen, // Green + kMagenta, // Magenta + kCyan, // Cyan + kOrange, // Orange + kViolet, // Violet + kYellow, // Yellow + kPink, // Pink + kAzure, // Azure + kSpring, // Spring Green + kTeal, // Teal + kBlack, // Black + kGray, // Gray + kOrange + 7, // Light Orange + kBlue - 9 // Light Blue +}; + +// Marker styles +static constexpr std::array patternMarkers = { + 20, // Full circle + 21, // Full square + 22, // Full triangle up + 23, // Full triangle down + 24, // Open circle + 25, // Open square + 26, // Open triangle up + 27, // Open cross + 28, // Star + 29, // Plus sign + 30, // Open diamond + 31, // Full diamond + 32, // Cross + 33, // Circle with cross + 34, // X sign + 35 // Double open cross +}; + +enum Labels : unsigned int { + eAll = 0, + eGood, + eFake, + eFakeBefore, + eFakeAfter, + eFakeMix, + eTopGood, + eBotGood, + eMixGood, + eTopFake, + eBotFake, + eMixFake, + eN, +}; +static const std::array names{ + "ALL #frac{ext trks}{all trks}", + "GOOD #frac{good ext trks}{all ext trks}", + "FAKE #frac{fake trks}{all ext trks}", + "FAKE BF #frac{fake bf trks}{fake ext trks}", + "FAKE AF #frac{fake af trks}{fake ext trks}", + "FAKE MIX #frac{fake mix trks}{fake ext trks}", + // Good Top/Bot/Mix + "TOP #frac{good top ext trks}{good ext trks}", + "BOT #frac{good bot ext trks}{good ext trks}", + "MIX #frac{good mix ext trks}{good ext trks}", + // Fake Top/Bot/Mix + "TOP #frac{fake top ext trks}{fake ext trks}", + "BOT #frac{fake bot ext trks}{fake ext trks}", + "MIX #frac{fake mix ext trks}{fake ext trks}", +}; +static const std::array colors{kBlack, kGreen, kRed, kCyan, kYellow, kAzure, + // Good Top/Bot/Mix + kBlue, kOrange, kPink, + // Fake Top/Bot/Mix + kBlue, kOrange, kPink}; +static const std::array markers{20, 21, 22, 23, 27, 28, + // Good Top/Bot/Mix + 29, 33, 39, + // Fake Top/Bot/Mix + 29, 33, 39}; +static const char* const texPtX = "#it{p}_{T} (GeV/#it{c})"; +static const char* const texEff = "Efficiency"; +static const char* const texPtRes = "#sigma(#Delta#it{p}_{T}/#it{p}_{T})"; +static const char* const texDCAxyRes = "#sigma(DCA_{#it{xy}}) (#mum)"; +static const char* const texDCAzRes = "#sigma(DCA_{#it{z}}) (#mum)"; +static const char* const fitOpt{"QWMER"}; + +void setStyle(); +TEfficiency* makeEff(TFile*, const char* num, const char* den); + +template +void style(T* t, Labels lab, TLegend* leg = nullptr) +{ + t->SetMarkerStyle(markers[lab]); + t->SetMarkerColor(colors[lab]); + t->SetLineColor(colors[lab]); + if (leg) { + leg->AddEntry(t, names[lab]); + } +} + +template +void stylePattern(T* t, int i, TLegend* leg = nullptr, const char* name = nullptr) +{ + t->SetMarkerStyle(patternMarkers[i]); + t->SetMarkerColor(patternColors[i]); + t->SetLineColor(patternColors[i]); + if (leg) { + leg->AddEntry(t, name); + } +} + +void PostTrackExtension(const char* fileName = "TrackExtensionStudy.root") +{ + setStyle(); + + std::unique_ptr fIn{TFile::Open(fileName, "READ")}; + if (!fIn || fIn->IsZombie()) { + Error("", "Cannot open file %s", fileName); + return; + } + + { // Purity & Fake-Rate + auto c = new TCanvas("cPFR", "", 800, 600); + auto h = c->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.35, 0.7, 0.7); + auto eff = fIn->Get("eExtension"); + style(eff, eAll, leg); + eff->Draw("same"); + auto effPurity = fIn->Get("eExtensionPurity"); + style(effPurity, eGood, leg); + effPurity->Draw("same"); + auto effFake = fIn->Get("eExtensionFake"); + style(effFake, eFake, leg); + effFake->Draw("same"); + leg->Draw(); + gPad->SetLogx(); + gPad->SetGrid(); + c->SaveAs("trkExt_purity_fake.pdf"); + } + + { // FAKE-Rate composition + auto c = new TCanvas("cFR", "", 800, 600); + auto h = c->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.35, 0.7, 0.7); + auto effFake = fIn->Get("eExtensionFake"); + style(effFake, eFake, leg); + effFake->Draw("same"); + auto effFakeBf = fIn->Get("eExtensionFakeBefore"); + style(effFakeBf, eFakeBefore, leg); + effFakeBf->Draw("same"); + auto effFakeAf = fIn->Get("eExtensionFakeAfter"); + style(effFakeAf, eFakeAfter, leg); + effFakeAf->Draw("same"); + auto effFakeMi = fIn->Get("eExtensionFakeMix"); + style(effFakeMi, eFakeMix, leg); + effFakeMi->Draw("same"); + leg->Draw(); + gPad->SetLogx(); + gPad->SetGrid(); + c->SaveAs("trkExt_fake.pdf"); + } + + { // GOOD Top/Bot/Mix Purity composition + auto c = new TCanvas("cGC", "", 800, 600); + auto h = c->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.35, 0.7, 0.7); + auto effTop = makeEff(fIn.get(), "eExtensionTopPurity", "eExtensionPurity"); + style(effTop, eTopGood, leg); + effTop->Draw("same"); + auto effBot = makeEff(fIn.get(), "eExtensionBotPurity", "eExtensionPurity"); + style(effBot, eBotGood, leg); + effBot->Draw("same"); + auto effMix = makeEff(fIn.get(), "eExtensionMixPurity", "eExtensionPurity"); + style(effMix, eMixGood, leg); + effMix->Draw("same"); + leg->Draw(); + gPad->SetLogx(); + gPad->SetGrid(); + c->SaveAs("trkExt_good_comp.pdf"); + } + + { // FAKE Top/Bot/Mix composition + auto c = new TCanvas("cFC", "", 800, 600); + auto h = c->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.35, 0.7, 0.7); + auto effTop = fIn->Get("eExtensionTopFake"); + style(effTop, eTopFake, leg); + effTop->Draw("same"); + auto effBot = fIn->Get("eExtensionBotFake"); + style(effBot, eBotFake, leg); + effBot->Draw("same"); + auto effMix = fIn->Get("eExtensionMixFake"); + style(effMix, eMixFake, leg); + effMix->Draw("same"); + leg->Draw(); + gPad->SetLogx(); + gPad->SetGrid(); + c->SaveAs("trkExt_fake_comp.pdf"); + } + + { // Good Patterns + auto c = new TCanvas("cPatGood", "", 3 * 800, 3 * 600); + c->Divide(3, 3); + for (int i{0}; i < (int)bitPatternsBefore.size(); ++i) { + auto p = c->cd(i + 1); + auto h = p->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.60, 0.7, 0.88); + leg->SetNColumns(4); + leg->SetHeader(std::format("BEFORE={:07b} GOOD Pattern AFTER/BEFORE", bitPatternsBefore[i]).c_str()); + for (int j{0}; j < (int)bitPatternsAfter.size(); ++j) { + if (bitsCleared(bitPatternsBefore[i], bitPatternsAfter[j])) { + continue; + } + auto eff = fIn->Get(std::format("eExtensionPatternGood_{:07b}_{:07b}", bitPatternsBefore[i], bitPatternsAfter[j]).c_str()); + stylePattern(eff, j, leg, std::format("{:07b}", bitPatternsAfter[j]).c_str()); + eff->Draw("same"); + } + leg->Draw(); + p->SetLogx(); + p->SetGrid(); + } + c->SaveAs("trkExt_good_pattern_comp.pdf"); + } + + { // Fake Patterns + auto c = new TCanvas("cPatFake", "", 3 * 800, 3 * 600); + c->Divide(3, 3); + for (int i{0}; i < (int)bitPatternsBefore.size(); ++i) { + auto p = c->cd(i + 1); + auto h = p->DrawFrame(0.05, 0.0, 10., 1.05); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texEff); + auto leg = new TLegend(0.35, 0.60, 0.7, 0.88); + leg->SetNColumns(4); + leg->SetHeader(std::format("BEFORE={:07b} FAKE Pattern AFTER/BEFORE", bitPatternsBefore[i]).c_str()); + for (int j{0}; j < (int)bitPatternsAfter.size(); ++j) { + if (bitsCleared(bitPatternsBefore[i], bitPatternsAfter[j])) { + continue; + } + auto eff = fIn->Get(std::format("eExtensionPatternFake_{:07b}_{:07b}", bitPatternsBefore[i], bitPatternsAfter[j]).c_str()); + stylePattern(eff, j, leg, std::format("{:07b}", bitPatternsAfter[j]).c_str()); + eff->Draw("same"); + } + leg->Draw(); + p->SetLogx(); + p->SetGrid(); + } + c->SaveAs("trkExt_fake_pattern_comp.pdf"); + } + + { // DCA + auto fGaus = new TF1("fGaus", "gaus", -200., 200.); + auto dcaXYVsPtNo = fIn->Get("hDCAxyVsPtResNormal"); + auto dcaXYVsPtYes = fIn->Get("hDCAxyVsPtResExtended"); + auto dcazVsPtNo = fIn->Get("hDCAzVsPtResNormal"); + auto dcazVsPtYes = fIn->Get("hDCAzVsPtResExtended"); + auto bins = dcazVsPtNo->GetXaxis()->GetXbins(); + auto dcaXYResNo = new TH1F("hDcaxyResNo", "NORMAL;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{xy}}) (#mum)", bins->GetSize() - 1, bins->GetArray()); + auto dcaXYResYes = new TH1F("hDcaxyResYes", "EXTENDED;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{xy}}) (#mum)", bins->GetSize() - 1, bins->GetArray()); + auto dcaZResNo = new TH1F("hDcazResNo", "NORMAL;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{z}}) (#mum)", bins->GetSize() - 1, bins->GetArray()); + auto dcaZResYes = new TH1F("hDcazResYes", "EXTENDED;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{z}}) (#mum)", bins->GetSize() - 1, bins->GetArray()); + TH1* proj; + for (int iPt{1}; iPt <= bins->GetSize(); ++iPt) { + auto ptMin = dcaXYResNo->GetXaxis()->GetBinLowEdge(iPt); + if (ptMin < 0.1) { + continue; + } + float minFit = (ptMin < 1.) ? -200. : -75.; + float maxFit = (ptMin < 1.) ? 200. : 75.; + + proj = dcaXYVsPtNo->ProjectionY(Form("hProjDCAxy_no_%d", iPt), iPt, iPt); + proj->Fit("fGaus", fitOpt, "", minFit, maxFit); + dcaXYResNo->SetBinContent(iPt, fGaus->GetParameter(2)); + dcaXYResNo->SetBinError(iPt, fGaus->GetParError(2)); + + proj = dcaXYVsPtYes->ProjectionY(Form("hProjDCAxy_yes_%d", iPt), iPt, iPt); + proj->Fit("fGaus", fitOpt, "", minFit, maxFit); + dcaXYResYes->SetBinContent(iPt, fGaus->GetParameter(2)); + dcaXYResYes->SetBinError(iPt, fGaus->GetParError(2)); + + proj = dcazVsPtNo->ProjectionY(Form("hProjDCAz_no_%d", iPt), iPt, iPt); + proj->Fit("fGaus", fitOpt, "", minFit, maxFit); + dcaZResNo->SetBinContent(iPt, fGaus->GetParameter(2)); + dcaZResNo->SetBinError(iPt, fGaus->GetParError(2)); + + proj = dcazVsPtYes->ProjectionY(Form("hProjDCAz_yes_%d", iPt), iPt, iPt); + proj->Fit("fGaus", fitOpt, "", minFit, maxFit); + dcaZResYes->SetBinContent(iPt, fGaus->GetParameter(2)); + dcaZResYes->SetBinError(iPt, fGaus->GetParError(2)); + } + + dcaXYResNo->SetLineColor(kRed); + dcaXYResNo->SetMarkerColor(kRed); + dcaXYResYes->SetLineColor(kBlue); + dcaXYResYes->SetMarkerColor(kBlue); + dcaZResNo->SetLineColor(kRed); + dcaZResNo->SetMarkerColor(kRed); + dcaZResYes->SetLineColor(kBlue); + dcaZResYes->SetMarkerColor(kBlue); + + auto c = new TCanvas("cDCA", "", 2 * 800, 600); + c->Divide(2, 1); + c->cd(1); + auto h = gPad->DrawFrame(0.1, 1, 10., 500); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texDCAxyRes); + dcaXYResNo->Draw("SAME"); + dcaXYResYes->Draw("SAME"); + gPad->SetLogx(); + gPad->SetLogy(); + gPad->SetGrid(); + auto leg = new TLegend(0.20, 0.20, 0.40, 0.40); + leg->AddEntry(dcaXYResNo, "Normal"); + leg->AddEntry(dcaXYResYes, "Extended"); + leg->Draw(); + + c->cd(2); + h = gPad->DrawFrame(0.1, 1, 10., 500); + h->GetXaxis()->SetTitle(texPtX); + h->GetYaxis()->SetTitle(texDCAzRes); + dcaZResNo->Draw("SAME"); + dcaZResYes->Draw("SAME"); + gPad->SetLogx(); + gPad->SetLogy(); + gPad->SetGrid(); + + c->SaveAs("trkExt_dca.pdf"); + } + + return; + { // Kinematic variables + auto t = fIn->Get("tree"); + auto c = new TCanvas("cKG", "", 800, 600); + c->Divide(3, 2); + { + auto p = c->cd(1); + p->SetGrid(); + auto h = p->DrawFrame(-.6, 0., .6, 9.); + h->GetXaxis()->SetTitle("#frac{Q^{2}}{p_{T,TRK}}-#frac{Q^{2}}{p_{T,MC}}"); + h->GetYaxis()->SetTitle("n. counts"); + t->Draw("trk.getQ2Pt()-mcTrk.getQ2Pt()>>hPtNo(100,-.6,.6)", "isGood&&!isExtended", "HIST;SAME"); + auto hNo = (TH1F*)p->GetPrimitive("hPtNo"); + hNo->Scale(1.0 / hNo->Integral("width")); + hNo->SetLineColor(kRed); + auto fitNo = new TF1("fitNo", "gaus", -0.04, 0.04); + hNo->Fit(fitNo, "QR"); + fitNo->SetLineColor(kRed); + fitNo->Draw("SAME"); + auto textNo = new TLatex(-0.55, 8.2, Form("#mu = %.3f, #sigma = %.3f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textNo->SetTextColor(kRed); + textNo->SetNDC(false); + textNo->SetTextSize(0.05); + textNo->Draw(); + + t->Draw("trk.getQ2Pt()-mcTrk.getQ2Pt()>>hPtYes(100,-.6,.6)", "isGood&&isExtended", "HIST;SAME"); + auto hYes = (TH1F*)p->GetPrimitive("hPtYes"); + hYes->Scale(1.0 / hYes->Integral("width")); + hYes->SetLineColor(kBlue); + auto fitYes = new TF1("fitYes", "gaus", -0.04, 0.04); + hYes->Fit(fitYes, "QR"); + fitYes->SetLineColor(kBlue); + fitYes->Draw("SAME"); + auto textYes = new TLatex(-0.55, 7, Form("#mu = %.4f, #sigma = %.4f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textYes->SetTextColor(kBlue); + textYes->SetNDC(false); + textYes->SetTextSize(0.05); + textYes->Draw(); + + p->Modified(); + p->Update(); + } + { + auto p = c->cd(2); + p->SetGrid(); + auto h = p->DrawFrame(-3, 0., 3, 2.); + h->GetXaxis()->SetTitle("Y_{TRK}-Y_{MC}"); + h->GetYaxis()->SetTitle("n. counts"); + t->Draw("trk.getY()-mcTrk.getY()>>hYNo(100,-3,3)", "isGood&&!isExtended", "HIST;SAME"); + auto hNo = (TH1F*)p->GetPrimitive("hYNo"); + hNo->Scale(1.0 / hNo->Integral("width")); + hNo->SetLineColor(kRed); + auto fitNo = new TF1("fitNo", "gaus", -0.5, 0.5); + hNo->Fit(fitNo, "QR"); + fitNo->SetLineColor(kRed); + fitNo->Draw("SAME"); + auto textNo = new TLatex(-2, 1.7, Form("#mu = %.3f, #sigma = %.3f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textNo->SetTextColor(kRed); + textNo->SetNDC(false); + textNo->SetTextSize(0.05); + textNo->Draw(); + + t->Draw("trk.getY()-mcTrk.getY()>>hYYes(100,-3,3)", "isGood&&isExtended", "HIST;SAME"); + auto hYes = (TH1F*)p->GetPrimitive("hYYes"); + hYes->Scale(1.0 / hYes->Integral("width")); + hYes->SetLineColor(kBlue); + auto fitYes = new TF1("fitYes", "gaus", -0.5, 0.5); + hYes->Fit(fitYes, "QR"); + fitYes->SetLineColor(kBlue); + fitYes->Draw("SAME"); + auto textYes = new TLatex(-2, 1.5, Form("#mu = %.4f, #sigma = %.4f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textYes->SetTextColor(kBlue); + textYes->SetNDC(false); + textYes->SetTextSize(0.05); + textYes->Draw(); + + p->Modified(); + p->Update(); + } + { + auto p = c->cd(3); + p->SetGrid(); + auto h = p->DrawFrame(-2, 0., 2, 4.2); + h->GetXaxis()->SetTitle("Z_{TRK}-Z_{MC}"); + h->GetYaxis()->SetTitle("n. counts"); + t->Draw("trk.getZ()-mcTrk.getZ()>>hZNo(100,-2,2)", "isGood&&!isExtended", "HIST;SAME"); + auto hNo = (TH1F*)p->GetPrimitive("hZNo"); + hNo->Scale(1.0 / hNo->Integral("width")); + hNo->SetLineColor(kRed); + auto fitNo = new TF1("fitNo", "gaus", -0.2, 0.2); + hNo->Fit(fitNo, "QR"); + fitNo->SetLineColor(kRed); + fitNo->Draw("SAME"); + auto textNo = new TLatex(-1.7, 3.8, Form("#mu = %.3f, #sigma = %.3f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textNo->SetTextColor(kRed); + textNo->SetNDC(false); + textNo->SetTextSize(0.05); + textNo->Draw(); + + t->Draw("trk.getZ()-mcTrk.getZ()>>hZYes(100,-2,2)", "isGood&&isExtended", "HIST;SAME"); + auto hYes = (TH1F*)p->GetPrimitive("hZYes"); + hYes->Scale(1.0 / hYes->Integral("width")); + hYes->SetLineColor(kBlue); + auto fitYes = new TF1("fitYes", "gaus", -0.2, 0.2); + hYes->Fit(fitYes, "QR"); + fitYes->SetLineColor(kBlue); + fitYes->Draw("SAME"); + auto textYes = new TLatex(-1.7, 3.5, Form("#mu = %.4f, #sigma = %.4f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textYes->SetTextColor(kBlue); + textYes->SetNDC(false); + textYes->SetTextSize(0.05); + textYes->Draw(); + + p->Modified(); + p->Update(); + } + { + auto p = c->cd(4); + p->SetGrid(); + auto h = p->DrawFrame(-0.02, 0., 0.02, 370.); + h->GetXaxis()->SetTitle("TGL_{TRK}-TGL_{MC}"); + h->GetYaxis()->SetTitle("n. counts"); + t->Draw("trk.getTgl()-mcTrk.getTgl()>>hTglNo(100,-0.02,0.02)", "isGood&&!isExtended", "HIST;SAME"); + auto hNo = (TH1F*)p->GetPrimitive("hTglNo"); + hNo->Scale(1.0 / hNo->Integral("width")); + hNo->SetLineColor(kRed); + auto fitNo = new TF1("fitNo", "gaus", -0.003, 0.003); + hNo->Fit(fitNo, "QR"); + fitNo->SetLineColor(kRed); + fitNo->Draw("SAME"); + auto textNo = new TLatex(-0.018, 330, Form("#mu = %.3f, #sigma = %.3f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textNo->SetTextColor(kRed); + textNo->SetNDC(false); + textNo->SetTextSize(0.05); + textNo->Draw(); + + t->Draw("trk.getTgl()-mcTrk.getTgl()>>hTglYes(100,-0.02,0.02)", "isGood&&isExtended", "HIST;SAME"); + auto hYes = (TH1F*)p->GetPrimitive("hTglYes"); + hYes->Scale(1.0 / hYes->Integral("width")); + hYes->SetLineColor(kBlue); + auto fitYes = new TF1("fitYes", "gaus", -0.003, 0.003); + hYes->Fit(fitYes, "QR"); + fitYes->SetLineColor(kBlue); + fitYes->Draw("SAME"); + auto textYes = new TLatex(-0.018, 310, Form("#mu = %.6f, #sigma = %.6f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textYes->SetTextColor(kBlue); + textYes->SetNDC(false); + textYes->SetTextSize(0.05); + textYes->Draw(); + + p->Modified(); + p->Update(); + } + { + auto p = c->cd(5); + p->SetGrid(); + auto h = p->DrawFrame(-0.08, 0., 0.08, 80.); + h->GetXaxis()->SetTitle("SNP_{TRK}-SNP_{MC}"); + h->GetYaxis()->SetTitle("n. counts"); + t->Draw("trk.getSnp()-mcTrk.getSnp()>>hSnpNo(100,-0.08,0.08)", "isGood&&!isExtended", "HIST;SAME"); + auto hNo = (TH1F*)p->GetPrimitive("hSnpNo"); + hNo->Scale(1.0 / hNo->Integral("width")); + hNo->SetLineColor(kRed); + auto fitNo = new TF1("fitNo", "gaus", -0.03, 0.03); + hNo->Fit(fitNo, "QR"); + fitNo->SetLineColor(kRed); + fitNo->Draw("SAME"); + auto textNo = new TLatex(-0.07, 72, Form("#mu = %.3f, #sigma = %.3f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textNo->SetTextColor(kRed); + textNo->SetNDC(false); + textNo->SetTextSize(0.05); + textNo->Draw(); + + t->Draw("trk.getSnp()-mcTrk.getSnp()>>hSnpYes(100,-0.08,0.08)", "isGood&&isExtended", "HIST;SAME"); + auto hYes = (TH1F*)p->GetPrimitive("hSnpYes"); + hYes->Scale(1.0 / hYes->Integral("width")); + hYes->SetLineColor(kBlue); + auto fitYes = new TF1("fitYes", "gaus", -0.03, 0.03); + hYes->Fit(fitYes, "QR"); + fitYes->SetLineColor(kBlue); + fitYes->Draw("SAME"); + auto textYes = new TLatex(-0.07, 66, Form("#mu = %.6f, #sigma = %.6f", fitNo->GetParameter(1), fitNo->GetParameter(2))); + textYes->SetTextColor(kBlue); + textYes->SetNDC(false); + textYes->SetTextSize(0.05); + textYes->Draw(); + + p->Modified(); + p->Update(); + } + { + auto p = c->cd(6); + auto legend = new TLegend(0.2, 0.2, 0.8, 0.8); + legend->SetTextSize(0.06); + legend->SetLineWidth(3); + legend->SetHeader("GOOD tracks", "C"); + auto mBlue = new TMarker(); + mBlue->SetMarkerColor(kBlue); + mBlue->SetMarkerSize(4); + legend->AddEntry(mBlue, "extended", "p"); + auto mRed = new TMarker(); + mRed->SetMarkerColor(kRed); + mRed->SetMarkerSize(4); + legend->AddEntry(mRed, "normal", "p"); + legend->SetLineColor(kRed); + legend->Draw(); + } + c->SaveAs("trkExt_kinematics.pdf"); + } +} + +void setStyle() +{ + gStyle->Reset("Plain"); + gStyle->SetOptTitle(0); + gStyle->SetOptStat(0); + gStyle->SetPalette(kRainbow); + gStyle->SetCanvasColor(10); + gStyle->SetCanvasBorderMode(0); + gStyle->SetFrameLineWidth(1); + gStyle->SetFrameFillColor(kWhite); + gStyle->SetPadColor(10); + gStyle->SetPadTickX(1); + gStyle->SetPadTickY(1); + gStyle->SetPadBottomMargin(0.15); + gStyle->SetPadLeftMargin(0.15); + gStyle->SetHistLineWidth(1); + gStyle->SetHistLineColor(kRed); + gStyle->SetFuncWidth(2); + gStyle->SetFuncColor(kGreen); + gStyle->SetLineWidth(2); + gStyle->SetLabelSize(0.045, "xyz"); + gStyle->SetLabelOffset(0.01, "y"); + gStyle->SetLabelOffset(0.01, "x"); + gStyle->SetLabelColor(kBlack, "xyz"); + gStyle->SetTitleSize(0.05, "xyz"); + gStyle->SetTitleOffset(1.25, "y"); + gStyle->SetTitleOffset(1.2, "x"); + gStyle->SetTitleFillColor(kWhite); + gStyle->SetTextSizePixels(26); + gStyle->SetTextFont(42); + gStyle->SetTickLength(0.04, "X"); + gStyle->SetTickLength(0.04, "Y"); + gStyle->SetLegendBorderSize(0); + gStyle->SetLegendFillColor(kWhite); + gStyle->SetFillColor(kWhite); + gStyle->SetLegendFont(42); +} + +TEfficiency* makeEff(TFile* fIn, const char* num, const char* den) +{ + auto h1 = fIn->Get(num)->GetPassedHistogram(); + auto h2 = fIn->Get(den)->GetPassedHistogram(); + auto e = new TEfficiency(*h1, *h2); + return e; +} diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx index 364a354c700b6..465365ffa3d86 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/TrackExtension.cxx @@ -14,17 +14,24 @@ #include "DataFormatsITS/TrackITS.h" #include "DataFormatsITSMFT/CompCluster.h" #include "DetectorsBase/GRPGeomHelper.h" +#include "DetectorsBase/Propagator.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/Task.h" #include "ITSBase/GeometryTGeo.h" #include "ITSStudies/Helpers.h" #include "ITSStudies/TrackExtension.h" +#include "SimulationDataFormat/MCEventHeader.h" #include "SimulationDataFormat/MCTrack.h" #include "Steer/MCKinematicsReader.h" +#include "ReconstructionDataFormats/Vertex.h" +#include "ReconstructionDataFormats/DCA.h" #include #include "TFile.h" +#include "TH1D.h" +#include "TH2D.h" +#include "TEfficiency.h" namespace o2::its::study { @@ -36,7 +43,9 @@ using o2::steer::MCKinematicsReader; class TrackExtensionStudy : public Task { struct ParticleInfo { - int event; + float eventX; + float eventY; + float eventZ; int pdg; float pt; float eta; @@ -60,24 +69,24 @@ class TrackExtensionStudy : public Task public: TrackExtensionStudy(std::shared_ptr dr, mask_t src, - bool useMC, std::shared_ptr kineReader, std::shared_ptr gr) : mDataRequest(dr), mTracksSrc(src), mKineReader(kineReader), mGGCCDBRequest(gr) { - if (useMC) { - LOGP(info, "Read MCKine reader with {} sources", mKineReader->getNSources()); - } + LOGP(info, "Read MCKine reader with {} sources", mKineReader->getNSources()); } ~TrackExtensionStudy() final = default; void init(InitContext& /*ic*/) final; void run(ProcessingContext& /*pc*/) final; void endOfStream(EndOfStreamContext& /*ec*/) final; + void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final; void process(); private: static constexpr std::array mBitPatternsBefore{15, 30, 31, 60, 62, 63, 120, 124, 126}; static constexpr std::array mBitPatternsAfter{31, 47, 61, 62, 63, 79, 94, 95, 111, 121, 122, 123, 124, 125, 126, 127}; + const std::bitset<7> mTopMask{"1110000"}; + const std::bitset<7> mBotMask{"0000111"}; void updateTimeDependentParams(ProcessingContext& pc); std::string mOutFileName = "TrackExtensionStudy.root"; @@ -101,12 +110,30 @@ class TrackExtensionStudy : public Task bool mWithTree{false}; std::unique_ptr mHTrackCounts; - std::unique_ptr mHClustersCounts; std::unique_ptr mHLengthAny, mHLengthGood, mHLengthFake; std::unique_ptr mHChi2Any, mHChi2Good, mHChi2Fake; std::unique_ptr mHPtAny, mHPtGood, mHPtFake; std::unique_ptr mHExtensionAny, mHExtensionGood, mHExtensionFake; - std::unique_ptr mHExtensionPatternsAny, mHExtensionPatternsGood, mHExtensionPatternsFake; + std::unique_ptr mHExtensionPatternsAny, mHExtensionPatternsGood, mHExtensionPatternsFake, mHExtensionPatternsGoodMissed, mHExtensionPatternsGoodEmpty; + std::unique_ptr mEExtensionNum, mEExtensionDen, mEExtensionPurityNum, mEExtensionPurityDen, mEExtensionFakeNum, mEExtensionFakeDen; + std::unique_ptr mEExtensionFakeBeforeNum, mEExtensionFakeAfterNum, mEExtensionFakeMixNum; + std::unique_ptr mEExtensionTopNum, mEExtensionTopPurityNum, mEExtensionTopFakeNum; + std::unique_ptr mEExtensionBotNum, mEExtensionBotPurityNum, mEExtensionBotFakeNum; + std::unique_ptr mEExtensionMixNum, mEExtensionMixPurityNum, mEExtensionMixFakeNum; + std::array, mBitPatternsBefore.size()> mEExtensionPatternGoodNum, mEExtensionPatternFakeNum; + std::array, mBitPatternsAfter.size()>, mBitPatternsBefore.size()> mEExtensionPatternIndGoodNum, mEExtensionPatternIndFakeNum; + // DCA + std::unique_ptr mDCAxyVsPtPionsNormal, mDCAxyVsPtPionsExtended; + std::unique_ptr mDCAzVsPtPionsNormal, mDCAzVsPtPionsExtended; + + template + std::unique_ptr createHistogram(C... n, F... b) + { + auto t = std::make_unique(n..., b...); + mHistograms.push_back(static_cast(t.get())); + return std::move(t); + } + std::vector mHistograms; }; void TrackExtensionStudy::init(InitContext& ic) @@ -114,13 +141,13 @@ void TrackExtensionStudy::init(InitContext& ic) o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); mWithTree = ic.options().get("with-tree"); - constexpr size_t effHistBins = 100; + constexpr size_t effHistBins = 40; constexpr float effPtCutLow = 0.01; constexpr float effPtCutHigh = 10.; auto xbins = helpers::makeLogBinning(effHistBins, effPtCutLow, effPtCutHigh); // Track Counting - mHTrackCounts = std::make_unique("hTrackCounts", "Track Stats", 10, 0, 10); + mHTrackCounts = createHistogram("hTrackCounts", "Track Stats", 10, 0, 10); mHTrackCounts->GetXaxis()->SetBinLabel(1, "Total Tracks"); mHTrackCounts->GetXaxis()->SetBinLabel(2, "Normal ANY Tracks"); mHTrackCounts->GetXaxis()->SetBinLabel(3, "Normal GOOD Tracks"); @@ -132,49 +159,87 @@ void TrackExtensionStudy::init(InitContext& ic) mHTrackCounts->GetXaxis()->SetBinLabel(9, "Extended FAKE AFTER Tracks"); mHTrackCounts->GetXaxis()->SetBinLabel(10, "Extended FAKE BEFORE&AFTER Tracks"); - // Cluster Counting - mHClustersCounts = std::make_unique("hClusterCounts", "Cluster Stats", 5, 0, 5); - mHClustersCounts->GetXaxis()->SetBinLabel(1, "Total Clusters"); - mHClustersCounts->GetXaxis()->SetBinLabel(2, "Tracking"); - mHClustersCounts->GetXaxis()->SetBinLabel(3, "Extension"); - mHClustersCounts->GetXaxis()->SetBinLabel(4, "Good Extension"); - mHClustersCounts->GetXaxis()->SetBinLabel(5, "Fake Extension"); - // Length - mHLengthAny = std::make_unique("hLengthAny", "Extended Tracks Length (ANY);NCluster;Entries", 5, 3, 8); - mHLengthGood = std::make_unique("hLengthGood", "Extended Tracks Length (GOOD);NCluster;Entries", 5, 3, 8); - mHLengthFake = std::make_unique("hLengthFake", "Extended Tracks Length (FAKE);NCluster;Entries", 5, 3, 8); + mHLengthAny = createHistogram("hLengthAny", "Extended Tracks Length (ANY);NCluster;Entries", 5, 3, 8); + mHLengthGood = createHistogram("hLengthGood", "Extended Tracks Length (GOOD);NCluster;Entries", 5, 3, 8); + mHLengthFake = createHistogram("hLengthFake", "Extended Tracks Length (FAKE);NCluster;Entries", 5, 3, 8); // Chi2 - mHChi2Any = std::make_unique("hChi2Any", "Extended Tracks Length (ANY);#chi^{2};Entries", 50, 0, 100); - mHChi2Good = std::make_unique("hChi2Good", "Extended Tracks Length (GOOD);#chi^{2};Entries", 50, 0, 100); - mHChi2Fake = std::make_unique("hChi2Fake", "Extended Tracks Length (FAKE);#chi^{2};Entries", 50, 0, 100); + mHChi2Any = createHistogram("hChi2Any", "Extended Tracks Length (ANY);#chi^{2};Entries", 50, 0, 100); + mHChi2Good = createHistogram("hChi2Good", "Extended Tracks Length (GOOD);#chi^{2};Entries", 50, 0, 100); + mHChi2Fake = createHistogram("hChi2Fake", "Extended Tracks Length (FAKE);#chi^{2};Entries", 50, 0, 100); // Pt - mHPtAny = std::make_unique("hPtAny", "Extended Tracks Length (ANY);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); - mHPtGood = std::make_unique("hPtGood", "Extended Tracks Length (GOOD);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); - mHPtFake = std::make_unique("hPtFake", "Extended Tracks Length (FAKE);#it{p}_{T};Entries", xbins.size(), effPtCutLow, effPtCutHigh); + mHPtAny = createHistogram("hPtAny", "Extended Tracks Length (ANY);#it{p}_{T};Entries", effHistBins, xbins.data()); + mHPtGood = createHistogram("hPtGood", "Extended Tracks Length (GOOD);#it{p}_{T};Entries", effHistBins, xbins.data()); + mHPtFake = createHistogram("hPtFake", "Extended Tracks Length (FAKE);#it{p}_{T};Entries", effHistBins, xbins.data()); // Length - mHExtensionAny = std::make_unique("hExtensionAny", "Extended Tracks Length (ANY);Extended Layer;Entries", 7, 0, 7); - mHExtensionGood = std::make_unique("hExtensionGood", "Extended Tracks Length (GOOD);Extended Layer;Entries", 7, 0, 7); - mHExtensionFake = std::make_unique("hExtensionFake", "Extended Tracks Length (FAKE);Extended Layer;Entries", 7, 0, 7); + mHExtensionAny = createHistogram("hExtensionAny", "Extended Tracks Length (ANY);Extended Layer;Entries", 7, 0, 7); + mHExtensionGood = createHistogram("hExtensionGood", "Extended Tracks Length (GOOD);Extended Layer;Entries", 7, 0, 7); + mHExtensionFake = createHistogram("hExtensionFake", "Extended Tracks Length (FAKE);Extended Layer;Entries", 7, 0, 7); // Patterns - auto makePatternAxisLabels = [&](TH1* h) { + auto makePatternAxisLabels = [&](TH1* h, bool xBefore = true) { for (int i{1}; i <= h->GetXaxis()->GetNbins(); ++i) { - h->GetXaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsBefore[i - 1]).c_str()); + if (xBefore) { + h->GetXaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsBefore[i - 1]).c_str()); + } else { + h->GetXaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsAfter[i - 1]).c_str()); + } } for (int i{1}; i <= h->GetYaxis()->GetNbins(); ++i) { h->GetYaxis()->SetBinLabel(i, fmt::format("{:07b}", mBitPatternsAfter[i - 1]).c_str()); } }; - mHExtensionPatternsAny = std::make_unique("hExtensionPatternsAny", "Extended Tracks Pattern (ANY);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + mHExtensionPatternsAny = createHistogram("hExtensionPatternsAny", "Extended Tracks Pattern (ANY);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); makePatternAxisLabels(mHExtensionPatternsAny.get()); - mHExtensionPatternsGood = std::make_unique("hExtensionPatternsGood", "Extended Tracks Pattern (GOOD);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + mHExtensionPatternsGood = createHistogram("hExtensionPatternsGood", "Extended Tracks Pattern (GOOD);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); makePatternAxisLabels(mHExtensionPatternsGood.get()); - mHExtensionPatternsFake = std::make_unique("hExtensionPatternsFake", "Extended Tracks Pattern (FAKE);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + mHExtensionPatternsFake = createHistogram("hExtensionPatternsFake", "Extended Tracks Pattern (FAKE);Before;After;Entries", mBitPatternsBefore.size(), 0, mBitPatternsBefore.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); makePatternAxisLabels(mHExtensionPatternsFake.get()); + mHExtensionPatternsGoodMissed = createHistogram("hExtensionPatternsGoodMissed", "Extended Tracks Pattern (GOOD) Missed Clusters;After;Missed;Entries", mBitPatternsAfter.size(), 0, mBitPatternsAfter.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + makePatternAxisLabels(mHExtensionPatternsGoodMissed.get(), false); + mHExtensionPatternsGoodEmpty = createHistogram("hExtensionPatternsGoodEmpty", "Extended Tracks Pattern (GOOD) Empty Clusters;Before;After;Entries", mBitPatternsAfter.size(), 0, mBitPatternsAfter.size(), mBitPatternsAfter.size(), 0, mBitPatternsAfter.size()); + makePatternAxisLabels(mHExtensionPatternsGoodEmpty.get(), false); + + /// Effiencies + mEExtensionNum = createHistogram("hExtensionNum", "Extension Numerator", effHistBins, xbins.data()); + mEExtensionDen = createHistogram("hExtensionDen", "Extension Dennominator", effHistBins, xbins.data()); + // Purity + mEExtensionPurityNum = createHistogram("hExtensionPurityNum", "Extension Purity Numerator", effHistBins, xbins.data()); + mEExtensionPurityDen = createHistogram("hExtensionPurityDen", "Extension Purity Denominator", effHistBins, xbins.data()); + // Fake + mEExtensionFakeNum = createHistogram("hExtensionFakeNum", "Extension Fake Numerator", effHistBins, xbins.data()); + mEExtensionFakeDen = createHistogram("hExtensionFakeDen", "Extension Fake Denominator", effHistBins, xbins.data()); + mEExtensionFakeBeforeNum = createHistogram("hExtensionFakeBeforeNum", "Extension Fake Before Numerator", effHistBins, xbins.data()); + mEExtensionFakeAfterNum = createHistogram("hExtensionFakeAfterNum", "Extension Fake After Numerator", effHistBins, xbins.data()); + mEExtensionFakeMixNum = createHistogram("hExtensionFakeMixNum", "Extension Fake Mix Numerator", effHistBins, xbins.data()); + // Top + mEExtensionTopNum = createHistogram("hExtensionTopNum", "Extension Top Numerator", effHistBins, xbins.data()); + mEExtensionTopPurityNum = createHistogram("hExtensionTopPurityNum", "Extension Top Purity Numerator", effHistBins, xbins.data()); + mEExtensionTopFakeNum = createHistogram("hExtensionTopFakeNum", "Extension Top Fake Numerator", effHistBins, xbins.data()); + mEExtensionBotNum = createHistogram("hExtensionBotNum", "Extension Bot Numerator", effHistBins, xbins.data()); + mEExtensionBotPurityNum = createHistogram("hExtensionBotPurityNum", "Extension Bot Purity Numerator", effHistBins, xbins.data()); + mEExtensionBotFakeNum = createHistogram("hExtensionBotFakeNum", "Extension Bot Fake Numerator", effHistBins, xbins.data()); + mEExtensionMixNum = createHistogram("hExtensionMixNum", "Extension Mix Numerator", effHistBins, xbins.data()); + mEExtensionMixPurityNum = createHistogram("hExtensionMixPurityNum", "Extension Mix Purity Numerator", effHistBins, xbins.data()); + mEExtensionMixFakeNum = createHistogram("hExtensionMixFakeNum", "Extension Mix Fake Numerator", effHistBins, xbins.data()); + // Patterns + for (int i{0}; i < mBitPatternsBefore.size(); ++i) { + mEExtensionPatternGoodNum[i] = createHistogram(fmt::format("hExtensionPatternGood_{:07b}", mBitPatternsBefore[i]).c_str(), fmt::format("Extended Tracks Pattern (GOOD) {:07b}", mBitPatternsBefore[i]).c_str(), effHistBins, xbins.data()); + mEExtensionPatternFakeNum[i] = createHistogram(fmt::format("hExtensionPatternFake_{:07b}", mBitPatternsBefore[i]).c_str(), fmt::format("Extended Tracks Pattern (FAKE) {:07b}", mBitPatternsBefore[i]).c_str(), effHistBins, xbins.data()); + for (int j{0}; j < mBitPatternsAfter.size(); ++j) { + mEExtensionPatternIndGoodNum[i][j] = createHistogram(fmt::format("hExtensionPatternGood_{:07b}_{:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), fmt::format("Extended Tracks Pattern (GOOD) {:07b} -> {:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), effHistBins, xbins.data()); + mEExtensionPatternIndFakeNum[i][j] = createHistogram(fmt::format("hExtensionPatternFake_{:07b}_{:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), fmt::format("Extended Tracks Pattern (FAKE) {:07b} -> {:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), effHistBins, xbins.data()); + } + } + + /// DCA + mDCAxyVsPtPionsNormal = createHistogram("hDCAxyVsPtResNormal", "DCA_{#it{xy}} NORMAL Pions;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{xy}}) (#mum)", effHistBins, xbins.data(), 1000, -500, 500); + mDCAxyVsPtPionsExtended = createHistogram("hDCAxyVsPtResExtended", "DCA_{#it{xy}} EXTENDED Pions;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{xy}}) (#mum)", effHistBins, xbins.data(), 1000, -500, 500); + mDCAzVsPtPionsNormal = createHistogram("hDCAzVsPtResNormal", "DCA_{#it{z}} NORMAL Pions;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{z}}) (#mum)", effHistBins, xbins.data(), 1000, -500, 500); + mDCAzVsPtPionsExtended = createHistogram("hDCAzVsPtResExtended", "DCA_{#it{z}} EXTENDED Pions;#it{p}_{T} (GeV/#it{c});#sigma(DCA_{#it{z}}) (#mum)", effHistBins, xbins.data(), 1000, -500, 500); mStream = std::make_unique(mOutFileName.c_str(), "RECREATE"); } @@ -192,8 +257,6 @@ void TrackExtensionStudy::run(ProcessingContext& pc) mClustersMCLCont = recoData.getITSClustersMCLabels(); mInputITSidxs = recoData.getITSTracksClusterRefs(); - mHClustersCounts->SetBinContent(1, mClusters.size()); - LOGP(info, "** Found in {} rofs:\n\t- {} clusters with {} labels\n\t- {} tracks with {} labels", mTracksROFRecords.size(), mClusters.size(), mClustersMCLCont->getIndexedSize(), mTracks.size(), mTracksMCLabels.size()); LOGP(info, "** Found {} sources from kinematic files", mKineReader->getNSources()); @@ -208,10 +271,13 @@ void TrackExtensionStudy::process() for (int iSource{0}; iSource < mKineReader->getNSources(); ++iSource) { mParticleInfo[iSource].resize(mKineReader->getNEvents(iSource)); // events for (int iEvent{0}; iEvent < mKineReader->getNEvents(iSource); ++iEvent) { + const auto& mcEvent = mKineReader->getMCEventHeader(iSource, iEvent); mParticleInfo[iSource][iEvent].resize(mKineReader->getTracks(iSource, iEvent).size()); // tracks for (auto iPart{0}; iPart < mKineReader->getTracks(iEvent).size(); ++iPart) { - auto& part = mKineReader->getTracks(iSource, iEvent)[iPart]; - mParticleInfo[iSource][iEvent][iPart].event = iEvent; + const auto& part = mKineReader->getTracks(iSource, iEvent)[iPart]; + mParticleInfo[iSource][iEvent][iPart].eventX = mcEvent.GetX(); + mParticleInfo[iSource][iEvent][iPart].eventY = mcEvent.GetY(); + mParticleInfo[iSource][iEvent][iPart].eventZ = mcEvent.GetZ(); mParticleInfo[iSource][iEvent][iPart].pdg = part.GetPdgCode(); mParticleInfo[iSource][iEvent][iPart].pt = part.GetPt(); mParticleInfo[iSource][iEvent][iPart].phi = part.GetPhi(); @@ -287,6 +353,8 @@ void TrackExtensionStudy::process() LOGP(info, "\t- Total number of good: {} ({:.2f} %)", good, good * 100. / mTracks.size()); LOGP(info, "\t- Total number of extensions: {} ({:.2f} %)", extended, extended * 100. / mTracks.size()); + o2::dataformats::VertexBase collision; + o2::dataformats::DCA impactParameter; LOGP(info, "** Filling histograms ... "); for (auto iTrack{0}; iTrack < mTracks.size(); ++iTrack) { auto& lab = mTracksMCLabels[iTrack]; @@ -302,6 +370,7 @@ void TrackExtensionStudy::process() continue; } const auto& trk = part.track; + bool isGood = part.isReco && !part.isFake; mHTrackCounts->Fill(0); std::bitset<7> extPattern{0}; @@ -311,44 +380,85 @@ void TrackExtensionStudy::process() } } - if (!extPattern.any()) { - mHTrackCounts->Fill(1); - if (part.isReco || !part.isFake) { - mHTrackCounts->Fill(2); - } else { - mHTrackCounts->Fill(3); + // Tree + while (mWithTree) { + constexpr float refRadius{70.f}; + constexpr float maxSnp{0.9f}; + auto cTrk = trk; + if (!o2::base::Propagator::Instance()->PropagateToXBxByBz(cTrk, refRadius, maxSnp, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrTGeo)) { + break; } - continue; - } - - if (mWithTree) { std::array xyz{(float)part.mcTrack.GetStartVertexCoordinatesX(), (float)part.mcTrack.GetStartVertexCoordinatesY(), (float)part.mcTrack.GetStartVertexCoordinatesZ()}; std::array pxyz{(float)part.mcTrack.GetStartVertexMomentumX(), (float)part.mcTrack.GetStartVertexMomentumY(), (float)part.mcTrack.GetStartVertexMomentumZ()}; auto pdg = O2DatabasePDG::Instance()->GetParticle(part.pdg); if (pdg == nullptr) { - LOGP(fatal, "MC info not available"); + LOGP(error, "MC info not available"); + break; } auto mcTrk = o2::track::TrackPar(xyz, pxyz, TMath::Nint(pdg->Charge() / 3.), true); + if (!mcTrk.rotate(cTrk.getAlpha()) || !o2::base::Propagator::Instance()->PropagateToXBxByBz(mcTrk, refRadius, maxSnp, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrTGeo)) { + break; + } (*mStream) << "tree" - << "trk=" << trk + << "trk=" << cTrk << "mcTrk=" << mcTrk + << "isGood=" << isGood + << "isExtended=" << extPattern.any() << "\n"; + break; + } + + // impact parameter + while (isGood && std::abs(part.pdg) == 211) { + auto trkC = part.track; + collision.setXYZ(part.eventX, part.eventY, part.eventZ); + if (!o2::base::Propagator::Instance()->propagateToDCA(collision, trkC, o2::base::Propagator::Instance()->getNominalBz(), 2.0, o2::base::Propagator::MatCorrType::USEMatCorrTGeo, &impactParameter)) { + break; + } + + auto dcaXY = impactParameter.getY() * 1e4; + auto dcaZ = impactParameter.getZ() * 1e4; + if (!extPattern.any()) { + mDCAxyVsPtPionsNormal->Fill(part.pt, dcaXY); + mDCAzVsPtPionsNormal->Fill(part.pt, dcaZ); + } else { + mDCAxyVsPtPionsExtended->Fill(part.pt, dcaXY); + mDCAzVsPtPionsExtended->Fill(part.pt, dcaZ); + } + break; + } + + mEExtensionDen->Fill(trk.getPt()); + + if (!extPattern.any()) { + mHTrackCounts->Fill(1); + if (part.isReco || !part.isFake) { + mHTrackCounts->Fill(2); + } else { + mHTrackCounts->Fill(3); + } + continue; } mHTrackCounts->Fill(4); mHLengthAny->Fill(trk.getNClusters()); mHChi2Any->Fill(trk.getChi2()); mHPtAny->Fill(trk.getPt()); - if (part.isReco || !part.isFake) { + mEExtensionNum->Fill(trk.getPt()); + mEExtensionPurityDen->Fill(trk.getPt()); + mEExtensionFakeDen->Fill(trk.getPt()); + if (isGood) { mHTrackCounts->Fill(5); mHLengthGood->Fill(trk.getNClusters()); mHChi2Good->Fill(trk.getChi2()); mHPtGood->Fill(trk.getPt()); + mEExtensionPurityNum->Fill(trk.getPt()); } else { mHTrackCounts->Fill(6); mHLengthFake->Fill(trk.getNClusters()); mHChi2Fake->Fill(trk.getChi2()); mHPtFake->Fill(trk.getPt()); + mEExtensionFakeNum->Fill(trk.getPt()); } std::bitset<7> clusPattern{static_cast(trk.getPattern())}; @@ -356,29 +466,28 @@ void TrackExtensionStudy::process() if (extPattern.test(iLayer)) { extPattern.set(iLayer); mHExtensionAny->Fill(iLayer); - if (part.isReco || !part.isFake) { + if (isGood) { mHExtensionGood->Fill(iLayer); } else { mHExtensionFake->Fill(iLayer); } - - if ((part.fakeClusters & (0x1 << iLayer)) == 0) { - mHClustersCounts->Fill(4); - } else { - mHClustersCounts->Fill(5); - } } } - std::bitset<7> oldPattern{clusPattern & ~extPattern}; + std::bitset<7> oldPattern{clusPattern & ~extPattern}, holePattern{clusPattern}; + holePattern.flip(); auto clusN = clusPattern.to_ulong(); auto clusIdx = std::distance(std::begin(mBitPatternsAfter), std::find(std::begin(mBitPatternsAfter), std::end(mBitPatternsAfter), clusN)); auto oldN = oldPattern.to_ulong(); auto oldIdx = std::distance(std::begin(mBitPatternsBefore), std::find(std::begin(mBitPatternsBefore), std::end(mBitPatternsBefore), oldN)); mHExtensionPatternsAny->Fill(oldIdx, clusIdx); - if (part.isReco || !part.isFake) { + if (isGood) { mHExtensionPatternsGood->Fill(oldIdx, clusIdx); + mEExtensionPatternGoodNum[oldIdx]->Fill(trk.getPt()); + mEExtensionPatternIndGoodNum[oldIdx][clusIdx]->Fill(trk.getPt()); } else { mHExtensionPatternsFake->Fill(oldIdx, clusIdx); + mEExtensionPatternFakeNum[oldIdx]->Fill(trk.getPt()); + mEExtensionPatternIndFakeNum[oldIdx][clusIdx]->Fill(trk.getPt()); } // old pattern @@ -392,17 +501,70 @@ void TrackExtensionStudy::process() } } } - if (oldFake && newFake) { mHTrackCounts->Fill(9); + mEExtensionFakeMixNum->Fill(trk.getPt()); } else if (oldFake) { mHTrackCounts->Fill(7); + mEExtensionFakeBeforeNum->Fill(trk.getPt()); } else if (newFake) { mHTrackCounts->Fill(8); + mEExtensionFakeAfterNum->Fill(trk.getPt()); } - mHClustersCounts->SetBinContent(2, mHClustersCounts->GetBinContent(2) + oldPattern.count()); - mHClustersCounts->SetBinContent(3, mHClustersCounts->GetBinContent(3) + extPattern.count()); + // Check if we missed some clusters + if (isGood && holePattern.any()) { + auto missPattern{clusPattern}, emptyPattern{clusPattern}; + for (int iLayer{0}; iLayer < 7; ++iLayer) { + if (!holePattern.test(iLayer)) { + continue; + } + + // Check if there was actually a cluster that we missed + if ((part.clusters & (1 << iLayer)) != 0) { + missPattern.set(iLayer); + } else { + emptyPattern.set(iLayer); + } + } + + if (missPattern != clusPattern) { + auto missN = missPattern.to_ulong(); + auto missIdx = std::distance(std::begin(mBitPatternsAfter), std::find(std::begin(mBitPatternsAfter), std::end(mBitPatternsAfter), missN)); + mHExtensionPatternsGoodMissed->Fill(clusIdx, missIdx); + } + if (emptyPattern != clusPattern) { + auto emptyN = emptyPattern.to_ulong(); + auto emptyIdx = std::distance(std::begin(mBitPatternsAfter), std::find(std::begin(mBitPatternsAfter), std::end(mBitPatternsAfter), emptyN)); + mHExtensionPatternsGoodEmpty->Fill(clusIdx, emptyIdx); + } + } + + // Top/Bot/Mixed Extension + bool isTop = (extPattern & mTopMask).any(); + bool isBot = (extPattern & mBotMask).any(); + if (isTop && isBot) { + mEExtensionMixNum->Fill(trk.getPt()); + if (isGood) { + mEExtensionMixPurityNum->Fill(trk.getPt()); + } else { + mEExtensionMixFakeNum->Fill(trk.getPt()); + } + } else if (isTop) { + mEExtensionTopNum->Fill(trk.getPt()); + if (isGood) { + mEExtensionTopPurityNum->Fill(trk.getPt()); + } else { + mEExtensionTopFakeNum->Fill(trk.getPt()); + } + } else { + mEExtensionBotNum->Fill(trk.getPt()); + if (isGood) { + mEExtensionBotPurityNum->Fill(trk.getPt()); + } else { + mEExtensionBotFakeNum->Fill(trk.getPt()); + } + } } } @@ -421,39 +583,57 @@ void TrackExtensionStudy::endOfStream(EndOfStreamContext& ec) { LOGP(info, "Writing results to {}", mOutFileName); mStream->GetFile()->cd(); + for (const auto h : mHistograms) { + h->Write(); + } - mHTrackCounts->Write(); - mHClustersCounts->Write(); - - mHLengthAny->Write(); - mHLengthGood->Write(); - mHLengthFake->Write(); - - mHChi2Any->Write(); - mHChi2Good->Write(); - mHChi2Fake->Write(); - - mHPtAny->Write(); - mHPtGood->Write(); - mHPtFake->Write(); - - mHExtensionAny->Write(); - mHExtensionGood->Write(); - mHExtensionFake->Write(); - - mHExtensionPatternsAny->Write(); - mHExtensionPatternsGood->Write(); - mHExtensionPatternsFake->Write(); + LOGP(info, "Calculating efficiencies"); + auto makeEff = [](auto num, auto den, const char* name, const char* title) { + auto e = std::make_unique(*num, *den); + e->SetName(name); + e->SetTitle(title); + e->Write(); + }; + makeEff(mEExtensionNum.get(), mEExtensionDen.get(), "eExtension", "Track Extension EXT TRK/ALL"); + makeEff(mEExtensionPurityNum.get(), mEExtensionPurityDen.get(), "eExtensionPurity", "Track Extension Purity GOOD/EXT TRK"); + makeEff(mEExtensionFakeNum.get(), mEExtensionFakeDen.get(), "eExtensionFake", "Track Extension Fake FAKE/EXT TRK"); + makeEff(mEExtensionFakeBeforeNum.get(), mEExtensionFakeNum.get(), "eExtensionFakeBefore", "Track Extension Fake FAKE BEF/FAKE EXT TRK"); + makeEff(mEExtensionFakeAfterNum.get(), mEExtensionFakeNum.get(), "eExtensionFakeAfter", "Track Extension Fake FAKE AFT/FAKE EXT TRK"); + makeEff(mEExtensionFakeMixNum.get(), mEExtensionFakeNum.get(), "eExtensionFakeMix", "Track Extension Fake FAKE MIX/FAKE EXT TRK"); + makeEff(mEExtensionTopNum.get(), mEExtensionDen.get(), "eExtensionTop", "Track Extension Top"); + makeEff(mEExtensionTopPurityNum.get(), mEExtensionPurityDen.get(), "eExtensionTopPurity", "Track Extension Purity GOOD TOP/EXT TRK"); + makeEff(mEExtensionTopFakeNum.get(), mEExtensionFakeNum.get(), "eExtensionTopFake", "Track Extension FAKE TOP/EXT FAKE TRK"); + makeEff(mEExtensionBotNum.get(), mEExtensionDen.get(), "eExtensionBot", "Track Extension Bot"); + makeEff(mEExtensionBotPurityNum.get(), mEExtensionPurityDen.get(), "eExtensionBotPurity", "Track Extension Purity GOOD BOT/EXT TRK"); + makeEff(mEExtensionBotFakeNum.get(), mEExtensionFakeNum.get(), "eExtensionBotFake", "Track Extension FAKE BOT/EXT FAKE TRK"); + makeEff(mEExtensionMixNum.get(), mEExtensionDen.get(), "eExtensionMix", "Track Extension Mix"); + makeEff(mEExtensionMixPurityNum.get(), mEExtensionPurityDen.get(), "eExtensionMixPurity", "Track Extension Purity GOOD MIX/EXT TRK"); + makeEff(mEExtensionMixFakeNum.get(), mEExtensionFakeNum.get(), "eExtensionMixFake", "Track Extension FAKE MIX/EXT FAKE TRK"); + for (int i{0}; i < mBitPatternsBefore.size(); ++i) { + makeEff(mEExtensionPatternGoodNum[i].get(), mEExtensionPurityNum.get(), fmt::format("eExtensionPatternGood_{:07b}", mBitPatternsBefore[i]).c_str(), fmt::format("Extended Tracks Pattern (GOOD) {:07b} GOOD EXT TRK/EXT TRK", mBitPatternsBefore[i]).c_str()); + makeEff(mEExtensionPatternFakeNum[i].get(), mEExtensionFakeNum.get(), fmt::format("eExtensionPatternFake_{:07b}", mBitPatternsBefore[i]).c_str(), fmt::format("Extended Tracks Pattern (FAKE) {:07b} FAKE EXT TRK/EXT TRK", mBitPatternsBefore[i]).c_str()); + for (int j{0}; j < mBitPatternsAfter.size(); ++j) { + makeEff(mEExtensionPatternIndGoodNum[i][j].get(), mEExtensionPatternGoodNum[i].get(), fmt::format("eExtensionPatternGood_{:07b}_{:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), fmt::format("Extended Tracks Pattern (GOOD) {:07b} -> {:07b} GOOD EXT TRK/EXT TRK", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str()); + makeEff(mEExtensionPatternIndFakeNum[i][j].get(), mEExtensionPatternFakeNum[i].get(), fmt::format("eExtensionPatternFake_{:07b}_{:07b}", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str(), fmt::format("Extended Tracks Pattern (FAKE) {:07b} -> {:07b} FAKE EXT TRK/EXT TRK", mBitPatternsBefore[i], mBitPatternsAfter[j]).c_str()); + } + } mStream->Close(); } -DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader) +void TrackExtensionStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) +{ + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { + return; + } +} + +DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcClustersMask, std::shared_ptr kineReader) { std::vector outputs; auto dataRequest = std::make_shared(); - dataRequest->requestTracks(srcTracksMask, useMC); - dataRequest->requestClusters(srcClustersMask, useMC); + dataRequest->requestTracks(srcTracksMask, true); + dataRequest->requestClusters(srcClustersMask, true); auto ggRequest = std::make_shared(false, // orbitResetTime true, // GRPECS=true @@ -468,7 +648,7 @@ DataProcessorSpec getTrackExtensionStudy(mask_t srcTracksMask, mask_t srcCluster "its-study-track-extension", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(dataRequest, srcTracksMask, useMC, kineReader, ggRequest)}, + AlgorithmSpec{adaptFromTask(dataRequest, srcTracksMask, kineReader, ggRequest)}, Options{{"with-tree", o2::framework::VariantType::Bool, false, {"Produce in addition a tree"}}}}; } diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx index 02a75def154fc..30fb39c77f235 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx @@ -113,11 +113,14 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) specs.emplace_back(o2::its::study::getAnomalyStudy(srcCls, useMC)); } if (configcontext.options().get("track-extension-study")) { + if (!useMC) { + LOGP(fatal, "Track Extension Study needs MC!"); + } anyStudy = true; srcTrc = GID::getSourcesMask(configcontext.options().get("track-sources")); srcCls = GID::getSourcesMask("ITS"); - o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, useMC, srcCls, srcTrc); - specs.emplace_back(o2::its::study::getTrackExtensionStudy(srcTrc, srcCls, useMC, mcKinematicsReader)); + o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true, srcCls, srcTrc); + specs.emplace_back(o2::its::study::getTrackExtensionStudy(srcTrc, srcCls, mcKinematicsReader)); } if (configcontext.options().get("efficiency-study")) { anyStudy = true; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h index 1c4d3360bc7a3..976d01f1d476b 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Configuration.h @@ -94,11 +94,17 @@ struct TrackingParameters { unsigned long MaxMemory = 12000000000UL; float MaxChi2ClusterAttachment = 60.f; float MaxChi2NDF = 30.f; - bool UseTrackFollower = false; bool FindShortTracks = false; bool PerPrimaryVertexProcessing = false; bool SaveTimeBenchmarks = false; bool DoUPCIteration = false; + /// Cluster attachment + bool UseTrackFollower = false; + bool UseTrackFollowerTop = false; + bool UseTrackFollowerBot = false; + bool UseTrackFollowerMix = false; + float TrackFollowerNSigmaCutZ = 1.f; + float TrackFollowerNSigmaCutPhi = 1.f; }; inline int TrackingParameters::CellMinimumLevel() diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h index 70de43d83d8d2..58483e4aa9f6f 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h @@ -122,7 +122,7 @@ float Tracker::evaluateTask(void (Tracker::*task)(T...), const char* taskName, s { float diff{0.f}; - if (constants::DoTimeBenchmarks) { + if constexpr (constants::DoTimeBenchmarks) { auto start = std::chrono::high_resolution_clock::now(); (this->*task)(std::forward(args)...); auto end = std::chrono::high_resolution_clock::now(); diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h index 207dd5d3d50f5..46499db92d4d5 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackerTraits.h @@ -78,10 +78,10 @@ class TrackerTraits bool isMatLUT() const; // Others - GPUhd() static constexpr int4 getEmptyBinsRect() { return int4{0, 0, 0, 0}; } - const int4 getBinsRect(const Cluster&, int layer, float z1, float z2, float maxdeltaz, float maxdeltaphi); - const int4 getBinsRect(int layer, float phi, float maxdeltaphi, float z, float maxdeltaz); - const int4 getBinsRect(int layer, float phi, float maxdeltaphi, float z1, float z2, float maxdeltaz); + GPUhd() static consteval int4 getEmptyBinsRect() { return int4{0, 0, 0, 0}; } + const int4 getBinsRect(const Cluster&, int layer, float z1, float z2, float maxdeltaz, float maxdeltaphi) const noexcept; + const int4 getBinsRect(int layer, float phi, float maxdeltaphi, float z, float maxdeltaz) const noexcept; + const int4 getBinsRect(int layer, float phi, float maxdeltaphi, float z1, float z2, float maxdeltaz) const noexcept; void SetRecoChain(o2::gpu::GPUChainITS* chain) { mChain = chain; } void setSmoothing(bool v) { mApplySmoothing = v; } bool getSmoothing() const { return mApplySmoothing; } @@ -112,6 +112,12 @@ class TrackerTraits bool mIsGPU = false; }; +inline void TrackerTraits::initialiseTimeFrame(const int iteration) +{ + mTimeFrame->initialise(iteration, mTrkParams[iteration], mTrkParams[iteration].NLayers); + setIsGPU(false); +} + inline float TrackerTraits::getBz() const { return mBz; @@ -122,40 +128,32 @@ inline void TrackerTraits::UpdateTrackingParameters(const std::vectorinitialise(iteration, mTrkParams[iteration], mTrkParams[iteration].NLayers); - setIsGPU(false); -} - -inline const int4 TrackerTraits::getBinsRect(const int layerIndex, float phi, float maxdeltaphi, - float z1, float z2, float maxdeltaz) +inline const int4 TrackerTraits::getBinsRect(const int layerIndex, float phi, float maxdeltaphi, float z1, float z2, float maxdeltaz) const noexcept { const float zRangeMin = o2::gpu::GPUCommonMath::Min(z1, z2) - maxdeltaz; const float phiRangeMin = (maxdeltaphi > constants::math::Pi) ? 0.f : phi - maxdeltaphi; const float zRangeMax = o2::gpu::GPUCommonMath::Max(z1, z2) + maxdeltaz; const float phiRangeMax = (maxdeltaphi > constants::math::Pi) ? constants::math::TwoPi : phi + maxdeltaphi; - if (zRangeMax < -mTrkParams[0].LayerZ[layerIndex + 1] || - zRangeMin > mTrkParams[0].LayerZ[layerIndex + 1] || zRangeMin > zRangeMax) { - + if (zRangeMax < -mTrkParams[0].LayerZ[layerIndex] || + zRangeMin > mTrkParams[0].LayerZ[layerIndex] || zRangeMin > zRangeMax) { return getEmptyBinsRect(); } const IndexTableUtils& utils{mTimeFrame->mIndexTableUtils}; - return int4{o2::gpu::GPUCommonMath::Max(0, utils.getZBinIndex(layerIndex + 1, zRangeMin)), + return int4{o2::gpu::GPUCommonMath::Max(0, utils.getZBinIndex(layerIndex, zRangeMin)), utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMin)), - o2::gpu::GPUCommonMath::Min(mTrkParams[0].ZBins - 1, utils.getZBinIndex(layerIndex + 1, zRangeMax)), // /!\ trkParams can potentially change across iterations + o2::gpu::GPUCommonMath::Min(mTrkParams[0].ZBins - 1, utils.getZBinIndex(layerIndex, zRangeMax)), // /!\ trkParams can potentially change across iterations utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMax))}; } } // namespace its diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h index fe5e52bd6277a..68bfdb51170b5 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h @@ -72,7 +72,9 @@ struct TrackerParamConfig : public o2::conf::ConfigurableParamHelper 0 off + float trackFollowerNSigmaZ = 1.f; // sigma in z-cut for track-following search rectangle + float trackFollowerNSigmaPhi = 1.f; // sigma in phi-cut for track-following search rectangle float cellsPerClusterLimit = -1.f; float trackletsPerClusterLimit = -1.f; int findShortTracks = -1; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Vertexer.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Vertexer.h index 7fb5d1421877e..ac0cf51921176 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Vertexer.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Vertexer.h @@ -176,7 +176,7 @@ float Vertexer::evaluateTask(void (Vertexer::*task)(T...), const char* taskName, { float diff{0.f}; - if (constants::DoTimeBenchmarks) { + if constexpr (constants::DoTimeBenchmarks) { auto start = std::chrono::high_resolution_clock::now(); (this->*task)(std::forward(args)...); auto end = std::chrono::high_resolution_clock::now(); diff --git a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx index 9a43402a2e93a..721452bf0361d 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx @@ -120,7 +120,7 @@ void Tracker::clustersToTracks(std::function logger, std::f total += evaluateTask(&Tracker::findShortPrimaries, "Short primaries finding", logger); std::stringstream sstream; - if (constants::DoTimeBenchmarks) { + if constexpr (constants::DoTimeBenchmarks) { sstream << std::setw(2) << " - " << "Timeframe " << mTimeFrameCounter++ << " processing completed in: " << total << "ms using " << mTraits->getNThreads() << " threads."; } @@ -200,7 +200,7 @@ void Tracker::clustersToTracksHybrid(std::function logger, // total += evaluateTask(&Tracker::findShortPrimaries, "Hybrid short primaries finding", logger); std::stringstream sstream; - if (constants::DoTimeBenchmarks) { + if constexpr (constants::DoTimeBenchmarks) { sstream << std::setw(2) << " - " << "Timeframe " << mTimeFrameCounter++ << " processing completed in: " << total << "ms using " << mTraits->getNThreads() << " threads."; } @@ -502,8 +502,16 @@ void Tracker::getGlobalConfiguration() if (tc.maxMemory) { params.MaxMemory = tc.maxMemory; } - if (tc.useTrackFollower >= 0) { - params.UseTrackFollower = tc.useTrackFollower; + if (tc.useTrackFollower > 0) { + params.UseTrackFollower = true; + // Bit 0: Allow for mixing of top&bot extension --> implies Bits 1&2 set + // Bit 1: Allow for top extension + // Bit 2: Allow for bot extension + params.UseTrackFollowerMix = ((tc.useTrackFollower & (1 << 0)) != 0); + params.UseTrackFollowerTop = ((tc.useTrackFollower & (1 << 1)) != 0); + params.UseTrackFollowerBot = ((tc.useTrackFollower & (1 << 2)) != 0); + params.TrackFollowerNSigmaCutZ = tc.trackFollowerNSigmaZ; + params.TrackFollowerNSigmaCutPhi = tc.trackFollowerNSigmaPhi; } if (tc.cellsPerClusterLimit >= 0) { params.CellsPerClusterLimit = tc.cellsPerClusterLimit; diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index 4457d4515e0a6..da0abbae9dc1f 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -111,7 +111,7 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in const float sqInverseDeltaZ0{1.f / (Sq(currentCluster.zCoordinate - primaryVertex.getZ()) + 2.e-8f)}; /// protecting from overflows adding the detector resolution const float sigmaZ{o2::gpu::CAMath::Sqrt(Sq(resolution) * Sq(tanLambda) * ((Sq(inverseR0) + sqInverseDeltaZ0) * Sq(meanDeltaR) + 1.f) + Sq(meanDeltaR * tf->getMSangle(iLayer)))}; - const int4 selectedBinsRect{getBinsRect(currentCluster, iLayer, zAtRmin, zAtRmax, + const int4 selectedBinsRect{getBinsRect(currentCluster, iLayer + 1, zAtRmin, zAtRmax, sigmaZ * mTrkParams[iteration].NSigmaCut, tf->getPhiCut(iLayer))}; if (selectedBinsRect.x == 0 && selectedBinsRect.y == 0 && selectedBinsRect.z == 0 && selectedBinsRect.w == 0) { continue; @@ -679,10 +679,11 @@ void TrackerTraits::extendTracks(const int iteration) for (auto& track : mTimeFrame->getTracks(rof)) { auto backup{track}; bool success{false}; - if (track.getLastClusterLayer() != mTrkParams[iteration].NLayers - 1) { + // the order here biases towards top extension, tracks should probably be fitted separately in the directions and then compared. + if ((mTrkParams[iteration].UseTrackFollowerMix || mTrkParams[iteration].UseTrackFollowerTop) && track.getLastClusterLayer() != mTrkParams[iteration].NLayers - 1) { success = success || trackFollowing(&track, rof, true, iteration); } - if (track.getFirstClusterLayer() != 0) { + if ((mTrkParams[iteration].UseTrackFollowerMix || (mTrkParams[iteration].UseTrackFollowerBot && !success)) && track.getFirstClusterLayer() != 0) { success = success || trackFollowing(&track, rof, false, iteration); } if (success) { @@ -830,8 +831,8 @@ bool TrackerTraits::fitTrack(TrackITSExt& track, int start, int end, int step, f } if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) { - float radl = 9.36f; // Radiation length of Si [cm] - float rho = 2.33f; // Density of Si [g/cm^3] + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] if (!track.correctForMaterial(mTrkParams[0].LayerxX0[iLayer], mTrkParams[0].LayerxX0[iLayer] * radl * rho, true)) { continue; } @@ -855,36 +856,40 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co auto propInstance = o2::base::Propagator::Instance(); const int step = -1 + outward * 2; const int end = outward ? mTrkParams[iteration].NLayers - 1 : 0; - std::vector hypotheses(1, *track); - for (auto& hypo : hypotheses) { - int iLayer = outward ? track->getLastClusterLayer() : track->getFirstClusterLayer(); + std::vector hypotheses(1, *track); // possibly avoid reallocation + for (size_t iHypo{0}; iHypo < hypotheses.size(); ++iHypo) { + auto hypo{hypotheses[iHypo]}; + int iLayer = static_cast(outward ? hypo.getLastClusterLayer() : hypo.getFirstClusterLayer()); + // per layer we add new hypotheses while (iLayer != end) { - iLayer += step; + iLayer += step; // step through all layers until we reach the end, this allows for skipping on empty layers const float r = mTrkParams[iteration].LayerRadii[iLayer]; + // get an estimate of the trackinf-frame x for the next step float x{-999}; if (!hypo.getXatLabR(r, x, mTimeFrame->getBz(), o2::track::DirAuto) || x <= 0.f) { continue; } - + // estimate hypo's trk parameters at that x auto& hypoParam{outward ? hypo.getParamOut() : hypo.getParamIn()}; if (!propInstance->propagateToX(hypoParam, x, mTimeFrame->getBz(), PropagatorF::MAX_SIN_PHI, PropagatorF::MAX_STEP, mTrkParams[iteration].CorrType)) { continue; } - if (mTrkParams[iteration].CorrType == PropagatorF::MatCorrType::USEMatCorrNONE) { - float radl = 9.36f; // Radiation length of Si [cm] - float rho = 2.33f; // Density of Si [g/cm^3] + if (mTrkParams[iteration].CorrType == PropagatorF::MatCorrType::USEMatCorrNONE) { // account for material affects if propagator does not + constexpr float radl = 9.36f; // Radiation length of Si [cm] + constexpr float rho = 2.33f; // Density of Si [g/cm^3] if (!hypoParam.correctForMaterial(mTrkParams[iteration].LayerxX0[iLayer], mTrkParams[iteration].LayerxX0[iLayer] * radl * rho, true)) { continue; } } + + // calculate the search window on this layer const float phi{hypoParam.getPhi()}; const float ePhi{o2::gpu::CAMath::Sqrt(hypoParam.getSigmaSnp2() / hypoParam.getCsp2())}; const float z{hypoParam.getZ()}; const float eZ{o2::gpu::CAMath::Sqrt(hypoParam.getSigmaZ2())}; - const int4 selectedBinsRect{getBinsRect(iLayer, phi, mTrkParams[iteration].NSigmaCut * ePhi, z, mTrkParams[iteration].NSigmaCut * eZ)}; - + const int4 selectedBinsRect{getBinsRect(iLayer, phi, mTrkParams[iteration].TrackFollowerNSigmaCutPhi * ePhi, z, mTrkParams[iteration].TrackFollowerNSigmaCutZ * eZ)}; if (selectedBinsRect.x == 0 && selectedBinsRect.y == 0 && selectedBinsRect.z == 0 && selectedBinsRect.w == 0) { continue; } @@ -900,9 +905,8 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co continue; } - TrackITSExt currentHypo{hypo}, newHypo{hypo}; - bool first{true}; - for (int iPhiCount{0}; iPhiCount < phiBinsNum; iPhiCount++) { + // check all clusters in search windows for possible new hypotheses + for (int iPhiCount = 0; iPhiCount < phiBinsNum; iPhiCount++) { int iPhiBin = (selectedBinsRect.y + iPhiCount) % mTrkParams[iteration].PhiBins; const int firstBinIndex{mTimeFrame->mIndexTableUtils.getBinIndex(selectedBinsRect.x, iPhiBin)}; const int maxBinIndex{firstBinIndex + selectedBinsRect.z - selectedBinsRect.x + 1}; @@ -921,7 +925,7 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co const TrackingFrameInfo& trackingHit = mTimeFrame->getTrackingFrameInfoOnLayer(iLayer).at(nextCluster.clusterId); - TrackITSExt& tbupdated = first ? hypo : newHypo; + auto tbupdated{hypo}; auto& tbuParams = outward ? tbupdated.getParamOut() : tbupdated.getParamIn(); if (!tbuParams.rotate(trackingHit.alphaTrackingFrame)) { continue; @@ -942,12 +946,7 @@ bool TrackerTraits::trackFollowing(TrackITSExt* track, int rof, bool outward, co } tbupdated.setChi2(tbupdated.getChi2() + predChi2); /// This is wrong for outward propagation as the chi2 refers to inward parameters tbupdated.setExternalClusterIndex(iLayer, nextCluster.clusterId, true); - - if (!first) { - hypotheses.emplace_back(tbupdated); - newHypo = currentHypo; - } - first = false; + hypotheses.emplace_back(tbupdated); } } } From 83049afbb3b006fa19be960363f66b53485a3bec Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 24 Nov 2024 18:42:16 +0100 Subject: [PATCH 0513/2205] Add AltroSyncSignal to TPC CDBTypeMap --- Detectors/TPC/base/include/TPCBase/CDBTypes.h | 128 +++++++++--------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/Detectors/TPC/base/include/TPCBase/CDBTypes.h b/Detectors/TPC/base/include/TPCBase/CDBTypes.h index 27cc2e5a79589..75278f2a76902 100644 --- a/Detectors/TPC/base/include/TPCBase/CDBTypes.h +++ b/Detectors/TPC/base/include/TPCBase/CDBTypes.h @@ -24,68 +24,70 @@ namespace o2::tpc /// Calibration and parameter types for CCDB enum class CDBType { - CalPedestal, ///< Pedestal calibration - CalNoise, ///< Noise calibration - CalPedestalNoise, ///< Pedestal and Noise calibration - CalPulser, ///< Pulser calibration - CalCE, ///< Laser CE calibration - CalPadGainFull, ///< Full pad gain calibration - CalPadGainResidual, ///< ResidualpPad gain calibration (e.g. from tracks) - CalLaserTracks, ///< Laser track calibration data - CalVDriftTgl, ///< ITS-TPC difTgl vdrift calibration - CalTimeGain, ///< Gain variation over time - CalTimeGainMC, ///< Gain variation over time for MC - CalGas, ///< DCS gas measurements - CalTemperature, ///< DCS temperature measurements - CalHV, ///< DCS HV measurements - CalTopologyGain, ///< Q cluster topology correction - /// - ConfigFEEPad, ///< FEE pad-by-pad configuration map - ConfigFEE, ///< FEE configuration map for each tag - ConfigRunInfo, ///< FEE run information (run -> tag) - /// - ParDetector, ///< Parameter for Detector - ParElectronics, ///< Parameter for Electronics - ParGas, ///< Parameter for Gas - ParGEM, ///< Parameter for GEM - /// - CalIDC0A, ///< I_0(r,\phi) = _t - CalIDC0C, ///< I_0(r,\phi) = _t - CalIDC1A, ///< I_1(t) = _{r,\phi} - CalIDC1C, ///< I_1(t) = _{r,\phi} - CalIDCDeltaA, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalIDCDeltaC, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalIDCFourierA, ///< Fourier coefficients of CalIDC1 - CalIDCFourierC, ///< Fourier coefficients of CalIDC1 - CalIDCPadStatusMapA, ///< Status map of the pads (dead etc. obatined from CalIDC0) - CalIDCPadStatusMapC, ///< Status map of the pads (dead etc. obatined from CalIDC0) - CalIDCGroupingParA, ///< Parameters which were used for the averaging of the CalIDCDelta - CalIDCGroupingParC, ///< Parameters which were used for the averaging of the CalIDCDelta - /// - CalSAC0, ///< I_0(r,\phi) = _t - CalSAC1, ///< I_1(t) = _{r,\phi} - CalSACDelta, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalSACFourier, ///< Fourier coefficients of CalSAC1 - /// - CalITPC0, ///< 2D average TPC clusters for longer time interval - CalITPC1, ///< 1D integrated TPC clusters - /// - CalCorrMap, ///< Cluster correction map (high IR rate distortions) - CalCorrMapRef, ///< Cluster correction reference map (static distortions) - CalCorrMapMC, ///< Cluster correction map (high IR rate distortions) for MC - CalCorrDerivMapMC, ///< Cluster correction reference map (static distortions) for MC - /// - CalCorrDerivMap, ///< Cluster correction map (derivative map) - /// - CalTimeSeries, ///< integrated DCAs for longer time interval - CalScaler, ///< Scaler from IDCs or combined estimator - CalScalerWeights, ///< Weights for scalers - CalMShape, ///< calibration object for M-shape distortions - /// - CorrMapParam, ///< parameters for CorrectionMapsLoader configuration - /// - DistortionMapMC, ///< full distortions (static + IR dependant) for MC used in the digitizer - DistortionMapDerivMC ///< derivative distortions for MC used in the digitizer for scaling + CalPedestal, ///< Pedestal calibration + CalNoise, ///< Noise calibration + CalPedestalNoise, ///< Pedestal and Noise calibration + CalPulser, ///< Pulser calibration + CalCE, ///< Laser CE calibration + CalPadGainFull, ///< Full pad gain calibration + CalPadGainResidual, ///< ResidualpPad gain calibration (e.g. from tracks) + CalLaserTracks, ///< Laser track calibration data + CalVDriftTgl, ///< ITS-TPC difTgl vdrift calibration + CalTimeGain, ///< Gain variation over time + CalTimeGainMC, ///< Gain variation over time for MC + CalGas, ///< DCS gas measurements + CalTemperature, ///< DCS temperature measurements + CalHV, ///< DCS HV measurements + CalTopologyGain, ///< Q cluster topology correction + /// + ConfigFEEPad, ///< FEE pad-by-pad configuration map + ConfigFEE, ///< FEE configuration map for each tag + ConfigRunInfo, ///< FEE run information (run -> tag) + /// + ParDetector, ///< Parameter for Detector + ParElectronics, ///< Parameter for Electronics + ParGas, ///< Parameter for Gas + ParGEM, ///< Parameter for GEM + /// + CalIDC0A, ///< I_0(r,\phi) = _t + CalIDC0C, ///< I_0(r,\phi) = _t + CalIDC1A, ///< I_1(t) = _{r,\phi} + CalIDC1C, ///< I_1(t) = _{r,\phi} + CalIDCDeltaA, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalIDCDeltaC, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalIDCFourierA, ///< Fourier coefficients of CalIDC1 + CalIDCFourierC, ///< Fourier coefficients of CalIDC1 + CalIDCPadStatusMapA, ///< Status map of the pads (dead etc. obatined from CalIDC0) + CalIDCPadStatusMapC, ///< Status map of the pads (dead etc. obatined from CalIDC0) + CalIDCGroupingParA, ///< Parameters which were used for the averaging of the CalIDCDelta + CalIDCGroupingParC, ///< Parameters which were used for the averaging of the CalIDCDelta + /// + CalSAC0, ///< I_0(r,\phi) = _t + CalSAC1, ///< I_1(t) = _{r,\phi} + CalSACDelta, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalSACFourier, ///< Fourier coefficients of CalSAC1 + /// + CalITPC0, ///< 2D average TPC clusters for longer time interval + CalITPC1, ///< 1D integrated TPC clusters + /// + CalCorrMap, ///< Cluster correction map (high IR rate distortions) + CalCorrMapRef, ///< Cluster correction reference map (static distortions) + CalCorrMapMC, ///< Cluster correction map (high IR rate distortions) for MC + CalCorrDerivMapMC, ///< Cluster correction reference map (static distortions) for MC + /// + CalCorrDerivMap, ///< Cluster correction map (derivative map) + /// + CalTimeSeries, ///< integrated DCAs for longer time interval + CalScaler, ///< Scaler from IDCs or combined estimator + CalScalerWeights, ///< Weights for scalers + CalMShape, ///< calibration object for M-shape distortions + /// + CorrMapParam, ///< parameters for CorrectionMapsLoader configuration + /// + DistortionMapMC, ///< full distortions (static + IR dependant) for MC used in the digitizer + DistortionMapDerivMC, ///< derivative distortions for MC used in the digitizer for scaling + + AltroSyncSignal ///< timing of Altro chip sync. signal }; /// Storage name in CCDB for each calibration and parameter type @@ -153,6 +155,8 @@ const std::unordered_map CDBTypeMap{ // distortion maps {CDBType::DistortionMapMC, "TPC/Calib/DistortionMapMC"}, {CDBType::DistortionMapDerivMC, "TPC/Calib/DistortionMapDerivativeMC"}, + // AltroSyncSignal + {CDBType::AltroSyncSignal, "TPC/Config/AltroSyncSignal"}, }; } // namespace o2::tpc From 756634ddda00e5794414877ed8476bc166e42fe3 Mon Sep 17 00:00:00 2001 From: pillot Date: Thu, 21 Nov 2024 16:16:55 +0100 Subject: [PATCH 0514/2205] change Mathieson K3xy --- Detectors/MUON/MCH/Base/include/MCHBase/ResponseParam.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Detectors/MUON/MCH/Base/include/MCHBase/ResponseParam.h b/Detectors/MUON/MCH/Base/include/MCHBase/ResponseParam.h index a545bb670d59b..6dba967694026 100644 --- a/Detectors/MUON/MCH/Base/include/MCHBase/ResponseParam.h +++ b/Detectors/MUON/MCH/Base/include/MCHBase/ResponseParam.h @@ -30,11 +30,11 @@ struct ResponseParam : public o2::conf::ConfigurableParamHelper { float pitchSt1 = 0.21; ///< anode-cathode pitch (cm) for station 1 float pitchSt2345 = 0.25; ///< anode-cathode pitch (cm) for station 2 to 5 - float mathiesonSqrtKx3St1 = 0.7000; ///< Mathieson parameter sqrt(K3) in x direction for station 1 - float mathiesonSqrtKx3St2345 = 0.7131; ///< Mathieson parameter sqrt(K3) in x direction for station 2 to 5 + float mathiesonSqrtKx3St1 = 0.5477; ///< Mathieson parameter sqrt(K3) in x direction for station 1 + float mathiesonSqrtKx3St2345 = 0.5477; ///< Mathieson parameter sqrt(K3) in x direction for station 2 to 5 - float mathiesonSqrtKy3St1 = 0.7550; ///< Mathieson parameter sqrt(K3) in y direction for station 1 - float mathiesonSqrtKy3St2345 = 0.7642; ///< Mathieson parameter sqrt(K3) in y direction for station 2 to 5 + float mathiesonSqrtKy3St1 = 0.5477; ///< Mathieson parameter sqrt(K3) in y direction for station 1 + float mathiesonSqrtKy3St2345 = 0.5477; ///< Mathieson parameter sqrt(K3) in y direction for station 2 to 5 float chargeSlopeSt1 = 25.; ///< charge slope used in E to charge conversion for station 1 float chargeSlopeSt2345 = 10.; ///< charge slope used in E to charge conversion for station 2 to 5 From c7c9f5464919fe5890a96cfff985ce66ccabbc75 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 25 Nov 2024 17:30:05 +0100 Subject: [PATCH 0515/2205] Fix in the parsing of ccdb-run-dependent options --- .../Core/src/DataDescriptorQueryBuilder.cxx | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/Framework/Core/src/DataDescriptorQueryBuilder.cxx b/Framework/Core/src/DataDescriptorQueryBuilder.cxx index 41a14d06f3acc..8b0c239699cc9 100644 --- a/Framework/Core/src/DataDescriptorQueryBuilder.cxx +++ b/Framework/Core/src/DataDescriptorQueryBuilder.cxx @@ -319,12 +319,9 @@ std::vector DataDescriptorQueryBuilder::parse(char const* config) if (*currentKey == "lifetime" && currentValue == "condition") { currentLifetime = Lifetime::Condition; } - if (*currentKey == "ccdb-run-dependent" && (currentValue != "false" && currentValue != "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, true, {}}); - } else if (*currentKey == "ccdb-run-dependent" && (currentValue == "false" || currentValue == "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, false, {}}); - } else if (*currentKey == "ccdb-run-dependent") { - error("ccdb-run-dependent can only be true or false"); + if (*currentKey == "ccdb-run-dependent") { + int val = currentValue == "false" ? 0 : (currentValue == "true" ? 1 : std::stoi(*currentValue)); + attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Int, val, {}}); } else { attributes.push_back(ConfigParamSpec{*currentKey, VariantType::String, *currentValue, {}}); } @@ -333,12 +330,9 @@ std::vector DataDescriptorQueryBuilder::parse(char const* config) if (*currentKey == "lifetime" && currentValue == "condition") { currentLifetime = Lifetime::Condition; } - if (*currentKey == "ccdb-run-dependent" && (currentValue != "false" && currentValue != "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, true, {}}); - } else if (*currentKey == "ccdb-run-dependent" && (currentValue == "false" || currentValue == "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, false, {}}); - } else if (*currentKey == "ccdb-run-dependent") { - error("ccdb-run-dependent can only be true or false"); + if (*currentKey == "ccdb-run-dependent") { + int val = currentValue == "false" ? 0 : (currentValue == "true" ? 1 : std::stoi(*currentValue)); + attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Int, val, {}}); } else { attributes.push_back(ConfigParamSpec{*currentKey, VariantType::String, *currentValue, {}}); } @@ -347,12 +341,9 @@ std::vector DataDescriptorQueryBuilder::parse(char const* config) if (*currentKey == "lifetime" && currentValue == "condition") { currentLifetime = Lifetime::Condition; } - if (*currentKey == "ccdb-run-dependent" && (currentValue != "false" && currentValue != "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, true, {}}); - } else if (*currentKey == "ccdb-run-dependent" && (currentValue == "false" || currentValue == "0")) { - attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Bool, false, {}}); - } else if (*currentKey == "ccdb-run-dependent") { - error("ccdb-run-dependent can only be true or false"); + if (*currentKey == "ccdb-run-dependent") { + int val = currentValue == "false" ? 0 : (currentValue == "true" ? 1 : std::stoi(*currentValue)); + attributes.push_back(ConfigParamSpec{*currentKey, VariantType::Int, val, {}}); } else { attributes.push_back(ConfigParamSpec{*currentKey, VariantType::String, *currentValue, {}}); } From 6321af7e1c7d840b49ab6f041afaaaefe3312516 Mon Sep 17 00:00:00 2001 From: swenzel Date: Mon, 25 Nov 2024 13:35:21 +0100 Subject: [PATCH 0516/2205] Ability to create configurable param from a given external struct This commit provides the new feature of being able to create configurable param instances from a given external C++ struct. For example, a C++ struct `struct A { double x; }` can be used to define a correspondig configurable parameter via ``` class MyConfigParamA : o2::conf::ConfigurableParamPromoter {} ``` This allows to: - have "template" structs to create multiple params of the same structure - separate data from configkey functionality - extract data copies from underlying configurable parameters The application thereof is demonstrated for GeneratorPythia8Param. A unit test is added to check the new functionality. --- .../include/CommonUtils/ConfigurableParam.h | 24 +-- .../CommonUtils/ConfigurableParamHelper.h | 158 +++++++++++++++++- Common/Utils/src/ConfigurableParamHelper.cxx | 30 ++-- Generators/CMakeLists.txt | 7 + .../Generators/GeneratorPythia8Param.h | 19 +-- Generators/src/GeneratorPythia8.cxx | 23 +-- Generators/src/GeneratorPythia8Param.cxx | 2 +- Generators/src/GeneratorsLinkDef.h | 3 +- .../test/test_GeneratorPythia8Param.cxx | 80 +++++++++ 9 files changed, 278 insertions(+), 68 deletions(-) create mode 100644 Generators/test/test_GeneratorPythia8Param.cxx diff --git a/Common/Utils/include/CommonUtils/ConfigurableParam.h b/Common/Utils/include/CommonUtils/ConfigurableParam.h index 717a4c425fc82..f44d9efcaea76 100644 --- a/Common/Utils/include/CommonUtils/ConfigurableParam.h +++ b/Common/Utils/include/CommonUtils/ConfigurableParam.h @@ -321,17 +321,19 @@ class ConfigurableParam } // end namespace o2 // a helper macro for boilerplate code in parameter classes -#define O2ParamDef(classname, key) \ - public: \ - classname(TRootIOCtor*) {} \ - classname(classname const&) = delete; \ - \ - private: \ - static constexpr char const* const sKey = key; \ - static classname sInstance; \ - classname() = default; \ - template \ - friend class o2::conf::ConfigurableParamHelper; +#define O2ParamDef(classname, key) \ + public: \ + classname(TRootIOCtor*) {} \ + classname(classname const&) = delete; \ + \ + private: \ + static constexpr char const* const sKey = key; \ + static classname sInstance; \ + classname() = default; \ + template \ + friend class o2::conf::ConfigurableParamHelper; \ + template \ + friend class o2::conf::ConfigurableParamPromoter; // a helper macro to implement necessary symbols in source #define O2ParamImpl(classname) classname classname::sInstance; diff --git a/Common/Utils/include/CommonUtils/ConfigurableParamHelper.h b/Common/Utils/include/CommonUtils/ConfigurableParamHelper.h index 1dc5d5c4c38f8..7d9cb78bb9968 100644 --- a/Common/Utils/include/CommonUtils/ConfigurableParamHelper.h +++ b/Common/Utils/include/CommonUtils/ConfigurableParamHelper.h @@ -45,18 +45,18 @@ class _ParamHelper { private: static std::vector* getDataMembersImpl(std::string const& mainkey, TClass* cl, void*, - std::map const* provmap); + std::map const* provmap, size_t virtualoffset); static void fillKeyValuesImpl(std::string const& mainkey, TClass* cl, void*, boost::property_tree::ptree*, std::map>*, - EnumRegistry*); + EnumRegistry*, size_t offset); static void printWarning(std::type_info const&); static void assignmentImpl(std::string const& mainkey, TClass* cl, void* to, void* from, - std::map* provmap); + std::map* provmap, size_t offset); static void syncCCDBandRegistry(std::string const& mainkey, TClass* cl, void* to, void* from, - std::map* provmap); + std::map* provmap, size_t offset); static void outputMembersImpl(std::ostream& out, std::string const& mainkey, std::vector const* members, bool showProv, bool useLogger); static void printMembersImpl(std::string const& mainkey, std::vector const* members, bool showProv, bool useLogger); @@ -65,6 +65,9 @@ class _ParamHelper template friend class ConfigurableParamHelper; + + template + friend class ConfigurableParamPromoter; }; // ---------------------------------------------------------------- @@ -140,7 +143,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam return nullptr; } - return _ParamHelper::getDataMembersImpl(getName(), cl, (void*)this, sValueProvenanceMap); + return _ParamHelper::getDataMembersImpl(getName(), cl, (void*)this, sValueProvenanceMap, 0); } // ---------------------------------------------------------------- @@ -153,7 +156,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam _ParamHelper::printWarning(typeid(P)); return; } - _ParamHelper::fillKeyValuesImpl(getName(), cl, (void*)this, tree, sKeyToStorageMap, sEnumRegistry); + _ParamHelper::fillKeyValuesImpl(getName(), cl, (void*)this, tree, sKeyToStorageMap, sEnumRegistry, 0); } // ---------------------------------------------------------------- @@ -167,7 +170,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam file->GetObject(getName().c_str(), readback); if (readback != nullptr) { _ParamHelper::assignmentImpl(getName(), TClass::GetClass(typeid(P)), (void*)this, (void*)readback, - sValueProvenanceMap); + sValueProvenanceMap, 0); delete readback; } setRegisterMode(true); @@ -185,7 +188,146 @@ class ConfigurableParamHelper : virtual public ConfigurableParam // setRegisterMode(false); _ParamHelper::syncCCDBandRegistry(getName(), TClass::GetClass(typeid(P)), (void*)this, (void*)externalobj, - sValueProvenanceMap); + sValueProvenanceMap, 0); + setRegisterMode(true); + } + + // ---------------------------------------------------------------- + + void serializeTo(TFile* file) const final + { + file->WriteObjectAny((void*)this, TClass::GetClass(typeid(P)), getName().c_str()); + } +}; + +// Promotes a simple struct Base to a configurable parameter class +// Aka implements all interfaces for a ConfigurableParam P, which shares or +// takes the fields from a Base struct +template +class ConfigurableParamPromoter : public Base, virtual public ConfigurableParam +{ + public: + using ConfigurableParam::ConfigurableParam; + + static const P& Instance() + { + return P::sInstance; + } + + // extracts a copy of the underlying data struct + Base detach() const + { + static_assert(std::copyable, "Base type must be copyable."); + return static_cast(*this); + } + + // ---------------------------------------------------------------- + std::string getName() const final + { + return P::sKey; + } + + // ---------------------------------------------------------------- + // get the provenace of the member with given key + EParamProvenance getMemberProvenance(const std::string& key) const final + { + return getProvenance(getName() + '.' + key); + } + + // ---------------------------------------------------------------- + + // one of the key methods, using introspection to print itself + void printKeyValues(bool showProv = true, bool useLogger = false) const final + { + if (!isInitialized()) { + initialize(); + } + auto members = getDataMembers(); + _ParamHelper::printMembersImpl(getName(), members, showProv, useLogger); + } + + // + size_t getHash() const final + { + return _ParamHelper::getHashImpl(getName(), getDataMembers()); + } + + // ---------------------------------------------------------------- + + void output(std::ostream& out) const final + { + auto members = getDataMembers(); + _ParamHelper::outputMembersImpl(out, getName(), members, true, false); + } + + // ---------------------------------------------------------------- + + // Grab the list of ConfigurableParam data members + // Returns a nullptr if the TClass of the P template class cannot be created. + std::vector* getDataMembers() const + { + // just a helper line to make sure P::sInstance is looked-up + // and that compiler complains about missing static sInstance of type P + // volatile void* ptr = (void*)&P::sInstance; + // static assert on type of sInstance: + static_assert(std::is_same::value, + "static instance must of same type as class"); + + // obtain the TClass for the Base type and delegate further + auto cl = TClass::GetClass(typeid(Base)); + if (!cl) { + _ParamHelper::printWarning(typeid(Base)); + return nullptr; + } + + // we need to put an offset of 8 bytes since internally this is using data members of the Base class + // which doesn't account for the virtual table of P + return _ParamHelper::getDataMembersImpl(getName(), cl, (void*)this, sValueProvenanceMap, 8); + } + + // ---------------------------------------------------------------- + + // fills the data structures with the initial default values + void putKeyValues(boost::property_tree::ptree* tree) final + { + auto cl = TClass::GetClass(typeid(Base)); + if (!cl) { + _ParamHelper::printWarning(typeid(Base)); + return; + } + _ParamHelper::fillKeyValuesImpl(getName(), cl, (void*)this, tree, sKeyToStorageMap, sEnumRegistry, 8); + } + + // ---------------------------------------------------------------- + + void initFrom(TFile* file) final + { + // switch off auto registering since the readback object is + // only a "temporary" singleton + setRegisterMode(false); + P* readback = nullptr; + file->GetObject(getName().c_str(), readback); + if (readback != nullptr) { + _ParamHelper::assignmentImpl(getName(), TClass::GetClass(typeid(Base)), (void*)this, (void*)readback, + sValueProvenanceMap, 8); + delete readback; + } + setRegisterMode(true); + } + + // ---------------------------------------------------------------- + + void syncCCDBandRegistry(void* externalobj) final + { + // We may be getting an external copy from CCDB which is passed as externalobj. + // The task of this function is to + // a) update the internal registry with fields coming from CCDB + // but only if keys have not been modified via RT == command line / ini file + // b) update the external object with with fields having RT provenance + // + setRegisterMode(false); + _ParamHelper::syncCCDBandRegistry(getName(), TClass::GetClass(typeid(Base)), (void*)this, (void*)externalobj, + sValueProvenanceMap, 8); setRegisterMode(true); } diff --git a/Common/Utils/src/ConfigurableParamHelper.cxx b/Common/Utils/src/ConfigurableParamHelper.cxx index 0fb213b722e26..f217d402bcb45 100644 --- a/Common/Utils/src/ConfigurableParamHelper.cxx +++ b/Common/Utils/src/ConfigurableParamHelper.cxx @@ -182,19 +182,19 @@ std::string asString(TDataMember const& dm, char* pointer) // potentially other cases to be added here LOG(error) << "COULD NOT REPRESENT AS STRING"; - return nullptr; + return std::string(); } // ---------------------------------------------------------------------- std::vector* _ParamHelper::getDataMembersImpl(std::string const& mainkey, TClass* cl, void* obj, - std::map const* provmap) + std::map const* provmap, size_t globaloffset) { std::vector* members = new std::vector; - auto toDataMember = [&members, obj, mainkey, provmap](const TDataMember* dm, int index, int size) { + auto toDataMember = [&members, obj, mainkey, provmap, globaloffset](const TDataMember* dm, int index, int size) { auto TS = getSizeOfUnderlyingType(*dm); - char* pointer = ((char*)obj) + dm->GetOffset() + index * TS; + char* pointer = ((char*)obj) + dm->GetOffset() + index * TS + globaloffset; const std::string name = getName(dm, index, size); auto value = asString(*dm, pointer); @@ -280,14 +280,14 @@ std::type_info const& nameToTypeInfo(const char* tname, TDataType const* dt) void _ParamHelper::fillKeyValuesImpl(std::string const& mainkey, TClass* cl, void* obj, boost::property_tree::ptree* tree, std::map>* keytostoragemap, - EnumRegistry* enumRegistry) + EnumRegistry* enumRegistry, size_t globaloffset) { boost::property_tree::ptree localtree; - auto fillMap = [obj, &mainkey, &localtree, &keytostoragemap, &enumRegistry](const TDataMember* dm, int index, int size) { + auto fillMap = [obj, &mainkey, &localtree, &keytostoragemap, &enumRegistry, globaloffset](const TDataMember* dm, int index, int size) { const auto name = getName(dm, index, size); auto dt = dm->GetDataType(); auto TS = getSizeOfUnderlyingType(*dm); - char* pointer = ((char*)obj) + dm->GetOffset() + index * TS; + char* pointer = ((char*)obj) + dm->GetOffset() + index * TS + globaloffset; localtree.put(name, asString(*dm, pointer)); auto key = mainkey + "." + name; @@ -355,14 +355,14 @@ bool isMemblockDifferent(char const* block1, char const* block2, int sizeinbytes // ---------------------------------------------------------------------- void _ParamHelper::assignmentImpl(std::string const& mainkey, TClass* cl, void* to, void* from, - std::map* provmap) + std::map* provmap, size_t globaloffset) { - auto assignifchanged = [to, from, &mainkey, provmap](const TDataMember* dm, int index, int size) { + auto assignifchanged = [to, from, &mainkey, provmap, globaloffset](const TDataMember* dm, int index, int size) { const auto name = getName(dm, index, size); auto dt = dm->GetDataType(); auto TS = getSizeOfUnderlyingType(*dm); - char* pointerto = ((char*)to) + dm->GetOffset() + index * TS; - char* pointerfrom = ((char*)from) + dm->GetOffset() + index * TS; + char* pointerto = ((char*)to) + dm->GetOffset() + index * TS + globaloffset; + char* pointerfrom = ((char*)from) + dm->GetOffset() + index * TS + globaloffset; // lambda to update the provenance auto updateProv = [&mainkey, name, provmap]() { @@ -402,14 +402,14 @@ void _ParamHelper::assignmentImpl(std::string const& mainkey, TClass* cl, void* // ---------------------------------------------------------------------- void _ParamHelper::syncCCDBandRegistry(const std::string& mainkey, TClass* cl, void* to, void* from, - std::map* provmap) + std::map* provmap, size_t globaloffset) { - auto sync = [to, from, &mainkey, provmap](const TDataMember* dm, int index, int size) { + auto sync = [to, from, &mainkey, provmap, globaloffset](const TDataMember* dm, int index, int size) { const auto name = getName(dm, index, size); auto dt = dm->GetDataType(); auto TS = getSizeOfUnderlyingType(*dm); - char* pointerto = ((char*)to) + dm->GetOffset() + index * TS; - char* pointerfrom = ((char*)from) + dm->GetOffset() + index * TS; + char* pointerto = ((char*)to) + dm->GetOffset() + index * TS + globaloffset; + char* pointerfrom = ((char*)from) + dm->GetOffset() + index * TS + globaloffset; // check current provenance auto key = mainkey + "." + name; diff --git a/Generators/CMakeLists.txt b/Generators/CMakeLists.txt index d60d185817c84..d909b3e604887 100644 --- a/Generators/CMakeLists.txt +++ b/Generators/CMakeLists.txt @@ -129,8 +129,15 @@ if(doBuildSimulation) COMPONENT_NAME Generator LABELS generator PUBLIC_LINK_LIBRARIES O2::Generators) + + o2_add_test(GeneratorPythia8Param NAME test_Generator_test_GeneratorPythia8Param + SOURCES test/test_GeneratorPythia8Param.cxx + COMPONENT_NAME Generator + LABELS generator + PUBLIC_LINK_LIBRARIES O2::Generators) endif() + o2_add_test_root_macro(share/external/tgenerator.C PUBLIC_LINK_LIBRARIES O2::Generators LABELS generators) diff --git a/Generators/include/Generators/GeneratorPythia8Param.h b/Generators/include/Generators/GeneratorPythia8Param.h index 165b1622239f5..612964fca73d9 100644 --- a/Generators/include/Generators/GeneratorPythia8Param.h +++ b/Generators/include/Generators/GeneratorPythia8Param.h @@ -24,28 +24,21 @@ namespace eventgen { /** - ** a parameter class/struct to keep the settings of - ** the Pythia8 event generator and - ** allow the user to modify them + ** a parameter class/struct to configure the settings of + ** the GeneratorPythia8 event generator **/ - -struct GeneratorPythia8Param : public o2::conf::ConfigurableParamHelper { +struct Pythia8GenConfig { std::string config = ""; std::string hooksFileName = ""; std::string hooksFuncName = ""; bool includePartonEvent = false; // whether to keep the event before hadronization std::string particleFilter = ""; // user particle filter int verbose = 0; // verbose control (if > 0 may show more info messages about what is going on) - O2ParamDef(GeneratorPythia8Param, "GeneratorPythia8"); }; -struct Pythia8GenConfig { - std::string config = ""; - std::string hooksFileName = ""; - std::string hooksFuncName = ""; - bool includePartonEvent = false; // whether to keep the event before hadronization - std::string particleFilter = ""; // user particle filter - int verbose = 0; // verbose control (if > 0 may show more info messages about what is going on) +// construct a configurable param singleton out of the Pythia8GenConfig struct +struct GeneratorPythia8Param : public o2::conf::ConfigurableParamPromoter { + O2ParamDef(GeneratorPythia8Param, "GeneratorPythia8"); }; } // end namespace eventgen diff --git a/Generators/src/GeneratorPythia8.cxx b/Generators/src/GeneratorPythia8.cxx index 8c9b4fcffdff2..fef2c4d2e9a1c 100644 --- a/Generators/src/GeneratorPythia8.cxx +++ b/Generators/src/GeneratorPythia8.cxx @@ -45,26 +45,11 @@ namespace eventgen /*****************************************************************/ /*****************************************************************/ -GeneratorPythia8::GeneratorPythia8() : Generator("ALICEo2", "ALICEo2 Pythia8 Generator") +// the default construct uses the GeneratorPythia8Param singleton to extract a config and delegates +// to the proper constructor +GeneratorPythia8::GeneratorPythia8() : GeneratorPythia8(GeneratorPythia8Param::Instance().detach()) { - /** default constructor **/ - - mInterface = reinterpret_cast(&mPythia); - mInterfaceName = "pythia8"; - - auto& param = GeneratorPythia8Param::Instance(); - LOG(info) << "Default Instance \'Pythia8\' generator with following parameters"; - LOG(info) << param; - - // convert the outside singleton config to the internally used one - o2::eventgen::Pythia8GenConfig config{param.config, - param.hooksFileName, param.hooksFuncName, param.includePartonEvent, param.particleFilter, param.verbose}; - mGenConfig = config; - - setConfig(config.config); - setHooksFileName(config.hooksFileName); - setHooksFuncName(config.hooksFuncName); - // TODO: use constructor delegation to other interface + LOG(info) << "GeneratorPythia8 constructed from GeneratorPythia8Param ConfigurableParam"; } /*****************************************************************/ diff --git a/Generators/src/GeneratorPythia8Param.cxx b/Generators/src/GeneratorPythia8Param.cxx index 984680e46ad01..6b477beb16ba9 100644 --- a/Generators/src/GeneratorPythia8Param.cxx +++ b/Generators/src/GeneratorPythia8Param.cxx @@ -12,4 +12,4 @@ /// \author R+Preghenella - January 2020 #include "Generators/GeneratorPythia8Param.h" -O2ParamImpl(o2::eventgen::GeneratorPythia8Param); +O2ParamImpl(o2::eventgen::GeneratorPythia8Param); \ No newline at end of file diff --git a/Generators/src/GeneratorsLinkDef.h b/Generators/src/GeneratorsLinkDef.h index 41e14b02f18b9..fe219c6f5476c 100644 --- a/Generators/src/GeneratorsLinkDef.h +++ b/Generators/src/GeneratorsLinkDef.h @@ -48,8 +48,9 @@ #pragma link C++ class o2::eventgen::GeneratorPythia8Param + ; #pragma link C++ class o2::eventgen::Pythia8GenConfig + ; #pragma link C++ class o2::eventgen::DecayerPythia8Param + ; -#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorPythia8Param> + ; +#pragma link C++ class o2::conf::ConfigurableParamPromoter < o2::eventgen::GeneratorPythia8Param, o2::eventgen::Pythia8GenConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::DecayerPythia8Param> + ; + #pragma link C++ class o2::eventgen::GeneratorFactory + ; #endif #if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3) diff --git a/Generators/test/test_GeneratorPythia8Param.cxx b/Generators/test/test_GeneratorPythia8Param.cxx new file mode 100644 index 0000000000000..c735487ea293c --- /dev/null +++ b/Generators/test/test_GeneratorPythia8Param.cxx @@ -0,0 +1,80 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#define BOOST_TEST_MODULE Test GeneratorPythia8Param class +#define BOOST_TEST_MAIN +#define BOOST_TEST_DYN_LINK +#include +#include +#include +#include +#include "CCDB/BasicCCDBManager.h" + +// Tests various aspects of the +// ConfigurableParamPromoter class, which is used to promote +// Pythia8GenConfig to a configurable param +BOOST_AUTO_TEST_CASE(pythia8_Pythia8GenConfig) +{ + o2::conf::ConfigurableParam::updateFromString( + "GeneratorPythia8.config=Foo;GeneratorPythia8.includePartonEvent=true"); + + using o2::eventgen::GeneratorPythia8Param; + + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().config, std::string("Foo")); + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().includePartonEvent, true); + + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().includePartonEvent, o2::conf::ConfigurableParam::getValueAs("GeneratorPythia8.includePartonEvent")); + // setValue - getValue + o2::conf::ConfigurableParam::setValue("GeneratorPythia8.config", "Baz"); + BOOST_CHECK_EQUAL(o2::conf::ConfigurableParam::getValueAs("GeneratorPythia8.config"), std::string("Baz")); + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().config, std::string("Baz")); + + // member provenance + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().getMemberProvenance("config"), o2::conf::ConfigurableParam::EParamProvenance::kRT); + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().getMemberProvenance("verbose"), o2::conf::ConfigurableParam::EParamProvenance::kCODE); + + // config detach + auto config_copy = GeneratorPythia8Param::Instance().detach(); + BOOST_CHECK_EQUAL(config_copy.config, std::string("Baz")); + BOOST_CHECK_EQUAL(config_copy.includePartonEvent, true); + + // file IO + TFile tmp_file("GeneratorParamConfig_tmp.root", "RECREATE"); + + GeneratorPythia8Param::Instance().serializeTo(&tmp_file); + // modify the instance to some intermediate fluent value + o2::conf::ConfigurableParam::setValue("GeneratorPythia8.includePartonEvent", "0"); + BOOST_CHECK_EQUAL(config_copy.includePartonEvent, true); + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().includePartonEvent, false); + tmp_file.Close(); + + // read back + TFile tmp_file2("GeneratorParamConfig_tmp.root", "READ"); + const_cast(GeneratorPythia8Param::Instance()).initFrom(&tmp_file2); + BOOST_CHECK_EQUAL(GeneratorPythia8Param::Instance().includePartonEvent, true); + tmp_file2.Close(); + + // CCDB IO + std::string ccdbUrl = "http://ccdb-test.cern.ch:8080"; + bool hostReachable = false; + o2::ccdb::CcdbApi api; + api.init(ccdbUrl); + std::string pathA = "/Generators/UnitTest/Pythia8/GeneratorPythia8Param"; + std::map md; + long start = 1000, stop = 2000; + api.storeAsTFileAny(&GeneratorPythia8Param::Instance(), pathA, md, start, stop); + + // modify the instance to some intermediate fluent value + o2::conf::ConfigurableParam::setValue("GeneratorPythia8.includePartonEvent", "0"); + + auto returnedobj = api.retrieveFromTFileAny(pathA, md, (start + stop) / 2); + GeneratorPythia8Param::Instance().printKeyValues(); +}; From 80827ee98564632ed38bd4ff1dfe990f20dd0885 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:16:12 +0100 Subject: [PATCH 0517/2205] DPL: add test for exception throwing in Variant (#13735) --- Framework/Core/include/Framework/Variant.h | 2 +- Framework/Core/test/test_Variants.cxx | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/Variant.h b/Framework/Core/include/Framework/Variant.h index 54a91e90c3638..e69ca05b91d98 100644 --- a/Framework/Core/include/Framework/Variant.h +++ b/Framework/Core/include/Framework/Variant.h @@ -355,7 +355,7 @@ class Variant T get() const { if (mType != variant_trait_v) { - throw runtime_error("Mismatch between types"); + throw runtime_error_f("Variant::get: Mismatch between types %d %d.", mType, variant_trait_v); } return variant_helper::get(&mStore); } diff --git a/Framework/Core/test/test_Variants.cxx b/Framework/Core/test/test_Variants.cxx index a0edf40cf9f0d..a364b228871da 100644 --- a/Framework/Core/test/test_Variants.cxx +++ b/Framework/Core/test/test_Variants.cxx @@ -338,3 +338,15 @@ TEST_CASE("VariantJSONConversionsTest") REQUIRE(vstrings[i] == vvstra.get()[i]); } } + +TEST_CASE("VariantThrowing") +{ + Variant a("true"); + REQUIRE_THROWS_AS(a.get(), o2::framework::RuntimeErrorRef); + try { + a.get(); + } catch (RuntimeErrorRef& ref) { + RuntimeError& error = error_from_ref(ref); + REQUIRE(error.what == std::string("Variant::get: Mismatch between types 4 0.")); + } +} From 73f5254100243ef666a98cea55afaec6f79da221 Mon Sep 17 00:00:00 2001 From: Sergio Date: Mon, 25 Nov 2024 10:41:03 +0100 Subject: [PATCH 0518/2205] Log TrackRefs size before failing assert --- run/checkStack.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run/checkStack.cxx b/run/checkStack.cxx index 4470ea463fd98..4c2b9d5b50075 100644 --- a/run/checkStack.cxx +++ b/run/checkStack.cxx @@ -143,8 +143,8 @@ int main(int argc, char** argv) if (havereferences) { for (auto& trackID : trackidsinTPC) { auto trackrefs = mcreader.getTrackRefs(eventID, trackID); - assert(trackrefs.size() > 0); LOG(debug) << " Track " << trackID << " has " << trackrefs.size() << " TrackRefs"; + assert(trackrefs.size() > 0); for (auto& ref : trackrefs) { assert(ref.getTrackID() == trackID); } From 63349508cdcd715c60c4755d7303206d314194e8 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Tue, 12 Nov 2024 15:33:18 +0100 Subject: [PATCH 0519/2205] QC: Glo change tpc DCAr axis-range --- Detectors/GLOQC/src/MatchITSTPCQC.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Detectors/GLOQC/src/MatchITSTPCQC.cxx b/Detectors/GLOQC/src/MatchITSTPCQC.cxx index 56462344850d6..f0345175b9a59 100644 --- a/Detectors/GLOQC/src/MatchITSTPCQC.cxx +++ b/Detectors/GLOQC/src/MatchITSTPCQC.cxx @@ -344,10 +344,10 @@ bool MatchITSTPCQC::init() mChi2Refit = new TH1F("mChi2Refit", "Chi2 of refit; chi2", 200, 0, 300); mChi2Refit->SetOption("logy"); mChi2Refit->GetYaxis()->SetTitleOffset(1.4); - mDCAr = new TH1F("mDCAr", "DCA of TPC tracks; DCAr", 200, -100, 100); - mDCArVsPtNum = new TH2F("mDCArVsPtNum", "DCA of TPC tracks Vs Pt Num; #it{p}_{T} [GeV/c]; DCAr", 100, 0, 20., 200, -30, 30); + mDCAr = new TH1F("mDCAr", "DCA of TPC tracks; DCAr", 100, -mDCATPCCutY, mDCATPCCutY); + mDCArVsPtNum = new TH2F("mDCArVsPtNum", "DCA of TPC tracks Vs Pt Num; #it{p}_{T} [GeV/c]; DCAr", 100, 0, 20., 100, -mDCATPCCutY, mDCATPCCutY); mDCArVsPtNum->Sumw2(); - mDCArVsPtDen = new TH2F("mDCArVsPtDen", "DCA of TPC tracks Vs Pt Den; #it{p}_{T} [GeV/c]; DCAr", 100, 0, 20., 200, -30, 30); + mDCArVsPtDen = new TH2F("mDCArVsPtDen", "DCA of TPC tracks Vs Pt Den; #it{p}_{T} [GeV/c]; DCAr", 100, 0, 20., 100, -mDCATPCCutY, mDCATPCCutY); mDCArVsPtDen->Sumw2(); mFractionITSTPCmatchDCArVsPt = new TEfficiency("mFractionITSTPCmatchDCArVsPt", "Fraction of ITSTPC matched tracks wrt TPC vs DCAr; #it{p}_{T} [GeV#it{c}]; DCAr; Eff", 100, 0, 20., 200, -30, 30); From 061a31051f224e2b2ece2bff8abadb8aa89a016b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 26 Nov 2024 13:25:31 +0100 Subject: [PATCH 0520/2205] GPU: Some cleanup, and fixes when running only part of processing on GPU --- GPU/GPUTracking/Global/GPUChainTracking.cxx | 27 ------------------ .../Global/GPUChainTrackingClusterizer.cxx | 5 ++-- .../Global/GPUChainTrackingSliceTracker.cxx | 27 ++++++++++++++++++ .../SliceTracker/GPUTPCSliceData.cxx | 28 +++++++++---------- .../SliceTracker/GPUTPCTracker.cxx | 4 +-- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 8c2599604387b..b06d636970da7 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -921,33 +921,6 @@ int32_t GPUChainTracking::FinalizePipelinedProcessing() return RunChainFinalize(); } -int32_t GPUChainTracking::HelperReadEvent(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) { return ReadEvent(iSlice, threadId); } - -int32_t GPUChainTracking::HelperOutput(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) -{ - if (param().rec.tpc.globalTracking) { - uint32_t tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); - uint32_t sliceLeft, sliceRight; - GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(tmpSlice, sliceLeft, sliceRight); - - while (mSliceSelectorReady < (int32_t)tmpSlice || mSliceSelectorReady < (int32_t)sliceLeft || mSliceSelectorReady < (int32_t)sliceRight) { - if (par->reset) { - return 1; - } - } - GlobalTracking(tmpSlice, 0); - WriteOutput(tmpSlice, 0); - } else { - while (mSliceSelectorReady < iSlice) { - if (par->reset) { - return 1; - } - } - WriteOutput(iSlice, threadId); - } - return 0; -} - int32_t GPUChainTracking::CheckErrorCodes(bool cpuOnly, bool forceShowErrors, std::vector>* fillErrors) { int32_t retVal = 0; diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index ae240181eba65..97870d74ca624 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -457,6 +457,7 @@ std::pair GPUChainTracking::RunTPCClusterizer_transferZS(int int32_t GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) { + bool doGPU = mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCClusterFinding; if (restorePointers) { for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice++) { processors()->tpcClusterer[iSlice].mPzsOffsets = mCFContext->ptrSave[iSlice].zsOffsetHost; @@ -512,7 +513,7 @@ int32_t GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers) uint32_t threshold = 40000000; uint32_t nDigitsScaled = nDigitsBase > threshold ? nDigitsBase : std::min((threshold + nDigitsBase) / 2, 2 * nDigitsBase); processors()->tpcClusterer[iSlice].SetNMaxDigits(processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits, mCFContext->nPagesFragmentMax, nDigitsScaled, mCFContext->nDigitsEndpointMax[iSlice]); - if (mRec->IsGPU()) { + if (doGPU) { processorsShadow()->tpcClusterer[iSlice].SetNMaxDigits(processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits, mCFContext->nPagesFragmentMax, nDigitsScaled, mCFContext->nDigitsEndpointMax[iSlice]); } if (mPipelineNotifyCtx && GetProcessingSettings().doublePipelineClusterizer) { @@ -578,7 +579,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) if (RunTPCClusterizer_prepare(mPipelineNotifyCtx && GetProcessingSettings().doublePipelineClusterizer)) { return 1; } - if (GetProcessingSettings().ompAutoNThreads && !mRec->IsGPU()) { + if (GetProcessingSettings().ompAutoNThreads && !doGPU) { mRec->SetNOMPThreads(mRec->MemoryScalers()->nTPCdigits / 20000); } diff --git a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx index 8db15fb1aef7e..62c93bcb1bfb5 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingSliceTracker.cxx @@ -532,3 +532,30 @@ void GPUChainTracking::WriteOutput(int32_t iSlice, int32_t threadId) GPUInfo("Finished WriteOutput for slice %d on thread %d\n", iSlice, threadId); } } + +int32_t GPUChainTracking::HelperReadEvent(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) { return ReadEvent(iSlice, threadId); } + +int32_t GPUChainTracking::HelperOutput(int32_t iSlice, int32_t threadId, GPUReconstructionHelpers::helperParam* par) +{ + if (param().rec.tpc.globalTracking) { + uint32_t tmpSlice = GPUTPCGlobalTracking::GlobalTrackingSliceOrder(iSlice); + uint32_t sliceLeft, sliceRight; + GPUTPCGlobalTracking::GlobalTrackingSliceLeftRight(tmpSlice, sliceLeft, sliceRight); + + while (mSliceSelectorReady < (int32_t)tmpSlice || mSliceSelectorReady < (int32_t)sliceLeft || mSliceSelectorReady < (int32_t)sliceRight) { + if (par->reset) { + return 1; + } + } + GlobalTracking(tmpSlice, 0); + WriteOutput(tmpSlice, 0); + } else { + while (mSliceSelectorReady < iSlice) { + if (par->reset) { + return 1; + } + } + WriteOutput(iSlice, threadId); + } + return 0; +} diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx index 6908bc326a535..6c456a28918ab 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCSliceData.cxx @@ -265,22 +265,20 @@ GPUdii() int32_t GPUTPCSliceData::InitFromClusterData(int32_t nBlocks, int32_t n for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { UpdateMinMaxYZ(yMin, yMax, zMin, zMax, YZData[RowOffset + i].x, YZData[RowOffset + i].y); } + } else if (mem->param.par.earlyTpcTransform) { // Early transform case with ClusterNative present + for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { + float2 tmp; + tmp.x = mClusterData[RowOffset + i].y; + tmp.y = mClusterData[RowOffset + i].z; + UpdateMinMaxYZ(yMin, yMax, zMin, zMax, tmp.x, tmp.y); + YZData[RowOffset + i] = tmp; + } } else { - if (mem->param.par.earlyTpcTransform) { // Early transform case with ClusterNative present - for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { - float2 tmp; - tmp.x = mClusterData[RowOffset + i].y; - tmp.y = mClusterData[RowOffset + i].z; - UpdateMinMaxYZ(yMin, yMax, zMin, zMax, tmp.x, tmp.y); - YZData[RowOffset + i] = tmp; - } - } else { - for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { - float x, y, z; - GPUTPCConvertImpl::convert(*mem, iSlice, rowIndex, mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getPad(), mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getTime(), x, y, z); - UpdateMinMaxYZ(yMin, yMax, zMin, zMax, y, z); - YZData[RowOffset + i] = CAMath::MakeFloat2(y, z); - } + for (uint32_t i = iThread; i < NumberOfClusters; i += nThreads) { + float x, y, z; + GPUTPCConvertImpl::convert(*mem, iSlice, rowIndex, mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getPad(), mem->ioPtrs.clustersNative->clusters[iSlice][rowIndex][i].getTime(), x, y, z); + UpdateMinMaxYZ(yMin, yMax, zMin, zMax, y, z); + YZData[RowOffset + i] = CAMath::MakeFloat2(y, z); } } diff --git a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx index 7428a4ccbd0ed..84bdc52ab6f46 100644 --- a/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx +++ b/GPU/GPUTracking/SliceTracker/GPUTPCTracker.cxx @@ -81,7 +81,7 @@ void* GPUTPCTracker::SetPointersScratch(void* mem) if (mRec->GetProcessingSettings().memoryAllocationStrategy != GPUMemoryResource::ALLOCATION_INDIVIDUAL) { mem = SetPointersTracklets(mem); } - if (mRec->IsGPU()) { + if (mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCSliceTracking) { computePointerWithAlignment(mem, mTrackletTmpStartHits, GPUCA_ROW_COUNT * mNMaxRowStartHits); computePointerWithAlignment(mem, mRowStartHitCountOffset, GPUCA_ROW_COUNT); } @@ -164,7 +164,7 @@ void GPUTPCTracker::SetMaxData(const GPUTrackingInOutPointers& io) mNMaxTracks = mRec->MemoryScalers()->NTPCSectorTracks(mData.NumberOfHits()); mNMaxTrackHits = mRec->MemoryScalers()->NTPCSectorTrackHits(mData.NumberOfHits(), mRec->GetProcessingSettings().tpcInputWithClusterRejection); #ifdef GPUCA_SORT_STARTHITS_GPU - if (mRec->IsGPU()) { + if (mRec->GetRecoStepsGPU() & GPUDataTypes::RecoStep::TPCSliceTracking) { if (mNMaxStartHits > mNMaxRowStartHits * GPUCA_ROW_COUNT) { mNMaxStartHits = mNMaxRowStartHits * GPUCA_ROW_COUNT; } From 3d3ee4df7e1e3e5b99b9eb623039633e2e0f721b Mon Sep 17 00:00:00 2001 From: Diego Stocco Date: Tue, 19 Nov 2024 10:40:33 +0100 Subject: [PATCH 0521/2205] Improvements on the MID reject list - Correctly build the reject list even for runs where the issue happens at the very last sampled QC object, just before EOR - Search for switched off boards at the end of the period with bad quality instead of the beginning. This should make sure that we do not miss additional boards that stops sending data - Remove additional time margin at the beginning and end of the run - Get run number from QC metadata --- .../MID/Calibration/macros/build_rejectlist.C | 162 +++++++++++------- 1 file changed, 96 insertions(+), 66 deletions(-) diff --git a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C index 7a395d2c099da..48391b4460687 100644 --- a/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C +++ b/Detectors/MUON/MID/Calibration/macros/build_rejectlist.C @@ -50,6 +50,17 @@ struct RejectListStruct { std::vector rejectList{}; /// Bad channels }; +/// @brief Useful metadata +struct MDStruct { + long start = 0; /// Start validity + long end = 0; /// End validity + int runNumber = 0; /// Run number + std::string runType; /// Run Type + + bool operator<(const MDStruct& other) const { return start < other.start; } + bool operator==(const MDStruct& other) const { return start == other.start; } +}; + /// @brief Get timestamp in milliseconds /// @param timestamp Input timestamp (in s or ms) /// @return Timestamp in ms @@ -96,23 +107,33 @@ std::string timeRangeToString(long start, long end) /// @param end Query objects created not after /// @param api CDB api /// @param path CDB path -/// @return Vector of start validity of each object sorted in ascending way -std::vector findObjectsTSInPeriod(long start, long end, const o2::ccdb::CcdbApi& api, const char* path) +/// @return Vector of metadata in ascending order +std::vector findObjectsMDInPeriod(long start, long end, const o2::ccdb::CcdbApi& api, const char* path) { - std::vector ts; - auto out = api.list(path, false, "text/plain", getTSMS(end), getTSMS(start)); - std::stringstream ss(out); - std::string token; - while (ss >> token) { - if (token.find("Validity") != std::string::npos) { - ss >> token; - ts.emplace_back(std::atol(token.c_str())); - } + std::vector mds; + auto out = api.list(path, false, "application/json", getTSMS(end), getTSMS(start)); + rapidjson::Document doc; + doc.Parse(out.c_str()); + for (auto& obj : doc["objects"].GetArray()) { + MDStruct md; + md.start = obj["validFrom"].GetInt64(); + md.end = obj["validUntil"].GetInt64(); + md.runNumber = std::atoi(obj["RunNumber"].GetString()); + md.runType = obj["RunType"].GetString(); + mds.emplace_back(md); } - ts.erase(std::unique(ts.begin(), ts.end()), ts.end()); + mds.erase(std::unique(mds.begin(), mds.end()), mds.end()); // Sort timestamps in ascending order - std::sort(ts.begin(), ts.end()); - return ts; + std::sort(mds.begin(), mds.end()); + return mds; +} + +/// @brief Gets the quality trend graph from the quality canvas +/// @param qcQuality MID QC quality canvas +/// @return Quality trend graph +TGraph* getQualityTrend(const TCanvas* qcQuality) +{ + return static_cast(qcQuality->GetListOfPrimitives()->FindObject("Graph")); } /// @brief Find the first and last time when the quality was good or bad @@ -127,7 +148,7 @@ std::pair findTSRange(TCanvas* qcQuality, bool selectBad = t // Medium: 2.5 // Bad: 1.5 // Null: 0.5 - auto* gr = static_cast(qcQuality->GetListOfPrimitives()->FindObject("Graph")); + auto* gr = getQualityTrend(qcQuality); double xp, yp; std::pair range{std::numeric_limits::max(), 0}; for (int ip = 0; ip < gr->GetN(); ++ip) { @@ -144,6 +165,32 @@ std::pair findTSRange(TCanvas* qcQuality, bool selectBad = t return range; } +/// @brief Gets the first and last timestamp in the quality +/// @param qcQuality MID QC quality canvas +/// @return Pair with the first and last timestamp in the quality trend +std::pair getFirstLast(const TCanvas* qcQuality) +{ + auto* gr = getQualityTrend(qcQuality); + double xp1, xp2, yp; + gr->GetPoint(0, xp1, yp); + gr->GetPoint(gr->GetN() - 1, xp2, yp); + return {static_cast(xp1 * 1000), static_cast(xp2 * 1000)}; +} + +/// @brief Update the selected range of timestamp +/// @param selectedTSRange Reference to the selected range to be modified +/// @param qcTSRange Range of the MID quality trend +/// @param runRange Run range +void updateRange(std::pair& selectedTSRange, const std::pair qcTSRange, const std::pair runRange) +{ + if (selectedTSRange.first == qcTSRange.first) { + selectedTSRange.first = runRange.first; + } + if (selectedTSRange.second == qcTSRange.second) { + selectedTSRange.second = runRange.second; + } +} + /// @brief Find bad channels from the occupancy histograms /// @param hits Occupancy histogram /// @param infos Mapping @@ -186,72 +233,61 @@ std::vector getRejectList(std::vector return badChannels; } -/// @brief Gets the run duration with a safety marging -/// @param ccdbApi CCDB api -/// @param marging margin in milliseconds -/// @return Pair with the timestamps of start-margin and end+margin for the run -std::pair getRunDuration(const o2::ccdb::CcdbApi& ccdbApi, int runNumber, int64_t margin = 120000) -{ - auto runRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, runNumber); - runRange.first -= margin; // Subtract margin - runRange.second += margin; // Add margin - return runRange; -} - /// @brief Builds the reject list for the selected timestamp -/// @param timestamp Timestamp for query +/// @param md MD structure /// @param qcdbApi QCDB api /// @param ccdbApi CCDB api /// @param outCCDBApi api of the CCDB where the reject list will be uploaded /// @return Reject list -RejectListStruct build_rejectlist(long timestamp, const o2::ccdb::CcdbApi& qcdbApi, const o2::ccdb::CcdbApi& ccdbApi) +RejectListStruct build_rejectlist(const MDStruct& md, const o2::ccdb::CcdbApi& qcdbApi, const o2::ccdb::CcdbApi& ccdbApi) { - std::map metadata; RejectListStruct rl; - auto* qcQuality = qcdbApi.retrieveFromTFileAny(sPathQCQuality, metadata, getTSMS(timestamp)); + if (md.runType != "PHYSICS") { + std::cout << "Run " << md.runNumber << " is of type " << md.runType << ": skip" << std::endl; + return rl; + } + + std::map metadata; + auto* qcQuality = qcdbApi.retrieveFromTFileAny(sPathQCQuality, metadata, getTSMS(md.start)); if (!qcQuality) { - std::cerr << "Cannot find QC quality for " << tsToString(timestamp) << std::endl; + std::cerr << "Cannot find QC quality for " << tsToString(md.start) << std::endl; return rl; } + // Find the first and last timestamp where the quality was bad (if any) auto badTSRange = findTSRange(qcQuality); if (badTSRange.second == 0) { std::cout << "All good" << std::endl; return rl; } + + // Find the first and last timestamp where the quality flag was set + auto qualityTSRange = getFirstLast(qcQuality); // Search for the last timestamp for which the run quality was good auto goodTSRange = findTSRange(qcQuality, false); - // Query the CCDB to see to which run the timestamp corresponds - auto oldestTSInQCQuality = (goodTSRange.first == 0) ? badTSRange.first : goodTSRange.first; - auto grpecs = *ccdbApi.retrieveFromTFileAny("GLO/Config/GRPECS", metadata, getTSMS(oldestTSInQCQuality)); - if (!grpecs.isDetReadOut(o2::detectors::DetID::MID)) { - std::cout << "Error: we are probably reading a parallel run" << std::endl; - grpecs.print(); - return rl; - } - if (grpecs.getRunType() != o2::parameters::GRPECS::PHYSICS) { - std::cout << "This is not a physics run: skip" << std::endl; - grpecs.print(); - return rl; - } - auto runRange = getRunDuration(ccdbApi, grpecs.getRun()); + auto runRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, md.runNumber); + updateRange(badTSRange, qualityTSRange, runRange); + updateRange(goodTSRange, qualityTSRange, runRange); // Search for hits histogram in the period where the QC quality was bad - auto tsVector = findObjectsTSInPeriod(badTSRange.first, badTSRange.second, qcdbApi, "qc/MID/MO/QcTaskMIDDigits/Hits"); - if (tsVector.empty()) { + auto mdVector = findObjectsMDInPeriod(badTSRange.first, badTSRange.second, qcdbApi, "qc/MID/MO/QcTaskMIDDigits/Hits"); + if (mdVector.empty()) { std::cerr << "Cannot find hits in period " << tsToString(badTSRange.first) << " - " << tsToString(badTSRange.second) << std::endl; return {}; } - // Focus on the first object found - TH1* occupancy = qcdbApi.retrieveFromTFileAny("qc/MID/MO/QcTaskMIDDigits/Hits", metadata, getTSMS(tsVector.front())); + // Focus on the last object found + // We chose the last instead of the first because it might happen that + // we lose additional boards before the EOR + // If we build the reject list for the first object, we would therefore miss some boards + TH1* occupancy = qcdbApi.retrieveFromTFileAny("qc/MID/MO/QcTaskMIDDigits/Hits", metadata, getTSMS(mdVector.back().start)); o2::mid::GlobalMapper gm; auto infos = gm.buildStripsInfo(); auto badChannels = findBadChannels(occupancy, infos); - auto badChannelsCCDB = *ccdbApi.retrieveFromTFileAny>("MID/Calib/BadChannels", metadata, getTSMS(timestamp)); + auto badChannelsCCDB = *ccdbApi.retrieveFromTFileAny>("MID/Calib/BadChannels", metadata, getTSMS(md.start)); rl.rejectList = getRejectList(badChannels, badChannelsCCDB); if (rl.rejectList.empty()) { - std::cout << "Warning: reject list was empty. It probably means that an entire board is already masked in calibration for run " << grpecs.getRun() << std::endl; + std::cout << "Warning: reject list was empty. It probably means that an entire board is already masked in calibration for run " << md.runNumber << std::endl; return rl; } @@ -260,21 +296,15 @@ RejectListStruct build_rejectlist(long timestamp, const o2::ccdb::CcdbApi& qcdbA for (auto& col : rl.rejectList) { std::cout << col << std::endl; } - std::cout << "Run number: " << grpecs.getRun() << std::endl; - std::cout << "SOR - EOR: " << timeRangeToString(grpecs.getTimeStart(), grpecs.getTimeEnd()) << std::endl; + std::cout << "Run number: " << md.runNumber << std::endl; std::cout << "SOT - EOT: " << timeRangeToString(runRange.first, runRange.second) << std::endl; std::cout << "Good: " << timeRangeToString(goodTSRange.first, goodTSRange.second) << std::endl; std::cout << "Bad: " << timeRangeToString(badTSRange.first, badTSRange.second) << std::endl; + std::cout << "Fraction bad: " << static_cast(badTSRange.second - badTSRange.first) / static_cast(runRange.second - runRange.first) << std::endl; // Set the start of the reject list to the last timestamp in which the occupancy was ok rl.start = goodTSRange.second; - if (goodTSRange.first == 0) { - // If the quality was bad for the full run, set the start of the reject list to the SOR - std::cout << "CAVEAT: no good TS found. Will use SOT instead" << std::endl; - rl.start = runRange.first; - } - // Set the end of the reject list to the end of run - rl.end = runRange.second; + rl.end = badTSRange.second; return rl; } @@ -301,8 +331,8 @@ RejectListStruct load_from_json(const o2::ccdb::CcdbApi& ccdbApi, const char* fi std::cerr << "Problem parsing " << filename << std::endl; return rl; } - auto startRange = getRunDuration(ccdbApi, doc["startRun"].GetInt()); - auto endRange = getRunDuration(ccdbApi, doc["endRun"].GetInt()); + auto startRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, doc["startRun"].GetInt()); + auto endRange = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, doc["endRun"].GetInt()); rl.start = startRange.first; rl.end = endRange.second; std::cout << "Manual RL validity: " << timeRangeToString(rl.start, rl.end) << std::endl; @@ -397,9 +427,9 @@ void build_rejectlist(long start, long end, const char* qcdbUrl = "http://ali-qc o2::ccdb::CcdbApi ccdbApi; ccdbApi.init(ccdbUrl); std::vector rls; - auto objectsTS = findObjectsTSInPeriod(start, end, qcdbApi, sPathQCQuality.c_str()); - for (auto ts : objectsTS) { - auto rl = build_rejectlist(ts, qcdbApi, ccdbApi); + auto objectsMD = findObjectsMDInPeriod(start, end, qcdbApi, sPathQCQuality.c_str()); + for (auto md : objectsMD) { + auto rl = build_rejectlist(md, qcdbApi, ccdbApi); if (rl.start != rl.end) { rls.emplace_back(rl); } From 64077ed05db5c336aa4bd5512411bb79c24ba11a Mon Sep 17 00:00:00 2001 From: pillot Date: Mon, 25 Nov 2024 16:24:40 +0100 Subject: [PATCH 0522/2205] send messages at every TF --- .../DevIO/Digits/digits-sampler-workflow.cxx | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/Detectors/MUON/MCH/DevIO/Digits/digits-sampler-workflow.cxx b/Detectors/MUON/MCH/DevIO/Digits/digits-sampler-workflow.cxx index 7f3819f110ba3..0184e1c78c0c6 100644 --- a/Detectors/MUON/MCH/DevIO/Digits/digits-sampler-workflow.cxx +++ b/Detectors/MUON/MCH/DevIO/Digits/digits-sampler-workflow.cxx @@ -27,6 +27,7 @@ #include #include #include +#include using namespace o2::framework; @@ -63,61 +64,64 @@ class DigitSamplerTask : public io::DigitIOBaseTask void outputAndClear(DataAllocator& out) { - printSummary(mDigits, mROFs, "-> to output"); + LOGP(info, "Sending {} rofs with {} digits", mROFs.size(), mDigits.size()); out.snapshot(OutputRef{"rofs"}, mROFs); out.snapshot(OutputRef{"digits"}, mDigits); mDigits.clear(); mROFs.clear(); } - bool shouldEnd() const + bool shouldEnd() { bool maxTFreached = mNofProcessedTFs >= mMaxNofTimeFrames; bool maxROFreached = mNofProcessedROFs >= mMaxNofROFs; - return !mReadIsOk || maxTFreached || maxROFreached; + bool lastTF = mInput.peek() == EOF; + return !mReadIsOk || lastTF || maxTFreached || maxROFreached; } void run(ProcessingContext& pc) { if (shouldEnd()) { - // output remaining data if any - if (mROFs.size() > 0) { - --mTFid; - outputAndClear(pc.outputs()); - } - pc.services().get().endOfStream(); - return; + throw std::invalid_argument("process should have ended already"); } std::vector rofs; std::vector digits; - mReadIsOk = mDigitSampler->read(digits, rofs); - if (!mReadIsOk) { - return; - } + while ((mReadIsOk = mDigitSampler->read(digits, rofs))) { + + // process the current input TF if requested + if (shouldProcess()) { + incNofProcessedTFs(); + mNofProcessedROFs += rofs.size(); + // append rofs to mROFs, but shift the indices by the amount of digits + // we have read so far. + auto offset = mDigits.size(); + std::transform(rofs.begin(), rofs.end(), std::back_inserter(mROFs), + [offset](ROFRecord r) { + r.setDataRef(r.getFirstIdx() + offset, r.getNEntries()); + return r; + }); + mDigits.insert(mDigits.end(), digits.begin(), digits.end()); + printSummary(mDigits, mROFs); + printFull(mDigits, mROFs); + } - if (shouldProcess()) { - incNofProcessedTFs(); - mNofProcessedROFs += rofs.size(); - // append rofs to mROFs, but shift the indices by the amount of digits - // we have read so far. - auto offset = mDigits.size(); - std::transform(rofs.begin(), rofs.end(), std::back_inserter(mROFs), - [offset](ROFRecord r) { - r.setDataRef(r.getFirstIdx() + offset, r.getNEntries()); - return r; - }); - mDigits.insert(mDigits.end(), digits.begin(), digits.end()); - printSummary(mDigits, mROFs); - printFull(mDigits, mROFs); - } + // increment the input TF id for the next one + incTFid(); - // output if we've accumulated enough ROFs - if (mROFs.size() >= mMinNumberOfROFsPerTF) { - outputAndClear(pc.outputs()); + // stop here if we've accumulated enough ROFs or TFs + if (mROFs.size() >= mMinNumberOfROFsPerTF || shouldEnd()) { + break; + } } - incTFid(); + // output whatever has been accumulated, even if empty + outputAndClear(pc.outputs()); + + if (shouldEnd()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } } }; From f5e440b943ae6229b5c6b991172940ab1f0e4897 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 26 Nov 2024 16:31:55 +0100 Subject: [PATCH 0523/2205] GPU TPC: Fix typo in name, and clean up setting of inputGPU struct --- .../DataFormatsTPC/CompressedClusters.h | 2 +- .../DataCompression/GPUTPCDecompression.cxx | 2 +- .../Global/GPUChainTrackingCompression.cxx | 34 ++----------------- 3 files changed, 4 insertions(+), 34 deletions(-) diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClusters.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClusters.h index 9f49884035b7e..46da2da2a702e 100644 --- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClusters.h +++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClusters.h @@ -29,7 +29,7 @@ struct CompressedClustersCounters { unsigned int nUnattachedClusters = 0; unsigned int nAttachedClustersReduced = 0; unsigned int nSliceRows = 36 * 152; - unsigned char nComppressionModes = 0; + unsigned char nComppressionModes = 0; // Don't fix this name due to ROOT dictionaries! float solenoidBz = -1e6f; int maxTimeBin = -1e6; diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx index 4039ebb0c100d..0f7acfce86094 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx @@ -43,7 +43,7 @@ void GPUTPCDecompression::SetPointersCompressedClusters(void*& mem, T& c, uint32 uint32_t nClAreduced = reducedClA ? nClA - nTr : nClA; - if (!(mRec->GetParam().rec.tpc.compressionTypeMask & GPUSettings::CompressionTrackModel)) { + if (!(c.nComppressionModes & GPUSettings::CompressionTrackModel)) { return; // Track model disabled, do not allocate memory } computePointerWithAlignment(mem, c.qTotA, nClA); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 98109447de034..b11b7d3b11cab 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -254,40 +254,10 @@ int32_t GPUChainTracking::RunTPCDecompression() int32_t inputStream = 0; int32_t unattachedStream = mRec->NStreams() - 1; - inputGPU.nAttachedClusters = cmprClsHost.nAttachedClusters; - inputGPU.nUnattachedClusters = cmprClsHost.nUnattachedClusters; - inputGPU.nTracks = cmprClsHost.nTracks; - inputGPU.nAttachedClustersReduced = inputGPU.nAttachedClusters - inputGPU.nTracks; - inputGPU.nSliceRows = NSLICES * GPUCA_ROW_COUNT; - inputGPU.nComppressionModes = param().rec.tpc.compressionTypeMask; - inputGPU.solenoidBz = param().bzkG; - inputGPU.maxTimeBin = param().continuousMaxTimeBin; + inputGPU = cmprClsHost; SetupGPUProcessor(&Decompressor, true); WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); - - inputGPU.nTrackClusters = cmprClsHost.nTrackClusters; - inputGPU.qTotU = cmprClsHost.qTotU; - inputGPU.qMaxU = cmprClsHost.qMaxU; - inputGPU.flagsU = cmprClsHost.flagsU; - inputGPU.padDiffU = cmprClsHost.padDiffU; - inputGPU.timeDiffU = cmprClsHost.timeDiffU; - inputGPU.sigmaPadU = cmprClsHost.sigmaPadU; - inputGPU.sigmaTimeU = cmprClsHost.sigmaTimeU; - inputGPU.nSliceRowClusters = cmprClsHost.nSliceRowClusters; - inputGPU.qTotA = cmprClsHost.qTotA; - inputGPU.qMaxA = cmprClsHost.qMaxA; - inputGPU.flagsA = cmprClsHost.flagsA; - inputGPU.rowDiffA = cmprClsHost.rowDiffA; - inputGPU.sliceLegDiffA = cmprClsHost.sliceLegDiffA; - inputGPU.padResA = cmprClsHost.padResA; - inputGPU.timeResA = cmprClsHost.timeResA; - inputGPU.sigmaPadA = cmprClsHost.sigmaPadA; - inputGPU.sigmaTimeA = cmprClsHost.sigmaTimeA; - inputGPU.qPtA = cmprClsHost.qPtA; - inputGPU.rowA = cmprClsHost.rowA; - inputGPU.sliceA = cmprClsHost.sliceA; - inputGPU.timeA = cmprClsHost.timeA; - inputGPU.padA = cmprClsHost.padA; + inputGPU = cmprClsHost; bool toGPU = true; runKernel({GetGridAutoStep(inputStream, RecoStep::TPCDecompression), krnlRunRangeNone, &mEvents->init}, DecompressorShadow.mNativeClustersIndex, NSLICES * GPUCA_ROW_COUNT * sizeof(DecompressorShadow.mNativeClustersIndex[0])); From 2af1b957f8c0edd472013ec9bc9fbb08ba40a926 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Sun, 24 Nov 2024 18:22:36 +0100 Subject: [PATCH 0524/2205] GPUWorkflow: clean up calib objects a bit --- GPU/Workflow/src/GPUWorkflowSpec.cxx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index 94b1c3c2b8a7b..37ae734845667 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -1095,8 +1095,12 @@ Inputs GPURecoWorkflowSpec::inputs() } else if (mSpecConfig.enableDoublePipeline == 1) { inputs.emplace_back("pipelineprepare", gDataOriginGPU, "PIPELINEPREPARE", 0, Lifetime::Timeframe); } + if (mSpecConfig.outputTracks || mSpecConfig.caClusterer) { + // calibration objects for TPC clusterization + inputs.emplace_back("tpcgain", gDataOriginTPC, "PADGAINFULL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPadGainFull))); + } if (mSpecConfig.outputTracks) { - // loading calibration objects from the CCDB + // calibration objects for TPC tracking const auto mapSources = mSpecConfig.tpcDeadMapSources; if (mapSources != 0) { tpc::SourcesDeadMap sources((mapSources > -1) ? static_cast(mapSources) : tpc::SourcesDeadMap::All); @@ -1107,7 +1111,7 @@ Inputs GPURecoWorkflowSpec::inputs() inputs.emplace_back("tpcruninfo", gDataOriginTPC, "TPCRUNINFO", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::ConfigRunInfo))); } } - inputs.emplace_back("tpcgain", gDataOriginTPC, "PADGAINFULL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPadGainFull))); + inputs.emplace_back("tpcgainresidual", gDataOriginTPC, "PADGAINRESIDUAL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPadGainResidual), {}, 1)); // time-dependent if (mSpecConfig.tpcUseMCTimeGain) { inputs.emplace_back("tpctimegain", gDataOriginTPC, "TIMEGAIN", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalTimeGainMC), {}, 1)); // time-dependent @@ -1124,11 +1128,6 @@ Inputs GPURecoWorkflowSpec::inputs() if (mSpecConfig.decompressTPC) { inputs.emplace_back(InputSpec{"input", ConcreteDataTypeMatcher{gDataOriginTPC, mSpecConfig.decompressTPCFromROOT ? o2::header::DataDescription("COMPCLUSTERS") : o2::header::DataDescription("COMPCLUSTERSFLAT")}, Lifetime::Timeframe}); } else if (mSpecConfig.caClusterer) { - // if the output type are tracks, then the input spec for the gain map is already defined - if (!mSpecConfig.outputTracks) { - inputs.emplace_back("tpcgain", gDataOriginTPC, "PADGAINFULL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPadGainFull))); - } - // We accept digits and MC labels also if we run on ZS Raw data, since they are needed for MC label propagation if ((!mSpecConfig.zsOnTheFly || mSpecConfig.processMC) && !mSpecConfig.zsDecoder) { inputs.emplace_back(InputSpec{"input", ConcreteDataTypeMatcher{gDataOriginTPC, "DIGITS"}, Lifetime::Timeframe}); From 2d89de5886811829d04a563f7f6c495546125c79 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 25 Nov 2024 09:01:34 +0100 Subject: [PATCH 0525/2205] GPU: Add dynamic configuration object to GPUReconstruction --- GPU/GPUTracking/Base/GPUParam.cxx | 5 ++++- GPU/GPUTracking/Base/GPUParam.h | 2 +- GPU/GPUTracking/Base/GPUReconstruction.cxx | 16 ++++++++++++---- GPU/GPUTracking/Base/GPUReconstruction.h | 3 ++- GPU/GPUTracking/Base/GPUReconstructionCPU.cxx | 2 +- GPU/GPUTracking/Definitions/GPUSettingsList.h | 6 ++++++ .../GPUTrackingLinkDef_O2_DataTypes.h | 1 + 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index 42d4f61f77116..a74ba87794ed4 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -124,7 +124,7 @@ void GPUParam::SetDefaults(float solenoidBz) par.earlyTpcTransform = false; } -void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p, const GPURecoStepConfiguration* w) +void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p, const GPURecoStepConfiguration* w, const GPUSettingsRecDynamic* d) { if (g) { UpdateBzOnly(g->solenoidBzNominalGPU); @@ -145,6 +145,9 @@ void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessi dodEdxDownscaled = (rand() % 100) < p->tpcDownscaledEdx; } } + if (d) { + rec.dyn = *d; + } } void GPUParam::UpdateBzOnly(float newSolenoidBz) diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h index 070ac76f58ffb..fd380c0a39593 100644 --- a/GPU/GPUTracking/Base/GPUParam.h +++ b/GPU/GPUTracking/Base/GPUParam.h @@ -84,7 +84,7 @@ struct GPUParam : public internal::GPUParam_t #ifndef GPUCA_GPUCODE void SetDefaults(float solenoidBz); void SetDefaults(const GPUSettingsGRP* g, const GPUSettingsRec* r = nullptr, const GPUSettingsProcessing* p = nullptr, const GPURecoStepConfiguration* w = nullptr); - void UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p = nullptr, const GPURecoStepConfiguration* w = nullptr); + void UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p = nullptr, const GPURecoStepConfiguration* w = nullptr, const GPUSettingsRecDynamic* d = nullptr); void UpdateBzOnly(float newSolenoidBz); void LoadClusterErrors(bool Print = 0); void UpdateRun3ClusterErrors(const float* yErrorParam, const float* zErrorParam); diff --git a/GPU/GPUTracking/Base/GPUReconstruction.cxx b/GPU/GPUTracking/Base/GPUReconstruction.cxx index 632bf0f331f31..9abe225c7848e 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.cxx +++ b/GPU/GPUTracking/Base/GPUReconstruction.cxx @@ -427,7 +427,7 @@ int32_t GPUReconstruction::InitPhaseAfterDevice() (mProcessors[i].proc->*(mProcessors[i].InitializeProcessor))(); } - WriteConstantParams(); // First initialization, if the user doesn't use RunChains + WriteConstantParams(); // Initialize with initial values, can optionally be updated later mInitialized = true; return 0; @@ -1105,7 +1105,12 @@ void GPUReconstruction::DumpSettings(const char* dir) } } -void GPUReconstruction::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p) +void GPUReconstruction::UpdateDynamicSettings(const GPUSettingsRecDynamic* d) +{ + UpdateSettings(nullptr, nullptr, d); +} + +void GPUReconstruction::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p, const GPUSettingsRecDynamic* d) { if (g) { mGRPSettings = *g; @@ -1114,8 +1119,11 @@ void GPUReconstruction::UpdateSettings(const GPUSettingsGRP* g, const GPUSetting mProcessingSettings.debugLevel = p->debugLevel; mProcessingSettings.resetTimers = p->resetTimers; } - GPURecoStepConfiguration w = mRecoSteps; - param().UpdateSettings(g, p, &w); + GPURecoStepConfiguration* w = nullptr; + if (mRecoSteps.steps.isSet(GPUDataTypes::RecoStep::TPCdEdx)) { + w = &mRecoSteps; + } + param().UpdateSettings(g, p, w, d); if (mInitialized) { WriteConstantParams(); } diff --git a/GPU/GPUTracking/Base/GPUReconstruction.h b/GPU/GPUTracking/Base/GPUReconstruction.h index 70a066532d938..efad0b41fd571 100644 --- a/GPU/GPUTracking/Base/GPUReconstruction.h +++ b/GPU/GPUTracking/Base/GPUReconstruction.h @@ -200,7 +200,8 @@ class GPUReconstruction void SetSettings(const GPUSettingsGRP* grp, const GPUSettingsRec* rec = nullptr, const GPUSettingsProcessing* proc = nullptr, const GPURecoStepConfiguration* workflow = nullptr); void SetResetTimers(bool reset) { mProcessingSettings.resetTimers = reset; } // May update also after Init() void SetDebugLevelTmp(int32_t level) { mProcessingSettings.debugLevel = level; } // Temporarily, before calling SetSettings() - void UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p = nullptr); + void UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessing* p = nullptr, const GPUSettingsRecDynamic* d = nullptr); + void UpdateDynamicSettings(const GPUSettingsRecDynamic* d); void SetOutputControl(const GPUOutputControl& v) { mOutputControl = v; } void SetOutputControl(void* ptr, size_t size); void SetInputControl(void* ptr, size_t size); diff --git a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx index 537c3cf63a628..271bee59db31b 100644 --- a/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx +++ b/GPU/GPUTracking/Base/GPUReconstructionCPU.cxx @@ -228,7 +228,7 @@ int32_t GPUReconstructionCPU::RunChains() mThreadId = GetThread(); } if (mSlaves.size() || mMaster) { - WriteConstantParams(); // Reinitialize + WriteConstantParams(); // Reinitialize // TODO: Get this in sync with GPUChainTracking::DoQueuedUpdates, and consider the doublePipeline } for (uint32_t i = 0; i < mChains.size(); i++) { int32_t retVal = mChains[i]->RunChain(); diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index d5494d04930f5..974ef6a9f0d18 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -181,6 +181,11 @@ AddOptionRTC(pileupBwdNBC, uint8_t, 80, "", 0, "Pre-trigger Pile-up integration AddHelp("help", 'h') EndConfig() +// Dynamic settings, must NOT use AddOptionRTC(...) !!! +BeginSubConfig(GPUSettingsRecDynamic, dyn, configStandalone.rec, "RECDYN", 0, "Reconstruction settings", rec_dyn) +AddHelp("help", 'h') +EndConfig() + BeginSubConfig(GPUSettingsRec, rec, configStandalone, "REC", 0, "Reconstruction settings", rec) AddOptionRTC(maxTrackQPtB5, float, 1.f / GPUCA_MIN_TRACK_PTB5_DEFAULT, "", 0, "required max Q/Pt (==min Pt) of tracks") AddOptionRTC(nonConsecutiveIDs, int8_t, false, "", 0, "Non-consecutive cluster IDs as in HLT, disables features that need access to slice data in TPC merger") @@ -193,6 +198,7 @@ AddOptionRTC(trackingRefitGPUModel, int8_t, 1, "", 0, "Use GPU track model for t AddCustomCPP(void SetMinTrackPtB5(float v) { maxTrackQPtB5 = v > 0.001f ? (1.f / v) : (1.f / 0.001f); }) AddSubConfig(GPUSettingsRecTPC, tpc) AddSubConfig(GPUSettingsRecTRD, trd) +AddSubConfig(GPUSettingsRecDynamic, dyn) AddHelp("help", 'h') EndConfig() diff --git a/GPU/GPUTracking/GPUTrackingLinkDef_O2_DataTypes.h b/GPU/GPUTracking/GPUTrackingLinkDef_O2_DataTypes.h index 16f9b769123f7..6ed4e036c6597 100644 --- a/GPU/GPUTracking/GPUTrackingLinkDef_O2_DataTypes.h +++ b/GPU/GPUTracking/GPUTrackingLinkDef_O2_DataTypes.h @@ -28,6 +28,7 @@ #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsRec + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsRecTPC + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsRecTRD + ; +#pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsRecDynamic + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsProcessing + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsProcessingParam + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsProcessingRTC + ; From 07d0819f5a5a467c397fa2f6e0df950076d9869d Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 25 Nov 2024 09:02:29 +0100 Subject: [PATCH 0526/2205] GPU TPC: Add option to apply timebin cut to CTF cluster decoding CPU-only version --- GPU/GPUTracking/Base/GPUParam.cxx | 2 ++ GPU/GPUTracking/Base/GPUParam.h | 1 + GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx | 3 +++ GPU/GPUTracking/DataTypes/GPUNewCalibValues.h | 2 ++ GPU/GPUTracking/DataTypes/GPUSettings.h | 1 + GPU/GPUTracking/Global/GPUChainTracking.cxx | 3 +++ GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx | 1 + GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx | 7 ++++--- .../Global/GPUChainTrackingDebugAndProfiling.cxx | 3 +++ GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h | 1 + GPU/Workflow/src/GPUWorkflowSpec.cxx | 9 +++++++-- GPU/Workflow/src/GPUWorkflowTPC.cxx | 9 +++++---- 12 files changed, 33 insertions(+), 9 deletions(-) diff --git a/GPU/GPUTracking/Base/GPUParam.cxx b/GPU/GPUTracking/Base/GPUParam.cxx index a74ba87794ed4..661ae830ca6f3 100644 --- a/GPU/GPUTracking/Base/GPUParam.cxx +++ b/GPU/GPUTracking/Base/GPUParam.cxx @@ -120,6 +120,7 @@ void GPUParam::SetDefaults(float solenoidBz) par.toyMCEventsFlag = false; par.continuousTracking = false; continuousMaxTimeBin = 0; + tpcCutTimeBin = 0; par.debugLevel = 0; par.earlyTpcTransform = false; } @@ -132,6 +133,7 @@ void GPUParam::UpdateSettings(const GPUSettingsGRP* g, const GPUSettingsProcessi par.toyMCEventsFlag = g->homemadeEvents; par.continuousTracking = g->grpContinuousMaxTimeBin != 0; continuousMaxTimeBin = g->grpContinuousMaxTimeBin == -1 ? GPUSettings::TPC_MAX_TF_TIME_BIN : g->grpContinuousMaxTimeBin; + tpcCutTimeBin = g->tpcCutTimeBin; } par.earlyTpcTransform = rec.tpc.forceEarlyTransform == -1 ? (!par.continuousTracking) : rec.tpc.forceEarlyTransform; qptB5Scaler = CAMath::Abs(bzkG) > 0.1f ? CAMath::Abs(bzkG) / 5.006680f : 1.f; // Repeat here, since passing in g is optional diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h index fd380c0a39593..ce9ac30b7c35b 100644 --- a/GPU/GPUTracking/Base/GPUParam.h +++ b/GPU/GPUTracking/Base/GPUParam.h @@ -59,6 +59,7 @@ struct GPUParam_t { int8_t dodEdxDownscaled; int32_t continuousMaxTimeBin; + int32_t tpcCutTimeBin; GPUTPCGeometry tpcGeometry; // TPC Geometry GPUTPCGMPolynomialField polynomialField; // Polynomial approx. of magnetic field for TPC GM diff --git a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx index f443809d15ef5..e86955d6da500 100644 --- a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx +++ b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx @@ -24,4 +24,7 @@ void GPUNewCalibValues::updateFrom(const GPUNewCalibValues* from) if (from->newContinuousMaxTimeBin) { continuousMaxTimeBin = from->continuousMaxTimeBin; } + if (from->newTPCTimeBinCut) { + tpcTimeBinCut = from->tpcTimeBinCut; + } } diff --git a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h index 802306e996553..5d5a31785928c 100644 --- a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h +++ b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.h @@ -25,8 +25,10 @@ namespace gpu struct GPUNewCalibValues { bool newSolenoidField = false; bool newContinuousMaxTimeBin = false; + bool newTPCTimeBinCut = false; float solenoidField = 0.f; uint32_t continuousMaxTimeBin = 0; + int32_t tpcTimeBinCut = 0; void updateFrom(const GPUNewCalibValues* from); }; diff --git a/GPU/GPUTracking/DataTypes/GPUSettings.h b/GPU/GPUTracking/DataTypes/GPUSettings.h index 69bfb15e3f4b0..b967a7ce42620 100644 --- a/GPU/GPUTracking/DataTypes/GPUSettings.h +++ b/GPU/GPUTracking/DataTypes/GPUSettings.h @@ -60,6 +60,7 @@ struct GPUSettingsGRP { int32_t grpContinuousMaxTimeBin = -2; // 0 for triggered events, -1 for automatic setting, -2 invalid default int32_t needsClusterer = 0; // Set to true if the data requires the clusterizer int32_t doCompClusterDecode = 0; // Set to true if the data contains compressed TPC clusters + int32_t tpcCutTimeBin = 0; // Cut TPC clusters and digits >= this cut }; // Parameters of the current time frame diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index b06d636970da7..7b8e590242fae 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -641,6 +641,9 @@ int32_t GPUChainTracking::DoQueuedUpdates(int32_t stream, bool updateSlave) if (mNewCalibValues->newContinuousMaxTimeBin) { grp->grpContinuousMaxTimeBin = mNewCalibValues->continuousMaxTimeBin; } + if (mNewCalibValues->newTPCTimeBinCut) { + grp->tpcCutTimeBin = mNewCalibValues->tpcTimeBinCut; + } } } if (GetProcessingSettings().tpcDownscaledEdx != 0) { diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index 97870d74ca624..35e5524732b97 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -18,6 +18,7 @@ #include "GPUO2DataTypes.h" #include "GPUMemorySizeScalers.h" #include "GPUTrackingInputProvider.h" +#include "GPUNewCalibValues.h" #include #ifdef GPUCA_O2_LIB diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index b11b7d3b11cab..8ca3a83e780fb 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -219,14 +219,15 @@ int32_t GPUChainTracking::RunTPCDecompression() return ((tmpBuffer = std::make_unique(size))).get(); }; auto& decompressTimer = getTimer("TPCDecompression", 0); - auto allocatorUse = GetProcessingSettings().tpcApplyCFCutsAtDecoding ? std::function{allocatorTmp} : std::function{allocatorFinal}; + bool runFiltering = GetProcessingSettings().tpcApplyCFCutsAtDecoding; + auto allocatorUse = runFiltering ? std::function{allocatorTmp} : std::function{allocatorFinal}; decompressTimer.Start(); if (decomp.decompress(mIOPtrs.tpcCompressedClusters, *mClusterNativeAccess, allocatorUse, param(), GetProcessingSettings().deterministicGPUReconstruction)) { GPUError("Error decompressing clusters"); return 1; } - if (GetProcessingSettings().tpcApplyCFCutsAtDecoding) { - RunTPCClusterFilter(mClusterNativeAccess.get(), allocatorFinal, true); + if (runFiltering) { + RunTPCClusterFilter(mClusterNativeAccess.get(), allocatorFinal, GetProcessingSettings().tpcApplyCFCutsAtDecoding); } decompressTimer.Stop(); mIOPtrs.clustersNative = mClusterNativeAccess.get(); diff --git a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx index f8a64e9d4faaa..7d4a3420995ad 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx @@ -315,6 +315,9 @@ void GPUChainTracking::RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* cluster keep = keep && cl.qTot > param().rec.tpc.cfQTotCutoff && cl.qMax > param().rec.tpc.cfQMaxCutoff; keep = keep && (!(cl.getFlags() & o2::tpc::ClusterNative::flagSingle) || ((cl.sigmaPadPacked || cl.qMax > param().rec.tpc.cfQMaxCutoffSinglePad) && (cl.sigmaTimePacked || cl.qMax > param().rec.tpc.cfQMaxCutoffSingleTime))); } + if (param().tpcCutTimeBin > 0) { + keep = keep && cl.getTime() < param().tpcCutTimeBin; + } keep = keep && (!GetProcessingSettings().tpcApplyDebugClusterFilter || clusterFilter.filter(iSector, iRow, cl)); if (iPhase && keep) { outputBuffer[countTotal] = cl; diff --git a/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h b/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h index b218a21306a34..eda3b28c6cff6 100644 --- a/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h +++ b/GPU/Workflow/include/GPUWorkflow/GPUWorkflowSpec.h @@ -233,6 +233,7 @@ class GPURecoWorkflowSpec : public o2::framework::Task bool mITSGeometryCreated = false; bool mTRDGeometryCreated = false; bool mPropagatorInstanceCreated = false; + int32_t mTPCCutAtTimeBin = -1; }; } // end namespace gpu diff --git a/GPU/Workflow/src/GPUWorkflowSpec.cxx b/GPU/Workflow/src/GPUWorkflowSpec.cxx index 37ae734845667..06942eab476c6 100644 --- a/GPU/Workflow/src/GPUWorkflowSpec.cxx +++ b/GPU/Workflow/src/GPUWorkflowSpec.cxx @@ -1013,9 +1013,8 @@ void GPURecoWorkflowSpec::doCalibUpdates(o2::framework::ProcessingContext& pc, c LOG(info) << "Updating solenoid field " << newCalibValues.solenoidField; } if (mAutoContinuousMaxTimeBin) { - mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(mTFSettings->nHBFPerTF); newCalibValues.newContinuousMaxTimeBin = true; - newCalibValues.continuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin; + newCalibValues.continuousMaxTimeBin = mConfig->configGRP.grpContinuousMaxTimeBin = GPUO2InterfaceUtils::getTpcMaxTimeBinFromNHbf(mTFSettings->nHBFPerTF); LOG(info) << "Updating max time bin " << newCalibValues.continuousMaxTimeBin << " (" << mTFSettings->nHBFPerTF << " orbits)"; } @@ -1050,6 +1049,11 @@ void GPURecoWorkflowSpec::doCalibUpdates(o2::framework::ProcessingContext& pc, c if (mSpecConfig.runITSTracking) { needCalibUpdate = fetchCalibsCCDBITS(pc) || needCalibUpdate; } + if (mTPCCutAtTimeBin != mConfig->configGRP.tpcCutTimeBin) { + newCalibValues.newTPCTimeBinCut = true; + newCalibValues.tpcTimeBinCut = mConfig->configGRP.tpcCutTimeBin = mTPCCutAtTimeBin; + needCalibUpdate = true; + } if (needCalibUpdate) { LOG(info) << "Updating GPUReconstruction calibration objects"; mGPUReco->UpdateCalibration(newCalibObjects, newCalibValues); @@ -1098,6 +1102,7 @@ Inputs GPURecoWorkflowSpec::inputs() if (mSpecConfig.outputTracks || mSpecConfig.caClusterer) { // calibration objects for TPC clusterization inputs.emplace_back("tpcgain", gDataOriginTPC, "PADGAINFULL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPadGainFull))); + inputs.emplace_back("tpcaltrosync", gDataOriginTPC, "ALTROSYNCSIGNAL", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::AltroSyncSignal))); } if (mSpecConfig.outputTracks) { // calibration objects for TPC tracking diff --git a/GPU/Workflow/src/GPUWorkflowTPC.cxx b/GPU/Workflow/src/GPUWorkflowTPC.cxx index 97bf3aed26368..b64c25b63cc54 100644 --- a/GPU/Workflow/src/GPUWorkflowTPC.cxx +++ b/GPU/Workflow/src/GPUWorkflowTPC.cxx @@ -65,10 +65,7 @@ #include "SimulationDataFormat/MCCompLabel.h" #include "Algorithm/Parser.h" #include "DataFormatsGlobalTracking/RecoContainer.h" -#include "DataFormatsTRD/RecoInputContainer.h" -#include "TRDBase/Geometry.h" -#include "TRDBase/GeometryFlat.h" -#include "ITSBase/GeometryTGeo.h" +#include "DataFormatsTPC/AltroSyncSignal.h" #include "CommonUtils/VerbosityConfig.h" #include "CommonUtils/DebugStreamer.h" #include @@ -308,6 +305,10 @@ bool GPURecoWorkflowSpec::fetchCalibsCCDBTPC(ProcessingCon pc.inputs().get*>("tpcgain"); } + if (mSpecConfig.outputTracks || mSpecConfig.caClusterer) { + mTPCCutAtTimeBin = pc.inputs().get("tpcaltrosync")->getTB2Cut(pc.services().get().tfCounter); + } + // these calibrations are only defined for the tracking if (mSpecConfig.outputTracks) { // update the calibration objects in case they changed in the CCDB From 9423b5709f649cfd5fdaac1422981834cafb035f Mon Sep 17 00:00:00 2001 From: David Rohr Date: Mon, 25 Nov 2024 13:21:58 +0100 Subject: [PATCH 0527/2205] GPU TPC: Provide time bin cut also to Clusterizer (not yet used) --- GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index 35e5524732b97..4bc0ee4e91ff1 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -574,6 +574,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) return ForwardTPCDigits(); } #ifdef GPUCA_TPC_GEOMETRY_O2 + int32_t tpcTimeBinCut = mUpdateNewCalibObjects && mNewCalibValues->newTPCTimeBinCut ? mNewCalibValues->tpcTimeBinCut : param().tpcCutTimeBin; mRec->PushNonPersistentMemory(qStr2Tag("TPCCLUST")); const auto& threadContext = GetThreadContext(); const bool doGPU = GetRecoStepsGPU() & RecoStep::TPCClusterFinding; @@ -766,6 +767,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) : 0; uint32_t nBlocks = doGPU ? clusterer.mPmemory->counters.nPagesSubslice : GPUTrackingInOutZS::NENDPOINTS; + (void)tpcTimeBinCut; // TODO: To be used in decoding kernels switch (mCFContext->zsVersion) { default: GPUFatal("Data with invalid TPC ZS mode (%d) received", mCFContext->zsVersion); From 91f1ac35acd5dabfb7c39b3cdbe5e2145053b993 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 26 Nov 2024 16:31:29 +0100 Subject: [PATCH 0528/2205] GPU TPC: Add some TODO comments --- GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx index d817278404534..74cc12e9bbd9a 100644 --- a/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx +++ b/GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx @@ -370,7 +370,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ CADEBUG(printf("Reinit linearization\n")); prop.SetTrack(this, prop.GetAlpha()); } - if (param.par.dodEdx && param.dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { + if (param.par.dodEdx && param.dodEdxDownscaled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg && !(clusterState & GPUTPCGMMergedTrackHit::flagEdge)) { // TODO: Costimize flag to remove, and option to remove double-clusters float qtot = 0, qmax = 0, pad = 0, relTime = 0; const int32_t clusterCount = (ihit - ihitMergeFirst) * wayDirection + 1; for (int32_t iTmp = ihitMergeFirst; iTmp != ihit + wayDirection; iTmp += wayDirection) { @@ -384,7 +384,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_ relTime += cl.getTime(); } } - qtot /= clusterCount; + qtot /= clusterCount; // TODO: Weighted Average pad /= clusterCount; relTime /= clusterCount; relTime = relTime - CAMath::Round(relTime); @@ -528,7 +528,7 @@ GPUd() int32_t GPUTPCGMTrackParam::MergeDoubleRowClusters(int32_t& ihit, int32_t } } else { CADEBUG(printf("\t\tMerging hit row %d X %f Y %f Z %f (dy %f, dz %f, chiY %f, chiZ %f)\n", clusters[ihit].row, clx, cly, clz, dy, dz, sqrtf(maxDistY), sqrtf(maxDistZ))); - xx += clx * clamp; + xx += clx * clamp; // TODO: Weight in pad/time instead of XYZ yy += cly * clamp; zz += clz * clamp; clusterState |= clusters[ihit].state; From f76f1a70c5664e4f8ed9219a067aaee0a2258378 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 27 Nov 2024 09:11:31 +0100 Subject: [PATCH 0529/2205] GPU TPC: Make TPC Time Bin Cut overrideable from configKeyValue --- GPU/GPUTracking/Definitions/GPUSettingsList.h | 1 + GPU/Workflow/src/GPUWorkflowTPC.cxx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index 974ef6a9f0d18..07cd320140909 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -536,6 +536,7 @@ AddOption(solenoidBzNominalGPU, float, -1e6f, "", 0, "Field strength of solenoid AddOption(constBz, bool, false, "", 0, "force constant Bz for tests") AddOption(setMaxTimeBin, int32_t, -2, "", 0, "maximum time bin of continuous data, 0 for triggered events, -1 for automatic continuous mode, -2 for automatic continuous / triggered") AddOption(overrideNHbfPerTF, int32_t, 0, "", 0, "Overrides the number of HBF per TF if != 0") +AddOption(overrideTPCTimeBinCur, int32_t, 0, "", 0, "Overrides TPC time bin cut if > 0") AddOption(deviceType, std::string, "CPU", "", 0, "Device type, CPU | CUDA | HIP | OCL1 | OCL2") AddOption(forceDeviceType, bool, true, "", 0, "force device type, otherwise allows fall-back to CPU") AddOption(synchronousProcessing, bool, false, "", 0, "Apply performance shortcuts for synchronous processing, disable unneeded steps") diff --git a/GPU/Workflow/src/GPUWorkflowTPC.cxx b/GPU/Workflow/src/GPUWorkflowTPC.cxx index b64c25b63cc54..f895587b8b020 100644 --- a/GPU/Workflow/src/GPUWorkflowTPC.cxx +++ b/GPU/Workflow/src/GPUWorkflowTPC.cxx @@ -306,7 +306,7 @@ bool GPURecoWorkflowSpec::fetchCalibsCCDBTPC(ProcessingCon } if (mSpecConfig.outputTracks || mSpecConfig.caClusterer) { - mTPCCutAtTimeBin = pc.inputs().get("tpcaltrosync")->getTB2Cut(pc.services().get().tfCounter); + mTPCCutAtTimeBin = mConfParam->overrideTPCTimeBinCur > 0 ? mConfParam->overrideTPCTimeBinCur : pc.inputs().get("tpcaltrosync")->getTB2Cut(pc.services().get().tfCounter); } // these calibrations are only defined for the tracking From 5d037e637b48b314cd22e6abe958ce93449ab8e6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 26 Nov 2024 18:15:30 +0100 Subject: [PATCH 0530/2205] GPU: Should not include std header in GPU device code --- .../include/CommonConstants/MathConstants.h | 3 ++- .../src/TrackParametrizationWithError.cxx | 15 +++++---------- GPU/Common/GPUCommonConstants.h | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Common/Constants/include/CommonConstants/MathConstants.h b/Common/Constants/include/CommonConstants/MathConstants.h index 6870b8ddd5712..9ef3b4dba5ae0 100644 --- a/Common/Constants/include/CommonConstants/MathConstants.h +++ b/Common/Constants/include/CommonConstants/MathConstants.h @@ -22,7 +22,8 @@ namespace constants { namespace math { -constexpr float Almost0 = 1.175494351e-38f; +constexpr float Almost0 = 0x1.0p-126f; // smallest non-denormal float +constexpr float Epsilon = 0x0.000002p0f; // smallest float such that 1 != 1 + Epsilon constexpr float Almost1 = 1.f - 1.0e-6f; constexpr float VeryBig = 1.f / Almost0; diff --git a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx index 0dd4a4441c0b3..81963adf79938 100644 --- a/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx +++ b/DataFormats/Reconstruction/src/TrackParametrizationWithError.cxx @@ -12,14 +12,9 @@ #include "ReconstructionDataFormats/TrackParametrizationWithError.h" #include "ReconstructionDataFormats/Vertex.h" #include "ReconstructionDataFormats/DCA.h" +#include "CommonConstants/MathConstants.h" #include -#ifndef __OPENCL__ -#include -#else -#include -#endif - #ifndef GPUCA_GPUCODE_DEVICE #include #endif @@ -794,11 +789,11 @@ GPUd() auto TrackParametrizationWithError::getPredictedChi2(const Track // get chi2 wrt other track, which must be defined at the same parameters X,alpha // Supplied non-initialized covToSet matrix is filled by inverse combined matrix for further use - if (gpu::CAMath::Abs(this->getAlpha() - rhs.getAlpha()) > FLT_EPSILON) { + if (gpu::CAMath::Abs(this->getAlpha() - rhs.getAlpha()) > o2::constants::math::Epsilon) { LOG(error) << "The reference Alpha of the tracks differ: " << this->getAlpha() << " : " << rhs.getAlpha(); return 2.f * HugeF; } - if (gpu::CAMath::Abs(this->getX() - rhs.getX()) > FLT_EPSILON) { + if (gpu::CAMath::Abs(this->getX() - rhs.getX()) > o2::constants::math::Epsilon) { LOG(error) << "The reference X of the tracks differ: " << this->getX() << " : " << rhs.getX(); return 2.f * HugeF; } @@ -827,11 +822,11 @@ GPUd() bool TrackParametrizationWithError::update(const TrackParametriz // update track with other track, the inverted combined cov matrix should be supplied // consider skipping this check, since it is usually already done upstream - if (gpu::CAMath::Abs(this->getAlpha() - rhs.getAlpha()) > FLT_EPSILON) { + if (gpu::CAMath::Abs(this->getAlpha() - rhs.getAlpha()) > o2::constants::math::Epsilon) { LOG(error) << "The reference Alpha of the tracks differ: " << this->getAlpha() << " : " << rhs.getAlpha(); return false; } - if (gpu::CAMath::Abs(this->getX() - rhs.getX()) > FLT_EPSILON) { + if (gpu::CAMath::Abs(this->getX() - rhs.getX()) > o2::constants::math::Epsilon) { LOG(error) << "The reference X of the tracks differ: " << this->getX() << " : " << rhs.getX(); return false; } diff --git a/GPU/Common/GPUCommonConstants.h b/GPU/Common/GPUCommonConstants.h index 883f64b7bdd12..f45aa05ed00ca 100644 --- a/GPU/Common/GPUCommonConstants.h +++ b/GPU/Common/GPUCommonConstants.h @@ -20,7 +20,7 @@ #if !defined(__OPENCL1__) namespace GPUCA_NAMESPACE::gpu::gpu_common_constants { -static CONSTEXPR const float kCLight = 0.000299792458f; +static CONSTEXPR const float kCLight = 0.000299792458f; // TODO: Duplicate of MathConstants, fix this when OpenCL1 is removed } #endif From 96e41889866f27476804d9ce6b1d89b0e48ab75b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Wed, 27 Nov 2024 14:08:25 +0100 Subject: [PATCH 0531/2205] GPU TPC: Fix TPC clusterizer qMax cut --- GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx index 8988126f7a15e..e8176ecb60d78 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx @@ -27,6 +27,10 @@ GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::Cl if (cn.qTot <= param.rec.tpc.cfQTotCutoff) { return false; } + cn.qMax = q; + if (cn.qMax <= param.rec.tpc.cfQMaxCutoff) { + return false; + } if (mTimeMean < param.rec.tpc.clustersShiftTimebinsClusterizer) { return false; } @@ -48,7 +52,6 @@ GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::Cl flags |= (wasSplitInPad) ? tpc::ClusterNative::flagSplitPad : 0; flags |= (isSingleCluster) ? tpc::ClusterNative::flagSingle : 0; - cn.qMax = q; cn.setTimeFlags(mTimeMean - param.rec.tpc.clustersShiftTimebinsClusterizer, flags); cn.setPad(mPadMean); cn.setSigmaTime(mTimeSigma); From d8d7b7c2111d5a01bba8761f0ce29bd7a715f95e Mon Sep 17 00:00:00 2001 From: Piotr Konopka Date: Wed, 27 Nov 2024 19:09:53 +0100 Subject: [PATCH 0532/2205] QC-1248 Update QC Flag documentation (#13720) * QC-1248 Update QC Flag documentation Small updates wrt what is ready to use and some clarifications. * rm trailing whitespace --- DataFormats/QualityControl/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DataFormats/QualityControl/README.md b/DataFormats/QualityControl/README.md index 486856c983306..33821319b7316 100644 --- a/DataFormats/QualityControl/README.md +++ b/DataFormats/QualityControl/README.md @@ -15,7 +15,7 @@ Data quality is determined through two methods: Both methods utilize the same data format for Flags. During processing (both synchronous and asynchronous), Checks produce Qualities and associate them with Flags. -The Quality Control framework then transmits these Flags to the RCT through a gRPC interface (**not ready yet**, to be done in the scope of QC-978). +The Quality Control framework then transmits these Flags to the RCT through a gRPC interface (more details in QC repository documentation). Detector experts can then review the automatically generated Flags and make any necessary modifications or additions directly in the RCT. ### Quality Control Flag Structure @@ -49,12 +49,13 @@ Each Flag Type has the following attributes: #### Creating and Managing Flag Types * **FlagTypeFactory** ensures a centralized and consistent list of available Flag Types. - New types can only be created through this factory. + New Flags can only be created through this factory. * **[flagTypes.csv](etc/flagTypes.csv)** defines the existing Flag Types, including their ID, name, and "bad quality" determinant, factory method name and a switch to deprecate a flag. The table serves as the source to automatically generate the corresponding methods in FlagTypeFactory. * **Adding new Flag Types:** If a new issue requires a flag not currently defined, propose the addition by contacting the async QC coordinators. They have the authority to add new Flag Types to the RCT. These changes will then be reflected in the [flagTypes.csv](etc/flagTypes.csv) file through a pull request. + Any proposals for new Flag Types should describe the effects on usability of data from analyzer point of view and they should not be detector-specific unless well-argumented. * **Modification of existing Flag Types:** Existing Flag Types should not be modified in terms of their definition. Instead, one may create a new Flag Type and mark the existing one as obsolete in the CSV table. This will add the `[[ deprecated ]]` attribute to the corresponding method. From 74c640eedba0f45814d421920b1aee2f9663c4ea Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Thu, 28 Nov 2024 11:28:39 +0100 Subject: [PATCH 0533/2205] Disable trackref assert This test is currently failing and disrupting the CI in Geant3 check kinematics. Disabling the assert on trackrefs for now. Will investigate the cause offline. Also renaming the variable to avoid shadowing an outer-scope variable. --- run/checkStack.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/run/checkStack.cxx b/run/checkStack.cxx index 4c2b9d5b50075..98f2669c9f97e 100644 --- a/run/checkStack.cxx +++ b/run/checkStack.cxx @@ -142,10 +142,10 @@ int main(int argc, char** argv) bool havereferences = trackrefs->size(); if (havereferences) { for (auto& trackID : trackidsinTPC) { - auto trackrefs = mcreader.getTrackRefs(eventID, trackID); - LOG(debug) << " Track " << trackID << " has " << trackrefs.size() << " TrackRefs"; - assert(trackrefs.size() > 0); - for (auto& ref : trackrefs) { + auto tpc_trackrefs = mcreader.getTrackRefs(eventID, trackID); + LOG(debug) << " Track " << trackID << " has " << tpc_trackrefs.size() << " TrackRefs"; + // assert(tpc_trackrefs.size() > 0); + for (auto& ref : tpc_trackrefs) { assert(ref.getTrackID() == trackID); } } From 66b81d8b6843b997a20b5bd7403e412d1e51f49b Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Thu, 28 Nov 2024 20:08:39 +0100 Subject: [PATCH 0534/2205] fix: +1 for L1 latency and trigger class check improved (#13682) * fix: +1 for L1 latency * fix: +1 for L1 latency * dev: decoder: checking only trigger class bits which belongs to run * clang * dev: ctp config added also to CTF decoder * clang * fix: getting ctpconfig * clang * fix: removing std:;cout * clang * removing macro's modification to have cleaner PR * dec: two latency vars, rew-decoder accessing ccdb * clang * TriggerParams old variable same name * clang * dev: reading of CCDB offset paraams in rawdatadecoder * clang * dev: config done only if run changed --- .../DataFormatsCTP/TriggerOffsetsParam.h | 3 +- .../include/CTPReconstruction/CTFCoder.h | 12 +++++++- .../CTPReconstruction/RawDataDecoder.h | 6 +++- .../CTP/reconstruction/src/RawDataDecoder.cxx | 25 +++++++++++++---- .../include/CTPWorkflow/EntropyDecoderSpec.h | 1 + .../include/CTPWorkflow/RawDecoderSpec.h | 3 ++ .../CTP/workflow/src/EntropyDecoderSpec.cxx | 19 +++++++++++-- Detectors/CTP/workflow/src/RawDecoderSpec.cxx | 28 ++++++++++++++++--- 8 files changed, 82 insertions(+), 15 deletions(-) diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/TriggerOffsetsParam.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/TriggerOffsetsParam.h index f931e9eaa8360..063336e5461ce 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/TriggerOffsetsParam.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/TriggerOffsetsParam.h @@ -24,9 +24,10 @@ namespace ctp struct TriggerOffsetsParam : public o2::conf::ConfigurableParamHelper { static constexpr int MaxNDet = 32; // take with margin to account for possible changes / upgrades int64_t LM_L0 = 15; - int64_t L0_L1 = 280; + int64_t L0_L1 = 281; // trigger input latency int64_t globalInputsShift = 0; // Global shift of inps; customOffset[CTP] is global shift of classes int64_t customOffset[MaxNDet] = {}; + int64_t L0_L1_classes = 280; // trigger input latency O2ParamDef(TriggerOffsetsParam, "TriggerOffsetsParam"); // boilerplate stuff + make principal key }; } // namespace ctp diff --git a/Detectors/CTP/reconstruction/include/CTPReconstruction/CTFCoder.h b/Detectors/CTP/reconstruction/include/CTPReconstruction/CTFCoder.h index 6ffb3575207e5..9189df5d12685 100644 --- a/Detectors/CTP/reconstruction/include/CTPReconstruction/CTFCoder.h +++ b/Detectors/CTP/reconstruction/include/CTPReconstruction/CTFCoder.h @@ -25,6 +25,7 @@ #include "DetectorsBase/CTFCoderBase.h" #include "CTPReconstruction/CTFHelper.h" #include "CTPReconstruction/RawDataDecoder.h" +#include "DataFormatsCTP/Configuration.h" class TTree; @@ -53,6 +54,9 @@ class CTFCoder : public o2::ctf::CTFCoderBase void createCoders(const std::vector& bufVec, o2::ctf::CTFCoderBase::OpType op) final; void setDecodeInps(bool decodeinps) { mDecodeInps = decodeinps; } + void setCTPConfig(CTPConfiguration cfg) { mCTPConfig = std::move(cfg); } + bool getDecodeInps() { return mDecodeInps; } + CTPConfiguration& getCTPConfig() { return mCTPConfig; } bool canApplyBCShiftInputs(const o2::InteractionRecord& ir) const { return canApplyBCShift(ir, mBCShiftInputs); } private: @@ -62,6 +66,7 @@ class CTFCoder : public o2::ctf::CTFCoderBase void appendToTree(TTree& tree, CTF& ec); void readFromTree(TTree& tree, int entry, std::vector& data, LumiInfo& lumi); std::vector mDataFilt; + CTPConfiguration mCTPConfig; int mBCShiftInputs = 0; bool mDecodeInps = false; }; @@ -215,8 +220,13 @@ o2::ctf::CTFIOSize CTFCoder::decode(const CTF::base& ec, VTRG& data, LumiInfo& l } } if (mDecodeInps) { + uint64_t trgclassmask = 0xffffffffffffffff; + if (mCTPConfig.getRunNumber() != 0) { + trgclassmask = mCTPConfig.getTriggerClassMask(); + } + // std::cout << "trgclassmask:" << std::hex << trgclassmask << std::dec << std::endl; o2::pmr::vector digits; - o2::ctp::RawDataDecoder::shiftInputs(digitsMap, digits, mFirstTFOrbit); + o2::ctp::RawDataDecoder::shiftInputs(digitsMap, digits, mFirstTFOrbit, trgclassmask); for (auto const& dig : digits) { data.emplace_back(dig); } diff --git a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h index c50079f9f8717..16a8ec6a6bef1 100644 --- a/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h +++ b/Detectors/CTP/reconstruction/include/CTPReconstruction/RawDataDecoder.h @@ -22,6 +22,7 @@ #include "Framework/InputRecord.h" #include "DataFormatsCTP/Digits.h" #include "DataFormatsCTP/LumiInfo.h" +#include "DataFormatsCTP/Configuration.h" namespace o2 { @@ -43,14 +44,16 @@ class RawDataDecoder void setVerbose(bool v) { mVerbose = v; } void setMAXErrors(int m) { mErrorMax = m; } int setLumiInp(int lumiinp, std::string inp); + void setCTPConfig(CTPConfiguration cfg) { mCTPConfig = std::move(cfg); }; uint32_t getIRRejected() const { return mIRRejected; } uint32_t getTCRRejected() const { return mTCRRejected; } std::vector& getTFOrbits() { return mTFOrbits; } int getErrorIR() { return mErrorIR; } int getErrorTCR() { return mErrorTCR; } + CTPConfiguration& getCTPConfig() { return mCTPConfig; } int init(); static int shiftNew(const o2::InteractionRecord& irin, uint32_t TFOrbit, std::bitset<48>& inpmask, int64_t shift, int level, std::map& digmap); - static int shiftInputs(std::map& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit); + static int shiftInputs(std::map& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit, uint64_t trgclassmask = 0xffffffffffffffff); private: static constexpr uint32_t TF_TRIGGERTYPE_MASK = 0x800; @@ -79,6 +82,7 @@ class RawDataDecoder int mErrorTCR = 0; int mErrorMax = 3; bool mStickyError = false; + CTPConfiguration mCTPConfig; }; } // namespace ctp } // namespace o2 diff --git a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx index 4e3d480e463cd..74e5b7481163d 100644 --- a/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx +++ b/Detectors/CTP/reconstruction/src/RawDataDecoder.cxx @@ -89,7 +89,7 @@ int RawDataDecoder::addCTPDigit(uint32_t linkCRU, uint32_t orbit, gbtword80_t& d } } else if (linkCRU == o2::ctp::GBTLinkIDClassRec) { int32_t BCShiftCorrection = -o2::ctp::TriggerOffsetsParam::Instance().customOffset[o2::detectors::DetID::CTP]; - int32_t offset = BCShiftCorrection + o2::ctp::TriggerOffsetsParam::Instance().LM_L0 + o2::ctp::TriggerOffsetsParam::Instance().L0_L1 - 1; + int32_t offset = BCShiftCorrection + o2::ctp::TriggerOffsetsParam::Instance().LM_L0 + o2::ctp::TriggerOffsetsParam::Instance().L0_L1_classes - 1; LOG(debug) << "tcr ir ori:" << ir; if ((ir.orbit <= mTFOrbit) && ((int32_t)ir.bc < offset)) { // LOG(warning) << "Loosing tclass:" << ir; @@ -293,7 +293,12 @@ int RawDataDecoder::decodeRaw(o2::framework::InputRecord& inputs, std::vector& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit) +int RawDataDecoder::shiftInputs(std::map& digitsMap, o2::pmr::vector& digits, uint32_t TFOrbit, uint64_t trgclassmask) { // int nClasswoInp = 0; // counting classes without input which should never happen int nLM = 0; @@ -527,6 +532,7 @@ int RawDataDecoder::shiftInputs(std::map& digit int nL1 = 0; int nTwI = 0; int nTwoI = 0; + int nTwoIlost = 0; std::map digitsMapShifted; auto L0shift = o2::ctp::TriggerOffsetsParam::Instance().LM_L0; auto L1shift = L0shift + o2::ctp::TriggerOffsetsParam::Instance().L0_L1; @@ -594,11 +600,17 @@ int RawDataDecoder::shiftInputs(std::map& digit if ((d.CTPInputMask & L1MASKInputs).count()) { nL1++; } - if (d.CTPClassMask.count()) { + if ((d.CTPClassMask).to_ulong() & trgclassmask) { if (d.CTPInputMask.count()) { nTwI++; } else { - nTwoI++; + if (d.intRecord.bc == (o2::constants::lhc::LHCMaxBunches - L1shift)) { // input can be lost because latency class-l1input = 1 + nTwoIlost++; + } else { + // LOG(error) << d.intRecord << " " << d.CTPClassMask << " " << d.CTPInputMask; + // std::cout << "ERROR:" << std::hex << d.CTPClassMask << " " << d.CTPInputMask << std::dec << std::endl; + nTwoI++; + } } } digits.push_back(dig.second); @@ -606,6 +618,9 @@ int RawDataDecoder::shiftInputs(std::map& digit if (nTwoI) { // Trigger class wo Input LOG(error) << "LM:" << nLM << " L0:" << nL0 << " L1:" << nL1 << " TwI:" << nTwI << " Trigger classes wo input:" << nTwoI; } + if (nTwoIlost) { + LOG(warn) << " Trigger classes wo input from diff latency 1:" << nTwoIlost; + } return 0; } // diff --git a/Detectors/CTP/workflow/include/CTPWorkflow/EntropyDecoderSpec.h b/Detectors/CTP/workflow/include/CTPWorkflow/EntropyDecoderSpec.h index 4596fe12cb31d..eee7abb08d16c 100644 --- a/Detectors/CTP/workflow/include/CTPWorkflow/EntropyDecoderSpec.h +++ b/Detectors/CTP/workflow/include/CTPWorkflow/EntropyDecoderSpec.h @@ -34,6 +34,7 @@ class EntropyDecoderSpec : public o2::framework::Task void init(o2::framework::InitContext& ic) final; void endOfStream(o2::framework::EndOfStreamContext& ec) final; void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final; + void updateTimeDependentParams(framework::ProcessingContext& pc); private: o2::ctp::CTFCoder mCTFCoder; diff --git a/Detectors/CTP/workflow/include/CTPWorkflow/RawDecoderSpec.h b/Detectors/CTP/workflow/include/CTPWorkflow/RawDecoderSpec.h index 607491b5cb48a..a5a1a75a0b594 100644 --- a/Detectors/CTP/workflow/include/CTPWorkflow/RawDecoderSpec.h +++ b/Detectors/CTP/workflow/include/CTPWorkflow/RawDecoderSpec.h @@ -16,6 +16,7 @@ #include #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" +#include "Framework/WorkflowSpec.h" #include "DataFormatsCTP/Digits.h" #include "DataFormatsCTP/LumiInfo.h" #include "CTPReconstruction/RawDataDecoder.h" @@ -50,6 +51,7 @@ class RawDecoderSpec : public framework::Task /// Input RawData: {"ROUT", "RAWDATA", 0, Lifetime::Timeframe} /// Output HW errors: {"CTP", "RAWHWERRORS", 0, Lifetime::Timeframe} -later void run(framework::ProcessingContext& ctx) final; + void updateTimeDependentParams(framework::ProcessingContext& pc); protected: private: @@ -68,6 +70,7 @@ class RawDecoderSpec : public framework::Task uint32_t mNTFToIntegrate = 1; uint32_t mNHBIntegratedT = 0; uint32_t mNHBIntegratedV = 0; + bool mDecodeinputs = 0; std::deque mHistoryT; std::deque mHistoryV; RawDataDecoder mDecoder; diff --git a/Detectors/CTP/workflow/src/EntropyDecoderSpec.cxx b/Detectors/CTP/workflow/src/EntropyDecoderSpec.cxx index 8f3da5f439f80..8c2f5d05aa031 100644 --- a/Detectors/CTP/workflow/src/EntropyDecoderSpec.cxx +++ b/Detectors/CTP/workflow/src/EntropyDecoderSpec.cxx @@ -55,9 +55,8 @@ void EntropyDecoderSpec::run(ProcessingContext& pc) mTimer.Start(false); o2::ctf::CTFIOSize iosize; - mCTFCoder.updateTimeDependentParams(pc, true); + updateTimeDependentParams(pc); auto buff = pc.inputs().get>("ctf_CTP"); - auto& digits = pc.outputs().make>(OutputRef{"digits"}); auto& lumi = pc.outputs().make(OutputRef{"CTPLumi"}); @@ -76,6 +75,20 @@ void EntropyDecoderSpec::endOfStream(EndOfStreamContext& ec) LOGF(info, "CTP Entropy Decoding total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } +void EntropyDecoderSpec::updateTimeDependentParams(framework::ProcessingContext& pc) +{ + mCTFCoder.updateTimeDependentParams(pc, true); + if (pc.services().get().globalRunNumberChanged) { + const auto ctpcfg = pc.inputs().get("ctpconfig"); + if (mCTFCoder.getDecodeInps()) { + const auto ctpcfg = pc.inputs().get("ctpconfig"); + if (ctpcfg != nullptr) { + mCTFCoder.setCTPConfig(*ctpcfg); + LOG(info) << "ctpconfig for run done:" << mCTFCoder.getCTPConfig().getRunNumber(); + } + } + } +} DataProcessorSpec getEntropyDecoderSpec(int verbosity, unsigned int sspec) { @@ -88,7 +101,7 @@ DataProcessorSpec getEntropyDecoderSpec(int verbosity, unsigned int sspec) inputs.emplace_back("ctf_CTP", "CTP", "CTFDATA", sspec, Lifetime::Timeframe); inputs.emplace_back("ctfdict_CTP", "CTP", "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/CTFDictionaryTree")); inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets")); - + inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config", 1)); return DataProcessorSpec{ "ctp-entropy-decoder", inputs, diff --git a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx index 415dbe2a1ffe3..81a927b3caee1 100644 --- a/Detectors/CTP/workflow/src/RawDecoderSpec.cxx +++ b/Detectors/CTP/workflow/src/RawDecoderSpec.cxx @@ -13,20 +13,21 @@ #include #include "Framework/InputRecordWalker.h" #include "Framework/DataRefUtils.h" -#include "Framework/WorkflowSpec.h" #include "Framework/ConfigParamRegistry.h" #include "DetectorsRaw/RDHUtils.h" #include "CTPWorkflow/RawDecoderSpec.h" #include "CommonUtils/VerbosityConfig.h" #include "Framework/InputRecord.h" #include "DataFormatsCTP/TriggerOffsetsParam.h" +#include "Framework/CCDBParamSpec.h" +#include "DataFormatsCTP/Configuration.h" using namespace o2::ctp::reco_workflow; void RawDecoderSpec::init(framework::InitContext& ctx) { - bool decodeinps = ctx.options().get("ctpinputs-decoding"); - mDecoder.setDecodeInps(decodeinps); + mDecodeinputs = ctx.options().get("ctpinputs-decoding"); + mDecoder.setDecodeInps(mDecodeinputs); mNTFToIntegrate = ctx.options().get("ntf-to-average"); mVerbose = ctx.options().get("use-verbose-mode"); int maxerrors = ctx.options().get("print-errors-num"); @@ -42,7 +43,7 @@ void RawDecoderSpec::init(framework::InitContext& ctx) mOutputLumiInfo.inp2 = inp2; mMaxInputSize = ctx.options().get("max-input-size"); mMaxInputSizeFatal = ctx.options().get("max-input-size-fatal"); - LOG(info) << "CTP reco init done. Inputs decoding here:" << decodeinps << " DoLumi:" << mDoLumi << " DoDigits:" << mDoDigits << " NTF:" << mNTFToIntegrate << " Lumi inputs:" << lumiinp1 << ":" << inp1 << " " << lumiinp2 << ":" << inp2 << " Max errors:" << maxerrors << " Max input size:" << mMaxInputSize << " MaxInputSizeFatal:" << mMaxInputSizeFatal; + LOG(info) << "CTP reco init done. Inputs decoding here:" << mDecodeinputs << " DoLumi:" << mDoLumi << " DoDigits:" << mDoDigits << " NTF:" << mNTFToIntegrate << " Lumi inputs:" << lumiinp1 << ":" << inp1 << " " << lumiinp2 << ":" << inp2 << " Max errors:" << maxerrors << " Max input size:" << mMaxInputSize << " MaxInputSizeFatal:" << mMaxInputSizeFatal; // mOutputLumiInfo.printInputs(); } void RawDecoderSpec::endOfStream(framework::EndOfStreamContext& ec) @@ -73,6 +74,7 @@ void RawDecoderSpec::endOfStream(framework::EndOfStreamContext& ec) } void RawDecoderSpec::run(framework::ProcessingContext& ctx) { + updateTimeDependentParams(ctx); mOutputDigits.clear(); std::map digits; using InputSpec = o2::framework::InputSpec; @@ -176,6 +178,7 @@ void RawDecoderSpec::run(framework::ProcessingContext& ctx) mOutputLumiInfo.orbit = lumiPointsHBF1[0].orbit; } mOutputLumiInfo.counts = mCountsT; + mOutputLumiInfo.countsFV0 = mCountsV; mOutputLumiInfo.nHBFCounted = mNHBIntegratedT; mOutputLumiInfo.nHBFCountedFV0 = mNHBIntegratedV; @@ -199,6 +202,8 @@ o2::framework::DataProcessorSpec o2::ctp::reco_workflow::getRawDecoderSpec(bool std::vector outputs; if (digits) { + inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/Config", 1)); + inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/TriggerOffsets")); outputs.emplace_back("CTP", "DIGITS", 0, o2::framework::Lifetime::Timeframe); } if (lumi) { @@ -219,3 +224,18 @@ o2::framework::DataProcessorSpec o2::ctp::reco_workflow::getRawDecoderSpec(bool {"max-input-size-fatal", o2::framework::VariantType::Bool, false, {"If true issue fatal error otherwise error on;y"}}, {"ctpinputs-decoding", o2::framework::VariantType::Bool, false, {"Inputs alignment: true - raw decoder - has to be compatible with CTF decoder: allowed options: 10,01,00"}}}}; } +void RawDecoderSpec::updateTimeDependentParams(framework::ProcessingContext& pc) +{ + if (pc.services().get().globalRunNumberChanged) { + pc.inputs().get("trigoffset"); + const auto& trigOffsParam = o2::ctp::TriggerOffsetsParam::Instance(); + LOG(info) << "updateing TroggerOffsetsParam: inputs L0_L1:" << trigOffsParam.L0_L1 << " classes L0_L1:" << trigOffsParam.L0_L1_classes; + if (mDecodeinputs) { + const auto ctpcfg = pc.inputs().get("ctpconfig"); + if (ctpcfg != nullptr) { + mDecoder.setCTPConfig(*ctpcfg); + LOG(info) << "ctpconfig for run done:" << mDecoder.getCTPConfig().getRunNumber(); + } + } + } +} From 78453a74d0d60b1bf9f421067265616ab9fa6f35 Mon Sep 17 00:00:00 2001 From: wiechula <11199190+wiechula@users.noreply.github.com> Date: Thu, 28 Nov 2024 15:53:15 +0100 Subject: [PATCH 0535/2205] TPC MC: Move hit exlusion after Track Ref creation --- Detectors/TPC/simulation/src/Detector.cxx | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Detectors/TPC/simulation/src/Detector.cxx b/Detectors/TPC/simulation/src/Detector.cxx index e261424c41332..36b86d8a6e532 100644 --- a/Detectors/TPC/simulation/src/Detector.cxx +++ b/Detectors/TPC/simulation/src/Detector.cxx @@ -142,6 +142,24 @@ Bool_t Detector::ProcessHits(FairVolume* vol) // TODO: Temporary hack to process only one sector // if (sectorID != 0) return kFALSE; + // ---| momentum and beta gamma |--- + static TLorentzVector momentum; // static to make avoid creation/deletion of this expensive object + fMC->TrackMomentum(momentum); + + const float time = fMC->TrackTime() * 1.0e9; + const int trackID = fMC->GetStack()->GetCurrentTrackNumber(); + const int detID = vol->getMCid(); + o2::data::Stack* stack = (o2::data::Stack*)fMC->GetStack(); + if (fMC->IsTrackEntering() || fMC->IsTrackExiting()) { + stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), + momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId())); + } + if (TMath::Abs(lastReferenceR - fMC->TrackLength()) > kMaxDistRef) { /// we can speedup + stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), + momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId())); + lastReferenceR = fMC->TrackLength(); + } + // ---| remove clusters between the IFC and the FC strips |--- // those should not enter the active readout area // do coarse selection before, to limit number of transformations @@ -164,24 +182,6 @@ Bool_t Detector::ProcessHits(FairVolume* vol) } } - // ---| momentum and beta gamma |--- - static TLorentzVector momentum; // static to make avoid creation/deletion of this expensive object - fMC->TrackMomentum(momentum); - - const float time = fMC->TrackTime() * 1.0e9; - const int trackID = fMC->GetStack()->GetCurrentTrackNumber(); - const int detID = vol->getMCid(); - o2::data::Stack* stack = (o2::data::Stack*)fMC->GetStack(); - if (fMC->IsTrackEntering() || fMC->IsTrackExiting()) { - stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), - momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId())); - } - if (TMath::Abs(lastReferenceR - fMC->TrackLength()) > kMaxDistRef) { /// we can speedup - stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), - momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId())); - lastReferenceR = fMC->TrackLength(); - } - // ===| CONVERT THE ENERGY LOSS TO IONIZATION ELECTRONS |===================== // // The energy loss is implemented directly below and taken GEANT3, From 4b86cfcf491827f6f3daa1984457a8b5609b10f0 Mon Sep 17 00:00:00 2001 From: wiechula <11199190+wiechula@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:04:10 +0100 Subject: [PATCH 0536/2205] Add missing setting of variable --- Detectors/TPC/simulation/src/Detector.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Detectors/TPC/simulation/src/Detector.cxx b/Detectors/TPC/simulation/src/Detector.cxx index 36b86d8a6e532..1a7c0fc25802b 100644 --- a/Detectors/TPC/simulation/src/Detector.cxx +++ b/Detectors/TPC/simulation/src/Detector.cxx @@ -153,6 +153,7 @@ Bool_t Detector::ProcessHits(FairVolume* vol) if (fMC->IsTrackEntering() || fMC->IsTrackExiting()) { stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId())); + lastReferenceR = fMC->TrackLength(); } if (TMath::Abs(lastReferenceR - fMC->TrackLength()) > kMaxDistRef) { /// we can speedup stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(), From 4f5e4fbe58d201bee5d4948aa003492593e78986 Mon Sep 17 00:00:00 2001 From: jditzelnew <58816213+jditzelnew@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:16:30 +0100 Subject: [PATCH 0537/2205] Updating hypernuclei information in O2 Databases (#13750) Adding correct masses and inserting Xi-bound states Adding Xi-bound states, fixing masses, lifetimes and decay channels. Removing excited states for A=4 hypernuclei (see latest AliRoot AliMC.cxx). --- .../SimulationDataFormat/O2DatabasePDG.h | 54 +++--- Steer/src/O2MCApplication.cxx | 173 +++++++++++++++--- 2 files changed, 165 insertions(+), 62 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h index 229a1a7a8a535..6b1690946e951 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h +++ b/DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h @@ -235,62 +235,38 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db) //Hyper nuclei and exotica ionCode = 1010010030; if (!db->GetParticle(ionCode)) { - db->AddParticle("HyperTriton", "HyperTriton", 2.99131, kFALSE, + db->AddParticle("HyperTriton", "HyperTriton", 2.991134, kFALSE, 2.5e-15, 3, "Ion", ionCode); } ionCode = -1010010030; if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperTriton", "AntiHyperTriton", 2.99131, kFALSE, + db->AddParticle("AntiHyperTriton", "AntiHyperTriton", 2.991134, kFALSE, 2.5e-15, 3, "Ion", ionCode); } //hyper hydrogen 4 ground state ionCode = 1010010040; if (!db->GetParticle(ionCode)) { - db->AddParticle("Hyperhydrog4", "Hyperhydrog4", 3.9226, kFALSE, + db->AddParticle("Hyperhydrog4", "Hyperhydrog4", 3.922434, kFALSE, 2.5e-15, 3, "Ion", ionCode); } //anti hyper hydrogen 4 ground state ionCode = -1010010040; if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperhydrog4", "AntiHyperhydrog4", 3.9226, kFALSE, - 2.5e-15, 3, "Ion", ionCode); - } - //hyper hydrogen 4 excited state - ionCode = 1010010041; - if (!db->GetParticle(ionCode)) { - db->AddParticle("Hyperhydrog4*", "Hyperhydrog4*", 3.9237, kFALSE, - 2.5e-15, 3, "Ion", ionCode); - } - //anti hyper hydrogen 4 excited state - ionCode = -1010010041; - if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperhydrog4*", "AntiHyperhydrog4*", 3.9237, kFALSE, + db->AddParticle("AntiHyperhydrog4", "AntiHyperhydrog4", 3.922434, kFALSE, 2.5e-15, 3, "Ion", ionCode); } //hyper helium 4 ground state ionCode = 1010020040; if (!db->GetParticle(ionCode)) { - db->AddParticle("Hyperhelium4", "Hyperhelium4", 3.9217, kFALSE, + db->AddParticle("Hyperhelium4", "Hyperhelium4", 3.921728, kFALSE, 2.5e-15, 6, "Ion", ionCode); } //anti hyper helium 4 ground state ionCode = -1010020040; if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperhelium4", "AntiHyperhelium4", 3.9217, kFALSE, - 2.5e-15, 6, "Ion", ionCode); - } - //hyper helium 4 excited state - ionCode = 1010020041; - if (!db->GetParticle(ionCode)) { - db->AddParticle("Hyperhelium4*", "Hyperhelium4*", 3.9231, kFALSE, - 2.5e-15, 6, "Ion", ionCode); - } - //anti hyper helium 4 excited state - ionCode = -1010020041; - if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperhelium4*", "AntiHyperhelium4*", 3.9231, kFALSE, + db->AddParticle("AntiHyperhelium4", "AntiHyperhelium4", 3.921728, kFALSE, 2.5e-15, 6, "Ion", ionCode); } @@ -309,13 +285,13 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db) ionCode = 1010020050; if (!db->GetParticle(ionCode)) { - db->AddParticle("Hyperhelium5", "Hyperhelium5", 4.841, kFALSE, + db->AddParticle("Hyperhelium5", "Hyperhelium5", 4.839961, kFALSE, 2.5e-15, 6, "Ion", ionCode); } ionCode = -1010020050; if (!db->GetParticle(ionCode)) { - db->AddParticle("AntiHyperhelium5", "AntiHyperhelium5", 4.841, kFALSE, + db->AddParticle("AntiHyperhelium5", "AntiHyperhelium5", 4.839961, kFALSE, 2.5e-15, 6, "Ion", ionCode); } @@ -331,6 +307,20 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db) 2.5e-15, 6, "Ion", ionCode); } + // 4-Xi-He + ionCode = 1120020040; + if (!db->GetParticle(ionCode)) { + db->AddParticle("4XiHe", "4XiHe", 4.128, kFALSE, 4.04e-15, 3, "Ion", ionCode); + db->AddAntiParticle("Anti4XiHe", -ionCode); + } + + // 4-Xi-H + ionCode = 1120010040; + if (!db->GetParticle(ionCode)) { + db->AddParticle("4XiH", "4XiH", 4.128, kFALSE, 4.04e-15, 3, "Ion", ionCode); + db->AddAntiParticle("Anti4XiH", -ionCode); + } + // hyper helium 4 sigma ionCode = 1110020040; if (!db->GetParticle(ionCode)) { diff --git a/Steer/src/O2MCApplication.cxx b/Steer/src/O2MCApplication.cxx index 96cc2f2e969db..02d332b0c0641 100644 --- a/Steer/src/O2MCApplication.cxx +++ b/Steer/src/O2MCApplication.cxx @@ -264,29 +264,19 @@ void addSpecialParticles() LOG(info) << "Adding custom particles to VMC"; //Hypertriton - TVirtualMC::GetMC()->DefineParticle(1010010030, "HyperTriton", kPTHadron, 2.99131, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 3, kFALSE); + TVirtualMC::GetMC()->DefineParticle(1010010030, "HyperTriton", kPTHadron, 2.991134, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 3, kFALSE); //Anti-Hypertriton - TVirtualMC::GetMC()->DefineParticle(-1010010030, "AntiHyperTriton", kPTHadron, 2.99131, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 3, kFALSE); + TVirtualMC::GetMC()->DefineParticle(-1010010030, "AntiHyperTriton", kPTHadron, 2.991134, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 3, kFALSE); //Hyper hydrogen 4 ground state - TVirtualMC::GetMC()->DefineParticle(1010010040, "Hyperhydrog4", kPTHadron, 3.9226, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + TVirtualMC::GetMC()->DefineParticle(1010010040, "Hyperhydrog4", kPTHadron, 3.922434, 1.0, 2.08e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); //Anti-Hyper hydrogen 4 ground state - TVirtualMC::GetMC()->DefineParticle(-1010010040, "AntiHyperhydrog4", kPTHadron, 3.9226, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); - - //Hyper hydrogen 4 excited state - TVirtualMC::GetMC()->DefineParticle(1010010041, "Hyperhydrog4*", kPTHadron, 3.9237, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); - //Anti-Hyper hydrogen 4 excited state - TVirtualMC::GetMC()->DefineParticle(-1010010041, "AntiHyperhydrog4*", kPTHadron, 3.9237, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + TVirtualMC::GetMC()->DefineParticle(-1010010040, "AntiHyperhydrog4", kPTHadron, 3.922434, 1.0, 2.08e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); //Hyper helium 4 ground state - TVirtualMC::GetMC()->DefineParticle(1010020040, "Hyperhelium4", kPTHadron, 3.9217, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + TVirtualMC::GetMC()->DefineParticle(1010020040, "Hyperhelium4", kPTHadron, 3.921728, 2.0, 2.50e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); //Anti-Hyper helium 4 ground state - TVirtualMC::GetMC()->DefineParticle(-1010020040, "AntiHyperhelium4", kPTHadron, 3.9217, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); - - //Hyper helium 4 excited state - TVirtualMC::GetMC()->DefineParticle(1010020041, "Hyperhelium4*", kPTHadron, 3.9231, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); - //Anti-Hyper helium 4 excited state - TVirtualMC::GetMC()->DefineParticle(-1010020041, "AntiHyperhelium4*", kPTHadron, 3.9231, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + TVirtualMC::GetMC()->DefineParticle(-1010020040, "AntiHyperhelium4", kPTHadron, 3.921728, 2.0, 2.50e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); // Lithium 4 ground state TVirtualMC::GetMC()->DefineParticle(1000030040, "Lithium4", kPTHadron, 3.7513, 3.0, 9.1e-23, "Ion", 0.003, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); @@ -294,15 +284,24 @@ void addSpecialParticles() TVirtualMC::GetMC()->DefineParticle(-1000030040, "AntiLithium4", kPTHadron, 3.7513, 3.0, 9.1e-23, "Ion", 0.003, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); //Hyper helium 5 - TVirtualMC::GetMC()->DefineParticle(1010020050, "Hyperhelium5", kPTHadron, 4.841, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE); + TVirtualMC::GetMC()->DefineParticle(1010020050, "Hyperhelium5", kPTHadron, 4.839961, 2.0, 2.74e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE); //Anti-Hyper helium 5 - TVirtualMC::GetMC()->DefineParticle(-1010020050, "AntiHyperhelium5", kPTHadron, 4.841, 2.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE); + TVirtualMC::GetMC()->DefineParticle(-1010020050, "AntiHyperhelium5", kPTHadron, 4.839961, 2.0, 2.74e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 5, kFALSE); //Double Hyper hydrogen 4 TVirtualMC::GetMC()->DefineParticle(1020010040, "DoubleHyperhydrogen4", kPTHadron, 4.106, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); //Double Anti-Hyper hydrogen 4 TVirtualMC::GetMC()->DefineParticle(-1020010040, "DoubleAntiHyperhydrogen4", kPTHadron, 4.106, 1.0, 2.632e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // 4Xi(-)H + TVirtualMC::GetMC()->DefineParticle(1120010040, "4XiH", kPTHadron, 4.128, 1.0, 1.639e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // Anti-4Xi(-)H + TVirtualMC::GetMC()->DefineParticle(-1120010040, "Anti4XiH", kPTHadron, 4.128, 1.0, 1.639e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // 4Xi(-)He + TVirtualMC::GetMC()->DefineParticle(1120020040, "4XiHe", kPTHadron, 4.128, 1.0, 1.639e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // Anti-4Xi(-)He + TVirtualMC::GetMC()->DefineParticle(-1120020040, "Anti4XiHe", kPTHadron, 4.128, 1.0, 1.639e-10, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); + // Hyper helium 4 sigma TVirtualMC::GetMC()->DefineParticle(1110020040, "Hyperhelium4sigma", kPTHadron, 3.995, 2.0, 8.018e-11, "Ion", 0.0, 0, 1, 0, 0, 0, 0, 0, 4, kFALSE); // Anti-Hyper helium 4 sigma @@ -586,8 +585,6 @@ void addSpecialParticles() mode3[1][2] = -211; // negative pion TVirtualMC::GetMC()->SetDecayMode(1010010040, bratio3, mode3); - //Decay for the excited state (after em transition) - TVirtualMC::GetMC()->SetDecayMode(1010010041, bratio3, mode3); // Define the 2- and 3-body phase space decay for the Hyper Hydrogen 4 Int_t amode3[6][3]; @@ -608,8 +605,6 @@ void addSpecialParticles() amode3[1][2] = 211; // positive pion TVirtualMC::GetMC()->SetDecayMode(-1010010040, abratio3, amode3); - //Decay for the excited state (after em transition) - TVirtualMC::GetMC()->SetDecayMode(-1010010041, abratio3, amode3); // Define the 3-body phase space decay for the Hyper Helium 4 Int_t mode4[6][3]; @@ -621,14 +616,16 @@ void addSpecialParticles() mode4[kz][1] = 0; mode4[kz][2] = 0; } - bratio4[0] = 100.; + bratio4[0] = 50.; mode4[0][0] = 1000020030; // Helium3 mode4[0][1] = -211; // negative pion mode4[0][2] = 2212; // proton + bratio4[1] = 50.; + mode4[1][0] = 1000030040; // lithium-4 + mode4[1][1] = -211; // negative pion + TVirtualMC::GetMC()->SetDecayMode(1010020040, bratio4, mode4); - //Decay for the excited state (after em transition) - TVirtualMC::GetMC()->SetDecayMode(1010020041, bratio4, mode4); // Define the 2-body phase space decay for the Anti-Hyper Helium 4 Int_t amode4[6][3]; @@ -640,14 +637,16 @@ void addSpecialParticles() amode4[kz][1] = 0; amode4[kz][2] = 0; } - abratio4[0] = 100.; + abratio4[0] = 50.; amode4[0][0] = -1000020030; // anti-Helium 3 amode4[0][1] = 211; // positive pion amode4[0][2] = -2212; // anti proton + abratio4[1] = 50.; + amode4[1][0] = -1000030040; // antilithium-4 + amode4[1][1] = 211; // positive pion + TVirtualMC::GetMC()->SetDecayMode(-1010020040, abratio4, amode4); - //Decay for the excited state (after em transition) - TVirtualMC::GetMC()->SetDecayMode(-1010020041, abratio4, amode4); // Define the 2-body phase space decay for the Lithium 4 Int_t model4[6][3]; @@ -733,10 +732,15 @@ void addSpecialParticles() mode42[kz][1] = 0; mode42[kz][2] = 0; } - bratio42[0] = 100.; + bratio42[0] = 50.; mode42[0][0] = 1010020040; // Hyper-Helium4 mode42[0][1] = -211; // negative pion + bratio42[1] = 50.; + mode42[1][0] = 1010010030; // Hypertriton + mode42[1][1] = 2212; // proton + mode42[1][2] = -211; // negative pion + TVirtualMC::GetMC()->SetDecayMode(1020010040, bratio42, mode42); // Define the 2-body phase space decay for the Anti Double Hyper Hydrogen 4 @@ -749,12 +753,121 @@ void addSpecialParticles() amode42[kz][1] = 0; amode42[kz][2] = 0; } - abratio42[0] = 100.; + abratio42[0] = 50.; amode42[0][0] = -1010020040; // anti-Hyper-Helium 4 amode42[0][1] = 211; // positive pion + abratio42[1] = 50.; + amode42[1][0] = -1010010030; // anti-Hypertriton + amode42[1][1] = -2212; // antiproton + amode42[1][2] = 211; // positive pion + TVirtualMC::GetMC()->SetDecayMode(-1020010040, abratio42, amode42); + // Define the decay for the 4Xi(-)He + Int_t mode4XiHe[6][3]; + Float_t bratio4XiHe[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + bratio4XiHe[kz] = 0.; + mode4XiHe[kz][0] = 0; + mode4XiHe[kz][1] = 0; + mode4XiHe[kz][2] = 0; + } + bratio4XiHe[0] = 33.; + mode4XiHe[0][0] = 1010020040; // HyperHelium4 + mode4XiHe[0][1] = -211; // negative pion + + bratio4XiHe[1] = 33.; + mode4XiHe[1][0] = 3122; // lambda + mode4XiHe[1][1] = 1000020030; // helium-3 + mode4XiHe[1][2] = -211; // negative pion + + bratio4XiHe[2] = 33.; + mode4XiHe[2][0] = 1000030040; // lithium-4 + mode4XiHe[2][1] = -211; // negative pion + mode4XiHe[2][2] = -211; // negative pion + + TVirtualMC::GetMC()->SetDecayMode(1120020040, bratio4XiHe, mode4XiHe); + + // Define the decay for the Anti-4Xi(-)He + Int_t amode4XiHe[6][3]; + Float_t abratio4XiHe[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + abratio4XiHe[kz] = 0.; + amode4XiHe[kz][0] = 0; + amode4XiHe[kz][1] = 0; + amode4XiHe[kz][2] = 0; + } + abratio4XiHe[0] = 33.; + amode4XiHe[0][0] = -1010020040; // antiHyperHelium-4 + amode4XiHe[0][1] = 211; // positive pion + + abratio4XiHe[1] = 33.; + amode4XiHe[1][0] = -3122; // antilambda + amode4XiHe[1][1] = -1000020030; // antihelium-3 + amode4XiHe[1][2] = 211; // positive pion + + abratio4XiHe[2] = 33.; + amode4XiHe[2][0] = -1000030040; // antilithium-4 + amode4XiHe[2][1] = 211; // positive pion + amode4XiHe[2][2] = 211; // positive pion + + TVirtualMC::GetMC()->SetDecayMode(-1120020040, abratio4XiHe, amode4XiHe); + + // Define the decay for the 4Xi(-)H + Int_t mode4XiH[6][3]; + Float_t bratio4XiH[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + bratio4XiH[kz] = 0.; + mode4XiH[kz][0] = 0; + mode4XiH[kz][1] = 0; + mode4XiH[kz][2] = 0; + } + bratio4XiH[0] = 33.; + mode4XiH[0][0] = 1010010040; // HyperHydrogen4 + mode4XiH[0][1] = -211; // negative pion + + bratio4XiH[1] = 33.; + mode4XiH[1][0] = 3122; // lambda + mode4XiH[1][1] = 1000010030; // triton + mode4XiH[1][2] = -211; // negative pion + + bratio4XiH[2] = 33.; + mode4XiH[2][0] = 1000020040; // alpha + mode4XiH[2][1] = -211; // negative pion + mode4XiH[2][2] = -211; // negative pion + + TVirtualMC::GetMC()->SetDecayMode(1120010040, bratio4XiH, mode4XiH); + + // Define the decay for the Anti-4Xi(-)H + Int_t amode4XiH[6][3]; + Float_t abratio4XiH[6]; + + for (Int_t kz = 0; kz < 6; kz++) { + abratio4XiH[kz] = 0.; + amode4XiH[kz][0] = 0; + amode4XiH[kz][1] = 0; + amode4XiH[kz][2] = 0; + } + abratio4XiH[0] = 33.; + amode4XiH[0][0] = -1010010040; // antiHyperHydrogen-4 + amode4XiH[0][1] = 211; // positive pion + + abratio4XiH[1] = 33.; + amode4XiH[1][0] = -3122; // antilambda + amode4XiH[1][1] = -1000010030; // antitriton + amode4XiH[1][2] = 211; // positive pion + + abratio4XiH[2] = 33.; + amode4XiH[2][0] = -1000020040; // antialpha + amode4XiH[2][1] = 211; // positive pion + amode4XiH[2][2] = 211; // positive pion + + TVirtualMC::GetMC()->SetDecayMode(-1120010040, abratio4XiH, amode4XiH); + // Define the 2- and 3-body phase space decay for the Hyper Helium 4 sigma Int_t mode4s[6][3]; Float_t bratio4s[6]; From 167b8c0de7f447ee0a462d88d91f4c69f8677f8b Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Fri, 29 Nov 2024 17:37:07 +0100 Subject: [PATCH 0538/2205] Re-enabled TPC TrackRef check after fix (#13756) * Re-enabled TPC TrackRef check after fix * Set fixed seed for Geant3/4 tests, previously failing the CI --- run/CMakeLists.txt | 4 ++++ run/checkStack.cxx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/run/CMakeLists.txt b/run/CMakeLists.txt index f21ecafb0528a..662716901ed0a 100644 --- a/run/CMakeLists.txt +++ b/run/CMakeLists.txt @@ -193,6 +193,8 @@ o2_add_test_command(NAME o2sim_G4 2 --skipModules MFT ZDC + --seed + 15946057944514955802 --configKeyValues "align-geom.mDetectors=none" ENVIRONMENT "${SIMENV}" @@ -255,6 +257,8 @@ o2_add_test_command(NAME o2sim_G3 pythia8pp --chunkSize 10 + --seed + 15946057944514955802 --configKeyValues "align-geom.mDetectors=none" LABELS g3 sim long diff --git a/run/checkStack.cxx b/run/checkStack.cxx index 98f2669c9f97e..36a9da7a62c13 100644 --- a/run/checkStack.cxx +++ b/run/checkStack.cxx @@ -144,7 +144,7 @@ int main(int argc, char** argv) for (auto& trackID : trackidsinTPC) { auto tpc_trackrefs = mcreader.getTrackRefs(eventID, trackID); LOG(debug) << " Track " << trackID << " has " << tpc_trackrefs.size() << " TrackRefs"; - // assert(tpc_trackrefs.size() > 0); + assert(tpc_trackrefs.size() > 0); for (auto& ref : tpc_trackrefs) { assert(ref.getTrackID() == trackID); } From dc760aaed875633b84ce0953ad9cb744892a747d Mon Sep 17 00:00:00 2001 From: Gabriele Cimador <92120560+cima22@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:18:26 +0100 Subject: [PATCH 0539/2205] GPU TPC: Decoding: Add option to apply timebin cut to CTF cluster decoding on GPUs (#13753) * GPU: TPC Decoding: add optional timebin cut to CTF cluster decoding * GPU: TPC Decoding: add missing checks on track model parameters --- .../DataCompression/GPUTPCDecompression.cxx | 21 +++++ .../DataCompression/GPUTPCDecompression.h | 9 ++ .../GPUTPCDecompressionKernels.cxx | 47 +++++++++- .../GPUTPCDecompressionKernels.h | 6 +- .../Definitions/GPUDefGPUParameters.h | 6 ++ .../Global/GPUChainTrackingCompression.cxx | 89 +++++++++++++++---- GPU/GPUTracking/kernels.cmake | 2 + 7 files changed, 163 insertions(+), 17 deletions(-) diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx index 0f7acfce86094..7c10f0eeef74f 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.cxx @@ -84,6 +84,24 @@ void* GPUTPCDecompression::SetPointersTmpNativeBuffersInput(void* mem) return mem; } +void* GPUTPCDecompression::SetPointersTmpClusterNativeAccessForFiltering(void* mem) +{ + computePointerWithAlignment(mem, mNativeClustersBuffer, mNClusterNativeBeforeFiltering); + return mem; +} + +void* GPUTPCDecompression::SetPointersInputClusterNativeAccess(void* mem) +{ + computePointerWithAlignment(mem, mClusterNativeAccess); + return mem; +} + +void* GPUTPCDecompression::SetPointersNClusterPerSectorRow(void* mem) +{ + computePointerWithAlignment(mem, mNClusterPerSectorRow, NSLICES * GPUCA_ROW_COUNT); + return mem; +} + void GPUTPCDecompression::RegisterMemoryAllocation() { AllocateAndInitializeLate(); @@ -91,6 +109,9 @@ void GPUTPCDecompression::RegisterMemoryAllocation() mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersTmpNativeBuffersGPU, GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpBuffersGPU"); mResourceTmpIndexes = mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersTmpNativeBuffersOutput, GPUMemoryResource::MEMORY_OUTPUT | GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpBuffersOutput"); mResourceTmpClustersOffsets = mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersTmpNativeBuffersInput, GPUMemoryResource::MEMORY_INPUT | GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpBuffersInput"); + mResourceTmpBufferBeforeFiltering = mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersTmpClusterNativeAccessForFiltering, GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpBufferForFiltering"); + mResourceClusterNativeAccess = mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersInputClusterNativeAccess, GPUMemoryResource::MEMORY_INPUT | GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpClusterAccessForFiltering"); + mResourceNClusterPerSectorRow = mRec->RegisterMemoryAllocation(this, &GPUTPCDecompression::SetPointersNClusterPerSectorRow, GPUMemoryResource::MEMORY_OUTPUT | GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_SCRATCH, "TPCDecompressionTmpClusterCountForFiltering"); } void GPUTPCDecompression::SetMaxData(const GPUTrackingInOutPointers& io) diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h index d9871613d8401..47c64008b176e 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h @@ -55,6 +55,9 @@ class GPUTPCDecompression : public GPUProcessor void* SetPointersTmpNativeBuffersGPU(void* mem); void* SetPointersTmpNativeBuffersOutput(void* mem); void* SetPointersTmpNativeBuffersInput(void* mem); + void* SetPointersTmpClusterNativeAccessForFiltering(void* mem); + void* SetPointersInputClusterNativeAccess(void* mem); + void* SetPointersNClusterPerSectorRow(void* mem); #endif @@ -63,11 +66,14 @@ class GPUTPCDecompression : public GPUProcessor o2::tpc::CompressedClusters mInputGPU; uint32_t mMaxNativeClustersPerBuffer; + uint32_t mNClusterNativeBeforeFiltering; uint32_t* mNativeClustersIndex; uint32_t* mUnattachedClustersOffsets; uint32_t* mAttachedClustersOffsets; + uint32_t* mNClusterPerSectorRow; o2::tpc::ClusterNative* mTmpNativeClusters; o2::tpc::ClusterNative* mNativeClustersBuffer; + o2::tpc::ClusterNativeAccess* mClusterNativeAccess; template void SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA); @@ -75,6 +81,9 @@ class GPUTPCDecompression : public GPUProcessor int16_t mMemoryResInputGPU = -1; int16_t mResourceTmpIndexes = -1; int16_t mResourceTmpClustersOffsets = -1; + int16_t mResourceTmpBufferBeforeFiltering = -1; + int16_t mResourceClusterNativeAccess = -1; + int16_t mResourceNClusterPerSectorRow = -1; }; } // namespace GPUCA_NAMESPACE::gpu #endif // GPUTPCDECOMPRESSION_H diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx index 2c88ea0079a26..d7f1e2ac88368 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.cxx @@ -43,7 +43,7 @@ GPUdii() void GPUTPCDecompressionKernels::Thread 0 ? cl.getTime() < param.tpcCutTimeBin : true; +} + +template <> +GPUdii() void GPUTPCDecompressionUtilKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) +{ + const GPUParam& GPUrestrict() param = processors.param; + GPUTPCDecompression& GPUrestrict() decompressor = processors.tpcDecompressor; + const ClusterNativeAccess* clusterAccess = decompressor.mClusterNativeAccess; + for (uint32_t i = get_global_id(0); i < GPUCA_NSLICES * GPUCA_ROW_COUNT; i += get_global_size(0)) { + uint32_t slice = i / GPUCA_ROW_COUNT; + uint32_t row = i % GPUCA_ROW_COUNT; + for (uint32_t k = 0; k < clusterAccess->nClusters[slice][row]; k++) { + ClusterNative cl = clusterAccess->clusters[slice][row][k]; + if (isClusterKept(cl, param)) { + decompressor.mNClusterPerSectorRow[i]++; + } + } + } +} + +template <> +GPUdii() void GPUTPCDecompressionUtilKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) +{ + const GPUParam& GPUrestrict() param = processors.param; + GPUTPCDecompression& GPUrestrict() decompressor = processors.tpcDecompressor; + ClusterNative* GPUrestrict() clusterBuffer = decompressor.mNativeClustersBuffer; + const ClusterNativeAccess* clusterAccess = decompressor.mClusterNativeAccess; + const ClusterNativeAccess* outputAccess = processors.ioPtrs.clustersNative; + for (uint32_t i = get_global_id(0); i < GPUCA_NSLICES * GPUCA_ROW_COUNT; i += get_global_size(0)) { + uint32_t slice = i / GPUCA_ROW_COUNT; + uint32_t row = i % GPUCA_ROW_COUNT; + uint32_t count = 0; + for (uint32_t k = 0; k < clusterAccess->nClusters[slice][row]; k++) { + const ClusterNative cl = clusterAccess->clusters[slice][row][k]; + if (isClusterKept(cl, param)) { + clusterBuffer[outputAccess->clusterOffset[slice][row] + count] = cl; + count++; + } + } + } +} + template <> GPUdii() void GPUTPCDecompressionUtilKernels::Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& processors) { diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h index 622e1fd984fa7..b45af622ebac8 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompressionKernels.h @@ -59,11 +59,15 @@ class GPUTPCDecompressionUtilKernels : public GPUKernelTemplate { public: enum K : int32_t { - sortPerSectorRow = 0, + countFilteredClusters = 0, + storeFilteredClusters = 1, + sortPerSectorRow = 2, }; template GPUd() static void Thread(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() processors); + + GPUdi() static bool isClusterKept(const o2::tpc::ClusterNative& cl, const GPUParam& GPUrestrict() param); }; } // namespace GPUCA_NAMESPACE::gpu diff --git a/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h b/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h index 970e1b2926853..3852d37f6facf 100644 --- a/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h +++ b/GPU/GPUTracking/Definitions/GPUDefGPUParameters.h @@ -344,6 +344,12 @@ #endif #ifndef GPUCA_LB_GPUTPCDecompressionUtilKernels_sortPerSectorRow #define GPUCA_LB_GPUTPCDecompressionUtilKernels_sortPerSectorRow 256 + #endif + #ifndef GPUCA_LB_GPUTPCDecompressionUtilKernels_countFilteredClusters + #define GPUCA_LB_GPUTPCDecompressionUtilKernels_countFilteredClusters 256 + #endif + #ifndef GPUCA_LB_GPUTPCDecompressionUtilKernels_storeFilteredClusters + #define GPUCA_LB_GPUTPCDecompressionUtilKernels_storeFilteredClusters 256 #endif #ifndef GPUCA_LB_GPUTPCCFDecodeZS #define GPUCA_LB_GPUTPCCFDecodeZS 128, 4 diff --git a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx index 8ca3a83e780fb..01e4d011d08b9 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx @@ -246,6 +246,7 @@ int32_t GPUChainTracking::RunTPCDecompression() mRec->PushNonPersistentMemory(qStr2Tag("TPCDCMPR")); RecoStep myStep = RecoStep::TPCDecompression; bool doGPU = GetRecoStepsGPU() & RecoStep::TPCDecompression; + bool runFiltering = param().tpcCutTimeBin > 0; GPUTPCDecompression& Decompressor = processors()->tpcDecompressor; GPUTPCDecompression& DecompressorShadow = doGPU ? processorsShadow()->tpcDecompressor : Decompressor; const auto& threadContext = GetThreadContext(); @@ -253,6 +254,13 @@ int32_t GPUChainTracking::RunTPCDecompression() CompressedClusters& inputGPU = Decompressor.mInputGPU; CompressedClusters& inputGPUShadow = DecompressorShadow.mInputGPU; + if (cmprClsHost.nTracks && cmprClsHost.solenoidBz != -1e6f && cmprClsHost.solenoidBz != param().bzkG) { + throw std::runtime_error("Configured solenoid Bz does not match value used for track model encoding"); + } + if (cmprClsHost.nTracks && cmprClsHost.maxTimeBin != -1e6 && cmprClsHost.maxTimeBin != param().continuousMaxTimeBin) { + throw std::runtime_error("Configured max time bin does not match value used for track model encoding"); + } + int32_t inputStream = 0; int32_t unattachedStream = mRec->NStreams() - 1; inputGPU = cmprClsHost; @@ -300,12 +308,6 @@ int32_t GPUChainTracking::RunTPCDecompression() GPUMemCpy(myStep, inputGPUShadow.sigmaPadU, cmprClsHost.sigmaPadU, cmprClsHost.nUnattachedClusters * sizeof(cmprClsHost.sigmaPadU[0]), unattachedStream, toGPU); GPUMemCpy(myStep, inputGPUShadow.sigmaTimeU, cmprClsHost.sigmaTimeU, cmprClsHost.nUnattachedClusters * sizeof(cmprClsHost.sigmaTimeU[0]), unattachedStream, toGPU); - mInputsHost->mNClusterNative = mInputsShadow->mNClusterNative = cmprClsHost.nAttachedClusters + cmprClsHost.nUnattachedClusters; - AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); - AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeBuffer); - DecompressorShadow.mNativeClustersBuffer = mInputsShadow->mPclusterNativeBuffer; - Decompressor.mNativeClustersBuffer = mInputsHost->mPclusterNativeOutput; - WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); TransferMemoryResourceLinkToHost(RecoStep::TPCDecompression, Decompressor.mResourceTmpIndexes, inputStream, nullptr, mEvents->stream, nStreams); SynchronizeStream(inputStream); uint32_t offset = 0; @@ -324,27 +326,83 @@ int32_t GPUChainTracking::RunTPCDecompression() if (decodedAttachedClusters != cmprClsHost.nAttachedClusters) { GPUWarning("%u / %u clusters failed track model decoding (%f %%)", cmprClsHost.nAttachedClusters - decodedAttachedClusters, cmprClsHost.nAttachedClusters, 100.f * (float)(cmprClsHost.nAttachedClusters - decodedAttachedClusters) / (float)cmprClsHost.nAttachedClusters); } - if (doGPU) { - mClusterNativeAccess->clustersLinear = mInputsShadow->mPclusterNativeBuffer; + if (runFiltering) { // If filtering, allocate a temporary buffer and cluster native access in decompressor context + Decompressor.mNClusterNativeBeforeFiltering = DecompressorShadow.mNClusterNativeBeforeFiltering = decodedAttachedClusters + cmprClsHost.nUnattachedClusters; + AllocateRegisteredMemory(Decompressor.mResourceTmpBufferBeforeFiltering); + AllocateRegisteredMemory(Decompressor.mResourceClusterNativeAccess); + mClusterNativeAccess->clustersLinear = DecompressorShadow.mNativeClustersBuffer; + mClusterNativeAccess->setOffsetPtrs(); + *Decompressor.mClusterNativeAccess = *mClusterNativeAccess; + WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); + TransferMemoryResourceLinkToGPU(RecoStep::TPCDecompression, Decompressor.mResourceClusterNativeAccess, inputStream, &mEvents->single); + } else { // If not filtering, directly allocate the final buffers + mInputsHost->mNClusterNative = mInputsShadow->mNClusterNative = cmprClsHost.nAttachedClusters + cmprClsHost.nUnattachedClusters; + AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeBuffer); + DecompressorShadow.mNativeClustersBuffer = mInputsShadow->mPclusterNativeBuffer; + Decompressor.mNativeClustersBuffer = mInputsHost->mPclusterNativeOutput; + DecompressorShadow.mClusterNativeAccess = mInputsShadow->mPclusterNativeAccess; + Decompressor.mClusterNativeAccess = mInputsHost->mPclusterNativeAccess; + WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), inputStream); + if (doGPU) { + mClusterNativeAccess->clustersLinear = mInputsShadow->mPclusterNativeBuffer; + mClusterNativeAccess->setOffsetPtrs(); + *mInputsHost->mPclusterNativeAccess = *mClusterNativeAccess; + processorsShadow()->ioPtrs.clustersNative = mInputsShadow->mPclusterNativeAccess; + WriteToConstantMemory(RecoStep::TPCDecompression, (char*)&processors()->ioPtrs - (char*)processors(), &processorsShadow()->ioPtrs, sizeof(processorsShadow()->ioPtrs), inputStream); + TransferMemoryResourceLinkToGPU(RecoStep::TPCDecompression, mInputsHost->mResourceClusterNativeAccess, inputStream, &mEvents->single); + } + mIOPtrs.clustersNative = mClusterNativeAccess.get(); + mClusterNativeAccess->clustersLinear = mInputsHost->mPclusterNativeOutput; mClusterNativeAccess->setOffsetPtrs(); *mInputsHost->mPclusterNativeAccess = *mClusterNativeAccess; - processorsShadow()->ioPtrs.clustersNative = mInputsShadow->mPclusterNativeAccess; - WriteToConstantMemory(RecoStep::TPCDecompression, (char*)&processors()->ioPtrs - (char*)processors(), &processorsShadow()->ioPtrs, sizeof(processorsShadow()->ioPtrs), inputStream); - TransferMemoryResourceLinkToGPU(RecoStep::TPCDecompression, mInputsHost->mResourceClusterNativeAccess, inputStream, &mEvents->single); } - mIOPtrs.clustersNative = mClusterNativeAccess.get(); - mClusterNativeAccess->clustersLinear = mInputsHost->mPclusterNativeOutput; - mClusterNativeAccess->setOffsetPtrs(); uint32_t batchSize = doGPU ? 6 : NSLICES; for (uint32_t iSlice = 0; iSlice < NSLICES; iSlice = iSlice + batchSize) { int32_t iStream = (iSlice / batchSize) % mRec->NStreams(); runKernel({GetGridAuto(iStream), krnlRunRangeNone, {nullptr, &mEvents->single}}, iSlice, batchSize); uint32_t copySize = std::accumulate(mClusterNativeAccess->nClustersSector + iSlice, mClusterNativeAccess->nClustersSector + iSlice + batchSize, 0u); - GPUMemCpy(RecoStep::TPCDecompression, mInputsHost->mPclusterNativeOutput + mClusterNativeAccess->clusterOffset[iSlice][0], DecompressorShadow.mNativeClustersBuffer + mClusterNativeAccess->clusterOffset[iSlice][0], sizeof(Decompressor.mNativeClustersBuffer[0]) * copySize, iStream, false); + if (!runFiltering) { + GPUMemCpy(RecoStep::TPCDecompression, mInputsHost->mPclusterNativeOutput + mClusterNativeAccess->clusterOffset[iSlice][0], DecompressorShadow.mNativeClustersBuffer + mClusterNativeAccess->clusterOffset[iSlice][0], sizeof(Decompressor.mNativeClustersBuffer[0]) * copySize, iStream, false); + } } SynchronizeGPU(); + if (runFiltering) { // If filtering is applied, count how many clusters will remain after filtering and allocate final buffers accordingly + AllocateRegisteredMemory(Decompressor.mResourceNClusterPerSectorRow); + WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), unattachedStream); + runKernel({GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression), krnlRunRangeNone}, DecompressorShadow.mNClusterPerSectorRow, NSLICES * GPUCA_ROW_COUNT * sizeof(DecompressorShadow.mNClusterPerSectorRow[0])); + runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); + TransferMemoryResourceLinkToHost(RecoStep::TPCDecompression, Decompressor.mResourceNClusterPerSectorRow, unattachedStream); + SynchronizeStream(unattachedStream); + uint32_t nClustersFinal = std::accumulate(Decompressor.mNClusterPerSectorRow, Decompressor.mNClusterPerSectorRow + inputGPU.nSliceRows, 0u); + mInputsHost->mNClusterNative = mInputsShadow->mNClusterNative = nClustersFinal; + AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeOutput, mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::clustersNative)]); + AllocateRegisteredMemory(mInputsHost->mResourceClusterNativeBuffer); + DecompressorShadow.mNativeClustersBuffer = mInputsShadow->mPclusterNativeBuffer; + Decompressor.mNativeClustersBuffer = mInputsHost->mPclusterNativeOutput; + WriteToConstantMemory(myStep, (char*)&processors()->tpcDecompressor - (char*)processors(), &DecompressorShadow, sizeof(DecompressorShadow), unattachedStream); + for (uint32_t i = 0; i < NSLICES; i++) { + for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) { + mClusterNativeAccess->nClusters[i][j] = Decompressor.mNClusterPerSectorRow[i * GPUCA_ROW_COUNT + j]; + } + } + if (doGPU) { + mClusterNativeAccess->clustersLinear = mInputsShadow->mPclusterNativeBuffer; + mClusterNativeAccess->setOffsetPtrs(); + *mInputsHost->mPclusterNativeAccess = *mClusterNativeAccess; + processorsShadow()->ioPtrs.clustersNative = mInputsShadow->mPclusterNativeAccess; + WriteToConstantMemory(RecoStep::TPCDecompression, (char*)&processors()->ioPtrs - (char*)processors(), &processorsShadow()->ioPtrs, sizeof(processorsShadow()->ioPtrs), unattachedStream); + TransferMemoryResourceLinkToGPU(RecoStep::TPCDecompression, mInputsHost->mResourceClusterNativeAccess, unattachedStream); + } + mIOPtrs.clustersNative = mClusterNativeAccess.get(); + mClusterNativeAccess->clustersLinear = mInputsHost->mPclusterNativeOutput; + mClusterNativeAccess->setOffsetPtrs(); + runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); + GPUMemCpy(RecoStep::TPCDecompression, mInputsHost->mPclusterNativeOutput, DecompressorShadow.mNativeClustersBuffer, sizeof(Decompressor.mNativeClustersBuffer[0]) * nClustersFinal, unattachedStream, false); + SynchronizeStream(unattachedStream); + } if (GetProcessingSettings().deterministicGPUReconstruction || GetProcessingSettings().debugLevel >= 4) { runKernel(GetGridAutoStep(unattachedStream, RecoStep::TPCDecompression)); const ClusterNativeAccess* decoded = mIOPtrs.clustersNative; @@ -357,6 +415,7 @@ int32_t GPUChainTracking::RunTPCDecompression() } } } + SynchronizeStream(unattachedStream); } mRec->PopNonPersistentMemory(RecoStep::TPCDecompression, qStr2Tag("TPCDCMPR")); } diff --git a/GPU/GPUTracking/kernels.cmake b/GPU/GPUTracking/kernels.cmake index b0aed5aba1166..f028c6990f267 100644 --- a/GPU/GPUTracking/kernels.cmake +++ b/GPU/GPUTracking/kernels.cmake @@ -108,6 +108,8 @@ o2_gpu_add_kernel("GPUTPCCompressionGatherKernels, multiBlock" "GPUTPCCom o2_gpu_add_kernel("GPUTPCDecompressionKernels, step0attached" "= TPCDECOMPRESSION" LB simple int32_t trackStart int32_t trackEnd) o2_gpu_add_kernel("GPUTPCDecompressionKernels, step1unattached" "= TPCDECOMPRESSION" LB simple int32_t sliceStart int32_t nSlices) o2_gpu_add_kernel("GPUTPCDecompressionUtilKernels, sortPerSectorRow" "GPUTPCDecompressionKernels" LB simple) +o2_gpu_add_kernel("GPUTPCDecompressionUtilKernels, countFilteredClusters" "GPUTPCDecompressionKernels" LB simple) +o2_gpu_add_kernel("GPUTPCDecompressionUtilKernels, storeFilteredClusters" "GPUTPCDecompressionKernels" LB simple) o2_gpu_add_kernel("GPUTPCCFCheckPadBaseline" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, fillIndexMap" "= TPCCLUSTERFINDER" LB single) o2_gpu_add_kernel("GPUTPCCFChargeMapFiller, fillFromDigits" "= TPCCLUSTERFINDER" LB single) From 73a96c308c3feac2884787b671d4b6f1421bf32b Mon Sep 17 00:00:00 2001 From: shahoian Date: Sun, 1 Dec 2024 15:14:35 +0100 Subject: [PATCH 0540/2205] Fixes to propagate updates of GPU params (D.Rohr) --- GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx | 5 ++++- GPU/GPUTracking/Global/GPUChainTracking.cxx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx index e86955d6da500..f4061fa12873c 100644 --- a/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx +++ b/GPU/GPUTracking/DataTypes/GPUNewCalibValues.cxx @@ -19,12 +19,15 @@ using namespace GPUCA_NAMESPACE::gpu; void GPUNewCalibValues::updateFrom(const GPUNewCalibValues* from) { if (from->newSolenoidField) { - solenoidField = from->newSolenoidField; + newSolenoidField = true; + solenoidField = from->solenoidField; } if (from->newContinuousMaxTimeBin) { + newContinuousMaxTimeBin = true; continuousMaxTimeBin = from->continuousMaxTimeBin; } if (from->newTPCTimeBinCut) { + newTPCTimeBinCut = true; tpcTimeBinCut = from->tpcTimeBinCut; } } diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 7b8e590242fae..ff476716febe8 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -633,7 +633,7 @@ int32_t GPUChainTracking::DoQueuedUpdates(int32_t stream, bool updateSlave) const GPUSettingsProcessing* p = nullptr; std::lock_guard lk(mMutexUpdateCalib); if (mUpdateNewCalibObjects) { - if (mNewCalibValues->newSolenoidField || mNewCalibValues->newContinuousMaxTimeBin) { + if (mNewCalibValues->newSolenoidField || mNewCalibValues->newContinuousMaxTimeBin || mNewCalibValues->newTPCTimeBinCut) { grp = std::make_unique(mRec->GetGRPSettings()); if (mNewCalibValues->newSolenoidField) { grp->solenoidBzNominalGPU = mNewCalibValues->solenoidField; From feea3ade7df2a217615e356e74906569eac9a24c Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Mon, 2 Dec 2024 10:40:48 +0100 Subject: [PATCH 0541/2205] Qatable (#13633) * TreeStream: Allow also for int8_t to be dumped as signed char Signed-off-by: Felix Schlepper * AOD: Extend TrackQA table * AOD: TrackQA leave _000 as default * COMMON: Add helper macros for bitwise enum struct * AOD: Add optional streamer to producer --------- Signed-off-by: Felix Schlepper --- .../include/CommonUtils/EnumBitOperators.h | 66 ++++++ Common/Utils/include/CommonUtils/TreeStream.h | 7 + .../AODProducerWorkflowSpec.h | 52 +++-- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 188 +++++++++++++++--- .../include/Framework/AnalysisDataModel.h | 57 ++++-- Framework/Core/include/Framework/DataTypes.h | 10 + 6 files changed, 324 insertions(+), 56 deletions(-) create mode 100644 Common/Utils/include/CommonUtils/EnumBitOperators.h diff --git a/Common/Utils/include/CommonUtils/EnumBitOperators.h b/Common/Utils/include/CommonUtils/EnumBitOperators.h new file mode 100644 index 0000000000000..3369a8eacf615 --- /dev/null +++ b/Common/Utils/include/CommonUtils/EnumBitOperators.h @@ -0,0 +1,66 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef O2_FRAMEWORK_ENUM_BIT_OPERATORS_H_ +#define O2_FRAMEWORK_ENUM_BIT_OPERATORS_H_ + +#include + +#define O2_DEFINE_ENUM_BIT_OPERATORS(enum_t) \ + constexpr auto operator|(enum_t lhs, enum_t rhs) \ + { \ + return static_cast( \ + static_cast>(lhs) | \ + static_cast>(rhs)); \ + } \ + \ + constexpr auto operator&(enum_t lhs, enum_t rhs) \ + { \ + return static_cast( \ + static_cast>(lhs) & \ + static_cast>(rhs)); \ + } \ + \ + constexpr auto operator^(enum_t lhs, enum_t rhs) \ + { \ + return static_cast( \ + static_cast>(lhs) ^ \ + static_cast>(rhs)); \ + } \ + \ + constexpr auto operator~(enum_t op) \ + { \ + return static_cast( \ + ~static_cast>(op)); \ + } \ + \ + constexpr auto& operator|=(enum_t& lhs, enum_t rhs) \ + { \ + lhs = lhs | rhs; \ + return lhs; \ + } \ + \ + constexpr auto& operator&=(enum_t& lhs, enum_t rhs) \ + { \ + lhs = lhs & rhs; \ + return lhs; \ + } \ + \ + constexpr enum_t& operator^=(enum_t& lhs, enum_t rhs) \ + { \ + lhs = lhs ^ rhs; \ + return lhs; \ + } + +#define O2_ENUM_TEST_BIT(mask, value) ((mask & value) == value) +#define O2_ENUM_SET_BIT(bit) ((1 << bit)) +#define O2_ENUM_ANY_BIT(enum) ((static_cast>(enum) != 0)) + +#endif diff --git a/Common/Utils/include/CommonUtils/TreeStream.h b/Common/Utils/include/CommonUtils/TreeStream.h index 2c55f48c98d3a..2aa02f6509d2c 100644 --- a/Common/Utils/include/CommonUtils/TreeStream.h +++ b/Common/Utils/include/CommonUtils/TreeStream.h @@ -63,6 +63,7 @@ class TreeStream const char* getName() const { return mTree.GetName(); } void setID(int id) { mID = id; } int getID() const { return mID; } + TreeStream& operator<<(const Bool_t& b) { CheckIn('B', &b); @@ -75,6 +76,12 @@ class TreeStream return *this; } + TreeStream& operator<<(const int8_t& i) + { + CheckIn('B', &i); + return *this; + } + TreeStream& operator<<(const UChar_t& c) { CheckIn('b', &c); diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 94f4526fe30a1..d9481917f9a05 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -30,7 +30,11 @@ #include "TStopwatch.h" #include "ZDCBase/Constants.h" #include "GlobalTracking/MatchGlobalFwd.h" +#include "CommonUtils/TreeStreamRedirector.h" +#include "CommonUtils/EnumBitOperators.h" +#include +#include #include #include #include @@ -203,7 +207,15 @@ class BunchCrossings std::vector mTimeWindows; // the time window structure covering the complete duration of mBCTimeVector double mWindowSize; // the size of a single time window -}; // end internal class +}; // end internal class + +// Steering bits for additional output during AOD production +enum struct AODProducerStreamerMask : uint8_t { + None = 0, + TrackQA = O2_ENUM_SET_BIT(0), + All = std::numeric_limits>::max(), +}; +O2_DEFINE_ENUM_BIT_OPERATORS(AODProducerStreamerMask) class AODProducerWorkflowDPL : public Task { @@ -241,6 +253,9 @@ class AODProducerWorkflowDPL : public Task std::unordered_set mGIDUsedBySVtx; std::unordered_set mGIDUsedByStr; + AODProducerStreamerMask mStreamerMask; + std::shared_ptr mStreamer; + int mNThreads = 1; bool mUseMC = true; bool mEnableSV = true; // enable secondary vertices @@ -339,6 +354,7 @@ class AODProducerWorkflowDPL : public Task uint32_t mTrackCovOffDiag = 0xFFFF0000; // 7 bits uint32_t mTrackSignal = 0xFFFFFF00; // 15 bits uint32_t mTrackTime = 0xFFFFFFFF; // use full float precision for time + uint32_t mTPCTime0 = 0xFFFFFFE0; // 18 bits, providing 14256./(1<<19) = 0.027 TB precision e.g., ~0.13 mm in z uint32_t mTrackTimeError = 0xFFFFFF00; // 15 bits uint32_t mTrackPosEMCAL = 0xFFFFFF00; // 15 bits uint32_t mTracklets = 0xFFFFFF00; // 15 bits @@ -397,18 +413,28 @@ class AODProducerWorkflowDPL : public Task struct TrackQA { GID trackID; - float tpcTime0; - int16_t tpcdcaR; - int16_t tpcdcaZ; - uint8_t tpcClusterByteMask; - uint8_t tpcdEdxMax0R; - uint8_t tpcdEdxMax1R; - uint8_t tpcdEdxMax2R; - uint8_t tpcdEdxMax3R; - uint8_t tpcdEdxTot0R; - uint8_t tpcdEdxTot1R; - uint8_t tpcdEdxTot2R; - uint8_t tpcdEdxTot3R; + float tpcTime0{}; + int16_t tpcdcaR{}; + int16_t tpcdcaZ{}; + uint8_t tpcClusterByteMask{}; + uint8_t tpcdEdxMax0R{}; + uint8_t tpcdEdxMax1R{}; + uint8_t tpcdEdxMax2R{}; + uint8_t tpcdEdxMax3R{}; + uint8_t tpcdEdxTot0R{}; + uint8_t tpcdEdxTot1R{}; + uint8_t tpcdEdxTot2R{}; + uint8_t tpcdEdxTot3R{}; + int8_t dRefContY{std::numeric_limits::min()}; + int8_t dRefContZ{std::numeric_limits::min()}; + int8_t dRefContSnp{std::numeric_limits::min()}; + int8_t dRefContTgl{std::numeric_limits::min()}; + int8_t dRefContQ2Pt{std::numeric_limits::min()}; + int8_t dRefGloY{std::numeric_limits::min()}; + int8_t dRefGloZ{std::numeric_limits::min()}; + int8_t dRefGloSnp{std::numeric_limits::min()}; + int8_t dRefGloTgl{std::numeric_limits::min()}; + int8_t dRefGloQ2Pt{std::numeric_limits::min()}; }; // helper struct for addToFwdTracksTable() diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 6c3a418612478..8a2443b57c7ff 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -51,6 +51,7 @@ #include "Framework/DataTypes.h" #include "Framework/TableBuilder.h" #include "Framework/CCDBParamSpec.h" +#include "CommonUtils/TreeStreamRedirector.h" #include "FT0Base/Geometry.h" #include "GlobalTracking/MatchTOF.h" #include "ReconstructionDataFormats/Cascade.h" @@ -85,8 +86,10 @@ #include "MathUtils/Utils.h" #include "Math/SMatrix.h" #include "TString.h" +#include #include #include +#include #include #include #include @@ -355,25 +358,47 @@ void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracks template void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder) { - - // trackQA - tracksQACursor( - - // truncateFloatFraction(trackQAInfoHolder.tpcdcaR, mTrackChi2), - // truncateFloatFraction(trackQAInfoHolder.tpcdcaZ, mTrackChi2), - trackQAInfoHolder.trackID, - trackQAInfoHolder.tpcTime0, - trackQAInfoHolder.tpcdcaR, - trackQAInfoHolder.tpcdcaZ, - trackQAInfoHolder.tpcClusterByteMask, - trackQAInfoHolder.tpcdEdxMax0R, - trackQAInfoHolder.tpcdEdxMax1R, - trackQAInfoHolder.tpcdEdxMax2R, - trackQAInfoHolder.tpcdEdxMax3R, - trackQAInfoHolder.tpcdEdxTot0R, - trackQAInfoHolder.tpcdEdxTot1R, - trackQAInfoHolder.tpcdEdxTot2R, - trackQAInfoHolder.tpcdEdxTot3R); + if constexpr (std::is_same_v) { // TODO remove remove once version changes + tracksQACursor( + trackQAInfoHolder.trackID, + truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0), + trackQAInfoHolder.tpcdcaR, + trackQAInfoHolder.tpcdcaZ, + trackQAInfoHolder.tpcClusterByteMask, + trackQAInfoHolder.tpcdEdxMax0R, + trackQAInfoHolder.tpcdEdxMax1R, + trackQAInfoHolder.tpcdEdxMax2R, + trackQAInfoHolder.tpcdEdxMax3R, + trackQAInfoHolder.tpcdEdxTot0R, + trackQAInfoHolder.tpcdEdxTot1R, + trackQAInfoHolder.tpcdEdxTot2R, + trackQAInfoHolder.tpcdEdxTot3R, + trackQAInfoHolder.dRefContY, + trackQAInfoHolder.dRefContZ, + trackQAInfoHolder.dRefContSnp, + trackQAInfoHolder.dRefContTgl, + trackQAInfoHolder.dRefContQ2Pt, + trackQAInfoHolder.dRefGloY, + trackQAInfoHolder.dRefGloZ, + trackQAInfoHolder.dRefGloSnp, + trackQAInfoHolder.dRefGloTgl, + trackQAInfoHolder.dRefGloQ2Pt); + } else { + tracksQACursor( + trackQAInfoHolder.trackID, + trackQAInfoHolder.tpcTime0, + trackQAInfoHolder.tpcdcaR, + trackQAInfoHolder.tpcdcaZ, + trackQAInfoHolder.tpcClusterByteMask, + trackQAInfoHolder.tpcdEdxMax0R, + trackQAInfoHolder.tpcdEdxMax1R, + trackQAInfoHolder.tpcdEdxMax2R, + trackQAInfoHolder.tpcdEdxMax3R, + trackQAInfoHolder.tpcdEdxTot0R, + trackQAInfoHolder.tpcdEdxTot1R, + trackQAInfoHolder.tpcdEdxTot2R, + trackQAInfoHolder.tpcdEdxTot3R); + } } template @@ -1664,6 +1689,14 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mThinTracks = ic.options().get("thin-tracks"); mPropTracks = ic.options().get("propagate-tracks"); mPropMuons = ic.options().get("propagate-muons"); + if (auto s = ic.options().get("with-streamers"); !s.empty()) { + mStreamerMask = static_cast(std::stoul(s, nullptr, 2)); + if (O2_ENUM_ANY_BIT(mStreamerMask)) { + LOGP(info, "Writing streamer data with mask {:0{}b}", static_cast>(mStreamerMask), std::numeric_limits>::digits); + } else { + LOGP(warn, "Specified non-default empty streamer mask!"); + } + } mTrackQCFraction = ic.options().get("trackqc-fraction"); mTrackQCNTrCut = ic.options().get("trackqc-NTrCut"); if (auto seed = ic.options().get("seed"); seed == 0) { @@ -1705,6 +1738,7 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mTrackCovOffDiag = 0xFFFFFFFF; mTrackSignal = 0xFFFFFFFF; mTrackTime = 0xFFFFFFFF; + mTPCTime0 = 0xFFFFFFFF; mTrackTimeError = 0xFFFFFFFF; mTrackPosEMCAL = 0xFFFFFFFF; mTracklets = 0xFFFFFFFF; @@ -1748,6 +1782,10 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mHeavyIonUpdate = when; mTimer.Reset(); + + if (O2_ENUM_ANY_BIT(mStreamerMask)) { + mStreamer = std::make_unique("AO2DStreamer.root", "RECREATE"); + } } void AODProducerWorkflowDPL::run(ProcessingContext& pc) @@ -1816,7 +1854,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto tracksCursor = createTableCursor(pc); auto tracksCovCursor = createTableCursor(pc); auto tracksExtraCursor = createTableCursor(pc); - auto tracksQACursor = createTableCursor(pc); + auto tracksQACursor = createTableCursor(pc); auto ambigTracksCursor = createTableCursor(pc); auto ambigMFTTracksCursor = createTableCursor(pc); auto ambigFwdTracksCursor = createTableCursor(pc); @@ -2534,16 +2572,15 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int TrackQA trackQAHolder; auto contributorsGID = data.getTPCContributorGID(trackIndex); const auto& trackPar = data.getTrackParam(trackIndex); - // auto src = trackIndex.getSource(); if (contributorsGID.isIndexSet()) { + auto prop = o2::base::Propagator::Instance(); const auto& tpcOrig = data.getTPCTrack(contributorsGID); /// getDCA - should be done with the copy of TPC only track - // LOGP(info, "GloIdx: {} TPCIdx: {}, NTPCTracks: {}", trackIndex.asString(), contributorsGID.asString(), data.getTPCTracks().size()); - o2::track::TrackParametrization tpcTMP = tpcOrig; /// get backup of the track - o2::base::Propagator::MatCorrType mMatType = o2::base::Propagator::MatCorrType::USEMatCorrLUT; /// should be parameterized - o2::dataformats::VertexBase v = mVtx.getMeanVertex(collisionID < 0 ? 0.f : data.getPrimaryVertex(collisionID).getZ()); + o2::track::TrackParametrization tpcTMP = tpcOrig; /// get backup of the track + const o2::base::Propagator::MatCorrType mMatType = o2::base::Propagator::MatCorrType::USEMatCorrLUT; /// should be parameterized + const o2::dataformats::VertexBase v = mVtx.getMeanVertex(collisionID < 0 ? 0.f : data.getPrimaryVertex(collisionID).getZ()); o2::gpu::gpustd::array dcaInfo{-999., -999.}; - if (o2::base::Propagator::Instance()->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) { + if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) { trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt()); trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt()); } @@ -2567,7 +2604,7 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int } trackQAHolder.tpcTime0 = tpcOrig.getTime0(); trackQAHolder.tpcClusterByteMask = byteMask; - float dEdxNorm = (tpcOrig.getdEdx().dEdxTotTPC > 0) ? 100. / tpcOrig.getdEdx().dEdxTotTPC : 0; + const float dEdxNorm = (tpcOrig.getdEdx().dEdxTotTPC > 0) ? 100. / tpcOrig.getdEdx().dEdxTotTPC : 0; trackQAHolder.tpcdEdxMax0R = uint8_t(tpcOrig.getdEdx().dEdxMaxIROC * dEdxNorm); trackQAHolder.tpcdEdxMax1R = uint8_t(tpcOrig.getdEdx().dEdxMaxOROC1 * dEdxNorm); trackQAHolder.tpcdEdxMax2R = uint8_t(tpcOrig.getdEdx().dEdxMaxOROC2 * dEdxNorm); @@ -2577,7 +2614,99 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int trackQAHolder.tpcdEdxTot1R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC1 * dEdxNorm); trackQAHolder.tpcdEdxTot2R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC2 * dEdxNorm); trackQAHolder.tpcdEdxTot3R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC3 * dEdxNorm); - /// + + if constexpr (std::is_same_v) { // TODO remove remove once version changes + // Add matching information at a reference point (defined by + // o2::aod::track::trackQARefRadius) in the same frame as the global track + // without material corrections and error propagation + if (auto itsContGID = data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() != GIndex::ITSAB) { + const auto& itsOrig = data.getITSTrack(itsContGID); + o2::track::TrackPar gloCopy = trackPar; + o2::track::TrackPar itsCopy = itsOrig; + o2::track::TrackPar tpcCopy = tpcOrig; + if (prop->propagateToX(gloCopy, o2::aod::track::trackQARefRadius, prop->getNominalBz(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr) && + prop->propagateToAlphaX(tpcCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr) && + prop->propagateToAlphaX(itsCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr)) { + // All tracks are now at the same radius and in the same frame and we can calculate the deltas wrt. to the global track + // The scale is defined by the global track scaling depending on beta0 + const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f)); + const float qpt = gloCopy.getQ2Pt(); + const float x = qpt / beta0; + // scaling is defined as sigmaBins/sqrt(p0^2 + (p1 * q/pt / beta)^2) + auto scaleCont = [&x](int i) -> float { + return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleContP0[i] * o2::aod::track::trackQAScaleContP0[i] + (o2::aod::track::trackQAScaleContP1[i] * x) * (o2::aod::track::trackQAScaleContP1[i] * x)); + }; + auto scaleGlo = [&x](int i) -> float { + return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleGloP0[i] * o2::aod::track::trackQAScaleGloP0[i] + (o2::aod::track::trackQAScaleGloP1[i] * x) * (o2::aod::track::trackQAScaleGloP1[i] * x)); + }; + + // This allows to safely clamp any float to one byte, using the + // minmal/maximum values as under-/overflow borders and rounding to the nearest integer + auto safeInt8Clamp = [](auto value) -> int8_t { + using ValType = decltype(value); + return static_cast(TMath::Nint(std::clamp(value, static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max())))); + }; + + // Calculate deltas for contributors + trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0)); + trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1)); + trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2)); + trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3)); + trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4)); + // Calculate deltas for global track against averaged contributors + trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0)); + trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1)); + trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2)); + trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3)); + trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4)); + + if (O2_ENUM_TEST_BIT(mStreamerMask, AODProducerStreamerMask::TrackQA)) { + (*mStreamer) << "trackQA" + << "trackITSOrig=" << itsOrig + << "trackTPCOrig=" << tpcOrig + << "trackITSTPCOrig=" << trackPar + << "trackITSProp=" << itsCopy + << "trackTPCProp=" << tpcCopy + << "trackITSTPCProp=" << gloCopy + << "refRadius=" << o2::aod::track::trackQARefRadius + << "scaleBins=" << o2::aod::track::trackQAScaleBins + << "scaleCont0=" << scaleCont(0) + << "scaleCont1=" << scaleCont(1) + << "scaleCont2=" << scaleCont(2) + << "scaleCont3=" << scaleCont(3) + << "scaleCont4=" << scaleCont(4) + << "scaleGlo0=" << scaleGlo(0) + << "scaleGlo1=" << scaleGlo(1) + << "scaleGlo2=" << scaleGlo(2) + << "scaleGlo3=" << scaleGlo(3) + << "scaleGlo4=" << scaleGlo(4) + << "trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0 + << "trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR + << "trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ + << "trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask + << "trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R + << "trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R + << "trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R + << "trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R + << "trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R + << "trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R + << "trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R + << "trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R + << "trackQAHolder.dRefContY=" << trackQAHolder.dRefContY + << "trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ + << "trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp + << "trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl + << "trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt + << "trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY + << "trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ + << "trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp + << "trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl + << "trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt + << "\n"; + } + } + } + } } return trackQAHolder; @@ -2944,6 +3073,8 @@ void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& /*ec*/) { LOGF(info, "aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); + + mStreamer.reset(); } DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun) @@ -3076,6 +3207,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo ConfigParamSpec{"thin-tracks", VariantType::Bool, false, {"Produce thinned track tables"}}, ConfigParamSpec{"trackqc-fraction", VariantType::Float, float(0.1), {"Fraction of tracks to QC"}}, ConfigParamSpec{"trackqc-NTrCut", VariantType::Int64, 4L, {"Minimal length of the track - in amount of tracklets"}}, + ConfigParamSpec{"with-streamers", VariantType::String, "", {"Bit-mask to steer writing of intermediate streamer files"}}, ConfigParamSpec{"seed", VariantType::Int, 0, {"Set seed for random generator used for sampling (0 (default) means using a random_device)"}}, }}; } diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index c90e46bf6da06..e277925ed5603 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -15,6 +15,7 @@ #include #include +#include #include #include // std::move @@ -667,28 +668,54 @@ using FullTrack = FullTracks::iterator; namespace trackqa { // TRACKQA TABLE COLUMNS -DECLARE_SOA_INDEX_COLUMN(Track, track); //! track to which this QA information belongs -DECLARE_SOA_COLUMN(TPCTime0, tpcTime0, float); //! tpc only time0 (mTime0 in TPC track) -DECLARE_SOA_COLUMN(TPCDCAR, tpcdcaR, int16_t); //! tpc only DCAr -DECLARE_SOA_COLUMN(TPCDCAZ, tpcdcaZ, int16_t); //! tpc only DCAz -DECLARE_SOA_COLUMN(TPCClusterByteMask, tpcClusterByteMask, uint8_t); //! tracklet bitmask - track defining 8 tracklets (152=8*19 rows) bit set if nCluster>thr (default 5) -DECLARE_SOA_COLUMN(TPCdEdxMax0R, tpcdEdxMax0R, uint8_t); //! TPC dEdxQMax -ROC0/dEdx -DECLARE_SOA_COLUMN(TPCdEdxMax1R, tpcdEdxMax1R, uint8_t); //! TPC dEdxQMax -ROC1/dEdx -DECLARE_SOA_COLUMN(TPCdEdxMax2R, tpcdEdxMax2R, uint8_t); //! TPC dEdxQMax -ROC2/dEdx -DECLARE_SOA_COLUMN(TPCdEdxMax3R, tpcdEdxMax3R, uint8_t); //! TPC dEdxQMax -ROC3/dEdx -DECLARE_SOA_COLUMN(TPCdEdxTot0R, tpcdEdxTot0R, uint8_t); //! TPC dEdxQtot -ROC0/dEdx -DECLARE_SOA_COLUMN(TPCdEdxTot1R, tpcdEdxTot1R, uint8_t); //! TPC dEdxQtot -ROC1/dEdx -DECLARE_SOA_COLUMN(TPCdEdxTot2R, tpcdEdxTot2R, uint8_t); //! TPC dEdxQtot -ROC2/dEdx -DECLARE_SOA_COLUMN(TPCdEdxTot3R, tpcdEdxTot3R, uint8_t); //! TPC dEdxQtot -ROC3/dEdx +DECLARE_SOA_INDEX_COLUMN(Track, track); //! track to which this QA information belongs +DECLARE_SOA_COLUMN(TPCTime0, tpcTime0, float); //! tpc only time0 (mTime0 in TPC track) +DECLARE_SOA_COLUMN(TPCDCAR, tpcdcaR, int16_t); //! tpc only DCAr +DECLARE_SOA_COLUMN(TPCDCAZ, tpcdcaZ, int16_t); //! tpc only DCAz +DECLARE_SOA_COLUMN(TPCClusterByteMask, tpcClusterByteMask, uint8_t); //! tracklet bitmask - track defining 8 tracklets (152=8*19 rows) bit set if nCluster>thr (default 5) +DECLARE_SOA_COLUMN(TPCdEdxMax0R, tpcdEdxMax0R, uint8_t); //! TPC dEdxQMax -ROC0/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax1R, tpcdEdxMax1R, uint8_t); //! TPC dEdxQMax -ROC1/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax2R, tpcdEdxMax2R, uint8_t); //! TPC dEdxQMax -ROC2/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax3R, tpcdEdxMax3R, uint8_t); //! TPC dEdxQMax -ROC3/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot0R, tpcdEdxTot0R, uint8_t); //! TPC dEdxQtot -ROC0/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot1R, tpcdEdxTot1R, uint8_t); //! TPC dEdxQtot -ROC1/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot2R, tpcdEdxTot2R, uint8_t); //! TPC dEdxQtot -ROC2/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot3R, tpcdEdxTot3R, uint8_t); //! TPC dEdxQtot -ROC3/dEdx +DECLARE_SOA_COLUMN(DeltaRefContParamY, deltaRefContParamY, int8_t); //! Normalized delta of contributor tracks at reference point in the same frame Y +DECLARE_SOA_COLUMN(DeltaRefContParamZ, deltaRefITSParamZ, int8_t); //! Normalized delta of contributor tracks at reference point in the same frame Z +DECLARE_SOA_COLUMN(DeltaRefContParamSnp, deltaRefContParamSnp, int8_t); //! Normalized delta of contributor tracks at reference point in the same frame Snp +DECLARE_SOA_COLUMN(DeltaRefContParamTgl, deltaRefContParamTgl, int8_t); //! Normalized delta of contributor tracks at reference point in the same frame Tgl +DECLARE_SOA_COLUMN(DeltaRefContParamQ2Pt, deltaRefContParamQ2Pt, int8_t); //! Normalized delta of contributor tracks at reference point in the same frame Q2Pt +DECLARE_SOA_COLUMN(DeltaRefGloParamY, deltaRefGloParamY, int8_t); //! Normalized delta of global track to average contributors matched tracks at reference point in the same frame Y +DECLARE_SOA_COLUMN(DeltaRefGloParamZ, deltaRefGloParamZ, int8_t); //! Normalized delta of global track to average contributors matched tracks at reference point in the same frame Z +DECLARE_SOA_COLUMN(DeltaRefGloParamSnp, deltaRefGloParamSnp, int8_t); //! Normalized delta of global track to average contributors matched tracks at reference point in the same frame Snp +DECLARE_SOA_COLUMN(DeltaRefGloParamTgl, deltaRefGloParamTgl, int8_t); //! Normalized delta of global track to average contributors matched tracks at reference point in the same frame Tgl +DECLARE_SOA_COLUMN(DeltaRefGloParamQ2Pt, deltaRefGloParamQ2Pt, int8_t); //! Normalized delta of global track to average contributors matched tracks at reference point in the same frame Q2Pt + +DECLARE_SOA_DYNAMIC_COLUMN(IsDummy, isDummy, //! indicates if the propagation of the contrib. tracks was successful and residuals are available + [](int8_t cY, int8_t cZ, int8_t cSnp, int8_t cTgl, int8_t cQ2Pt, int8_t gY, int8_t gZ, int8_t gSnp, int8_t gTgl, int8_t gQ2Pt) -> bool { + constexpr int8_t m = std::numeric_limits::min(); + return (cY == m && cZ == m && cSnp == m && cTgl == m && cQ2Pt == m && gY == m && gZ == m && gSnp == m && gTgl == m && gQ2Pt == m); + }); } // namespace trackqa -DECLARE_SOA_TABLE(TracksQA, "AOD", "TRACKQA", //! trackQA information - sampled QA information currently for the TPC +DECLARE_SOA_TABLE(TracksQA_000, "AOD", "TRACKQA", //! trackQA information - sampled QA information currently for the TPC - version 0 o2::soa::Index<>, trackqa::TrackId, trackqa::TPCTime0, trackqa::TPCDCAR, trackqa::TPCDCAZ, trackqa::TPCClusterByteMask, trackqa::TPCdEdxMax0R, trackqa::TPCdEdxMax1R, trackqa::TPCdEdxMax2R, trackqa::TPCdEdxMax3R, trackqa::TPCdEdxTot0R, trackqa::TPCdEdxTot1R, trackqa::TPCdEdxTot2R, trackqa::TPCdEdxTot3R); // o2::soa::Index<>, trackqa::TrackId, trackqa::TPCDCAR, trackqa::TPCDCAZ, trackqa::TPCClusterByteMask, -using TrackQA = TracksQA::iterator; +DECLARE_SOA_TABLE_VERSIONED(TracksQA_001, "AOD", "TRACKQA", 1, //! trackQA information - version 1 - including contributor residuals of matched tracks at reference radius + o2::soa::Index<>, trackqa::TrackId, trackqa::TPCTime0, trackqa::TPCDCAR, trackqa::TPCDCAZ, trackqa::TPCClusterByteMask, + trackqa::TPCdEdxMax0R, trackqa::TPCdEdxMax1R, trackqa::TPCdEdxMax2R, trackqa::TPCdEdxMax3R, + trackqa::TPCdEdxTot0R, trackqa::TPCdEdxTot1R, trackqa::TPCdEdxTot2R, trackqa::TPCdEdxTot3R, + trackqa::DeltaRefContParamY, trackqa::DeltaRefContParamZ, trackqa::DeltaRefContParamSnp, trackqa::DeltaRefContParamTgl, trackqa::DeltaRefContParamQ2Pt, + trackqa::DeltaRefGloParamY, trackqa::DeltaRefGloParamZ, trackqa::DeltaRefGloParamSnp, trackqa::DeltaRefGloParamTgl, trackqa::DeltaRefGloParamQ2Pt, + trackqa::IsDummy); + +using TracksQAVersion = TracksQA_000; +using TracksQA = TracksQAVersion::iterator; namespace fwdtrack { diff --git a/Framework/Core/include/Framework/DataTypes.h b/Framework/Core/include/Framework/DataTypes.h index 92af1f79e2314..9d829159718d8 100644 --- a/Framework/Core/include/Framework/DataTypes.h +++ b/Framework/Core/include/Framework/DataTypes.h @@ -15,6 +15,7 @@ #include #include +#include namespace o2::aod::bc { @@ -120,6 +121,15 @@ struct TPCTimeErrEncoding { } }; } // namespace extensions + +// Reference radius for extrapolated tracks +constexpr float trackQARefRadius{50.f}; +constexpr float trackQAScaleBins{5.f}; +// Fit parameters for scale dY, dZ, dSnp, dTgl, dQ2Pt +constexpr std::array trackQAScaleContP0{0.257192, 0.0775375, 0.00424283, 0.00107201, 0.0335447}; +constexpr std::array trackQAScaleContP1{0.189371, 0.409071, 0.00694444, 0.00720038, 0.0806902}; +constexpr std::array trackQAScaleGloP0{0.130985, 0.0775375, 0.00194703, 0.000405458, 0.0160007}; +constexpr std::array trackQAScaleGloP1{0.183731, 0.409071, 0.00621802, 0.00624881, 0.0418957}; } // namespace o2::aod::track namespace o2::aod::fwdtrack From 950b8b700fbd47743cd151895eaf7102e2b3dd67 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:45:43 +0100 Subject: [PATCH 0542/2205] DPL Analysis: improve arrow::Dataset support for TTree (#13759) --- Framework/Core/src/RootArrowFilesystem.cxx | 7 +- Framework/Core/test/test_Root2ArrowTable.cxx | 120 ++++++++----------- 2 files changed, 54 insertions(+), 73 deletions(-) diff --git a/Framework/Core/src/RootArrowFilesystem.cxx b/Framework/Core/src/RootArrowFilesystem.cxx index 7e331814272a6..5f2d21d942d37 100644 --- a/Framework/Core/src/RootArrowFilesystem.cxx +++ b/Framework/Core/src/RootArrowFilesystem.cxx @@ -13,6 +13,7 @@ #include "Framework/RuntimeError.h" #include "Framework/Signpost.h" #include +#include #include #include #include @@ -427,7 +428,7 @@ class TTreeFileWriter : public arrow::dataset::FileWriter O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s exists and uses %d bytes per entry.", branch->GetName(), valueSize); // This should probably lookup the - auto column = firstBatch->GetColumnByName(branch->GetName()); + auto column = firstBatch->GetColumnByName(schema_->field(i)->name()); auto list = std::static_pointer_cast(column); O2_SIGNPOST_EVENT_EMIT(root_arrow_fs, sid, "finaliseBasketSize", "Branch %s needed. Associated size branch %s and there are %lli entries of size %d in that list.", branch->GetName(), sizeBranch->GetName(), list->length(), valueSize); @@ -497,8 +498,8 @@ class TTreeFileWriter : public arrow::dataset::FileWriter } break; case arrow::Type::LIST: { valueTypes.push_back(field->type()->field(0)->type()); - listSizes.back() = 0; // VLA, we need to calculate it on the fly; std::string leafList = fmt::format("{}[{}_size]{}", field->name(), field->name(), rootSuffixFromArrow(valueTypes.back()->id())); + listSizes.back() = -1; // VLA, we need to calculate it on the fly; std::string sizeLeafList = field->name() + "_size/I"; sizesBranches.push_back(treeStream->CreateBranch((field->name() + "_size").c_str(), sizeLeafList.c_str())); branches.push_back(treeStream->CreateBranch(field->name().c_str(), leafList.c_str())); @@ -765,7 +766,7 @@ arrow::Result TTreeFileFormat::ScanBatchesAsync( typeSize = fixedSizeList->field(0)->type()->byte_width(); } else if (auto vlaListType = std::dynamic_pointer_cast(physicalField->type())) { listSize = -1; - typeSize = fixedSizeList->field(0)->type()->byte_width(); + typeSize = vlaListType->field(0)->type()->byte_width(); } if (listSize == -1) { mSizeBranch = branch->GetTree()->GetBranch((std::string{branch->GetName()} + "_size").c_str()); diff --git a/Framework/Core/test/test_Root2ArrowTable.cxx b/Framework/Core/test/test_Root2ArrowTable.cxx index a659d488ae24a..2b0ab9154250c 100644 --- a/Framework/Core/test/test_Root2ArrowTable.cxx +++ b/Framework/Core/test/test_Root2ArrowTable.cxx @@ -322,12 +322,26 @@ bool validateContents(std::shared_ptr batch) REQUIRE(bool_array->Value(1) == (i % 5 == 0)); } } + + { + auto list_array = std::static_pointer_cast(batch->GetColumnByName("vla")); + + REQUIRE(list_array->length() == 100); + for (int64_t i = 0; i < list_array->length(); i++) { + auto value_slice = list_array->value_slice(i); + REQUIRE(value_slice->length() == (i % 10)); + auto int_array = std::static_pointer_cast(value_slice); + for (size_t j = 0; j < value_slice->length(); j++) { + REQUIRE(int_array->Value(j) == j); + } + } + } return true; } bool validateSchema(std::shared_ptr schema) { - REQUIRE(schema->num_fields() == 9); + REQUIRE(schema->num_fields() == 10); REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); @@ -337,6 +351,7 @@ bool validateSchema(std::shared_ptr schema) REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); REQUIRE(schema->field(7)->type()->id() == arrow::boolean()->id()); REQUIRE(schema->field(8)->type()->id() == arrow::fixed_size_list(arrow::boolean(), 2)->id()); + REQUIRE(schema->field(9)->type()->id() == arrow::list(arrow::int32())->id()); return true; } @@ -390,6 +405,8 @@ TEST_CASE("RootTree2Dataset") Int_t ev; bool oneBool; bool manyBool[2]; + int vla[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + int vlaSize = 0; t->Branch("px", &px, "px/F"); t->Branch("py", &py, "py/F"); @@ -400,6 +417,8 @@ TEST_CASE("RootTree2Dataset") t->Branch("ij", ij, "ij[2]/I"); t->Branch("bools", &oneBool, "bools/O"); t->Branch("manyBools", &manyBool, "manyBools[2]/O"); + t->Branch("vla_size", &vlaSize, "vla_size/I"); + t->Branch("vla", vla, "vla[vla_size]/I"); // fill the tree for (Int_t i = 0; i < 100; i++) { xyz[0] = 1; @@ -415,9 +434,11 @@ TEST_CASE("RootTree2Dataset") oneBool = (i % 3 == 0); manyBool[0] = (i % 4 == 0); manyBool[1] = (i % 5 == 0); + vlaSize = i % 10; t->Fill(); } } + f->Write(); size_t totalSizeCompressed = 0; size_t totalSizeUncompressed = 0; @@ -428,16 +449,7 @@ TEST_CASE("RootTree2Dataset") auto schemaOpt = format->Inspect(source); REQUIRE(schemaOpt.ok()); auto schema = *schemaOpt; - REQUIRE(schema->num_fields() == 9); - REQUIRE(schema->field(0)->type()->id() == arrow::float32()->id()); - REQUIRE(schema->field(1)->type()->id() == arrow::float32()->id()); - REQUIRE(schema->field(2)->type()->id() == arrow::float32()->id()); - REQUIRE(schema->field(3)->type()->id() == arrow::float64()->id()); - REQUIRE(schema->field(4)->type()->id() == arrow::int32()->id()); - REQUIRE(schema->field(5)->type()->id() == arrow::fixed_size_list(arrow::float32(), 3)->id()); - REQUIRE(schema->field(6)->type()->id() == arrow::fixed_size_list(arrow::int32(), 2)->id()); - REQUIRE(schema->field(7)->type()->id() == arrow::boolean()->id()); - REQUIRE(schema->field(8)->type()->id() == arrow::fixed_size_list(arrow::boolean(), 2)->id()); + validateSchema(schema); auto fragment = format->MakeFragment(source, {}, schema); REQUIRE(fragment.ok()); @@ -448,41 +460,9 @@ TEST_CASE("RootTree2Dataset") auto batches = (*scanner)(); auto result = batches.result(); REQUIRE(result.ok()); - REQUIRE((*result)->columns().size() == 9); + REQUIRE((*result)->columns().size() == 10); REQUIRE((*result)->num_rows() == 100); - - { - auto int_array = std::static_pointer_cast((*result)->GetColumnByName("ev")); - for (int64_t j = 0; j < int_array->length(); j++) { - REQUIRE(int_array->Value(j) == j + 1); - } - } - - { - auto list_array = std::static_pointer_cast((*result)->GetColumnByName("xyz")); - - // Iterate over the FixedSizeListArray - for (int64_t i = 0; i < list_array->length(); i++) { - auto value_slice = list_array->value_slice(i); - auto float_array = std::static_pointer_cast(value_slice); - - REQUIRE(float_array->Value(0) == 1); - REQUIRE(float_array->Value(1) == 2); - REQUIRE(float_array->Value(2) == i + 1); - } - } - - { - auto list_array = std::static_pointer_cast((*result)->GetColumnByName("ij")); - - // Iterate over the FixedSizeListArray - for (int64_t i = 0; i < list_array->length(); i++) { - auto value_slice = list_array->value_slice(i); - auto int_array = std::static_pointer_cast(value_slice); - REQUIRE(int_array->Value(0) == i); - REQUIRE(int_array->Value(1) == i + 1); - } - } + validateContents(*result); auto* output = new TMemFile("foo", "RECREATE"); auto outFs = std::make_shared(output, 0); @@ -497,31 +477,31 @@ TEST_CASE("RootTree2Dataset") auto success = writer->get()->Write(*result); auto rootDestination = std::dynamic_pointer_cast(*destination); - REQUIRE(success.ok()); - // Let's read it back... - arrow::dataset::FileSource source2("/DF_3", outFs); - auto newTreeFS = outFs->GetSubFilesystem(source2); - - REQUIRE(format->IsSupported(source) == true); - - auto schemaOptWritten = format->Inspect(source); - REQUIRE(schemaOptWritten.ok()); - auto schemaWritten = *schemaOptWritten; - REQUIRE(validateSchema(schemaWritten)); - - auto fragmentWritten = format->MakeFragment(source, {}, schema); - REQUIRE(fragmentWritten.ok()); - auto optionsWritten = std::make_shared(); - options->dataset_schema = schemaWritten; - auto scannerWritten = format->ScanBatchesAsync(optionsWritten, *fragment); - REQUIRE(scannerWritten.ok()); - auto batchesWritten = (*scanner)(); - auto resultWritten = batches.result(); - REQUIRE(resultWritten.ok()); - REQUIRE((*resultWritten)->columns().size() == 9); - REQUIRE((*resultWritten)->num_rows() == 100); - validateContents(*resultWritten); - + SECTION("Read tree") { + REQUIRE(success.ok()); + // Let's read it back... + arrow::dataset::FileSource source2("/DF_3", outFs); + auto newTreeFS = outFs->GetSubFilesystem(source2); + + REQUIRE(format->IsSupported(source) == true); + + auto schemaOptWritten = format->Inspect(source); + REQUIRE(schemaOptWritten.ok()); + auto schemaWritten = *schemaOptWritten; + REQUIRE(validateSchema(schemaWritten)); + + auto fragmentWritten = format->MakeFragment(source, {}, schema); + REQUIRE(fragmentWritten.ok()); + auto optionsWritten = std::make_shared(); + options->dataset_schema = schemaWritten; + auto scannerWritten = format->ScanBatchesAsync(optionsWritten, *fragment); + REQUIRE(scannerWritten.ok()); + auto batchesWritten = (*scanner)(); + auto resultWritten = batches.result(); + REQUIRE(resultWritten.ok()); + REQUIRE((*resultWritten)->columns().size() == 10); + REQUIRE((*resultWritten)->num_rows() == 100); + validateContents(*resultWritten); } } From 4bffbfaa980608a077c39528c079c6c2635ad425 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 2 Dec 2024 18:15:20 +0100 Subject: [PATCH 0543/2205] Optionally select CTFs in timestamps or orbits range New option --run-time-span-file allows to push to DPL only those TFs which overlap with the (separators can be any whitespace, comma or semicolon) records provided via text file (assuming that there are some entries for a given run, otherwise the option is ignored). Multiple ranges per run and multiple runs can be mentioned in a single input file. The range limits can be indicated either as a UNIX timestamp in ms or as an orbit number (in the fill the run belongs to). In case an option --invert-irframe-selection is provided, the selections above are inverted: TFs matching some of the provided ranges will be discarded, while the rest will be pushed to the DPL At the end of the processing the ctf-writer will create a local file ctf_read_ntf.txt containing only the number of TFs pushed to the DPL. In case no TF passed the selections above, this file will contain 0. --- .../include/CommonUtils/IRFrameSelector.h | 2 + Common/Utils/src/IRFrameSelector.cxx | 12 ++ Detectors/CTF/README.md | 48 ++++-- .../include/CTFWorkflow/CTFReaderSpec.h | 2 + Detectors/CTF/workflow/src/CTFReaderSpec.cxx | 157 ++++++++++++++++-- .../CTF/workflow/src/ctf-reader-workflow.cxx | 10 ++ 6 files changed, 208 insertions(+), 23 deletions(-) diff --git a/Common/Utils/include/CommonUtils/IRFrameSelector.h b/Common/Utils/include/CommonUtils/IRFrameSelector.h index 6312ae8314c3a..a4365030b6a12 100644 --- a/Common/Utils/include/CommonUtils/IRFrameSelector.h +++ b/Common/Utils/include/CommonUtils/IRFrameSelector.h @@ -46,6 +46,8 @@ class IRFrameSelector auto getIRFrames() const { return mFrames; } bool isSet() const { return mIsSet; } + void setOwnList(const std::vector& lst, bool toBeSorted); + private: gsl::span mFrames{}; // externally provided span of IRFrames, must be sorted in IRFrame.getMin() o2::dataformats::IRFrame mLastIRFrameChecked{}; // last frame which was checked diff --git a/Common/Utils/src/IRFrameSelector.cxx b/Common/Utils/src/IRFrameSelector.cxx index 8122484659f45..abc0ee1ee6ce3 100644 --- a/Common/Utils/src/IRFrameSelector.cxx +++ b/Common/Utils/src/IRFrameSelector.cxx @@ -167,6 +167,16 @@ size_t IRFrameSelector::loadIRFrames(const std::string& fname) return mOwnList.size(); } +void IRFrameSelector::setOwnList(const std::vector& lst, bool toBeSorted) +{ + clear(); + mOwnList.insert(mOwnList.end(), lst.begin(), lst.end()); + if (toBeSorted) { + std::sort(mOwnList.begin(), mOwnList.end(), [](const auto& a, const auto& b) { return a.getMin() < b.getMin(); }); + } + setSelectedIRFrames(mOwnList, 0, 0, 0, false); +} + void IRFrameSelector::print(bool lst) const { LOGP(info, "Last query stopped at entry {} for IRFrame {}:{}", mLastBoundID, @@ -183,6 +193,8 @@ void IRFrameSelector::clear() { mIsSet = false; mOwnList.clear(); + mLastIRFrameChecked.getMin().clear(); // invalidate + mLastBoundID = -1; mFrames = {}; } diff --git a/Detectors/CTF/README.md b/Detectors/CTF/README.md index e1e65060db523..47ce765de289a 100644 --- a/Detectors/CTF/README.md +++ b/Detectors/CTF/README.md @@ -95,6 +95,14 @@ comma-separated list of detectors to read, Overrides skipDet ``` comma-separated list of detectors to skip + +By default an exception will be thrown if detector is requested but missing in the CTF. To enable injection of the empty output in such case one should use option `--allow-missing-detectors`. + +``` +--ctf-data-subspec arg (=0) +``` +allows to alter the `subSpecification` used to send the CTFDATA from the reader to decoders. Non-0 value must be used in case the data extracted by the CTF-reader should be processed and stored in new CTFs (in order to avoid clash of CTFDATA messages of the reader and writer). + ``` --max-tf arg (=-1) ``` @@ -141,6 +149,8 @@ There is a possibility to read remote root files directly, w/o caching them loca 2) provide proper regex to define remote files, e.g. for the example above: `--remote-regex "^root://.+/eos/aliceo2/.+"`. 3) pass an option `--copy-cmd no-copy`. +## Selective TF reading + ``` --select-ctf-ids ``` @@ -148,24 +158,25 @@ This is a `ctf-reader` device local option allowing selective reading of particu Note that the index corresponds not to the entry of the TF in the CTF tree but to the reader own counter incremented throught all input files (e.g. if the 10 CTF files with 20 TFs each are provided for the input and the selection of TFs `0,2,22,66` is provided, the reader will inject to the DPL the TFs at entries 0 and 2 from the 1st CTF file, entry 5 of the second file, entry 6 of the 3d and will finish the job. -For the ITS and MFT entropy decoding one can request either to decompose clusters to digits and send them instead of clusters (via `o2-ctf-reader-workflow` global options `--its-digits` and `--mft-digits` respectively) -or to apply the noise mask to decoded clusters (or decoded digits). If the masking (e.g. via option `--its-entropy-decoder " --mask-noise "`) is requested, user should provide to the entropy decoder the noise mask file (eventually will be loaded from CCDB) and cluster patterns decoding dictionary (if the clusters were encoded with patterns IDs). -For example, ``` -o2-ctf-reader-workflow --ctf-input --onlyDet ITS,MFT --its-entropy-decoder ' --mask-noise' | ... +--ir-frames-files --skip-skimmed-out-tf ``` -will decode ITS and MFT data, decompose on the fly ITS clusters to digits, mask the noisy pixels with the provided masks, recluster remaining ITS digits and send the new clusters out, together with unchanged MFT clusters. +This option (used for skimming) allow to push to DPL only those TFs which overlap with selected BC-ranges provided via input root file (for various formats see `o2::utils::IRFrameSelector::loadIRFrames` method). + ``` -o2-ctf-reader-workflow --ctf-input --onlyDet ITS,MFT --mft-digits --mft-entropy-decoder ' --mask-noise' | ... +--ir-frames-files ``` -will send decompose clusters to digits and send ben out after masking the noise for the MFT, while ITS clusters will be sent as decoded. - -By default an exception will be thrown if detector is requested but missing in the CTF. To enable injection of the empty output in such case one should use option `--allow-missing-detectors`. +This option allows to push to DPL only those TFs which overlap with the ` ` (separators can be any whitespace, comma or semicolon) records provided via text file (assuming that there are some entries for a given run, otherwise the option is ignored). +Multiple ranges per run and multiple runs can be mentioned in a single input file. The range limits can be indicated either as a UNIX timestamp in `ms` or as an orbit number (in the fill the run belongs to). +In case an option ``` ---ctf-data-subspec arg (=0) +--invert-irframe-selection ``` -allows to alter the `subSpecification` used to send the CTFDATA from the reader to decoders. Non-0 value must be used in case the data extracted by the CTF-reader should be processed and stored in new CTFs (in order to avoid clash of CTFDATA messages of the reader and writer). +is provided, the selections above are inverted: TFs matching some of the provided ranges will be discarded, while the rest will be pushed to the DPL + +At the end of the processing the `ctf-writer` will create a local file `ctf_read_ntf.txt` containing only the number of TFs pushed to the DPL. +In case no TF passed the selections above, this file will contain 0. ## Support for externally provided encoding dictionaries @@ -201,3 +212,18 @@ Additionally, one may throttle on the free SHM by providing an option to the rea Note that by default the reader reads into the memory the CTF data and prepares all output messages but injects them only once the rate-limiter allows that. With the option `--limit-tf-before-reading` set also the preparation of the data to inject will be conditioned by the green light from the rate-limiter. + + +## Modifying ITS/MFT CTF output + +For the ITS and MFT entropy decoding one can request either to decompose clusters to digits and send them instead of clusters (via `o2-ctf-reader-workflow` global options `--its-digits` and `--mft-digits` respectively) +or to apply the noise mask to decoded clusters (or decoded digits). If the masking (e.g. via option `--its-entropy-decoder " --mask-noise "`) is requested, user should provide to the entropy decoder the noise mask file (eventually will be loaded from CCDB) and cluster patterns decoding dictionary (if the clusters were encoded with patterns IDs). +For example, +``` +o2-ctf-reader-workflow --ctf-input --onlyDet ITS,MFT --its-entropy-decoder ' --mask-noise' | ... +``` +will decode ITS and MFT data, decompose on the fly ITS clusters to digits, mask the noisy pixels with the provided masks, recluster remaining ITS digits and send the new clusters out, together with unchanged MFT clusters. +``` +o2-ctf-reader-workflow --ctf-input --onlyDet ITS,MFT --mft-digits --mft-entropy-decoder ' --mask-noise' | ... +``` +will send decompose clusters to digits and send ben out after masking the noise for the MFT, while ITS clusters will be sent as decoded. diff --git a/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h b/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h index 997572e0371b2..b202013a6eea1 100644 --- a/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h +++ b/Detectors/CTF/workflow/include/CTFWorkflow/CTFReaderSpec.h @@ -31,8 +31,10 @@ struct CTFReaderInp { std::string remoteRegex{}; std::string metricChannel{}; std::string fileIRFrames{}; + std::string fileRunTimeSpans{}; std::vector ctfIDs{}; bool skipSkimmedOutTF = false; + bool invertIRFramesSelection = false; bool allowMissingDetectors = false; bool checkTFLimitBeforeReading = false; bool sup0xccdb = false; diff --git a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx index 70bb589e8836a..bcf3b5d975b74 100644 --- a/Detectors/CTF/workflow/src/CTFReaderSpec.cxx +++ b/Detectors/CTF/workflow/src/CTFReaderSpec.cxx @@ -45,6 +45,9 @@ #include "DataFormatsZDC/CTF.h" #include "DataFormatsHMP/CTF.h" #include "DataFormatsCTP/CTF.h" +#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/LHCConstants.h" #include "Algorithm/RangeTokenizer.h" #include #include @@ -81,6 +84,8 @@ class CTFReaderSpec : public o2::framework::Task void run(o2::framework::ProcessingContext& pc) final; private: + void runTimeRangesToIRFrameSelector(const o2::framework::TimingInfo& timingInfo); + void loadRunTimeSpans(const std::string& flname); void openCTFFile(const std::string& flname); bool processTF(ProcessingContext& pc); void checkTreeEntries(); @@ -91,16 +96,20 @@ class CTFReaderSpec : public o2::framework::Task void tryToFixCTFHeader(CTFHeader& ctfHeader) const; CTFReaderInp mInput{}; o2::utils::IRFrameSelector mIRFrameSelector; // optional IR frames selector + std::map>> mRunTimeRanges; std::unique_ptr mFileFetcher; std::unique_ptr mCTFFile; std::unique_ptr mCTFTree; bool mRunning = false; bool mUseLocalTFCounter = false; + int mConvRunTimeRangesToOrbits = -1; // not defined yet int mCTFCounter = 0; + int mCTFCounterAcc = 0; int mNFailedFiles = 0; int mFilesRead = 0; int mTFLength = 128; int mNWaits = 0; + int mRunNumberPrev = -1; long mTotalWaitTime = 0; long mLastSendTime = 0L; long mCurrTreeEntry = 0L; @@ -129,8 +138,8 @@ void CTFReaderSpec::stopReader() return; } LOGP(info, "CTFReader stops processing, {} files read, {} files failed", mFilesRead - mNFailedFiles, mNFailedFiles); - LOGP(info, "CTF reading total timing: Cpu: {:.3f} Real: {:.3f} s for {} TFs in {} loops, spent {:.2} s in {} data waiting states", - mTimer.CpuTime(), mTimer.RealTime(), mCTFCounter, mFileFetcher->getNLoops(), 1e-6 * mTotalWaitTime, mNWaits); + LOGP(info, "CTF reading total timing: Cpu: {:.3f} Real: {:.3f} s for {} TFs ({} accepted) in {} loops, spent {:.2} s in {} data waiting states", + mTimer.CpuTime(), mTimer.RealTime(), mCTFCounter, mCTFCounterAcc, mFileFetcher->getNLoops(), 1e-6 * mTotalWaitTime, mNWaits); mRunning = false; mFileFetcher->stop(); mFileFetcher.reset(); @@ -164,6 +173,111 @@ void CTFReaderSpec::init(InitContext& ic) mTFLength = hbfu.nHBFPerTF; LOGP(info, "IRFrames will be selected from {}, assumed TF length: {} HBF", mInput.fileIRFrames, mTFLength); } + if (!mInput.fileRunTimeSpans.empty()) { + loadRunTimeSpans(mInput.fileRunTimeSpans); + } +} + +void CTFReaderSpec::runTimeRangesToIRFrameSelector(const o2::framework::TimingInfo& timingInfo) +{ + // convert entries in the runTimeRanges to IRFrameSelector, if needed, convert time to orbit + mIRFrameSelector.clear(); + auto ent = mRunTimeRanges.find(timingInfo.runNumber); + if (ent == mRunTimeRanges.end()) { + LOGP(info, "RunTimeRanges selection was provided but run {} has no entries, all TFs will be processed", timingInfo.runNumber); + return; + } + o2::parameters::AggregatedRunInfo rinfo; + auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); + rinfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(ccdb, timingInfo.runNumber); + if (rinfo.runNumber != timingInfo.runNumber || rinfo.orbitsPerTF < 1) { + LOGP(fatal, "failed to extract AggregatedRunInfo for run {}", timingInfo.runNumber); + } + mTFLength = rinfo.orbitsPerTF; + std::vector frames; + for (const auto& rng : ent->second) { + long orbMin = 0, orbMax = 0; + if (mConvRunTimeRangesToOrbits > 0) { + orbMin = rinfo.orbitSOR + (rng.first - rinfo.sor) / (o2::constants::lhc::LHCOrbitMUS * 0.001); + orbMax = rinfo.orbitSOR + (rng.second - rinfo.sor) / (o2::constants::lhc::LHCOrbitMUS * 0.001); + } else { + orbMin = rng.first; + orbMax = rng.second; + } + if (orbMin < 0) { + orbMin = 0; + } + if (orbMax < 0) { + orbMax = 0; + } + if (timingInfo.runNumber > 523897) { + orbMin = (orbMin / rinfo.orbitsPerTF) * rinfo.orbitsPerTF; + orbMax = (orbMax / rinfo.orbitsPerTF + 1) * rinfo.orbitsPerTF - 1; + } + LOGP(info, "TFs overlapping with orbits {}:{} will be {}", orbMin, orbMax, mInput.invertIRFramesSelection ? "rejected" : "selected"); + frames.emplace_back(InteractionRecord{0, uint32_t(orbMin)}, InteractionRecord{o2::constants::lhc::LHCMaxBunches, uint32_t(orbMax)}); + } + mIRFrameSelector.setOwnList(frames, true); +} + +void CTFReaderSpec::loadRunTimeSpans(const std::string& flname) +{ + std::ifstream inputFile(flname); + if (!inputFile) { + LOGP(fatal, "Failed to open selected run/timespans file {}", mInput.fileRunTimeSpans); + } + std::string line; + size_t cntl = 0, cntr = 0; + while (std::getline(inputFile, line)) { + cntl++; + for (char& ch : line) { // Replace semicolons and tabs with spaces for uniform processing + if (ch == ';' || ch == '\t' || ch == ',') { + ch = ' '; + } + } + o2::utils::Str::trim(line); + if (line.size() < 1 || line[0] == '#') { + continue; + } + auto tokens = o2::utils::Str::tokenize(line, ' '); + auto logError = [&cntl, &line]() { LOGP(error, "Expected format for selection is tripplet , failed on line#{}: {}", cntl, line); }; + if (tokens.size() >= 3) { + int run = 0; + long rmin, rmax; + try { + run = std::stoi(tokens[0]); + rmin = std::stol(tokens[1]); + rmax = std::stol(tokens[2]); + } catch (...) { + logError(); + continue; + } + + constexpr long ISTimeStamp = 1514761200000L; + int convmn = rmin > ISTimeStamp ? 1 : 0, convmx = rmax > ISTimeStamp ? 1 : 0; // values above ISTimeStamp are timestamps (need to be converted to orbits) + if (rmin > rmax) { + LOGP(fatal, "Provided range limits are not in increasing order, entry is {}", line); + } + if (mConvRunTimeRangesToOrbits == -1) { + if (convmn != convmx) { + LOGP(fatal, "Provided range limits should be both consistent either with orbit number or with unix timestamp in ms, entry is {}", line); + } + mConvRunTimeRangesToOrbits = convmn; // need to convert to orbit if time + LOGP(info, "Interpret selected time-spans input as {}", mConvRunTimeRangesToOrbits == 1 ? "timstamps(ms)" : "orbits"); + } else { + if (mConvRunTimeRangesToOrbits != convmn || mConvRunTimeRangesToOrbits != convmx) { + LOGP(fatal, "Provided range limits should are not consistent with previously determined {} input, entry is {}", mConvRunTimeRangesToOrbits == 1 ? "timestamps" : "orbits", line); + } + } + + mRunTimeRanges[run].emplace_back(rmin, rmax); + cntr++; + } else { + logError(); + } + } + LOGP(info, "Read {} time-spans for {} runs from {}", cntr, mRunTimeRanges.size(), mInput.fileRunTimeSpans); + inputFile.close(); } ///_______________________________________ @@ -256,6 +370,17 @@ void CTFReaderSpec::run(ProcessingContext& pc) pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); stopReader(); + const std::string dummy{"ctf_read_ntf.txt"}; + if (mCTFCounterAcc == 0) { + LOGP(warn, "No TF passed selection, writing a 0 to file {}", dummy); + } + try { + std::ofstream outfile; + outfile.open(dummy, std::ios::out | std::ios::trunc); + outfile << mCTFCounterAcc << std::endl; + } catch (...) { + LOGP(error, "Failed to write {}", dummy); + } } } @@ -278,7 +403,7 @@ bool CTFReaderSpec::processTF(ProcessingContext& pc) } if (mUseLocalTFCounter) { - ctfHeader.tfCounter = mCTFCounter; + ctfHeader.tfCounter = mCTFCounterAcc; } LOG(info) << ctfHeader; @@ -289,19 +414,26 @@ bool CTFReaderSpec::processTF(ProcessingContext& pc) timingInfo.tfCounter = ctfHeader.tfCounter; timingInfo.runNumber = ctfHeader.run; + if (mRunTimeRanges.size() && timingInfo.runNumber != mRunNumberPrev) { + runTimeRangesToIRFrameSelector(timingInfo); + } + mRunNumberPrev = timingInfo.runNumber; + if (mIRFrameSelector.isSet()) { o2::InteractionRecord ir0(0, timingInfo.firstTForbit); - // we cannot have GRPECS via DPL CCDB fetcher in the CTFReader, so we use mTFLength extracted from the HBFUtils o2::InteractionRecord ir1(o2::constants::lhc::LHCMaxBunches - 1, timingInfo.firstTForbit < 0xffffffff - (mTFLength - 1) ? timingInfo.firstTForbit + (mTFLength - 1) : 0xffffffff); auto irSpan = mIRFrameSelector.getMatchingFrames({ir0, ir1}); - if (irSpan.size() == 0 && mInput.skipSkimmedOutTF) { - LOGP(info, "Skimming did not define any selection for TF [{}] : [{}]", ir0.asString(), ir1.asString()); + bool acc = true; + if (mInput.skipSkimmedOutTF) { + acc = (irSpan.size() > 0) ? !mInput.invertIRFramesSelection : mInput.invertIRFramesSelection; + LOGP(info, "IRFrame selection contains {} frames for TF [{}] : [{}]: {}use this TF (selection inversion mode is {})", + irSpan.size(), ir0.asString(), ir1.asString(), acc ? "" : "do not ", mInput.invertIRFramesSelection ? "ON" : "OFF"); + } + if (!acc) { return false; - } else { - if (mInput.checkTFLimitBeforeReading) { - limiter.check(pc, mInput.tfRateLimit, mInput.minSHM); - } - LOGP(info, "{} IR-Frames are selected for TF [{}] : [{}]", irSpan.size(), ir0.asString(), ir1.asString()); + } + if (mInput.checkTFLimitBeforeReading) { + limiter.check(pc, mInput.tfRateLimit, mInput.minSHM); } auto outVec = pc.outputs().make>(OutputRef{"selIRFrames"}, irSpan.begin(), irSpan.end()); } else { @@ -329,6 +461,7 @@ bool CTFReaderSpec::processTF(ProcessingContext& pc) processDetector(DetID::CPV, ctfHeader, pc); processDetector(DetID::ZDC, ctfHeader, pc); processDetector(DetID::CTP, ctfHeader, pc); + mCTFCounterAcc++; // send sTF acknowledge message if (!mInput.sup0xccdb) { @@ -466,7 +599,7 @@ DataProcessorSpec getCTFReaderSpec(const CTFReaderInp& inp) outputs.emplace_back(OutputLabel{det.getName()}, det.getDataOrigin(), "CTFDATA", inp.subspec, Lifetime::Timeframe); } } - if (!inp.fileIRFrames.empty()) { + if (!inp.fileIRFrames.empty() || !inp.fileRunTimeSpans.empty()) { outputs.emplace_back(OutputLabel{"selIRFrames"}, "CTF", "SELIRFRAMES", 0, Lifetime::Timeframe); } if (!inp.sup0xccdb) { diff --git a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx index 90d259f4e3a5c..1f0ef9a3b871b 100644 --- a/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx +++ b/Detectors/CTF/workflow/src/ctf-reader-workflow.cxx @@ -66,7 +66,9 @@ void customize(std::vector& workflowOptions) options.push_back(ConfigParamSpec{"ctf-data-subspec", VariantType::Int, 0, {"subspec to use for decoded CTF messages (use non-0 if CTF writer will be attached downstream)"}}); options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}}); options.push_back(ConfigParamSpec{"ir-frames-files", VariantType::String, "", {"If non empty, inject selected IRFrames from this file"}}); + options.push_back(ConfigParamSpec{"run-time-span-file", VariantType::String, "", {"If non empty, inject selected IRFrames from this text file (run, min/max orbit or unix time)"}}); options.push_back(ConfigParamSpec{"skip-skimmed-out-tf", VariantType::Bool, false, {"Do not process TFs with empty IR-Frame coverage"}}); + options.push_back(ConfigParamSpec{"invert-irframe-selection", VariantType::Bool, false, {"Select only frames mentioned in ir-frames-file (skip-skimmed-out-tf applied to TF not selected!)"}}); // options.push_back(ConfigParamSpec{"its-digits", VariantType::Bool, false, {"convert ITS clusters to digits"}}); options.push_back(ConfigParamSpec{"mft-digits", VariantType::Bool, false, {"convert MFT clusters to digits"}}); @@ -125,7 +127,9 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) ctfInput.sup0xccdb = !configcontext.options().get("send-diststf-0xccdb"); ctfInput.minSHM = std::stoul(configcontext.options().get("timeframes-shm-limit")); ctfInput.fileIRFrames = configcontext.options().get("ir-frames-files"); + ctfInput.fileRunTimeSpans = configcontext.options().get("run-time-span-file"); ctfInput.skipSkimmedOutTF = configcontext.options().get("skip-skimmed-out-tf"); + ctfInput.invertIRFramesSelection = configcontext.options().get("invert-irframe-selection"); int verbosity = configcontext.options().get("ctf-reader-verbosity"); int rateLimitingIPCID = std::stoi(configcontext.options().get("timeframes-rate-limit-ipcid")); @@ -133,6 +137,12 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (rateLimitingIPCID > -1 && !chanFmt.empty()) { ctfInput.metricChannel = fmt::format(fmt::runtime(chanFmt), o2::framework::ChannelSpecHelpers::defaultIPCFolder(), rateLimitingIPCID); } + if (!ctfInput.fileRunTimeSpans.empty()) { + ctfInput.skipSkimmedOutTF = true; + } + if (!ctfInput.fileIRFrames.empty() && !ctfInput.fileRunTimeSpans.empty()) { + LOGP(fatal, "One cannot provide --ir-frames-files and --run-time-span-file options simultaneously"); + } specs.push_back(o2::ctf::getCTFReaderSpec(ctfInput)); From 33b421259e216f9e87c41438ae4c1fcc63691163 Mon Sep 17 00:00:00 2001 From: Matteo Concas Date: Tue, 3 Dec 2024 16:07:27 +0100 Subject: [PATCH 0544/2205] ITS-GPU: Move Tracklet finder on GPU (#13737) * Fix hybrid vertexer printouts * Move multiplicity mask to a vector * Add gpuSpan * Debugging getSpan * Checkpointing * Fix access in tracklet finding * Fix tracklet LUTs issue * Debugging small discrepancies * Fix bad PhiBins pick * Add tracklet counting * Fix indices for used clusters * Add tracklet writing on the buffer * tracklets on gpu * Tracklet finder on GPU --- .../include/ITSReconstruction/FastMultEst.h | 2 +- .../ITS/reconstruction/src/FastMultEst.cxx | 2 +- .../GPU/ITStrackingGPU/TimeFrameGPU.h | 63 +- .../GPU/ITStrackingGPU/TrackingKernels.h | 71 +- .../ITS/tracking/GPU/ITStrackingGPU/Utils.h | 43 ++ .../ITS/tracking/GPU/cuda/TimeFrameGPU.cu | 168 +++- .../tracking/GPU/cuda/TrackerTraitsGPU.cxx | 335 +++----- .../ITS/tracking/GPU/cuda/TrackingKernels.cu | 723 +++++++++++------- .../tracking/include/ITStracking/TimeFrame.h | 25 +- .../ITSMFT/ITS/tracking/src/TrackerTraits.cxx | 11 +- .../ITS/tracking/src/TrackingInterface.cxx | 2 +- .../ITSMFT/ITS/tracking/src/Vertexer.cxx | 8 +- .../ITS/workflow/src/CookedTrackerSpec.cxx | 2 +- 13 files changed, 848 insertions(+), 607 deletions(-) diff --git a/Detectors/ITSMFT/ITS/reconstruction/include/ITSReconstruction/FastMultEst.h b/Detectors/ITSMFT/ITS/reconstruction/include/ITSReconstruction/FastMultEst.h index 457381862cc42..9e8299e89b404 100644 --- a/Detectors/ITSMFT/ITS/reconstruction/include/ITSReconstruction/FastMultEst.h +++ b/Detectors/ITSMFT/ITS/reconstruction/include/ITSReconstruction/FastMultEst.h @@ -45,7 +45,7 @@ struct FastMultEst { static uint32_t getCurrentRandomSeed(); int selectROFs(const gsl::span rofs, const gsl::span clus, - const gsl::span trig, std::vector& sel); + const gsl::span trig, std::vector& sel); void fillNClPerLayer(const gsl::span& clusters); float process(const std::array ncl) diff --git a/Detectors/ITSMFT/ITS/reconstruction/src/FastMultEst.cxx b/Detectors/ITSMFT/ITS/reconstruction/src/FastMultEst.cxx index a55fafdf60409..c547996c6f356 100644 --- a/Detectors/ITSMFT/ITS/reconstruction/src/FastMultEst.cxx +++ b/Detectors/ITSMFT/ITS/reconstruction/src/FastMultEst.cxx @@ -125,7 +125,7 @@ float FastMultEst::processNoiseImposed(const std::array ncl) } int FastMultEst::selectROFs(const gsl::span rofs, const gsl::span clus, - const gsl::span trig, std::vector& sel) + const gsl::span trig, std::vector& sel) { int nrof = rofs.size(), nsel = 0; const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h index ad8724f315ec8..37f392ebbd3a7 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TimeFrameGPU.h @@ -51,9 +51,19 @@ class TimeFrameGPU : public TimeFrame void initialise(const int, const TrackingParameters&, const int, IndexTableUtils* utils = nullptr, const TimeFrameGPUParameters* pars = nullptr); void initDevice(IndexTableUtils*, const TrackingParameters& trkParam, const TimeFrameGPUParameters&, const int, const int); void initDeviceSAFitting(); + void loadIndexTableUtils(const int); void loadTrackingFrameInfoDevice(const int); void loadUnsortedClustersDevice(const int); void loadClustersDevice(const int); + void loadClustersIndexTables(const int iteration); + void createUsedClustersDevice(const int); + void loadUsedClustersDevice(); + void loadROframeClustersDevice(const int); + void loadMultiplicityCutMask(const int); + void loadVertices(const int); + + /// + void createTrackletsLUTDevice(const int); void loadTrackletsDevice(); void loadTrackletsLUTDevice(); void loadCellsDevice(); @@ -62,6 +72,7 @@ class TimeFrameGPU : public TimeFrame void loadTrackSeedsChi2Device(); void loadRoadsDevice(); void loadTrackSeedsDevice(std::vector&); + void createTrackletsBuffers(); void createCellsBuffers(const int); void createCellsDevice(); void createCellsLUTDevice(); @@ -93,7 +104,7 @@ class TimeFrameGPU : public TimeFrame std::vector>& getLabelsInChunks() { return mLabelsInChunks; } int getNAllocatedROFs() const { return mNrof; } // Allocated means maximum nROF for each chunk while populated is the number of loaded ones. StaticTrackingParameters* getDeviceTrackingParameters() { return mTrackingParamsDevice; } - Vertex* getDeviceVertices() { return mVerticesDevice; } + Vertex* getDeviceVertices() { return mPrimaryVerticesDevice; } int* getDeviceROFramesPV() { return mROFramesPVDevice; } unsigned char* getDeviceUsedClusters(const int); const o2::base::Propagator* getChainPropagator(); @@ -107,8 +118,12 @@ class TimeFrameGPU : public TimeFrame const TrackingFrameInfo** getDeviceArrayTrackingFrameInfo() const { return mTrackingFrameInfoDeviceArray; } const Cluster** getDeviceArrayClusters() const { return mClustersDeviceArray; } const Cluster** getDeviceArrayUnsortedClusters() const { return mUnsortedClustersDeviceArray; } - const Tracklet** getDeviceArrayTracklets() const { return mTrackletsDeviceArray; } - const int** getDeviceArrayTrackletsLUT() const { return mTrackletsLUTDeviceArray; } + const int** getDeviceArrayClustersIndexTables() const { return mClustersIndexTablesDeviceArray; } + std::vector getClusterSizes(); + const unsigned char** getDeviceArrayUsedClusters() const { return mUsedClustersDeviceArray; } + const int** getDeviceROframeClusters() const { return mROFrameClustersDeviceArray; } + Tracklet** getDeviceArrayTracklets() { return mTrackletsDeviceArray; } + int** getDeviceArrayTrackletsLUT() const { return mTrackletsLUTDeviceArray; } int** getDeviceArrayCellsLUT() const { return mCellsLUTDeviceArray; } int** getDeviceArrayNeighboursCellLUT() const { return mNeighboursCellLUTDeviceArray; } CellSeed** getDeviceArrayCells() const { return mCellsDeviceArray; } @@ -116,17 +131,19 @@ class TimeFrameGPU : public TimeFrame o2::track::TrackParCovF** getDeviceArrayTrackSeeds() { return mCellSeedsDeviceArray; } float** getDeviceArrayTrackSeedsChi2() { return mCellSeedsChi2DeviceArray; } int* getDeviceNeighboursIndexTables(const int layer) { return mNeighboursIndexTablesDevice[layer]; } + uint8_t* getDeviceMultCutMask() { return mMultMaskDevice; } void setDevicePropagator(const o2::base::PropagatorImpl*) override; // Host-specific getters - gsl::span getHostNTracklets(const int chunkId); - gsl::span getHostNCells(const int chunkId); + gsl::span getNTracklets() { return mNTracklets; } + gsl::span getNCells() { return mNCells; } // Host-available device getters + gsl::span getDeviceTrackletsLUTs() { return mTrackletsLUTDevice; } gsl::span getDeviceCellLUTs() { return mCellsLUTDevice; } + gsl::span getDeviceTracklet() { return mTrackletsDevice; } gsl::span getDeviceCells() { return mCellsDevice; } - gsl::span getNCellsDevice() { return mNCells; } private: void allocMemAsync(void**, size_t, Stream*, bool); // Abstract owned and unowned memory allocations @@ -136,31 +153,37 @@ class TimeFrameGPU : public TimeFrame StaticTrackingParameters mStaticTrackingParams; // Host-available device buffer sizes + std::array mNTracklets; std::array mNCells; // Device pointers StaticTrackingParameters* mTrackingParamsDevice; IndexTableUtils* mIndexTableUtilsDevice; - std::array mROFramesClustersDevice; - std::array mUsedClustersDevice; - Vertex* mVerticesDevice; - int* mROFramesPVDevice; // Hybrid pref + uint8_t* mMultMaskDevice; + Vertex* mPrimaryVerticesDevice; + int* mROFramesPVDevice; std::array mClustersDevice; std::array mUnsortedClustersDevice; + std::array mClustersIndexTablesDevice; + std::array mUsedClustersDevice; + std::array mROFramesClustersDevice; const Cluster** mClustersDeviceArray; const Cluster** mUnsortedClustersDeviceArray; + const int** mClustersIndexTablesDeviceArray; + const unsigned char** mUsedClustersDeviceArray; + const int** mROFrameClustersDeviceArray; std::array mTrackletsDevice; - const Tracklet** mTrackletsDeviceArray; - const int** mTrackletsLUTDeviceArray; - std::array mTrackletsLUTDevice; + Tracklet** mTrackletsDeviceArray; + std::array mTrackletsLUTDevice; std::array mCellsLUTDevice; std::array mNeighboursLUTDevice; int** mCellsLUTDeviceArray; int** mNeighboursCellDeviceArray; int** mNeighboursCellLUTDeviceArray; + int** mTrackletsLUTDeviceArray; std::array mCellsDevice; std::array mNeighboursIndexTablesDevice; CellSeed* mTrackSeedsDevice; @@ -186,10 +209,6 @@ class TimeFrameGPU : public TimeFrame std::vector> mNVerticesInChunks; std::vector> mLabelsInChunks; - // Host memory used only in GPU tracking - std::vector mHostNTracklets; - std::vector mHostNCells; - // Temporary buffer for storing output tracks from GPU tracking std::vector mTrackITSExt; }; @@ -215,6 +234,16 @@ inline int TimeFrameGPU::getNClustersInRofSpan(const int rofIdstart, co { return static_cast(mROFramesClusters[layerId][(rofIdstart + rofSpanSize) < mROFramesClusters.size() ? rofIdstart + rofSpanSize : mROFramesClusters.size() - 1] - mROFramesClusters[layerId][rofIdstart]); } + +template +inline std::vector TimeFrameGPU::getClusterSizes() +{ + std::vector sizes(mUnsortedClusters.size()); + std::transform(mUnsortedClusters.begin(), mUnsortedClusters.end(), sizes.begin(), + [](const auto& v) { return static_cast(v.size()); }); + return sizes; +} + } // namespace gpu } // namespace its } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h index 34e6165b9530f..54bdae302e643 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/TrackingKernels.h @@ -50,11 +50,74 @@ GPUg() void fitTrackSeedsKernel( #endif } // namespace gpu +template +void countTrackletsInROFsHandler(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minR, + std::vector& maxR, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads); + +template +void computeTrackletsInROFsHandler(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + Tracklet** tracklets, + gsl::span spanTracklets, + gsl::span nTracklets, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minR, + std::vector& maxR, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads); + void countCellsHandler(const Cluster** sortedClusters, const Cluster** unsortedClusters, const TrackingFrameInfo** tfInfo, - const Tracklet** tracklets, - const int** trackletsLUT, + Tracklet** tracklets, + int** trackletsLUT, const int nTracklets, const int layer, CellSeed* cells, @@ -70,8 +133,8 @@ void countCellsHandler(const Cluster** sortedClusters, void computeCellsHandler(const Cluster** sortedClusters, const Cluster** unsortedClusters, const TrackingFrameInfo** tfInfo, - const Tracklet** tracklets, - const int** trackletsLUT, + Tracklet** tracklets, + int** trackletsLUT, const int nTracklets, const int layer, CellSeed* cells, diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h index 66244bf854b5f..a88e51742e84a 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h +++ b/Detectors/ITSMFT/ITS/tracking/GPU/ITStrackingGPU/Utils.h @@ -31,6 +31,49 @@ struct gpuPair { namespace gpu { +// Poor man implementation of a span-like struct. It is very limited. +template +struct gpuSpan { + using value_type = T; + using ptr = T*; + using ref = T&; + + GPUd() gpuSpan() : _data(nullptr), _size(0) {} + GPUd() gpuSpan(ptr data, unsigned int dim) : _data(data), _size(dim) {} + GPUd() ref operator[](unsigned int idx) const { return _data[idx]; } + GPUd() unsigned int size() const { return _size; } + GPUd() bool empty() const { return _size == 0; } + GPUd() ref front() const { return _data[0]; } + GPUd() ref back() const { return _data[_size - 1]; } + GPUd() ptr begin() const { return _data; } + GPUd() ptr end() const { return _data + _size; } + + protected: + ptr _data; + unsigned int _size; +}; + +template +struct gpuSpan { + using value_type = T; + using ptr = const T*; + using ref = const T&; + + GPUd() gpuSpan() : _data(nullptr), _size(0) {} + GPUd() gpuSpan(ptr data, unsigned int dim) : _data(data), _size(dim) {} + GPUd() gpuSpan(const gpuSpan& other) : _data(other._data), _size(other._size) {} + GPUd() ref operator[](unsigned int idx) const { return _data[idx]; } + GPUd() unsigned int size() const { return _size; } + GPUd() bool empty() const { return _size == 0; } + GPUd() ref front() const { return _data[0]; } + GPUd() ref back() const { return _data[_size - 1]; } + GPUd() ptr begin() const { return _data; } + GPUd() ptr end() const { return _data + _size; } + + protected: + ptr _data; + unsigned int _size; +}; enum class Task { Tracker = 0, diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu index 67144ba2c98ea..4bd15c0203d81 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TimeFrameGPU.cu @@ -92,6 +92,19 @@ void TimeFrameGPU::setDevicePropagator(const o2::base::PropagatorImpl +void TimeFrameGPU::loadIndexTableUtils(const int iteration) +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading indextable utils"); + if (!iteration) { + LOGP(debug, "gpu-allocation: allocating IndexTableUtils buffer, for {} MB.", sizeof(IndexTableUtils) / MB); + allocMemAsync(reinterpret_cast(&mIndexTableUtilsDevice), sizeof(IndexTableUtils), nullptr, getExtAllocator()); + } + LOGP(debug, "gpu-transfer: loading IndexTableUtils object, for {} MB.", sizeof(IndexTableUtils) / MB); + checkGPUError(cudaMemcpyAsync(mIndexTableUtilsDevice, &mIndexTableUtils, sizeof(IndexTableUtils), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + template void TimeFrameGPU::loadUnsortedClustersDevice(const int iteration) { @@ -128,6 +141,65 @@ void TimeFrameGPU::loadClustersDevice(const int iteration) } } +template +void TimeFrameGPU::loadClustersIndexTables(const int iteration) +{ + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading sorted clusters"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading clusters indextable for layer {} with {} elements, for {} MB.", iLayer, mIndexTables[iLayer].size(), mIndexTables[iLayer].size() * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mClustersIndexTablesDevice[iLayer]), mIndexTables[iLayer].size() * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mClustersIndexTablesDevice[iLayer], mIndexTables[iLayer].data(), mIndexTables[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mClustersIndexTablesDeviceArray), nLayers * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mClustersIndexTablesDeviceArray, mClustersIndexTablesDevice.data(), nLayers * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); + } +} + +template +void TimeFrameGPU::createUsedClustersDevice(const int iteration) +{ + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating used clusters flags"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: creating {} used clusters flags on layer {}, for {} MB.", mUsedClusters[iLayer].size(), iLayer, mUsedClusters[iLayer].size() * sizeof(unsigned char) / MB); + allocMemAsync(reinterpret_cast(&mUsedClustersDevice[iLayer]), mUsedClusters[iLayer].size() * sizeof(unsigned char), nullptr, getExtAllocator()); + checkGPUError(cudaMemsetAsync(mUsedClustersDevice[iLayer], 0, mUsedClusters[iLayer].size() * sizeof(unsigned char), mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mUsedClustersDeviceArray), nLayers * sizeof(unsigned char*), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mUsedClustersDeviceArray, mUsedClustersDevice.data(), nLayers * sizeof(unsigned char*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); + } +} + +template +void TimeFrameGPU::loadUsedClustersDevice() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading used clusters flags"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} used clusters flags on layer {}, for {} MB.", mUsedClusters[iLayer].size(), iLayer, mClusters[iLayer].size() * sizeof(unsigned char) / MB); + checkGPUError(cudaMemcpyAsync(mUsedClustersDevice[iLayer], mUsedClusters[iLayer].data(), mUsedClusters[iLayer].size() * sizeof(unsigned char), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::loadROframeClustersDevice(const int iteration) +{ + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading ROframe clusters"); + for (auto iLayer{0}; iLayer < nLayers; ++iLayer) { + LOGP(debug, "gpu-transfer: loading {} ROframe clusters info on layer {}, for {} MB.", mROFramesClusters[iLayer].size(), iLayer, mROFramesClusters[iLayer].size() * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mROFramesClustersDevice[iLayer]), mROFramesClusters[iLayer].size() * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mROFramesClustersDevice[iLayer], mROFramesClusters[iLayer].data(), mROFramesClusters[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + allocMemAsync(reinterpret_cast(&mROFrameClustersDeviceArray), nLayers * sizeof(int*), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mROFrameClustersDeviceArray, mROFramesClustersDevice.data(), nLayers * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); + } +} + template void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) { @@ -146,19 +218,76 @@ void TimeFrameGPU::loadTrackingFrameInfoDevice(const int iteration) STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } +template +void TimeFrameGPU::loadMultiplicityCutMask(const int iteration) +{ + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading multiplicity cut mask"); + LOGP(debug, "gpu-transfer: loading multiplicity cut mask with {} elements, for {} MB.", mMultiplicityCutMask.size(), mMultiplicityCutMask.size() * sizeof(bool) / MB); + allocMemAsync(reinterpret_cast(&mMultMaskDevice), mMultiplicityCutMask.size() * sizeof(uint8_t), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mMultMaskDevice, mMultiplicityCutMask.data(), mMultiplicityCutMask.size() * sizeof(uint8_t), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); + } +} + +template +void TimeFrameGPU::loadVertices(const int iteration) +{ + if (!iteration) { + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading seeding vertices"); + LOGP(debug, "gpu-transfer: loading {} ROframes vertices, for {} MB.", mROFramesPV.size(), mROFramesPV.size() * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mROFramesPVDevice), mROFramesPV.size() * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mROFramesPVDevice, mROFramesPV.data(), mROFramesPV.size() * sizeof(int), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + LOGP(debug, "gpu-transfer: loading {} seeding vertices, for {} MB.", mPrimaryVertices.size(), mPrimaryVertices.size() * sizeof(Vertex) / MB); + allocMemAsync(reinterpret_cast(&mPrimaryVerticesDevice), mPrimaryVertices.size() * sizeof(Vertex), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mPrimaryVerticesDevice, mPrimaryVertices.data(), mPrimaryVertices.size() * sizeof(Vertex), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); + } +} + +template +void TimeFrameGPU::createTrackletsLUTDevice(const int iteration) +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating tracklets LUTs"); + for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { + if (!iteration) { + LOGP(debug, "gpu-transfer: creating tracklets LUT for {} elements on layer {}, for {} MB.", mClusters[iLayer].size() + 1, iLayer, (mClusters[iLayer].size() + 1) * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mTrackletsLUTDevice[iLayer]), (mClusters[iLayer].size() + 1) * sizeof(int), nullptr, getExtAllocator()); + } + checkGPUError(cudaMemsetAsync(mTrackletsLUTDevice[iLayer], 0, (mClusters[iLayer].size() + 1) * sizeof(int), mGpuStreams[0].get())); + } + if (!iteration) { + allocMemAsync(reinterpret_cast(&mTrackletsLUTDeviceArray), (nLayers - 1) * sizeof(int*), nullptr, getExtAllocator()); + checkGPUError(cudaMemcpyAsync(mTrackletsLUTDeviceArray, mTrackletsLUTDevice.data(), mTrackletsLUTDevice.size() * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + } + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + +template +void TimeFrameGPU::createTrackletsBuffers() +{ + START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating cells buffers"); + for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { + mNTracklets[iLayer] = 0; + checkGPUError(cudaMemcpyAsync(&mNTracklets[iLayer], mTrackletsLUTDevice[iLayer] + mClusters[iLayer].size(), sizeof(int), cudaMemcpyDeviceToHost)); + LOGP(debug, "gpu-transfer: creating tracklets buffer for {} elements on layer {}, for {} MB.", mNTracklets[iLayer], iLayer, mNTracklets[iLayer] * sizeof(Tracklet) / MB); + allocMemAsync(reinterpret_cast(&mTrackletsDevice[iLayer]), mNTracklets[iLayer] * sizeof(Tracklet), nullptr, getExtAllocator()); + } + allocMemAsync(reinterpret_cast(&mTrackletsDeviceArray), (nLayers - 1) * sizeof(Tracklet*), nullptr, getExtAllocator()); + checkGPUError(cudaHostRegister(mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsDeviceArray, mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); + STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); +} + template void TimeFrameGPU::loadTrackletsDevice() { START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading tracklets"); for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { LOGP(debug, "gpu-transfer: loading {} tracklets on layer {}, for {} MB.", mTracklets[iLayer].size(), iLayer, mTracklets[iLayer].size() * sizeof(Tracklet) / MB); - allocMemAsync(reinterpret_cast(&mTrackletsDevice[iLayer]), mTracklets[iLayer].size() * sizeof(Tracklet), nullptr, getExtAllocator()); checkGPUError(cudaHostRegister(mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaHostRegisterPortable)); checkGPUError(cudaMemcpyAsync(mTrackletsDevice[iLayer], mTracklets[iLayer].data(), mTracklets[iLayer].size() * sizeof(Tracklet), cudaMemcpyHostToDevice, mGpuStreams[0].get())); } - allocMemAsync(reinterpret_cast(&mTrackletsDeviceArray), (nLayers - 1) * sizeof(Tracklet*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackletsDeviceArray, mTrackletsDevice.data(), (nLayers - 1) * sizeof(Tracklet*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } @@ -167,14 +296,12 @@ void TimeFrameGPU::loadTrackletsLUTDevice() { START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "loading tracklets"); for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { - LOGP(debug, "gpu-transfer: loading tracklets LUT for {} elements on layer {}, for {} MB", mTrackletsLookupTable[iLayer].size(), iLayer, mTrackletsLookupTable[iLayer].size() * sizeof(int) / MB); - allocMemAsync(reinterpret_cast(&mTrackletsLUTDevice[iLayer]), mTrackletsLookupTable[iLayer].size() * sizeof(int), nullptr, getExtAllocator()); + LOGP(debug, "gpu-transfer: loading tracklets LUT for {} elements on layer {}, for {} MB", mTrackletsLookupTable[iLayer].size(), iLayer + 1, mTrackletsLookupTable[iLayer].size() * sizeof(int) / MB); checkGPUError(cudaHostRegister(mTrackletsLookupTable[iLayer].data(), mTrackletsLookupTable[iLayer].size() * sizeof(int), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackletsLUTDevice[iLayer], mTrackletsLookupTable[iLayer].data(), mTrackletsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); + checkGPUError(cudaMemcpyAsync(mTrackletsLUTDevice[iLayer + 1], mTrackletsLookupTable[iLayer].data(), mTrackletsLookupTable[iLayer].size() * sizeof(int), cudaMemcpyHostToDevice)); } - allocMemAsync(reinterpret_cast(&mTrackletsLUTDeviceArray), (nLayers - 2) * sizeof(int*), nullptr, getExtAllocator()); - checkGPUError(cudaHostRegister(mTrackletsLUTDevice.data(), (nLayers - 2) * sizeof(int*), cudaHostRegisterPortable)); - checkGPUError(cudaMemcpyAsync(mTrackletsLUTDeviceArray, mTrackletsLUTDevice.data(), (nLayers - 2) * sizeof(int*), cudaMemcpyHostToDevice)); + checkGPUError(cudaHostRegister(mTrackletsLUTDevice.data(), (nLayers - 1) * sizeof(int*), cudaHostRegisterPortable)); + checkGPUError(cudaMemcpyAsync(mTrackletsLUTDeviceArray, mTrackletsLUTDevice.data(), (nLayers - 1) * sizeof(int*), cudaMemcpyHostToDevice)); STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } @@ -214,9 +341,9 @@ void TimeFrameGPU::createCellsLUTDevice() { START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating cells LUTs"); for (auto iLayer{0}; iLayer < nLayers - 2; ++iLayer) { - LOGP(debug, "gpu-transfer: creating cell LUT for {} elements on layer {}, for {} MB.", mTracklets[iLayer].size() + 1, iLayer, (mTracklets[iLayer].size() + 1) * sizeof(int) / MB); - allocMemAsync(reinterpret_cast(&mCellsLUTDevice[iLayer]), (mTracklets[iLayer].size() + 1) * sizeof(int), nullptr, getExtAllocator()); - checkGPUError(cudaMemsetAsync(mCellsLUTDevice[iLayer], 0, (mTracklets[iLayer].size() + 1) * sizeof(int), mGpuStreams[0].get())); + LOGP(debug, "gpu-transfer: creating cell LUT for {} elements on layer {}, for {} MB.", mNTracklets[iLayer] + 1, iLayer, (mNTracklets[iLayer] + 1) * sizeof(int) / MB); + allocMemAsync(reinterpret_cast(&mCellsLUTDevice[iLayer]), (mNTracklets[iLayer] + 1) * sizeof(int), nullptr, getExtAllocator()); + checkGPUError(cudaMemsetAsync(mCellsLUTDevice[iLayer], 0, (mNTracklets[iLayer] + 1) * sizeof(int), mGpuStreams[0].get())); } allocMemAsync(reinterpret_cast(&mCellsLUTDeviceArray), (nLayers - 2) * sizeof(int*), nullptr, getExtAllocator()); checkGPUError(cudaMemcpyAsync(mCellsLUTDeviceArray, mCellsLUTDevice.data(), mCellsLUTDevice.size() * sizeof(int*), cudaMemcpyHostToDevice, mGpuStreams[0].get())); @@ -228,7 +355,7 @@ void TimeFrameGPU::createCellsBuffers(const int layer) { START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "creating cells buffers"); mNCells[layer] = 0; - checkGPUError(cudaMemcpyAsync(&mNCells[layer], mCellsLUTDevice[layer] + mTracklets[layer].size(), sizeof(int), cudaMemcpyDeviceToHost)); + checkGPUError(cudaMemcpyAsync(&mNCells[layer], mCellsLUTDevice[layer] + mNTracklets[layer], sizeof(int), cudaMemcpyDeviceToHost)); LOGP(debug, "gpu-transfer: creating cell buffer for {} elements on layer {}, for {} MB.", mNCells[layer], layer, mNCells[layer] * sizeof(CellSeed) / MB); allocMemAsync(reinterpret_cast(&mCellsDevice[layer]), mNCells[layer] * sizeof(CellSeed), nullptr, getExtAllocator()); @@ -319,9 +446,9 @@ void TimeFrameGPU::downloadCellsLUTDevice() { START_GPU_STREAM_TIMER(mGpuStreams[0].get(), "downloading cell luts"); for (auto iLayer{0}; iLayer < nLayers - 3; ++iLayer) { - LOGP(debug, "gpu-transfer: downloading cells lut on layer {} for {} elements", iLayer, (mTracklets[iLayer + 1].size() + 1)); - mCellsLookupTable[iLayer].resize(mTracklets[iLayer + 1].size() + 1); - checkGPUError(cudaMemcpyAsync(mCellsLookupTable[iLayer].data(), mCellsLUTDevice[iLayer + 1], (mTracklets[iLayer + 1].size() + 1) * sizeof(int), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); + LOGP(debug, "gpu-transfer: downloading cells lut on layer {} for {} elements", iLayer, (mNTracklets[iLayer + 1] + 1)); + mCellsLookupTable[iLayer].resize(mNTracklets[iLayer + 1] + 1); + checkGPUError(cudaMemcpyAsync(mCellsLookupTable[iLayer].data(), mCellsLUTDevice[iLayer + 1], (mNTracklets[iLayer + 1] + 1) * sizeof(int), cudaMemcpyDeviceToHost, mGpuStreams[0].get())); } STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } @@ -362,13 +489,6 @@ void TimeFrameGPU::unregisterRest() LOGP(debug, "unregistering rest of the host memory..."); checkGPUError(cudaHostUnregister(mCellsDevice.data())); checkGPUError(cudaHostUnregister(mTrackletsDevice.data())); - checkGPUError(cudaHostUnregister(mTrackletsLUTDevice.data())); - for (auto iLayer{0}; iLayer < nLayers - 1; ++iLayer) { - if (iLayer < nLayers - 2) { - checkGPUError(cudaHostUnregister(mTrackletsLookupTable[iLayer].data())); - } - checkGPUError(cudaHostUnregister(mTracklets[iLayer].data())); - } STOP_GPU_STREAM_TIMER(mGpuStreams[0].get()); } diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx index 3c6a307fc4ff6..ae86507e46325 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackerTraitsGPU.cxx @@ -31,241 +31,18 @@ void TrackerTraitsGPU::initialiseTimeFrame(const int iteration) mTimeFrameGPU->initialise(iteration, mTrkParams[iteration], nLayers); mTimeFrameGPU->loadClustersDevice(iteration); mTimeFrameGPU->loadUnsortedClustersDevice(iteration); + mTimeFrameGPU->loadClustersIndexTables(iteration); mTimeFrameGPU->loadTrackingFrameInfoDevice(iteration); + mTimeFrameGPU->loadMultiplicityCutMask(iteration); + mTimeFrameGPU->loadVertices(iteration); + mTimeFrameGPU->loadROframeClustersDevice(iteration); + mTimeFrameGPU->createUsedClustersDevice(iteration); + mTimeFrameGPU->loadIndexTableUtils(iteration); } template void TrackerTraitsGPU::computeLayerTracklets(const int iteration, int, int) { - // if (!mTimeFrameGPU->getClusters().size()) { - // return; - // } - // const Vertex diamondVert({mTrkParams[iteration].Diamond[0], mTrkParams[iteration].Diamond[1], mTrkParams[iteration].Diamond[2]}, {25.e-6f, 0.f, 0.f, 25.e-6f, 0.f, 36.f}, 1, 1.f); - // gsl::span diamondSpan(&diamondVert, 1); - // std::vector threads(mTimeFrameGPU->getNChunks()); - - // for (int chunkId{0}; chunkId < mTimeFrameGPU->getNChunks(); ++chunkId) { - // int maxTracklets{static_cast(mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->clustersPerROfCapacity) * - // static_cast(mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->maxTrackletsPerCluster)}; - // int maxRofPerChunk{mTimeFrameGPU->mNrof / (int)mTimeFrameGPU->getNChunks()}; - // // Define workload - // auto doTrackReconstruction = [&, chunkId, maxRofPerChunk, iteration]() -> void { - // auto offset = chunkId * maxRofPerChunk; - // auto maxROF = offset + maxRofPerChunk; - // while (offset < maxROF) { - // auto rofs = mTimeFrameGPU->loadChunkData(chunkId, offset, maxROF); - // //////////////////// - // /// Tracklet finding - - // for (int iLayer{0}; iLayer < nLayers - 1; ++iLayer) { - // auto nclus = mTimeFrameGPU->getTotalClustersPerROFrange(offset, rofs, iLayer); - // const float meanDeltaR{mTrkParams[iteration].LayerRadii[iLayer + 1] - mTrkParams[iteration].LayerRadii[iLayer]}; - // gpu::computeLayerTrackletsKernelMultipleRof<<getStream(chunkId).get()>>>( - // iLayer, // const int layerIndex, - // iteration, // const int iteration, - // offset, // const unsigned int startRofId, - // rofs, // const unsigned int rofSize, - // 0, // const unsigned int deltaRof, - // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(iLayer), // const Cluster* clustersCurrentLayer, - // mTimeFrameGPU->getChunk(chunkId).getDeviceClusters(iLayer + 1), // const Cluster* clustersNextLayer, - // mTimeFrameGPU->getDeviceROframesClusters(iLayer), // const int* roFrameClustersCurrentLayer, // Number of clusters on layer 0 per ROF - // mTimeFrameGPU->getDeviceROframesClusters(iLayer + 1), // const int* roFrameClustersNextLayer, // Number of clusters on layer 1 per ROF - // mTimeFrameGPU->getChunk(chunkId).getDeviceIndexTables(iLayer + 1), // const int* indexTableNextLayer, - // mTimeFrameGPU->getDeviceUsedClusters(iLayer), // const int* usedClustersCurrentLayer, - // mTimeFrameGPU->getDeviceUsedClusters(iLayer + 1), // const int* usedClustersNextLayer, - // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer), // Tracklet* tracklets, // output data - // mTimeFrameGPU->getDeviceVertices(), // const Vertex* vertices, - // mTimeFrameGPU->getDeviceROframesPV(), // const int* pvROFrame, - // mTimeFrameGPU->getPhiCut(iLayer), // const float phiCut, - // mTimeFrameGPU->getMinR(iLayer + 1), // const float minR, - // mTimeFrameGPU->getMaxR(iLayer + 1), // const float maxR, - // meanDeltaR, // const float meanDeltaR, - // mTimeFrameGPU->getPositionResolution(iLayer), // const float positionResolution, - // mTimeFrameGPU->getMSangle(iLayer), // const float mSAngle, - // mTimeFrameGPU->getDeviceTrackingParameters(), // const StaticTrackingParameters* trkPars, - // mTimeFrameGPU->getDeviceIndexTableUtils(), // const IndexTableUtils* utils - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->clustersPerROfCapacity, // const int clustersPerROfCapacity, - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->maxTrackletsPerCluster); // const int maxTrackletsPerCluster - - // // Remove empty tracklets due to striding. - // auto nulltracklet = o2::its::Tracklet{}; - // auto thrustTrackletsBegin = thrust::device_ptr(mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer)); - // auto thrustTrackletsEnd = thrust::device_ptr(mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer) + (int)rofs * maxTracklets); - // auto thrustTrackletsAfterEraseEnd = thrust::remove(THRUST_NAMESPACE::par.on(mTimeFrameGPU->getStream(chunkId).get()), - // thrustTrackletsBegin, - // thrustTrackletsEnd, - // nulltracklet); - // // Sort tracklets by first cluster index. - // thrust::sort(THRUST_NAMESPACE::par.on(mTimeFrameGPU->getStream(chunkId).get()), - // thrustTrackletsBegin, - // thrustTrackletsAfterEraseEnd, - // gpu::trackletSortIndexFunctor()); - - // // Remove duplicates. - // auto thrustTrackletsAfterUniqueEnd = thrust::unique(THRUST_NAMESPACE::par.on(mTimeFrameGPU->getStream(chunkId).get()), thrustTrackletsBegin, thrustTrackletsAfterEraseEnd); - - // discardResult(cudaStreamSynchronize(mTimeFrameGPU->getStream(chunkId).get())); - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer] = thrustTrackletsAfterUniqueEnd - thrustTrackletsBegin; - // // Compute tracklet lookup table. - // gpu::compileTrackletsLookupTableKernel<<getStream(chunkId).get()>>>(mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceTrackletsLookupTables(iLayer), - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer]); - // discardResult(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), // d_temp_storage - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, // temp_storage_bytes - // mTimeFrameGPU->getChunk(chunkId).getDeviceTrackletsLookupTables(iLayer), // d_in - // mTimeFrameGPU->getChunk(chunkId).getDeviceTrackletsLookupTables(iLayer), // d_out - // nclus, // num_items - // mTimeFrameGPU->getStream(chunkId).get())); - - // // Create tracklets labels, at the moment on the host - // if (mTimeFrameGPU->hasMCinformation()) { - // std::vector tracklets(mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer]); - // checkGPUError(cudaHostRegister(tracklets.data(), tracklets.size() * sizeof(o2::its::Tracklet), cudaHostRegisterDefault)); - // checkGPUError(cudaMemcpyAsync(tracklets.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer), tracklets.size() * sizeof(o2::its::Tracklet), cudaMemcpyDeviceToHost, mTimeFrameGPU->getStream(chunkId).get())); - // for (auto& trk : tracklets) { - // MCCompLabel label; - // int currentId{mTimeFrameGPU->mClusters[iLayer][trk.firstClusterIndex].clusterId}; // This is not yet offsetted to the index of the first cluster of the chunk - // int nextId{mTimeFrameGPU->mClusters[iLayer + 1][trk.secondClusterIndex].clusterId}; // This is not yet offsetted to the index of the first cluster of the chunk - // for (auto& lab1 : mTimeFrameGPU->getClusterLabels(iLayer, currentId)) { - // for (auto& lab2 : mTimeFrameGPU->getClusterLabels(iLayer + 1, nextId)) { - // if (lab1 == lab2 && lab1.isValid()) { - // label = lab1; - // break; - // } - // } - // if (label.isValid()) { - // break; - // } - // } - // // TODO: implment label merging. - // // mTimeFrameGPU->getTrackletsLabel(iLayer).emplace_back(label); - // } - // checkGPUError(cudaHostUnregister(tracklets.data())); - // } - // } - - // //////////////// - // /// Cell finding - // for (int iLayer{0}; iLayer < nLayers - 2; ++iLayer) { - // // Compute layer cells. - // gpu::computeLayerCellsKernel<<<10, 1024, 0, mTimeFrameGPU->getStream(chunkId).get()>>>( - // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer + 1), - // mTimeFrameGPU->getChunk(chunkId).getDeviceTrackletsLookupTables(iLayer + 1), - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer], - // nullptr, - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer), - // mTimeFrameGPU->getDeviceTrackingParameters()); - - // // Compute number of found Cells - // checkGPUError(cub::DeviceReduce::Sum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), // d_temp_storage - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, // temp_storage_bytes - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer), // d_in - // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundCells() + iLayer, // d_out - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer], // num_items - // mTimeFrameGPU->getStream(chunkId).get())); - // // Compute LUT - // discardResult(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), // d_temp_storage - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, // temp_storage_bytes - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer), // d_in - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer), // d_out - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer], // num_items - // mTimeFrameGPU->getStream(chunkId).get())); - - // gpu::computeLayerCellsKernel<<<10, 1024, 0, mTimeFrameGPU->getStream(chunkId).get()>>>( - // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceTracklets(iLayer + 1), - // mTimeFrameGPU->getChunk(chunkId).getDeviceTrackletsLookupTables(iLayer + 1), - // mTimeFrameGPU->getHostNTracklets(chunkId)[iLayer], - // mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer), - // mTimeFrameGPU->getDeviceTrackingParameters()); - // } - // checkGPUError(cudaMemcpyAsync(mTimeFrameGPU->getHostNCells(chunkId).data(), - // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundCells(), - // (nLayers - 2) * sizeof(int), - // cudaMemcpyDeviceToHost, - // mTimeFrameGPU->getStream(chunkId).get())); - - // // Create cells labels - // // TODO: make it work after fixing the tracklets labels - // if (mTimeFrameGPU->hasMCinformation()) { - // for (int iLayer{0}; iLayer < nLayers - 2; ++iLayer) { - // std::vector cells(mTimeFrameGPU->getHostNCells(chunkId)[iLayer]); - // // Async with not registered memory? - // checkGPUError(cudaMemcpyAsync(cells.data(), mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer), mTimeFrameGPU->getHostNCells(chunkId)[iLayer] * sizeof(o2::its::Cell), cudaMemcpyDeviceToHost)); - // for (auto& cell : cells) { - // MCCompLabel currentLab{mTimeFrameGPU->getTrackletsLabel(iLayer)[cell.getFirstTrackletIndex()]}; - // MCCompLabel nextLab{mTimeFrameGPU->getTrackletsLabel(iLayer + 1)[cell.getSecondTrackletIndex()]}; - // mTimeFrameGPU->getCellsLabel(iLayer).emplace_back(currentLab == nextLab ? currentLab : MCCompLabel()); - // } - // } - // } - - // ///////////////////// - // /// Neighbour finding - // for (int iLayer{0}; iLayer < nLayers - 3; ++iLayer) { - // gpu::computeLayerCellNeighboursKernel<<<10, 1024, 0, mTimeFrameGPU->getStream(chunkId).get()>>>( - // mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer + 1), - // iLayer, - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer + 1), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), - // nullptr, - // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundCells(), - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->maxNeighboursSize); - - // // Compute Cell Neighbours LUT - // checkGPUError(cub::DeviceScan::ExclusiveSum(mTimeFrameGPU->getChunk(chunkId).getDeviceCUBTmpBuffer(), // d_temp_storage - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->tmpCUBBufferSize, // temp_storage_bytes - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), // d_in - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), // d_out - // mTimeFrameGPU->getHostNCells(chunkId)[iLayer + 1], // num_items - // mTimeFrameGPU->getStream(chunkId).get())); - - // gpu::computeLayerCellNeighboursKernel<<<10, 1024, 0, mTimeFrameGPU->getStream(chunkId).get()>>>( - // mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCells(iLayer + 1), - // iLayer, - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellsLookupTables(iLayer + 1), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeigboursLookupTables(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeighbours(iLayer), - // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundCells(), - // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->maxNeighboursSize); - - // // if (!chunkId) { - // // gpu::printBufferLayerOnThread<<<1, 1, 0, mTimeFrameGPU->getStream(chunkId).get()>>>(iLayer, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceCellNeighbours(iLayer), - // // mTimeFrameGPU->getChunk(chunkId).getTimeFrameGPUParameters()->maxNeighboursSize * rofs); - // // } - // } - // // Download cells into vectors - - // for (int iLevel{nLayers - 2}; iLevel >= mTrkParams[iteration].CellMinimumLevel(); --iLevel) { - // const int minimumLevel{iLevel - 1}; - // for (int iLayer{nLayers - 3}; iLayer >= minimumLevel; --iLayer) { - // // gpu::computeLayerRoadsKernel<<<1, 1, 0, mTimeFrameGPU->getStream(chunkId).get()>>>(iLevel, // const int level, - // // iLayer, // const int layerIndex, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceArrayCells(), // const CellSeed** cells, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceNFoundCells(), // const int* nCells, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceArrayNeighboursCell(), // const int** neighbours, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceArrayNeighboursCellLUT(), // const int** neighboursLUT, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceRoads(), // Road* roads, - // // mTimeFrameGPU->getChunk(chunkId).getDeviceRoadsLookupTables(iLayer)); // int* roadsLookupTable - // } - // } - - // // End of tracking for this chunk - // offset += rofs; - // } - // }; - // threads[chunkId] = std::thread(doTrackReconstruction); - // } - // for (auto& thread : threads) { - // thread.join(); - // } - - // mTimeFrameGPU->wipe(nLayers); } template @@ -299,7 +76,7 @@ int TrackerTraitsGPU::getTFNumberOfClusters() const template int TrackerTraitsGPU::getTFNumberOfTracklets() const { - return mTimeFrameGPU->getNumberOfTracklets(); + return std::accumulate(mTimeFrameGPU->getNTracklets().begin(), mTimeFrameGPU->getNTracklets().end(), 0); } template @@ -313,31 +90,94 @@ int TrackerTraitsGPU::getTFNumberOfCells() const template void TrackerTraitsGPU::computeTrackletsHybrid(const int iteration, int iROFslice, int iVertex) { - TrackerTraits::computeLayerTracklets(iteration, iROFslice, iVertex); + auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); + // TrackerTraits::computeLayerTracklets(iteration, iROFslice, iVertex); + mTimeFrameGPU->createTrackletsLUTDevice(iteration); + + const Vertex diamondVert({mTrkParams[iteration].Diamond[0], mTrkParams[iteration].Diamond[1], mTrkParams[iteration].Diamond[2]}, {25.e-6f, 0.f, 0.f, 25.e-6f, 0.f, 36.f}, 1, 1.f); + gsl::span diamondSpan(&diamondVert, 1); + int startROF{mTrkParams[iteration].nROFsPerIterations > 0 ? iROFslice * mTrkParams[iteration].nROFsPerIterations : 0}; + int endROF{mTrkParams[iteration].nROFsPerIterations > 0 ? (iROFslice + 1) * mTrkParams[iteration].nROFsPerIterations + mTrkParams[iteration].DeltaROF : mTimeFrameGPU->getNrof()}; + + countTrackletsInROFsHandler(mTimeFrameGPU->getDeviceIndexTableUtils(), + mTimeFrameGPU->getDeviceMultCutMask(), + startROF, + endROF, + mTimeFrameGPU->getNrof(), + mTrkParams[iteration].DeltaROF, + iVertex, + mTimeFrameGPU->getDeviceVertices(), + mTimeFrameGPU->getDeviceROFramesPV(), + mTimeFrameGPU->getPrimaryVerticesNum(), + mTimeFrameGPU->getDeviceArrayClusters(), + mTimeFrameGPU->getClusterSizes(), + mTimeFrameGPU->getDeviceROframeClusters(), + mTimeFrameGPU->getDeviceArrayUsedClusters(), + mTimeFrameGPU->getDeviceArrayClustersIndexTables(), + mTimeFrameGPU->getDeviceArrayTrackletsLUT(), + mTimeFrameGPU->getDeviceTrackletsLUTs(), // Required for the exclusive sums + iteration, + mTrkParams[iteration].NSigmaCut, + mTimeFrameGPU->getPhiCuts(), + mTrkParams[iteration].PVres, + mTimeFrameGPU->getMinRs(), + mTimeFrameGPU->getMaxRs(), + mTimeFrameGPU->getPositionResolutions(), + mTrkParams[iteration].LayerRadii, + mTimeFrameGPU->getMSangles(), + conf.nBlocks, + conf.nThreads); + mTimeFrameGPU->createTrackletsBuffers(); + computeTrackletsInROFsHandler(mTimeFrameGPU->getDeviceIndexTableUtils(), + mTimeFrameGPU->getDeviceMultCutMask(), + startROF, + endROF, + mTimeFrameGPU->getNrof(), + mTrkParams[iteration].DeltaROF, + iVertex, + mTimeFrameGPU->getDeviceVertices(), + mTimeFrameGPU->getDeviceROFramesPV(), + mTimeFrameGPU->getPrimaryVerticesNum(), + mTimeFrameGPU->getDeviceArrayClusters(), + mTimeFrameGPU->getClusterSizes(), + mTimeFrameGPU->getDeviceROframeClusters(), + mTimeFrameGPU->getDeviceArrayUsedClusters(), + mTimeFrameGPU->getDeviceArrayClustersIndexTables(), + mTimeFrameGPU->getDeviceArrayTracklets(), + mTimeFrameGPU->getDeviceTracklet(), + mTimeFrameGPU->getNTracklets(), + mTimeFrameGPU->getDeviceArrayTrackletsLUT(), + mTimeFrameGPU->getDeviceTrackletsLUTs(), + iteration, + mTrkParams[iteration].NSigmaCut, + mTimeFrameGPU->getPhiCuts(), + mTrkParams[iteration].PVres, + mTimeFrameGPU->getMinRs(), + mTimeFrameGPU->getMaxRs(), + mTimeFrameGPU->getPositionResolutions(), + mTrkParams[iteration].LayerRadii, + mTimeFrameGPU->getMSangles(), + conf.nBlocks, + conf.nThreads); } template void TrackerTraitsGPU::computeCellsHybrid(const int iteration) { - mTimeFrameGPU->loadTrackletsDevice(); - mTimeFrameGPU->loadTrackletsLUTDevice(); mTimeFrameGPU->createCellsLUTDevice(); auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); - // #pragma omp parallel for num_threads(nLayers) for (int iLayer = 0; iLayer < mTrkParams[iteration].CellsPerRoad(); ++iLayer) { - if (mTimeFrameGPU->getTracklets()[iLayer + 1].empty() || - mTimeFrameGPU->getTracklets()[iLayer].empty()) { + if (!mTimeFrameGPU->getNTracklets()[iLayer + 1] || !mTimeFrameGPU->getNTracklets()[iLayer]) { continue; } - - const int currentLayerTrackletsNum{static_cast(mTimeFrameGPU->getTracklets()[iLayer].size())}; + const int currentLayerTrackletsNum{static_cast(mTimeFrameGPU->getNTracklets()[iLayer])}; countCellsHandler(mTimeFrameGPU->getDeviceArrayClusters(), mTimeFrameGPU->getDeviceArrayUnsortedClusters(), mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), mTimeFrameGPU->getDeviceArrayTracklets(), mTimeFrameGPU->getDeviceArrayTrackletsLUT(), - mTimeFrameGPU->getTracklets()[iLayer].size(), + mTimeFrameGPU->getNTracklets()[iLayer], iLayer, nullptr, mTimeFrameGPU->getDeviceArrayCellsLUT(), @@ -354,7 +194,7 @@ void TrackerTraitsGPU::computeCellsHybrid(const int iteration) mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(), mTimeFrameGPU->getDeviceArrayTracklets(), mTimeFrameGPU->getDeviceArrayTrackletsLUT(), - mTimeFrameGPU->getTracklets()[iLayer].size(), + mTimeFrameGPU->getNTracklets()[iLayer], iLayer, mTimeFrameGPU->getDeviceCells()[iLayer], mTimeFrameGPU->getDeviceArrayCellsLUT(), @@ -378,7 +218,7 @@ void TrackerTraitsGPU::findCellsNeighboursHybrid(const int iteration) auto& conf = o2::its::ITSGpuTrackingParamConfig::Instance(); std::vector>> cellsNeighboursLayer(mTrkParams[iteration].CellsPerRoad() - 1); for (int iLayer{0}; iLayer < mTrkParams[iteration].CellsPerRoad() - 1; ++iLayer) { - const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getNCellsDevice()[iLayer + 1])}; + const int nextLayerCellsNum{static_cast(mTimeFrameGPU->getNCells()[iLayer + 1])}; mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].clear(); mTimeFrameGPU->getCellsNeighboursLUT()[iLayer].resize(nextLayerCellsNum, 0); @@ -441,7 +281,7 @@ void TrackerTraitsGPU::findRoads(const int iteration) std::vector lastCellId, updatedCellId; std::vector lastCellSeed, updatedCellSeed; - processNeighbours(startLayer, startLevel, mTimeFrame->getCells()[startLayer], lastCellId, updatedCellSeed, updatedCellId); + processNeighbours(startLayer, startLevel, mTimeFrameGPU->getCells()[startLayer], lastCellId, updatedCellSeed, updatedCellId); int level = startLevel; for (int iLayer{startLayer - 1}; iLayer > 0 && level > 2; --iLayer) { @@ -495,8 +335,8 @@ void TrackerTraitsGPU::findRoads(const int iteration) if (track.getClusterIndex(iLayer) == UnusedIndex) { continue; } - nShared += int(mTimeFrame->isClusterUsed(iLayer, track.getClusterIndex(iLayer))); - isFirstShared |= !iLayer && mTimeFrame->isClusterUsed(iLayer, track.getClusterIndex(iLayer)); + nShared += int(mTimeFrameGPU->isClusterUsed(iLayer, track.getClusterIndex(iLayer))); + isFirstShared |= !iLayer && mTimeFrameGPU->isClusterUsed(iLayer, track.getClusterIndex(iLayer)); } if (nShared > mTrkParams[0].ClusterSharing) { @@ -508,8 +348,8 @@ void TrackerTraitsGPU::findRoads(const int iteration) if (track.getClusterIndex(iLayer) == UnusedIndex) { continue; } - mTimeFrame->markUsedCluster(iLayer, track.getClusterIndex(iLayer)); - int currentROF = mTimeFrame->getClusterROF(iLayer, track.getClusterIndex(iLayer)); + mTimeFrameGPU->markUsedCluster(iLayer, track.getClusterIndex(iLayer)); + int currentROF = mTimeFrameGPU->getClusterROF(iLayer, track.getClusterIndex(iLayer)); for (int iR{0}; iR < 3; ++iR) { if (rofs[iR] == INT_MAX) { rofs[iR] = currentROF; @@ -525,9 +365,10 @@ void TrackerTraitsGPU::findRoads(const int iteration) if (rofs[1] != INT_MAX) { track.setNextROFbit(); } - mTimeFrame->getTracks(std::min(rofs[0], rofs[1])).emplace_back(track); + mTimeFrameGPU->getTracks(std::min(rofs[0], rofs[1])).emplace_back(track); } } + mTimeFrameGPU->loadUsedClustersDevice(); if (iteration == mTrkParams.size() - 1) { mTimeFrameGPU->unregisterHostMemory(0); } diff --git a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu index 73dcf3bcb4894..229827611c077 100644 --- a/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu +++ b/Detectors/ITSMFT/ITS/tracking/GPU/cuda/TrackingKernels.cu @@ -32,6 +32,7 @@ #include "ITStracking/IndexTableUtils.h" #include "ITStracking/MathUtils.h" #include "DataFormatsITS/TrackITS.h" +#include "ReconstructionDataFormats/Vertex.h" #include "ITStrackingGPU/TrackerTraitsGPU.h" #include "ITStrackingGPU/TrackingKernels.h" @@ -70,12 +71,39 @@ inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort = } namespace o2::its - { using namespace constants::its2; +using Vertex = o2::dataformats::Vertex>; + +GPUd() float Sq(float v) +{ + return v * v; +} namespace gpu { + +GPUd() const int4 getBinsRect(const Cluster& currentCluster, const int layerIndex, + const o2::its::IndexTableUtils& utils, + const float z1, const float z2, float maxdeltaz, float maxdeltaphi) +{ + const float zRangeMin = o2::gpu::CAMath::Min(z1, z2) - maxdeltaz; + const float phiRangeMin = (maxdeltaphi > constants::math::Pi) ? 0.f : currentCluster.phi - maxdeltaphi; + const float zRangeMax = o2::gpu::CAMath::Max(z1, z2) + maxdeltaz; + const float phiRangeMax = (maxdeltaphi > constants::math::Pi) ? constants::math::TwoPi : currentCluster.phi + maxdeltaphi; + + if (zRangeMax < -LayersZCoordinate()[layerIndex + 1] || + zRangeMin > LayersZCoordinate()[layerIndex + 1] || zRangeMin > zRangeMax) { + + return getEmptyBinsRect(); + } + + return int4{o2::gpu::CAMath::Max(0, utils.getZBinIndex(layerIndex + 1, zRangeMin)), + utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMin)), + o2::gpu::CAMath::Min(ZBins - 1, utils.getZBinIndex(layerIndex + 1, zRangeMax)), + utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMax))}; +} + GPUd() bool fitTrack(TrackITSExt& track, int start, int end, @@ -127,7 +155,7 @@ GPUd() bool fitTrack(TrackITSExt& track, } nCl++; } - return o2::gpu::GPUCommonMath::Abs(track.getQ2Pt()) < maxQoverPt && track.getChi2() < chi2ndfcut * (nCl * 2 - 5); + return o2::gpu::CAMath::Abs(track.getQ2Pt()) < maxQoverPt && track.getChi2() < chi2ndfcut * (nCl * 2 - 5); } GPUd() o2::track::TrackParCov buildTrackSeed(const Cluster& cluster1, @@ -146,7 +174,7 @@ GPUd() o2::track::TrackParCov buildTrackSeed(const Cluster& cluster1, const float y3 = tf3.positionTrackingFrame[0]; const float z3 = tf3.positionTrackingFrame[1]; - const bool zeroField{o2::gpu::GPUCommonMath::Abs(bz) < o2::constants::math::Almost0}; + const bool zeroField{o2::gpu::CAMath::Abs(bz) < o2::constants::math::Almost0}; const float tgp = zeroField ? o2::gpu::CAMath::ATan2(y3 - y1, x3 - x1) : 1.f; const float crv = zeroField ? 1.f : math_utils::computeCurvature(x3, y3, x2, y2, x1, y1); const float snp = zeroField ? tgp / o2::gpu::CAMath::Sqrt(1.f + tgp * tgp) : crv * (x3 - math_utils::computeCurvatureCentreX(x3, y3, x2, y2, x1, y1)); @@ -164,6 +192,17 @@ GPUd() o2::track::TrackParCov buildTrackSeed(const Cluster& cluster1, 0.f, 0.f, 0.f, 0.f, sg2q2pt}); } +// auto sort_tracklets = [] GPUhdni()(const Tracklet& a, const Tracklet& b) { return a.firstClusterIndex < b.firstClusterIndex || (a.firstClusterIndex == b.firstClusterIndex && a.secondClusterIndex < b.secondClusterIndex); }; +// auto equal_tracklets = [] GPUhdni()(const Tracklet& a, const Tracklet& b) { return a.firstClusterIndex == b.firstClusterIndex && a.secondClusterIndex == b.secondClusterIndex; }; + +struct sort_tracklets { + GPUhd() bool operator()(const Tracklet& a, const Tracklet& b) { return a.firstClusterIndex < b.firstClusterIndex || (a.firstClusterIndex == b.firstClusterIndex && a.secondClusterIndex < b.secondClusterIndex); } +}; + +struct equal_tracklets { + GPUhd() bool operator()(const Tracklet& a, const Tracklet& b) { return a.firstClusterIndex == b.firstClusterIndex && a.secondClusterIndex == b.secondClusterIndex; } +}; + template struct pair_to_first : public thrust::unary_function, T1> { GPUhd() int operator()(const gpuPair& a) const @@ -196,6 +235,33 @@ struct is_valid_pair { } }; +GPUd() gpuSpan getPrimaryVertices(const int rof, + const int* roframesPV, + const int nROF, + const uint8_t* mask, + const Vertex* vertices) +{ + const int start_pv_id = roframesPV[rof]; + const int stop_rof = rof >= nROF - 1 ? nROF : rof + 1; + size_t delta = mask[rof] ? roframesPV[stop_rof] - start_pv_id : 0; // return empty span if ROF is excluded + return gpuSpan(&vertices[start_pv_id], delta); +}; + +GPUd() gpuSpan getClustersOnLayer(const int rof, + const int totROFs, + const int layer, + const int** roframesClus, + const Cluster** clusters) +{ + if (rof < 0 || rof >= totROFs) { + return gpuSpan(); + } + const int start_clus_id{roframesClus[layer][rof]}; + const int stop_rof = rof >= totROFs - 1 ? totROFs : rof + 1; + const unsigned int delta = roframesClus[layer][stop_rof] - start_clus_id; + return gpuSpan(&(clusters[layer][start_clus_id]), delta); +} + template GPUg() void fitTrackSeedsKernel( CellSeed* trackSeeds, @@ -314,8 +380,8 @@ GPUg() void computeLayerCellsKernel( const Cluster** sortedClusters, const Cluster** unsortedClusters, const TrackingFrameInfo** tfInfo, - const Tracklet** tracklets, - const int** trackletsLUT, + Tracklet** tracklets, + int** trackletsLUT, const int nTrackletsCurrent, const int layer, CellSeed* cells, @@ -331,8 +397,8 @@ GPUg() void computeLayerCellsKernel( for (int iCurrentTrackletIndex = blockIdx.x * blockDim.x + threadIdx.x; iCurrentTrackletIndex < nTrackletsCurrent; iCurrentTrackletIndex += blockDim.x * gridDim.x) { const Tracklet& currentTracklet = tracklets[layer][iCurrentTrackletIndex]; const int nextLayerClusterIndex{currentTracklet.secondClusterIndex}; - const int nextLayerFirstTrackletIndex{trackletsLUT[layer][nextLayerClusterIndex]}; - const int nextLayerLastTrackletIndex{trackletsLUT[layer][nextLayerClusterIndex + 1]}; + const int nextLayerFirstTrackletIndex{trackletsLUT[layer + 1][nextLayerClusterIndex]}; + const int nextLayerLastTrackletIndex{trackletsLUT[layer + 1][nextLayerClusterIndex + 1]}; if (nextLayerFirstTrackletIndex == nextLayerLastTrackletIndex) { continue; } @@ -342,7 +408,7 @@ GPUg() void computeLayerCellsKernel( break; } const Tracklet& nextTracklet = tracklets[layer + 1][iNextTrackletIndex]; - const float deltaTanLambda{o2::gpu::GPUCommonMath::Abs(currentTracklet.tanLambda - nextTracklet.tanLambda)}; + const float deltaTanLambda{o2::gpu::CAMath::Abs(currentTracklet.tanLambda - nextTracklet.tanLambda)}; if (deltaTanLambda / cellDeltaTanLambdaSigma < nSigmaCut) { const int clusId[3]{ @@ -394,35 +460,124 @@ GPUg() void computeLayerCellsKernel( } } -///////////////////////////////////////// -// Debug Kernels -///////////////////////////////////////// -GPUd() const int4 getBinsRect(const Cluster& currentCluster, const int layerIndex, - const o2::its::IndexTableUtils& utils, - const float z1, const float z2, float maxdeltaz, float maxdeltaphi) +template +GPUg() void computeLayerTrackletsMultiROFKernel( + const IndexTableUtils* utils, + const uint8_t* multMask, + const int layerIndex, + const int startROF, + const int endROF, + const int totalROFs, + const int deltaROF, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const int vertexId, + const Cluster** clusters, // Input data rof0 + const int** ROFClusters, // Number of clusters on layers per ROF + const unsigned char** usedClusters, // Used clusters + const int** indexTables, // Input data rof0-delta getNphiBins()}; + const int zBins{utils->getNzBins()}; + for (unsigned int iROF{blockIdx.x}; iROF < endROF - startROF; iROF += gridDim.x) { + const short rof0 = iROF + startROF; + auto primaryVertices = getPrimaryVertices(rof0, rofPV, totalROFs, multMask, vertices); + const auto startVtx{vertexId >= 0 ? vertexId : 0}; + const auto endVtx{vertexId >= 0 ? o2::gpu::CAMath::Min(vertexId + 1, static_cast(primaryVertices.size())) : static_cast(primaryVertices.size())}; + const short minROF = o2::gpu::CAMath::Max(startROF, static_cast(rof0 - deltaROF)); + const short maxROF = o2::gpu::CAMath::Min(endROF - 1, static_cast(rof0 + deltaROF)); + auto clustersCurrentLayer = getClustersOnLayer(rof0, totalROFs, layerIndex, ROFClusters, clusters); + if (clustersCurrentLayer.empty()) { + continue; + } - if (zRangeMax < -LayersZCoordinate()[layerIndex + 1] || - zRangeMin > LayersZCoordinate()[layerIndex + 1] || zRangeMin > zRangeMax) { + for (int currentClusterIndex = threadIdx.x; currentClusterIndex < clustersCurrentLayer.size(); currentClusterIndex += blockDim.x) { + unsigned int storedTracklets{0}; + auto currentCluster{clustersCurrentLayer[currentClusterIndex]}; + const int currentSortedIndex{ROFClusters[layerIndex][rof0] + currentClusterIndex}; + if (usedClusters[layerIndex][currentCluster.clusterId]) { + continue; + } - return getEmptyBinsRect(); - } + const float inverseR0{1.f / currentCluster.radius}; + for (int iV{startVtx}; iV < endVtx; ++iV) { + auto& primaryVertex{primaryVertices[iV]}; + if (primaryVertex.isFlagSet(2) && iteration != 3) { + continue; + } + const float resolution = o2::gpu::CAMath::Sqrt(Sq(resolutionPV) / primaryVertex.getNContributors() + Sq(positionResolution)); + const float tanLambda{(currentCluster.zCoordinate - primaryVertex.getZ()) * inverseR0}; + const float zAtRmin{tanLambda * (minR - currentCluster.radius) + currentCluster.zCoordinate}; + const float zAtRmax{tanLambda * (maxR - currentCluster.radius) + currentCluster.zCoordinate}; + const float sqInverseDeltaZ0{1.f / (Sq(currentCluster.zCoordinate - primaryVertex.getZ()) + 2.e-8f)}; /// protecting from overflows adding the detector resolution + const float sigmaZ{o2::gpu::CAMath::Sqrt(Sq(resolution) * Sq(tanLambda) * ((Sq(inverseR0) + sqInverseDeltaZ0) * Sq(meanDeltaR) + 1.f) + Sq(meanDeltaR * MSAngle))}; + const int4 selectedBinsRect{getBinsRect(currentCluster, layerIndex, *utils, zAtRmin, zAtRmax, sigmaZ * NSigmaCut, phiCut)}; + if (selectedBinsRect.x == 0 && selectedBinsRect.y == 0 && selectedBinsRect.z == 0 && selectedBinsRect.w == 0) { + continue; + } + int phiBinsNum{selectedBinsRect.w - selectedBinsRect.y + 1}; - return int4{o2::gpu::GPUCommonMath::Max(0, utils.getZBinIndex(layerIndex + 1, zRangeMin)), - utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMin)), - o2::gpu::GPUCommonMath::Min(ZBins - 1, utils.getZBinIndex(layerIndex + 1, zRangeMax)), - utils.getPhiBinIndex(math_utils::getNormalizedPhi(phiRangeMax))}; -} + if (phiBinsNum < 0) { + phiBinsNum += phiBins; + } -GPUhd() float Sq(float q) -{ - return q * q; + const int tableSize{phiBins * zBins + 1}; + for (short rof1{minROF}; rof1 <= maxROF; ++rof1) { + auto clustersNextLayer = getClustersOnLayer(rof1, totalROFs, layerIndex + 1, ROFClusters, clusters); + if (clustersNextLayer.empty()) { + continue; + } + for (int iPhiCount{0}; iPhiCount < phiBinsNum; iPhiCount++) { + int iPhiBin = (selectedBinsRect.y + iPhiCount) % phiBins; + const int firstBinIndex{utils->getBinIndex(selectedBinsRect.x, iPhiBin)}; + const int maxBinIndex{firstBinIndex + selectedBinsRect.z - selectedBinsRect.x + 1}; + const int firstRowClusterIndex = indexTables[layerIndex + 1][(rof1 - startROF) * tableSize + firstBinIndex]; + const int maxRowClusterIndex = indexTables[layerIndex + 1][(rof1 - startROF) * tableSize + maxBinIndex]; + for (int nextClusterIndex{firstRowClusterIndex}; nextClusterIndex < maxRowClusterIndex; ++nextClusterIndex) { + if (nextClusterIndex >= clustersNextLayer.size()) { + break; + } + const Cluster& nextCluster{clustersNextLayer[nextClusterIndex]}; + if (usedClusters[layerIndex + 1][nextCluster.clusterId]) { + continue; + } + const float deltaPhi{o2::gpu::CAMath::Abs(currentCluster.phi - nextCluster.phi)}; + const float deltaZ{o2::gpu::CAMath::Abs(tanLambda * (nextCluster.radius - currentCluster.radius) + currentCluster.zCoordinate - nextCluster.zCoordinate)}; + const int nextSortedIndex{ROFClusters[layerIndex + 1][rof1] + nextClusterIndex}; + if (deltaZ / sigmaZ < NSigmaCut && (deltaPhi < phiCut || o2::gpu::CAMath::Abs(deltaPhi - constants::math::TwoPi) < phiCut)) { + if constexpr (initRun) { + trackletsLUT[layerIndex][currentSortedIndex]++; // we need l0 as well for usual exclusive sums. + } else { + const float phi{o2::gpu::CAMath::ATan2(currentCluster.yCoordinate - nextCluster.yCoordinate, currentCluster.xCoordinate - nextCluster.xCoordinate)}; + const float tanL{(currentCluster.zCoordinate - nextCluster.zCoordinate) / (currentCluster.radius - nextCluster.radius)}; + new (tracklets[layerIndex] + trackletsLUT[layerIndex][currentSortedIndex] + storedTracklets) Tracklet{currentSortedIndex, nextSortedIndex, tanL, phi, rof0, rof1}; + } + ++storedTracklets; + } + } + } + } + } + } + } } +///////////////////////////////////////// +// Debug Kernels +///////////////////////////////////////// + template GPUd() void pPointer(T* ptr) { @@ -437,7 +592,6 @@ GPUg() void printPointersKernel(std::tuple args) std::apply(print_all, args); } -// Functors to sort tracklets template struct trackletSortEmptyFunctor : public thrust::binary_function { GPUhd() bool operator()(const T& lhs, const T& rhs) const @@ -454,7 +608,6 @@ struct trackletSortIndexFunctor : public thrust::binary_function { } }; -// Print layer buffer GPUg() void printBufferLayerOnThread(const int layer, const int* v, unsigned int size, const int len = 150, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { @@ -494,52 +647,12 @@ GPUg() void printBufferPointersLayerOnThread(const int layer, void** v, unsigned } } -// Dump vertices GPUg() void printVertices(const Vertex* v, unsigned int size, const unsigned int tId = 0) { if (blockIdx.x * blockDim.x + threadIdx.x == tId) { - printf("vertices: "); + printf("vertices: \n"); for (int i{0}; i < size; ++i) { - printf("x=%f y=%f z=%f\n", v[i].getX(), v[i].getY(), v[i].getZ()); - } - } -} - -// Dump tracklets -GPUg() void printTracklets(const Tracklet* t, - const int offset, - const int startRof, - const int nrof, - const int* roFrameClustersCurrentLayer, // Number of clusters on layer 0 per ROF - const int* roFrameClustersNextLayer, // Number of clusters on layer 1 per ROF - const int maxClustersPerRof = 5e2, - const int maxTrackletsPerCluster = 50, - const unsigned int tId = 0) -{ - if (threadIdx.x == tId) { - auto offsetCurrent{roFrameClustersCurrentLayer[offset]}; - auto offsetNext{roFrameClustersNextLayer[offset]}; - auto offsetChunk{(startRof - offset) * maxClustersPerRof * maxTrackletsPerCluster}; - for (int i{offsetChunk}; i < offsetChunk + nrof * maxClustersPerRof * maxTrackletsPerCluster; ++i) { - if (t[i].firstClusterIndex != -1) { - t[i].dump(offsetCurrent, offsetNext); - } - } - } -} - -GPUg() void printTrackletsNotStrided(const Tracklet* t, - const int offset, - const int* roFrameClustersCurrentLayer, // Number of clusters on layer 0 per ROF - const int* roFrameClustersNextLayer, // Number of clusters on layer 1 per ROF - const int ntracklets, - const unsigned int tId = 0) -{ - if (threadIdx.x == tId) { - auto offsetCurrent{roFrameClustersCurrentLayer[offset]}; - auto offsetNext{roFrameClustersNextLayer[offset]}; - for (int i{0}; i < ntracklets; ++i) { - t[i].dump(offsetCurrent, offsetNext); + printf("\tx=%f y=%f z=%f\n", v[i].getX(), v[i].getY(), v[i].getZ()); } } } @@ -556,102 +669,25 @@ GPUg() void printNeighbours(const gpuPair* neighbours, } } -// Compute the tracklets for a given layer -template -GPUg() void computeLayerTrackletsKernelSingleRof( - const short rof0, - const short maxRofs, - const int layerIndex, - const Cluster* clustersCurrentLayer, // input data rof0 - const Cluster* clustersNextLayer, // input data rof0-delta * trkPars, - const IndexTableUtils* utils, - const unsigned int maxTrackletsPerCluster = 50) +GPUg() void printTrackletsLUTPerROF(const int layerId, + const int** ROFClusters, + int** luts, + const int tId = 0) { - for (int currentClusterIndex = blockIdx.x * blockDim.x + threadIdx.x; currentClusterIndex < currentLayerClustersSize; currentClusterIndex += blockDim.x * gridDim.x) { - unsigned int storedTracklets{0}; - const Cluster& currentCluster{clustersCurrentLayer[currentClusterIndex]}; - const int currentSortedIndex{roFrameClusters[rof0] + currentClusterIndex}; - if (usedClustersLayer[currentSortedIndex]) { - continue; - } - short minRof = (rof0 >= trkPars->DeltaROF) ? rof0 - trkPars->DeltaROF : 0; - short maxRof = (rof0 == static_cast(maxRofs - trkPars->DeltaROF)) ? rof0 : rof0 + trkPars->DeltaROF; - const float inverseR0{1.f / currentCluster.radius}; - for (int iPrimaryVertex{0}; iPrimaryVertex < nVertices; iPrimaryVertex++) { - const auto& primaryVertex{vertices[iPrimaryVertex]}; - if (primaryVertex.getX() == 0.f && primaryVertex.getY() == 0.f && primaryVertex.getZ() == 0.f) { - continue; - } - const float resolution{o2::gpu::GPUCommonMath::Sqrt(Sq(trkPars->PVres) / primaryVertex.getNContributors() + Sq(positionResolution))}; - const float tanLambda{(currentCluster.zCoordinate - primaryVertex.getZ()) * inverseR0}; - const float zAtRmin{tanLambda * (minR - currentCluster.radius) + currentCluster.zCoordinate}; - const float zAtRmax{tanLambda * (maxR - currentCluster.radius) + currentCluster.zCoordinate}; - const float sqInverseDeltaZ0{1.f / (Sq(currentCluster.zCoordinate - primaryVertex.getZ()) + 2.e-8f)}; /// protecting from overflows adding the detector resolution - const float sigmaZ{o2::gpu::CAMath::Sqrt(Sq(resolution) * Sq(tanLambda) * ((Sq(inverseR0) + sqInverseDeltaZ0) * Sq(meanDeltaR) + 1.f) + Sq(meanDeltaR * mSAngle))}; - - const int4 selectedBinsRect{getBinsRect(currentCluster, layerIndex, *utils, zAtRmin, zAtRmax, sigmaZ * trkPars->NSigmaCut, phiCut)}; - if (selectedBinsRect.x == 0 && selectedBinsRect.y == 0 && selectedBinsRect.z == 0 && selectedBinsRect.w == 0) { + if (blockIdx.x * blockDim.x + threadIdx.x == tId) { + for (auto rofId{0}; rofId < 2304; ++rofId) { + int nClus = ROFClusters[layerId][rofId + 1] - ROFClusters[layerId][rofId]; + if (!nClus) { continue; } - int phiBinsNum{selectedBinsRect.w - selectedBinsRect.y + 1}; - if (phiBinsNum < 0) { - phiBinsNum += trkPars->PhiBins; - } - constexpr int tableSize{256 * 128 + 1}; // hardcoded for the time being + printf("rof: %d (%d) ==> ", rofId, nClus); - for (short rof1{minRof}; rof1 <= maxRof; ++rof1) { - if (!(roFrameClustersNext[rof1 + 1] - roFrameClustersNext[rof1])) { // number of clusters on next layer > 0 - continue; - } - for (int iPhiCount{0}; iPhiCount < phiBinsNum; iPhiCount++) { - int iPhiBin = (selectedBinsRect.y + iPhiCount) % trkPars->PhiBins; - const int firstBinIndex{utils->getBinIndex(selectedBinsRect.x, iPhiBin)}; - const int maxBinIndex{firstBinIndex + selectedBinsRect.z - selectedBinsRect.x + 1}; - const int firstRowClusterIndex = indexTable[rof1 * tableSize + firstBinIndex]; - const int maxRowClusterIndex = indexTable[rof1 * tableSize + maxBinIndex]; - for (int iNextCluster{firstRowClusterIndex}; iNextCluster < maxRowClusterIndex; ++iNextCluster) { - if (iNextCluster >= (roFrameClustersNext[rof1 + 1] - roFrameClustersNext[rof1])) { - break; - } - const Cluster& nextCluster{getPtrFromRuler(rof1, clustersNextLayer, roFrameClustersNext)[iNextCluster]}; - if (usedClustersNextLayer[nextCluster.clusterId]) { - continue; - } - const float deltaPhi{o2::gpu::GPUCommonMath::Abs(currentCluster.phi - nextCluster.phi)}; - const float deltaZ{o2::gpu::GPUCommonMath::Abs(tanLambda * (nextCluster.radius - currentCluster.radius) + currentCluster.zCoordinate - nextCluster.zCoordinate)}; - - if (deltaZ / sigmaZ < trkPars->NSigmaCut && (deltaPhi < phiCut || o2::gpu::GPUCommonMath::Abs(deltaPhi - constants::math::TwoPi) < phiCut)) { - trackletsLookUpTable[currentSortedIndex]++; // Race-condition safe - const float phi{o2::gpu::GPUCommonMath::ATan2(currentCluster.yCoordinate - nextCluster.yCoordinate, currentCluster.xCoordinate - nextCluster.xCoordinate)}; - const float tanL{(currentCluster.zCoordinate - nextCluster.zCoordinate) / (currentCluster.radius - nextCluster.radius)}; - const unsigned int stride{currentClusterIndex * maxTrackletsPerCluster}; - new (tracklets + stride + storedTracklets) Tracklet{currentSortedIndex, roFrameClustersNext[rof1] + iNextCluster, tanL, phi, rof0, rof1}; - ++storedTracklets; - } - } - } + for (int iC{0}; iC < nClus; ++iC) { + int nT = luts[layerId][ROFClusters[layerId][rofId] + iC]; + printf("%d\t", nT); } + printf("\n"); } - // if (storedTracklets > maxTrackletsPerCluster) { - // printf("its-gpu-tracklet finder: found more tracklets per clusters (%d) than maximum set (%d), check the configuration!\n", maxTrackletsPerCluster, storedTracklets); - // } } } @@ -661,124 +697,7 @@ GPUg() void compileTrackletsLookupTableKernel(const Tracklet* tracklets, const int nTracklets) { for (int currentTrackletIndex = blockIdx.x * blockDim.x + threadIdx.x; currentTrackletIndex < nTracklets; currentTrackletIndex += blockDim.x * gridDim.x) { - auto& tracklet{tracklets[currentTrackletIndex]}; - if (tracklet.firstClusterIndex >= 0) { - atomicAdd(trackletsLookUpTable + tracklet.firstClusterIndex, 1); - } - } -} - -template -GPUg() void computeLayerTrackletsKernelMultipleRof( - const int layerIndex, - const int iteration, - const unsigned int startRofId, - const unsigned int rofSize, - const int maxRofs, - const Cluster* clustersCurrentLayer, // input data rof0 - const Cluster* clustersNextLayer, // input data rof0-delta * trkPars, - const IndexTableUtils* utils, - const unsigned int maxClustersPerRof = 5e2, - const unsigned int maxTrackletsPerCluster = 50) -{ - const int phiBins{utils->getNphiBins()}; - const int zBins{utils->getNzBins()}; - for (unsigned int iRof{blockIdx.x}; iRof < rofSize; iRof += gridDim.x) { - auto rof0 = iRof + startRofId; - auto nClustersCurrentLayerRof = o2::gpu::GPUCommonMath::Min(roFrameClustersCurrentLayer[rof0 + 1] - roFrameClustersCurrentLayer[rof0], (int)maxClustersPerRof); - // if (nClustersCurrentLayerRof > maxClustersPerRof) { - // printf("its-gpu-tracklet finder: on layer %d found more clusters per ROF (%d) than maximum set (%d), check the configuration!\n", layerIndex, nClustersCurrentLayerRof, maxClustersPerRof); - // } - auto* clustersCurrentLayerRof = clustersCurrentLayer + (roFrameClustersCurrentLayer[rof0] - roFrameClustersCurrentLayer[startRofId]); - auto nVerticesRof0 = nVertices[rof0 + 1] - nVertices[rof0]; - auto trackletsRof0 = tracklets + maxTrackletsPerCluster * maxClustersPerRof * iRof; - for (int currentClusterIndex = threadIdx.x; currentClusterIndex < nClustersCurrentLayerRof; currentClusterIndex += blockDim.x) { - unsigned int storedTracklets{0}; - const Cluster& currentCluster{clustersCurrentLayerRof[currentClusterIndex]}; - const int currentSortedIndex{roFrameClustersCurrentLayer[rof0] + currentClusterIndex}; - const int currentSortedIndexChunk{currentSortedIndex - roFrameClustersCurrentLayer[startRofId]}; - if (usedClustersLayer[currentSortedIndex]) { - continue; - } - - int minRof = (rof0 >= trkPars->DeltaROF) ? rof0 - trkPars->DeltaROF : 0; - int maxRof = (rof0 == maxRofs - trkPars->DeltaROF) ? rof0 : rof0 + trkPars->DeltaROF; // works with delta = {0, 1} - const float inverseR0{1.f / currentCluster.radius}; - - for (int iPrimaryVertex{0}; iPrimaryVertex < nVerticesRof0; iPrimaryVertex++) { - const auto& primaryVertex{vertices[nVertices[rof0] + iPrimaryVertex]}; - const float resolution{o2::gpu::GPUCommonMath::Sqrt(Sq(trkPars->PVres) / primaryVertex.getNContributors() + Sq(positionResolution))}; - const float tanLambda{(currentCluster.zCoordinate - primaryVertex.getZ()) * inverseR0}; - const float zAtRmin{tanLambda * (minR - currentCluster.radius) + currentCluster.zCoordinate}; - const float zAtRmax{tanLambda * (maxR - currentCluster.radius) + currentCluster.zCoordinate}; - const float sqInverseDeltaZ0{1.f / (Sq(currentCluster.zCoordinate - primaryVertex.getZ()) + 2.e-8f)}; /// protecting from overflows adding the detector resolution - const float sigmaZ{o2::gpu::CAMath::Sqrt(Sq(resolution) * Sq(tanLambda) * ((Sq(inverseR0) + sqInverseDeltaZ0) * Sq(meanDeltaR) + 1.f) + Sq(meanDeltaR * mSAngle))}; - - const int4 selectedBinsRect{getBinsRect(currentCluster, layerIndex, *utils, zAtRmin, zAtRmax, sigmaZ * trkPars->NSigmaCut, phiCut)}; - - if (selectedBinsRect.x == 0 && selectedBinsRect.y == 0 && selectedBinsRect.z == 0 && selectedBinsRect.w == 0) { - continue; - } - int phiBinsNum{selectedBinsRect.w - selectedBinsRect.y + 1}; - if (phiBinsNum < 0) { - phiBinsNum += trkPars->PhiBins; - } - const int tableSize{phiBins * zBins + 1}; - for (int rof1{minRof}; rof1 <= maxRof; ++rof1) { - auto nClustersNext{roFrameClustersNextLayer[rof1 + 1] - roFrameClustersNextLayer[rof1]}; - if (!nClustersNext) { // number of clusters on next layer > 0 - continue; - } - for (int iPhiCount{0}; iPhiCount < phiBinsNum; iPhiCount++) { - int iPhiBin = (selectedBinsRect.y + iPhiCount) % trkPars->PhiBins; - const int firstBinIndex{utils->getBinIndex(selectedBinsRect.x, iPhiBin)}; - const int maxBinIndex{firstBinIndex + selectedBinsRect.z - selectedBinsRect.x + 1}; - const int firstRowClusterIndex = indexTablesNext[(rof1 - startRofId) * tableSize + firstBinIndex]; - const int maxRowClusterIndex = indexTablesNext[(rof1 - startRofId) * tableSize + maxBinIndex]; - for (int iNextCluster{firstRowClusterIndex}; iNextCluster < maxRowClusterIndex; ++iNextCluster) { - if (iNextCluster >= nClustersNext) { - break; - } - auto nextClusterIndex{roFrameClustersNextLayer[rof1] - roFrameClustersNextLayer[startRofId] + iNextCluster}; - const Cluster& nextCluster{clustersNextLayer[nextClusterIndex]}; - if (usedClustersNextLayer[nextCluster.clusterId]) { - continue; - } - const float deltaPhi{o2::gpu::GPUCommonMath::Abs(currentCluster.phi - nextCluster.phi)}; - const float deltaZ{o2::gpu::GPUCommonMath::Abs(tanLambda * (nextCluster.radius - currentCluster.radius) + currentCluster.zCoordinate - nextCluster.zCoordinate)}; - - if ((deltaZ / sigmaZ < trkPars->NSigmaCut && (deltaPhi < phiCut || o2::gpu::GPUCommonMath::Abs(deltaPhi - constants::math::TwoPi) < phiCut))) { - const float phi{o2::gpu::GPUCommonMath::ATan2(currentCluster.yCoordinate - nextCluster.yCoordinate, currentCluster.xCoordinate - nextCluster.xCoordinate)}; - const float tanL{(currentCluster.zCoordinate - nextCluster.zCoordinate) / (currentCluster.radius - nextCluster.radius)}; - const unsigned int stride{currentClusterIndex * maxTrackletsPerCluster}; - if (storedTracklets < maxTrackletsPerCluster) { - new (trackletsRof0 + stride + storedTracklets) Tracklet{currentSortedIndexChunk, nextClusterIndex, tanL, phi, static_cast(rof0), static_cast(rof1)}; - } - // else { - // printf("its-gpu-tracklet-finder: on rof %d layer: %d: found more tracklets (%d) than maximum allowed per cluster. This is lossy!\n", rof0, layerIndex, storedTracklets); - // } - ++storedTracklets; - } - } - } - } - } - } + atomicAdd(&trackletsLookUpTable[tracklets[currentTrackletIndex].firstClusterIndex], 1); } } @@ -803,12 +722,176 @@ GPUg() void removeDuplicateTrackletsEntriesLUTKernel( } // namespace gpu +template +void countTrackletsInROFsHandler(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minRs, + std::vector& maxRs, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads) +{ + for (int iLayer = 0; iLayer < nLayers - 1; ++iLayer) { + gpu::computeLayerTrackletsMultiROFKernel<<>>( + utils, + multMask, + iLayer, + startROF, + endROF, + maxROF, + deltaROF, + vertices, + rofPV, + nVertices, + vertexId, + clusters, + ROFClusters, + usedClusters, + clustersIndexTables, + nullptr, + trackletsLUTs, + iteration, + NSigmaCut, + phiCuts[iLayer], + resolutionPV, + minRs[iLayer + 1], + maxRs[iLayer + 1], + resolutions[iLayer], + radii[iLayer + 1] - radii[iLayer], + mulScatAng[iLayer]); + void* d_temp_storage = nullptr; + size_t temp_storage_bytes = 0; + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + trackletsLUTsHost[iLayer], // d_in + trackletsLUTsHost[iLayer], // d_out + nClusters[iLayer] + 1, // num_items + 0)); // NOLINT: this is the offset of the sum, not a pointer + discardResult(cudaMalloc(&d_temp_storage, temp_storage_bytes)); + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + trackletsLUTsHost[iLayer], // d_in + trackletsLUTsHost[iLayer], // d_out + nClusters[iLayer] + 1, // num_items + 0)); // NOLINT: this is the offset of the sum, not a pointer + gpuCheckError(cudaFree(d_temp_storage)); + } +} + +template +void computeTrackletsInROFsHandler(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + Tracklet** tracklets, + gsl::span spanTracklets, + gsl::span nTracklets, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minRs, + std::vector& maxRs, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads) +{ + for (int iLayer = 0; iLayer < nLayers - 1; ++iLayer) { + gpu::computeLayerTrackletsMultiROFKernel<<>>(utils, + multMask, + iLayer, + startROF, + endROF, + maxROF, + deltaROF, + vertices, + rofPV, + nVertices, + vertexId, + clusters, + ROFClusters, + usedClusters, + clustersIndexTables, + tracklets, + trackletsLUTs, + iteration, + NSigmaCut, + phiCuts[iLayer], + resolutionPV, + minRs[iLayer + 1], + maxRs[iLayer + 1], + resolutions[iLayer], + radii[iLayer + 1] - radii[iLayer], + mulScatAng[iLayer]); + thrust::device_ptr tracklets_ptr(spanTracklets[iLayer]); + thrust::sort(thrust::device, tracklets_ptr, tracklets_ptr + nTracklets[iLayer], gpu::sort_tracklets()); + auto unique_end = thrust::unique(thrust::device, tracklets_ptr, tracklets_ptr + nTracklets[iLayer], gpu::equal_tracklets()); + nTracklets[iLayer] = unique_end - tracklets_ptr; + if (iLayer > 0) { + gpuCheckError(cudaMemset(trackletsLUTsHost[iLayer], 0, nClusters[iLayer] * sizeof(int))); + gpu::compileTrackletsLookupTableKernel<<>>(spanTracklets[iLayer], trackletsLUTsHost[iLayer], nTracklets[iLayer]); + void* d_temp_storage = nullptr; + size_t temp_storage_bytes = 0; + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + trackletsLUTsHost[iLayer], // d_in + trackletsLUTsHost[iLayer], // d_out + nClusters[iLayer] + 1, // num_items + 0)); // NOLINT: this is the offset of the sum, not a pointer + discardResult(cudaMalloc(&d_temp_storage, temp_storage_bytes)); + gpuCheckError(cub::DeviceScan::ExclusiveSum(d_temp_storage, // d_temp_storage + temp_storage_bytes, // temp_storage_bytes + trackletsLUTsHost[iLayer], // d_in + trackletsLUTsHost[iLayer], // d_out + nClusters[iLayer] + 1, // num_items + 0)); // NOLINT: this is the offset of the sum, not a pointer + gpuCheckError(cudaFree(d_temp_storage)); + } + } +} + void countCellsHandler( const Cluster** sortedClusters, const Cluster** unsortedClusters, const TrackingFrameInfo** tfInfo, - const Tracklet** tracklets, - const int** trackletsLUT, + Tracklet** tracklets, + int** trackletsLUT, const int nTracklets, const int layer, CellSeed* cells, @@ -850,7 +933,6 @@ void countCellsHandler( cellsLUTsHost, // d_out nTracklets + 1, // num_items 0)); // NOLINT: this is the offset of the sum, not a pointer - // gpu::printBufferLayerOnThread<<<1, 1>>>(layer, cellsLUTsHost, nTracklets + 1); gpuCheckError(cudaFree(d_temp_storage)); } @@ -858,8 +940,8 @@ void computeCellsHandler( const Cluster** sortedClusters, const Cluster** unsortedClusters, const TrackingFrameInfo** tfInfo, - const Tracklet** tracklets, - const int** trackletsLUT, + Tracklet** tracklets, + int** trackletsLUT, const int nTracklets, const int layer, CellSeed* cells, @@ -963,8 +1045,8 @@ void computeCellNeighboursHandler(CellSeed** cellsLayersDevice, const int nThreads) { - gpu::computeLayerCellNeighboursKernel<<>>( + gpu::computeLayerCellNeighboursKernel<<>>( cellsLayersDevice, neighboursLUT, neighboursIndexTable, @@ -1032,4 +1114,65 @@ void trackSeedHandler(CellSeed* trackSeeds, gpuCheckError(cudaPeekAtLastError()); gpuCheckError(cudaDeviceSynchronize()); } -} // namespace o2::its + +template void countTrackletsInROFsHandler<7>(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minRs, + std::vector& maxRs, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads); + +template void computeTrackletsInROFsHandler<7>(const IndexTableUtils* utils, + const uint8_t* multMask, + const int startROF, + const int endROF, + const int maxROF, + const int deltaROF, + const int vertexId, + const Vertex* vertices, + const int* rofPV, + const int nVertices, + const Cluster** clusters, + std::vector nClusters, + const int** ROFClusters, + const unsigned char** usedClusters, + const int** clustersIndexTables, + Tracklet** tracklets, + gsl::span spanTracklets, + gsl::span nTracklets, + int** trackletsLUTs, + gsl::span trackletsLUTsHost, + const int iteration, + const float NSigmaCut, + std::vector& phiCuts, + const float resolutionPV, + std::vector& minRs, + std::vector& maxRs, + std::vector& resolutions, + std::vector& radii, + std::vector& mulScatAng, + const int nBlocks, + const int nThreads); +} // namespace o2::its \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index 906eb0fa5c21e..fa4f33782d16a 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -106,12 +106,16 @@ class TimeFrame float getBeamX() const; float getBeamY() const; - + std::vector& getMinRs() { return mMinR; } + std::vector& getMaxRs() { return mMaxR; } float getMinR(int layer) const { return mMinR[layer]; } float getMaxR(int layer) const { return mMaxR[layer]; } float getMSangle(int layer) const { return mMSangles[layer]; } + std::vector& getMSangles() { return mMSangles; } float getPhiCut(int layer) const { return mPhiCuts[layer]; } + std::vector& getPhiCuts() { return mPhiCuts; } float getPositionResolution(int layer) const { return mPositionResolution[layer]; } + std::vector& getPositionResolutions() { return mPositionResolution; } gsl::span getClustersOnLayer(int rofId, int layerId); gsl::span getClustersOnLayer(int rofId, int layerId) const; @@ -209,8 +213,8 @@ class TimeFrame const unsigned long long& getRoadLabel(int i) const; bool isRoadFake(int i) const; - void setMultiplicityCutMask(const std::vector& cutMask) { mMultiplicityCutMask = cutMask; } - void setROFMask(const std::vector& rofMask) { mROFMask = rofMask; } + void setMultiplicityCutMask(const std::vector& cutMask) { mMultiplicityCutMask = cutMask; } + void setROFMask(const std::vector& rofMask) { mROFMask = rofMask; } void swapMasks() { mMultiplicityCutMask.swap(mROFMask); } int hasBogusClusters() const { return std::accumulate(mBogusClusters.begin(), mBogusClusters.end(), 0); } @@ -289,6 +293,7 @@ class TimeFrame std::vector> mTracks; std::vector> mCellsNeighbours; std::vector> mCellsLookupTable; + std::vector mMultiplicityCutMask; const o2::base::PropagatorImpl* mPropagatorDevice = nullptr; // Needed only for GPU protected: @@ -311,8 +316,8 @@ class TimeFrame std::vector mPhiCuts; std::vector mPositionResolution; std::vector mClusterSize; - std::vector mMultiplicityCutMask; - std::vector mROFMask; + + std::vector mROFMask; std::vector> mPValphaX; /// PV x and alpha for track propagation std::vector> mTrackletLabels; std::vector> mCellLabels; @@ -439,33 +444,33 @@ inline gsl::span TimeFrame::getClustersPerROFrange(int rofMin, in return gsl::span(); } int startIdx{mROFramesClusters[layerId][rofMin]}; // First cluster of rofMin - int endIdx{mROFramesClusters[layerId][std::min(rofMin + range, mNrof)]}; + int endIdx{mROFramesClusters[layerId][o2::gpu::CAMath::Min(rofMin + range, mNrof)]}; return {&mClusters[layerId][startIdx], static_cast::size_type>(endIdx - startIdx)}; } inline gsl::span TimeFrame::getROFramesClustersPerROFrange(int rofMin, int range, int layerId) const { - int chkdRange{std::min(range, mNrof - rofMin)}; + int chkdRange{o2::gpu::CAMath::Min(range, mNrof - rofMin)}; return {&mROFramesClusters[layerId][rofMin], static_cast::size_type>(chkdRange)}; } inline gsl::span TimeFrame::getNClustersROFrange(int rofMin, int range, int layerId) const { - int chkdRange{std::min(range, mNrof - rofMin)}; + int chkdRange{o2::gpu::CAMath::Min(range, mNrof - rofMin)}; return {&mNClustersPerROF[layerId][rofMin], static_cast::size_type>(chkdRange)}; } inline int TimeFrame::getTotalClustersPerROFrange(int rofMin, int range, int layerId) const { int startIdx{rofMin}; // First cluster of rofMin - int endIdx{std::min(rofMin + range, mNrof)}; + int endIdx{o2::gpu::CAMath::Min(rofMin + range, mNrof)}; return mROFramesClusters[layerId][endIdx] - mROFramesClusters[layerId][startIdx]; } inline gsl::span TimeFrame::getIndexTablePerROFrange(int rofMin, int range, int layerId) const { const int iTableSize{mIndexTableUtils.getNphiBins() * mIndexTableUtils.getNzBins() + 1}; - int chkdRange{std::min(range, mNrof - rofMin)}; + int chkdRange{o2::gpu::CAMath::Min(range, mNrof - rofMin)}; return {&mIndexTables[layerId][rofMin * iTableSize], static_cast::size_type>(chkdRange * iTableSize)}; } diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx index da0abbae9dc1f..409b20ea23235 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackerTraits.cxx @@ -75,9 +75,9 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in for (int rof0{startROF}; rof0 < endROF; ++rof0) { gsl::span primaryVertices = mTrkParams[iteration].UseDiamond ? diamondSpan : tf->getPrimaryVertices(rof0); const int startVtx{iVertex >= 0 ? iVertex : 0}; - const int endVtx{iVertex >= 0 ? std::min(iVertex + 1, static_cast(primaryVertices.size())) : static_cast(primaryVertices.size())}; - int minRof = std::max(startROF, rof0 - mTrkParams[iteration].DeltaROF); - int maxRof = std::min(endROF - 1, rof0 + mTrkParams[iteration].DeltaROF); + const int endVtx{iVertex >= 0 ? o2::gpu::CAMath::Min(iVertex + 1, static_cast(primaryVertices.size())) : static_cast(primaryVertices.size())}; + int minRof = o2::gpu::CAMath::Max(startROF, rof0 - mTrkParams[iteration].DeltaROF); + int maxRof = o2::gpu::CAMath::Min(endROF - 1, rof0 + mTrkParams[iteration].DeltaROF); #pragma omp parallel for num_threads(mNThreads) for (int iLayer = 0; iLayer < mTrkParams[iteration].TrackletsPerRoad(); ++iLayer) { gsl::span layer0 = tf->getClustersOnLayer(rof0, iLayer); @@ -128,7 +128,6 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in if (layer1.empty()) { continue; } - for (int iPhiCount{0}; iPhiCount < phiBinsNum; iPhiCount++) { int iPhiBin = (selectedBinsRect.y + iPhiCount) % mTrkParams[iteration].PhiBins; const int firstBinIndex{tf->mIndexTableUtils.getBinIndex(selectedBinsRect.x, iPhiBin)}; @@ -145,9 +144,7 @@ void TrackerTraits::computeLayerTracklets(const int iteration, int iROFslice, in } const int firstRowClusterIndex = tf->getIndexTable(rof1, iLayer + 1)[firstBinIndex]; const int maxRowClusterIndex = tf->getIndexTable(rof1, iLayer + 1)[maxBinIndex]; - for (int iNextCluster{firstRowClusterIndex}; iNextCluster < maxRowClusterIndex; ++iNextCluster) { - if (iNextCluster >= (int)layer1.size()) { break; } @@ -668,7 +665,7 @@ void TrackerTraits::findRoads(const int iteration) if (rofs[1] != INT_MAX) { track.setNextROFbit(); } - mTimeFrame->getTracks(std::min(rofs[0], rofs[1])).emplace_back(track); + mTimeFrame->getTracks(o2::gpu::CAMath::Min(rofs[0], rofs[1])).emplace_back(track); } } } diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx index f00d87164d7d6..5b8a9bb1cb0f2 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingInterface.cxx @@ -174,7 +174,7 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc) auto errorLogger = [&](std::string s) { LOG(error) << s; }; FastMultEst multEst; // mult estimator - std::vector processingMask, processUPCMask; + std::vector processingMask, processUPCMask; int cutVertexMult{0}, cutUPCVertex{0}, cutRandomMult = int(trackROFvec.size()) - multEst.selectROFs(trackROFvec, compClusters, physTriggers, processingMask); processUPCMask.resize(processingMask.size(), false); mTimeFrame->setMultiplicityCutMask(processingMask); diff --git a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx index 4eaddc8385b8a..e87e2289b49e7 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/Vertexer.cxx @@ -90,7 +90,7 @@ float Vertexer::clustersToVerticesHybrid(std::function logg auto timeVertexingIteration = evaluateTask( &Vertexer::findVerticesHybrid, "Hybrid Vertexer vertex finding", [](std::string) {}, iteration); - printEpilog(logger, true, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), mTimeFrame->getTotVertIteration().size(), timeInit, timeTracklet, timeSelection, timeVertexing); + printEpilog(logger, true, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), mTimeFrame->getTotVertIteration()[iteration], timeInitIteration, timeTrackletIteration, timeSelectionIteration, timeVertexingIteration); timeInit += timeInitIteration; timeTracklet += timeTrackletIteration; timeSelection += timeSelectionIteration; @@ -142,9 +142,9 @@ void Vertexer::printEpilog(std::function logger, const float initT, const float trackletT, const float selecT, const float vertexT) { float total = initT + trackletT + selecT + vertexT; - logger(fmt::format(" - {}Vertexer: found {} | {} tracklets in: {} ms", isHybrid ? "Hybrid" : "", trackletN01, trackletN12, trackletT)); - logger(fmt::format(" - {}Vertexer: selected {} tracklets in: {} ms", isHybrid ? "Hybrid" : "", selectedN, selecT)); - logger(fmt::format(" - {}Vertexer: found {} vertices in: {} ms", isHybrid ? "Hybrid" : "", vertexN, vertexT)); + logger(fmt::format(" - {}Vertexer: found {} | {} tracklets in: {} ms", isHybrid ? "Hybrid " : "", trackletN01, trackletN12, trackletT)); + logger(fmt::format(" - {}Vertexer: selected {} tracklets in: {} ms", isHybrid ? "Hybrid " : "", selectedN, selecT)); + logger(fmt::format(" - {}Vertexer: found {} vertices in: {} ms", isHybrid ? "Hybrid " : "", vertexN, vertexT)); // logger(fmt::format(" - Timeframe {} vertexing completed in: {} ms, using {} thread(s).", mTimeFrameCounter++, total, mTraits->getNThreads())); } diff --git a/Detectors/ITSMFT/ITS/workflow/src/CookedTrackerSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/CookedTrackerSpec.cxx index 01e649f982896..4a0470adcf07a 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/CookedTrackerSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/CookedTrackerSpec.cxx @@ -132,7 +132,7 @@ void CookedTrackerDPL::run(ProcessingContext& pc) const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts FastMultEst multEst; // mult estimator - std::vector processingMask; + std::vector processingMask; int cutVertexMult{0}, cutRandomMult = int(rofsinput.size()) - multEst.selectROFs(rofsinput, compClusters, physTriggers, processingMask); // auto processingMask_ephemeral = processingMask; From 8d75c84b1cd4a56055dc06476a8b258e4bc221b3 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 4 Dec 2024 07:34:47 +0100 Subject: [PATCH 0545/2205] AOD: switch TracksQA from 000 to 001 (#13758) --- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 241 ++++++++---------- .../include/Framework/AnalysisDataModel.h | 2 +- 2 files changed, 112 insertions(+), 131 deletions(-) diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 8a2443b57c7ff..8ee456634c1e1 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -358,47 +358,30 @@ void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracks template void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder) { - if constexpr (std::is_same_v) { // TODO remove remove once version changes - tracksQACursor( - trackQAInfoHolder.trackID, - truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0), - trackQAInfoHolder.tpcdcaR, - trackQAInfoHolder.tpcdcaZ, - trackQAInfoHolder.tpcClusterByteMask, - trackQAInfoHolder.tpcdEdxMax0R, - trackQAInfoHolder.tpcdEdxMax1R, - trackQAInfoHolder.tpcdEdxMax2R, - trackQAInfoHolder.tpcdEdxMax3R, - trackQAInfoHolder.tpcdEdxTot0R, - trackQAInfoHolder.tpcdEdxTot1R, - trackQAInfoHolder.tpcdEdxTot2R, - trackQAInfoHolder.tpcdEdxTot3R, - trackQAInfoHolder.dRefContY, - trackQAInfoHolder.dRefContZ, - trackQAInfoHolder.dRefContSnp, - trackQAInfoHolder.dRefContTgl, - trackQAInfoHolder.dRefContQ2Pt, - trackQAInfoHolder.dRefGloY, - trackQAInfoHolder.dRefGloZ, - trackQAInfoHolder.dRefGloSnp, - trackQAInfoHolder.dRefGloTgl, - trackQAInfoHolder.dRefGloQ2Pt); - } else { - tracksQACursor( - trackQAInfoHolder.trackID, - trackQAInfoHolder.tpcTime0, - trackQAInfoHolder.tpcdcaR, - trackQAInfoHolder.tpcdcaZ, - trackQAInfoHolder.tpcClusterByteMask, - trackQAInfoHolder.tpcdEdxMax0R, - trackQAInfoHolder.tpcdEdxMax1R, - trackQAInfoHolder.tpcdEdxMax2R, - trackQAInfoHolder.tpcdEdxMax3R, - trackQAInfoHolder.tpcdEdxTot0R, - trackQAInfoHolder.tpcdEdxTot1R, - trackQAInfoHolder.tpcdEdxTot2R, - trackQAInfoHolder.tpcdEdxTot3R); - } + tracksQACursor( + trackQAInfoHolder.trackID, + truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0), + trackQAInfoHolder.tpcdcaR, + trackQAInfoHolder.tpcdcaZ, + trackQAInfoHolder.tpcClusterByteMask, + trackQAInfoHolder.tpcdEdxMax0R, + trackQAInfoHolder.tpcdEdxMax1R, + trackQAInfoHolder.tpcdEdxMax2R, + trackQAInfoHolder.tpcdEdxMax3R, + trackQAInfoHolder.tpcdEdxTot0R, + trackQAInfoHolder.tpcdEdxTot1R, + trackQAInfoHolder.tpcdEdxTot2R, + trackQAInfoHolder.tpcdEdxTot3R, + trackQAInfoHolder.dRefContY, + trackQAInfoHolder.dRefContZ, + trackQAInfoHolder.dRefContSnp, + trackQAInfoHolder.dRefContTgl, + trackQAInfoHolder.dRefContQ2Pt, + trackQAInfoHolder.dRefGloY, + trackQAInfoHolder.dRefGloZ, + trackQAInfoHolder.dRefGloSnp, + trackQAInfoHolder.dRefGloTgl, + trackQAInfoHolder.dRefGloQ2Pt); } template @@ -2615,95 +2598,93 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int trackQAHolder.tpcdEdxTot2R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC2 * dEdxNorm); trackQAHolder.tpcdEdxTot3R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC3 * dEdxNorm); - if constexpr (std::is_same_v) { // TODO remove remove once version changes - // Add matching information at a reference point (defined by - // o2::aod::track::trackQARefRadius) in the same frame as the global track - // without material corrections and error propagation - if (auto itsContGID = data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() != GIndex::ITSAB) { - const auto& itsOrig = data.getITSTrack(itsContGID); - o2::track::TrackPar gloCopy = trackPar; - o2::track::TrackPar itsCopy = itsOrig; - o2::track::TrackPar tpcCopy = tpcOrig; - if (prop->propagateToX(gloCopy, o2::aod::track::trackQARefRadius, prop->getNominalBz(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr) && - prop->propagateToAlphaX(tpcCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr) && - prop->propagateToAlphaX(itsCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr)) { - // All tracks are now at the same radius and in the same frame and we can calculate the deltas wrt. to the global track - // The scale is defined by the global track scaling depending on beta0 - const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f)); - const float qpt = gloCopy.getQ2Pt(); - const float x = qpt / beta0; - // scaling is defined as sigmaBins/sqrt(p0^2 + (p1 * q/pt / beta)^2) - auto scaleCont = [&x](int i) -> float { - return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleContP0[i] * o2::aod::track::trackQAScaleContP0[i] + (o2::aod::track::trackQAScaleContP1[i] * x) * (o2::aod::track::trackQAScaleContP1[i] * x)); - }; - auto scaleGlo = [&x](int i) -> float { - return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleGloP0[i] * o2::aod::track::trackQAScaleGloP0[i] + (o2::aod::track::trackQAScaleGloP1[i] * x) * (o2::aod::track::trackQAScaleGloP1[i] * x)); - }; - - // This allows to safely clamp any float to one byte, using the - // minmal/maximum values as under-/overflow borders and rounding to the nearest integer - auto safeInt8Clamp = [](auto value) -> int8_t { - using ValType = decltype(value); - return static_cast(TMath::Nint(std::clamp(value, static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max())))); - }; - - // Calculate deltas for contributors - trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0)); - trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1)); - trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2)); - trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3)); - trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4)); - // Calculate deltas for global track against averaged contributors - trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0)); - trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1)); - trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2)); - trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3)); - trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4)); - - if (O2_ENUM_TEST_BIT(mStreamerMask, AODProducerStreamerMask::TrackQA)) { - (*mStreamer) << "trackQA" - << "trackITSOrig=" << itsOrig - << "trackTPCOrig=" << tpcOrig - << "trackITSTPCOrig=" << trackPar - << "trackITSProp=" << itsCopy - << "trackTPCProp=" << tpcCopy - << "trackITSTPCProp=" << gloCopy - << "refRadius=" << o2::aod::track::trackQARefRadius - << "scaleBins=" << o2::aod::track::trackQAScaleBins - << "scaleCont0=" << scaleCont(0) - << "scaleCont1=" << scaleCont(1) - << "scaleCont2=" << scaleCont(2) - << "scaleCont3=" << scaleCont(3) - << "scaleCont4=" << scaleCont(4) - << "scaleGlo0=" << scaleGlo(0) - << "scaleGlo1=" << scaleGlo(1) - << "scaleGlo2=" << scaleGlo(2) - << "scaleGlo3=" << scaleGlo(3) - << "scaleGlo4=" << scaleGlo(4) - << "trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0 - << "trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR - << "trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ - << "trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask - << "trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R - << "trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R - << "trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R - << "trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R - << "trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R - << "trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R - << "trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R - << "trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R - << "trackQAHolder.dRefContY=" << trackQAHolder.dRefContY - << "trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ - << "trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp - << "trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl - << "trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt - << "trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY - << "trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ - << "trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp - << "trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl - << "trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt - << "\n"; - } + // Add matching information at a reference point (defined by + // o2::aod::track::trackQARefRadius) in the same frame as the global track + // without material corrections and error propagation + if (auto itsContGID = data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() != GIndex::ITSAB) { + const auto& itsOrig = data.getITSTrack(itsContGID); + o2::track::TrackPar gloCopy = trackPar; + o2::track::TrackPar itsCopy = itsOrig; + o2::track::TrackPar tpcCopy = tpcOrig; + if (prop->propagateToX(gloCopy, o2::aod::track::trackQARefRadius, prop->getNominalBz(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr) && + prop->propagateToAlphaX(tpcCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr) && + prop->propagateToAlphaX(itsCopy, gloCopy.getAlpha(), o2::aod::track::trackQARefRadius, false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr)) { + // All tracks are now at the same radius and in the same frame and we can calculate the deltas wrt. to the global track + // The scale is defined by the global track scaling depending on beta0 + const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f)); + const float qpt = gloCopy.getQ2Pt(); + const float x = qpt / beta0; + // scaling is defined as sigmaBins/sqrt(p0^2 + (p1 * q/pt / beta)^2) + auto scaleCont = [&x](int i) -> float { + return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleContP0[i] * o2::aod::track::trackQAScaleContP0[i] + (o2::aod::track::trackQAScaleContP1[i] * x) * (o2::aod::track::trackQAScaleContP1[i] * x)); + }; + auto scaleGlo = [&x](int i) -> float { + return o2::aod::track::trackQAScaleBins / std::sqrt(o2::aod::track::trackQAScaleGloP0[i] * o2::aod::track::trackQAScaleGloP0[i] + (o2::aod::track::trackQAScaleGloP1[i] * x) * (o2::aod::track::trackQAScaleGloP1[i] * x)); + }; + + // This allows to safely clamp any float to one byte, using the + // minmal/maximum values as under-/overflow borders and rounding to the nearest integer + auto safeInt8Clamp = [](auto value) -> int8_t { + using ValType = decltype(value); + return static_cast(TMath::Nint(std::clamp(value, static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max())))); + }; + + // Calculate deltas for contributors + trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0)); + trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1)); + trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2)); + trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3)); + trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4)); + // Calculate deltas for global track against averaged contributors + trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0)); + trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1)); + trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2)); + trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3)); + trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4)); + + if (O2_ENUM_TEST_BIT(mStreamerMask, AODProducerStreamerMask::TrackQA)) { + (*mStreamer) << "trackQA" + << "trackITSOrig=" << itsOrig + << "trackTPCOrig=" << tpcOrig + << "trackITSTPCOrig=" << trackPar + << "trackITSProp=" << itsCopy + << "trackTPCProp=" << tpcCopy + << "trackITSTPCProp=" << gloCopy + << "refRadius=" << o2::aod::track::trackQARefRadius + << "scaleBins=" << o2::aod::track::trackQAScaleBins + << "scaleCont0=" << scaleCont(0) + << "scaleCont1=" << scaleCont(1) + << "scaleCont2=" << scaleCont(2) + << "scaleCont3=" << scaleCont(3) + << "scaleCont4=" << scaleCont(4) + << "scaleGlo0=" << scaleGlo(0) + << "scaleGlo1=" << scaleGlo(1) + << "scaleGlo2=" << scaleGlo(2) + << "scaleGlo3=" << scaleGlo(3) + << "scaleGlo4=" << scaleGlo(4) + << "trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0 + << "trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR + << "trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ + << "trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask + << "trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R + << "trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R + << "trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R + << "trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R + << "trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R + << "trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R + << "trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R + << "trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R + << "trackQAHolder.dRefContY=" << trackQAHolder.dRefContY + << "trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ + << "trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp + << "trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl + << "trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt + << "trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY + << "trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ + << "trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp + << "trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl + << "trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt + << "\n"; } } } diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index e277925ed5603..a50e99fd95968 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -714,7 +714,7 @@ DECLARE_SOA_TABLE_VERSIONED(TracksQA_001, "AOD", "TRACKQA", 1, //! trackQA infor trackqa::IsDummy); -using TracksQAVersion = TracksQA_000; +using TracksQAVersion = TracksQA_001; using TracksQA = TracksQAVersion::iterator; namespace fwdtrack From 7eaa964a5b1a07203d45e7b699c845ca61ff9131 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Wed, 4 Dec 2024 08:32:40 +0100 Subject: [PATCH 0546/2205] DPL Analysis: Table definition rewrite (#13664) --- .../AODProducerWorkflow/AODProducerHelpers.h | 4 +- .../AODProducerWorkflowSpec.h | 2 - Detectors/AOD/src/StandaloneAODProducer.cxx | 6 +- Framework/Core/CMakeLists.txt | 1 + Framework/Core/include/Framework/ASoA.h | 1851 +++++++++-------- .../Core/include/Framework/ASoAHelpers.h | 2 +- .../include/Framework/AnalysisDataModel.h | 79 +- .../Core/include/Framework/AnalysisHelpers.h | 334 +-- .../Core/include/Framework/AnalysisManagers.h | 75 +- .../Core/include/Framework/AnalysisTask.h | 107 +- .../Core/include/Framework/BinningPolicy.h | 8 +- .../Core/include/Framework/Expressions.h | 47 +- .../Core/include/Framework/GroupSlicer.h | 6 +- .../include/Framework/IndexBuilderHelpers.h | 12 +- .../Core/include/Framework/StringHelpers.h | 5 + .../Core/include/Framework/TableBuilder.h | 113 +- Framework/Core/src/AODReaderHelpers.cxx | 94 +- Framework/Core/src/ASoA.cxx | 15 +- Framework/Core/src/AnalysisDataModel.cxx | 14 +- Framework/Core/src/IndexBuilderHelpers.cxx | 4 +- Framework/Core/src/TableBuilder.cxx | 2 +- Framework/Core/src/verifyAODFile.cxx | 2 +- Framework/Core/test/benchmark_ASoA.cxx | 14 +- Framework/Core/test/benchmark_ASoAHelpers.cxx | 20 +- .../Core/test/benchmark_TableBuilder.cxx | 22 +- Framework/Core/test/test_ASoA.cxx | 135 +- Framework/Core/test/test_ASoAHelpers.cxx | 62 +- .../Core/test/test_AnalysisDataModel.cxx | 12 +- Framework/Core/test/test_AnalysisTask.cxx | 96 +- Framework/Core/test/test_Expressions.cxx | 2 +- Framework/Core/test/test_GroupSlicer.cxx | 22 +- .../Core/test/test_HistogramRegistry.cxx | 2 +- Framework/Core/test/test_IndexBuilder.cxx | 43 +- Framework/Core/test/test_Root2ArrowTable.cxx | 1 - Framework/Core/test/test_StaticFor.cxx | 8 +- Framework/Core/test/test_StringHelpers.cxx | 4 +- Framework/Core/test/test_TableBuilder.cxx | 12 +- Framework/Core/test/test_TableSpawner.cxx | 74 + Framework/Core/test/test_TreeToTable.cxx | 1 - Framework/Core/test/test_TypeTraits.cxx | 10 +- Framework/Foundation/include/Framework/Pack.h | 3 +- 41 files changed, 1917 insertions(+), 1409 deletions(-) create mode 100644 Framework/Core/test/test_TableSpawner.cxx diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h index 9ef05096b2fd2..5351504443269 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerHelpers.h @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include namespace o2::aodhelpers @@ -55,7 +53,7 @@ auto createTableCursor(framework::ProcessingContext& pc) framework::Produces c; c.resetCursor(pc.outputs() .make(framework::OutputForTable::ref())); - c.setLabel(o2::aod::MetadataTrait::metadata::tableLabel()); + c.setLabel(aod::label()); return c; } } // namespace o2::aodhelpers diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index d9481917f9a05..eaaf2d9eaedd9 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -21,7 +21,6 @@ #include "DataFormatsTRD/TrackTRD.h" #include "DetectorsBase/GRPGeomHelper.h" #include "DetectorsBase/Propagator.h" -#include "Framework/AnalysisHelpers.h" #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" #include "ReconstructionDataFormats/GlobalTrackID.h" @@ -36,7 +35,6 @@ #include #include #include -#include #include #include using namespace o2::framework; diff --git a/Detectors/AOD/src/StandaloneAODProducer.cxx b/Detectors/AOD/src/StandaloneAODProducer.cxx index a9f5a09141d8c..7ac59a556ac08 100644 --- a/Detectors/AOD/src/StandaloneAODProducer.cxx +++ b/Detectors/AOD/src/StandaloneAODProducer.cxx @@ -94,7 +94,7 @@ void fillMCollisionTable(o2::steer::MCKinematicsReader const& mcreader) TFile outfile("aod.root", "UPDATE"); { - TableToTree t2t(mccoltable, &outfile, aod::MetadataTrait::metadata::tableLabel()); + TableToTree t2t(mccoltable, &outfile, aod::description_str(aod::signature()).data()); t2t.addAllBranches(); t2t.process(); } @@ -200,12 +200,12 @@ void fillCollisionAndTrackTable() f.Close(); TFile outfile("aod.root", "RECREATE"); { - TableToTree t2t(colltable, &outfile, aod::MetadataTrait::metadata::tableLabel()); + TableToTree t2t(colltable, &outfile, aod::description_str(aod::signature()).data()); t2t.addAllBranches(); t2t.process(); } { - TableToTree t2t(tracktable, &outfile, "Tracks" /* aod::MetadataTrait::metadata::tableLabel() */); + TableToTree t2t(tracktable, &outfile, aod::description_str(aod::signature()).data()); t2t.addAllBranches(); t2t.process(); } diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index 02367afdcc556..5cdd1241ecfb0 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -236,6 +236,7 @@ add_executable(o2-test-framework-core test/test_Services.cxx test/test_StringHelpers.cxx test/test_StaticFor.cxx + test/test_TableSpawner.cxx test/test_TMessageSerializer.cxx test/test_TableBuilder.cxx test/test_TimeParallelPipelining.cxx diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 34d18476e483d..25e64daefeba7 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -15,6 +15,7 @@ #include "Framework/Pack.h" #include "Framework/FunctionalHelpers.h" #include "Headers/DataHeader.h" +#include "Headers/DataHeaderHelpers.h" #include "Framework/CompilerBuiltins.h" #include "Framework/Traits.h" #include "Framework/Expressions.h" @@ -26,152 +27,362 @@ #include #include #include +#include #include #include #include #include -#define DECLARE_SOA_METADATA() \ - template \ - struct MetadataTrait { \ - using metadata = std::void_t; \ - }; - -#define DECLARE_SOA_ITERATOR_METADATA() \ - template \ - requires(o2::soa::is_iterator) \ - struct MetadataTrait { \ - using metadata = typename MetadataTrait::metadata; \ - }; - namespace o2::framework { using ListVector = std::vector>; std::string cutString(std::string&& str); +std::string strToUpper(std::string&& str); +} // namespace o2::framework -struct OriginEnc { - static constexpr size_t size = 4; - uint32_t value; - consteval OriginEnc(uint32_t v) : value{v} - { - } - consteval OriginEnc(std::string_view in) : value{0} +namespace o2::soa +{ +void accessingInvalidIndexFor(const char* getter); +void dereferenceWithWrongType(); +void missingFilterDeclaration(int hash, int ai); +void notBoundTable(const char* tableName); +} // namespace o2::soa + +namespace o2::soa +{ +/// Generic identifier for a table type +struct TableRef { + consteval TableRef() + : label_hash{0}, + desc_hash{0}, + origin_hash{0}, + version{0} { - for (auto i = 0U; i < (size < in.size() ? size : in.size()); ++i) { - value |= ((uint8_t)in[i]) << (8 * i); - } } - operator const char*() const + consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version) + : label_hash{_label}, + desc_hash{_desc}, + origin_hash{_origin}, + version{_version} { - return (const char*)(&value); } + uint32_t label_hash; + uint32_t desc_hash; + uint32_t origin_hash; + uint32_t version; - consteval operator o2::header::DataOrigin() + constexpr bool operator==(TableRef const& other) const noexcept { - return o2::header::DataOrigin{value}; + return (this->label_hash == other.label_hash) && + (this->desc_hash == other.desc_hash) && + (this->origin_hash == other.origin_hash) && + (this->version == other.version); } - consteval OriginEnc(OriginEnc const& other) = default; - consteval OriginEnc(OriginEnc&& other) noexcept = default; - consteval OriginEnc& operator=(OriginEnc const& other) = default; - consteval OriginEnc& operator=(OriginEnc&& other) noexcept = default; -}; -} // namespace o2::framework - -template <> -struct fmt::formatter { - char presentation = 's'; - constexpr auto parse(format_parse_context& ctx) + constexpr bool descriptionCompatible(TableRef const& other) const noexcept { - auto it = ctx.begin(), end = ctx.end(); - if (it != end && (*it == 's')) { - presentation = *it++; - } - - // Check if reached the end of the range: - if (it != end && *it != '}') { - throw format_error("invalid pick format"); - } - - // Return an iterator past the end of the parsed range: - return it; + return this->desc_hash == other.desc_hash; } - template - auto format(o2::framework::OriginEnc const& origin, FormatContext& ctx) + constexpr bool descriptionCompatible(uint32_t _desc_hash) const noexcept { - return fmt::format_to(ctx.out(), "{}", (std::string_view)origin); + return this->desc_hash == _desc_hash; } + + constexpr TableRef(TableRef const&) = default; + constexpr TableRef& operator=(TableRef const&) = default; + constexpr TableRef(TableRef&&) = default; + constexpr TableRef& operator=(TableRef&&) = default; }; -namespace o2::aod +/// Helpers to manipulate TableRef arrays +template ar1, std::array ar2> +consteval auto merge() { -DECLARE_SOA_METADATA(); + constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](TableRef const& a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); }); + std::array out; + + auto pos = std::copy(ar1.begin(), ar1.end(), out.begin()); + std::copy_if(ar2.begin(), ar2.end(), pos, [&](TableRef const& a) { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); }); + return out; } -namespace o2::soa +template ar1, std::array ar2, typename L> +consteval auto merge_if(L l) { -/// special case for the template with origin -template class Ref> -struct is_specialization_origin : std::false_type { -}; + constexpr const int to_remove = std::ranges::count_if(ar1.begin(), ar1.end(), [&](TableRef const& a) { return !l(a); }); + constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](TableRef const& a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) || !l(a); }); + std::array out; -template